📄 timidity.c
字号:
static inline int parse_opt_Z1(const char *);static inline int parse_opt_default_module(const char *);__attribute__((noreturn))static inline int parse_opt_fail(const char *);static inline int set_value(int *, int, int, int, char *);static inline int set_val_i32(int32 *, int32, int32, int32, char *);static inline int set_channel_flag(ChannelBitMask *, int32, char *);static inline int y_or_n_p(const char *);static inline int set_flag(int32 *, int32, const char *);static inline FILE *open_pager(void);static inline void close_pager(FILE *);static void interesting_message(void);#ifdef IA_DYNAMICMAIN_INTERFACE char dynamic_interface_id;#endif /* IA_DYNAMIC */extern StringTable wrd_read_opts;extern int SecondMode;extern struct URL_module URL_module_file;#ifndef __MACOS__extern struct URL_module URL_module_dir;#endif /* __MACOS__ */#ifdef SUPPORT_SOCKETextern struct URL_module URL_module_http;extern struct URL_module URL_module_ftp;extern struct URL_module URL_module_news;extern struct URL_module URL_module_newsgroup;#endif /* SUPPORT_SOCKET */#ifdef HAVE_POPENextern struct URL_module URL_module_pipe;#endif /* HAVE_POPEN */MAIN_INTERFACE struct URL_module *url_module_list[] ={ &URL_module_file,#ifndef __MACOS__ &URL_module_dir,#endif /* __MACOS__ */#ifdef SUPPORT_SOCKET &URL_module_http, &URL_module_ftp, &URL_module_news, &URL_module_newsgroup,#endif /* SUPPORT_SOCKET */#if !defined(__MACOS__) && defined(HAVE_POPEN) &URL_module_pipe,#endif#if defined(main) || defined(ANOTHER_MAIN) /* You can put some other modules */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,#endif /* main */ NULL};#ifdef IA_DYNAMIC#include "dlutils.h"#ifndef SHARED_LIB_PATH#define SHARED_LIB_PATH PKGLIBDIR#endif /* SHARED_LIB_PATH */static char *dynamic_lib_root = SHARED_LIB_PATH;#endif /* IA_DYNAMIC */#ifndef MAXPATHLEN#define MAXPATHLEN 1024#endif /* MAXPATHLEN */int free_instruments_afterwards=0;int def_prog = -1;char def_instr_name[256]="";VOLATILE int intr = 0;#ifdef __W32__CRITICAL_SECTION critSect;#pragma argsusedstatic BOOL WINAPI handler(DWORD dw){#if defined(IA_WINSYN) || defined(IA_PORTMIDISYN) if( ctl->id_character == 'W' || ctl->id_character == 'P' ) { rtsyn_midiports_close(); }#endif printf ("***BREAK" NLS); fflush(stdout); intr++; return TRUE;}#endifint effect_lr_mode = -1;/* 0: left delay * 1: right delay * 2: rotate * -1: not use */int effect_lr_delay_msec = 25;extern char* pcm_alternate_file;/* NULL, "none": disabled (default) * "auto": automatically selected * filename: use the one. */#ifndef atofextern double atof(const char *);#endif/*! copy bank and, if necessary, map appropriately */static void copybank(ToneBank *to, ToneBank *from, int mapid, int bankmapfrom, int bankno){ ToneBankElement *toelm, *fromelm; int i; if (from == NULL) return; for(i = 0; i < 128; i++) { toelm = &to->tone[i]; fromelm = &from->tone[i]; if (fromelm->name == NULL) continue; copy_tone_bank_element(toelm, fromelm); toelm->instrument = NULL; if (mapid != INST_NO_MAP) set_instrument_map(mapid, bankmapfrom, i, bankno, i); }}/*! copy the whole mapped bank. returns 0 if no error. */static int copymap(int mapto, int mapfrom, int isdrum){ ToneBank **tb = isdrum ? drumset : tonebank; int i, bankfrom, bankto; for(i = 0; i < 128; i++) { bankfrom = find_instrument_map_bank(isdrum, mapfrom, i); if (bankfrom <= 0) /* not mapped */ continue; bankto = alloc_instrument_map_bank(isdrum, mapto, i); if (bankto == -1) /* failed */ return 1; copybank(tb[bankto], tb[bankfrom], mapto, i, bankto); } return 0;}static float *config_parse_tune(const char *cp, int *num){ const char *p; float *tune_list; int i; /* count num */ *num = 1, p = cp; while ((p = strchr(p, ',')) != NULL) (*num)++, p++; /* alloc */ tune_list = (float *) safe_malloc((*num) * sizeof(float)); /* regist */ for (i = 0, p = cp; i < *num; i++, p++) { tune_list[i] = atof(p); if (! (p = strchr(p, ','))) break; } return tune_list;}static int16 *config_parse_int16(const char *cp, int *num){ const char *p; int16 *list; int i; /* count num */ *num = 1, p = cp; while ((p = strchr(p, ',')) != NULL) (*num)++, p++; /* alloc */ list = (int16 *) safe_malloc((*num) * sizeof(int16)); /* regist */ for (i = 0, p = cp; i < *num; i++, p++) { list[i] = atoi(p); if (! (p = strchr(p, ','))) break; } return list;}static int **config_parse_envelope(const char *cp, int *num){ const char *p, *px; int **env_list; int i, j; /* count num */ *num = 1, p = cp; while ((p = strchr(p, ',')) != NULL) (*num)++, p++; /* alloc */ env_list = (int **) safe_malloc((*num) * sizeof(int *)); for (i = 0; i < *num; i++) env_list[i] = (int *) safe_malloc(6 * sizeof(int)); /* init */ for (i = 0; i < *num; i++) for (j = 0; j < 6; j++) env_list[i][j] = -1; /* regist */ for (i = 0, p = cp; i < *num; i++, p++) { px = strchr(p, ','); for (j = 0; j < 6; j++, p++) { if (*p == ':') continue; env_list[i][j] = atoi(p); if (! (p = strchr(p, ':'))) break; if (px && p > px) break; } if (! (p = px)) break; } return env_list;}static Quantity **config_parse_modulation(const char *name, int line, const char *cp, int *num, int mod_type){ const char *p, *px, *err; char buf[128], *delim; Quantity **mod_list; int i, j; static const char * qtypestr[] = {"tremolo", "vibrato"}; static const uint16 qtypes[] = { QUANTITY_UNIT_TYPE(TREMOLO_SWEEP), QUANTITY_UNIT_TYPE(TREMOLO_RATE), QUANTITY_UNIT_TYPE(DIRECT_INT), QUANTITY_UNIT_TYPE(VIBRATO_SWEEP), QUANTITY_UNIT_TYPE(VIBRATO_RATE), QUANTITY_UNIT_TYPE(DIRECT_INT) }; /* count num */ *num = 1, p = cp; while ((p = strchr(p, ',')) != NULL) (*num)++, p++; /* alloc */ mod_list = (Quantity **) safe_malloc((*num) * sizeof(Quantity *)); for (i = 0; i < *num; i++) mod_list[i] = (Quantity *) safe_malloc(3 * sizeof(Quantity)); /* init */ for (i = 0; i < *num; i++) for (j = 0; j < 3; j++) INIT_QUANTITY(mod_list[i][j]); buf[sizeof buf - 1] = '\0'; /* regist */ for (i = 0, p = cp; i < *num; i++, p++) { px = strchr(p, ','); for (j = 0; j < 3; j++, p++) { if (*p == ':') continue; if ((delim = strpbrk(strncpy(buf, p, sizeof buf - 1), ":,")) != NULL) *delim = '\0'; if (*buf != '\0' && (err = string_to_quantity(buf, &mod_list[i][j], qtypes[mod_type * 3 + j])) != NULL) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: line %d: %s: parameter %d of item %d: %s (%s)", name, line, qtypestr[mod_type], j+1, i+1, err, buf); free_ptr_list(mod_list, *num); mod_list = NULL; *num = 0; return NULL; } if (! (p = strchr(p, ':'))) break; if (px && p > px) break; } if (! (p = px)) break; } return mod_list;}static int set_gus_patchconf_opts(char *name, int line, char *opts, ToneBankElement *tone){ char *cp; int k; if (! (cp = strchr(opts, '='))) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: line %d: bad patch option %s", name, line, opts); return 1; } *cp++ = 0; if (! strcmp(opts, "amp")) { k = atoi(cp); if ((k < 0 || k > MAX_AMPLIFICATION) || (*cp < '0' || *cp > '9')) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: line %d: amplification must be between 0 and %d", name, line, MAX_AMPLIFICATION); return 1; } tone->amp = k; } else if (! strcmp(opts, "note")) { k = atoi(cp); if ((k < 0 || k > 127) || (*cp < '0' || *cp > '9')) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: line %d: note must be between 0 and 127", name, line); return 1; } tone->note = k; tone->scltune = config_parse_int16("100", &tone->scltunenum); } else if (! strcmp(opts, "pan")) { if (! strcmp(cp, "center")) k = 64; else if (! strcmp(cp, "left")) k = 0; else if (! strcmp(cp, "right")) k = 127; else { k = ((atoi(cp) + 100) * 100) / 157; if ((k < 0 || k > 127) || (k == 0 && *cp != '-' && (*cp < '0' || *cp > '9'))) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: line %d: panning must be left, right, " "center, or between -100 and 100", name, line); return 1; } } tone->pan = k; } else if (! strcmp(opts, "tune")) tone->tune = config_parse_tune(cp, &tone->tunenum); else if (! strcmp(opts, "rate")) tone->envrate = config_parse_envelope(cp, &tone->envratenum); else if (! strcmp(opts, "offset")) tone->envofs = config_parse_envelope(cp, &tone->envofsnum); else if (! strcmp(opts, "keep")) { if (! strcmp(cp, "env")) tone->strip_envelope = 0; else if (! strcmp(cp, "loop")) tone->strip_loop = 0; else { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: line %d: keep must be env or loop", name, line); return 1; } } else if (! strcmp(opts, "strip")) { if (! strcmp(cp, "env")) tone->strip_envelope = 1; else if (! strcmp(cp, "loop")) tone->strip_loop = 1; else if (! strcmp(cp, "tail")) tone->strip_tail = 1; else { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: line %d: strip must be env, loop, or tail", name, line); return 1; } } else if (! strcmp(opts, "tremolo")) { if ((tone->trem = config_parse_modulation(name, line, cp, &tone->tremnum, 0)) == NULL) return 1; } else if (! strcmp(opts, "vibrato")) { if ((tone->vib = config_parse_modulation(name, line, cp, &tone->vibnum, 1)) == NULL) return 1; } else if (! strcmp(opts, "sclnote")) tone->sclnote = config_parse_int16(cp, &tone->sclnotenum); else if (! strcmp(opts, "scltune")) tone->scltune = config_parse_int16(cp, &tone->scltunenum); else if (! strcmp(opts, "comm")) { char *p; if (tone->comment) free(tone->comment); p = tone->comment = safe_strdup(cp); while (*p) { if (*p == ',') *p = ' '; p++; } } else if (! strcmp(opts, "modrate")) tone->modenvrate = config_parse_envelope(cp, &tone->modenvratenum); else if (! strcmp(opts, "modoffset")) tone->modenvofs = config_parse_envelope(cp, &tone->modenvofsnum); else if (! strcmp(opts, "envkeyf")) tone->envkeyf = config_parse_envelope(cp, &tone->envkeyfnum); else if (! strcmp(opts, "envvelf")) tone->envvelf = config_parse_envelope(cp, &tone->envvelfnum); else if (! strcmp(opts, "modkeyf")) tone->modenvkeyf = config_parse_envelope(cp, &tone->modenvkeyfnum); else if (! strcmp(opts, "modvelf")) tone->modenvvelf = config_parse_envelope(cp, &tone->modenvvelfnum); else if (! strcmp(opts, "trempitch")) tone->trempitch = config_parse_int16(cp, &tone->trempitchnum); else if (! strcmp(opts, "tremfc")) tone->tremfc = config_parse_int16(cp, &tone->tremfcnum); else if (! strcmp(opts, "modpitch")) tone->modpitch = config_parse_int16(cp, &tone->modpitchnum); else if (! strcmp(opts, "modfc")) tone->modfc = config_parse_int16(cp, &tone->modfcnum); else if (! strcmp(opts, "fc")) tone->fc = config_parse_int16(cp, &tone->fcnum); else if (! strcmp(opts, "q")) tone->reso = config_parse_int16(cp, &tone->resonum); else if (! strcmp(opts, "fckeyf")) /* filter key-follow */ tone->key_to_fc = atoi(cp); else if (! strcmp(opts, "fcvelf")) /* filter velocity-follow */ tone->vel_to_fc = atoi(cp); else if (! strcmp(opts, "qvelf")) /* resonance velocity-follow */ tone->vel_to_resonance = atoi(cp); else { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: line %d: bad patch option %s", name, line, opts); return 1; } return 0;}static void reinit_tone_bank_element(ToneBankElement *tone){ free_tone_bank_element(tone); tone->note = tone->pan = -1; tone->strip_loop = tone->strip_envelope = tone->strip_tail = -1; tone->amp = -1; tone->rnddelay = 0; tone->loop_timeout = 0; tone->legato = tone->damper_mode = tone->key_to_fc = tone->vel_to_fc = 0; tone->reverb_send = tone->chorus_send = tone->delay_send = -1; tone->tva_level = -1; tone->play_note = -1;}#define SET_GUS_PATCHCONF_COMMENTstatic int set_gus_patchconf(char *name, int line, ToneBankElement *tone, char *pat, char **opts){ int j;#ifdef SET_GUS_PATCHCONF_COMMENT char *old_name = NULL; if(tone != NULL && tone->name != NULL) old_name = safe_strdup(tone->name);#endif reinit_tone_bank_element(tone); if(strcmp(pat, "%font") == 0) /* Font extention */ { /* %font filename bank prog [note-to-use] * %font filename 128 bank key */ if(opts[0] == NULL || opts[1] == NULL || opts[2] == NULL || (atoi(opts[1]) == 128 && opts[3] == NULL)) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: line %d: Syntax error", name, line); return 1; } tone->name = safe_strdup(opts[0]); tone->instype = 1; if(atoi(opts[1]) == 128) /* drum */ { tone->font_bank = 128; tone->font_preset = atoi(opts[2]); tone->font_keynote = atoi(opts[3]); opts += 4; } else { tone->font_bank = atoi(opts[1]); tone->font_preset = atoi(opts[2]); if(opts[3] && isdigit(opts[3][0])) { tone->font_keynote = atoi(opts[3]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -