2 TiMidity++ -- MIDI to WAVE converter and player
3 Copyright (C) 1999-2004 Masanao Izumo <iz@onicos.co.jp>
4 Copyright (C) 1995 Tuukka Toivonen <tt@cgs.fi>
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #endif /* HAVE_CONFIG_H */
42 #endif /* HAVE_UNISTD_H */
43 #include <fcntl.h> /* for open */
49 #ifndef __bool_true_false_are_defined
60 # define false ((bool)0)
61 # define true (!false)
62 # define __bool_true_false_are_defined true
63 #endif /* C99 _Bool hack */
65 #ifdef BORLANDC_EXCEPTION
67 #endif /* BORLANDC_EXCEPTION */
70 #if defined(__FreeBSD__) && !defined(__alpha__)
71 #include <floatingpoint.h> /* For FP exceptions */
73 #if defined(__NetBSD__) || defined(__OpenBSD__)
74 #include <ieeefp.h> /* For FP exceptions */
77 #include "interface.h"
79 #include "utils/tmdy_getopt.h"
87 #include "miditrace.h"
89 #ifdef SUPPORT_SOUNDSPEC
90 #include "soundspec.h"
91 #endif /* SUPPORT_SOUNDSPEC */
97 #define DEFINE_GLOBALS
102 #include "quantity.h"
106 #include "w32g_utl.h"
110 #define __attribute__(x) /* ignore */
117 TIM_OPT_VOLUME = TIM_OPT_FIRST,
121 TIM_OPT_BUFFER_FRAGS,
122 TIM_OPT_CONTROL_RATIO,
124 TIM_OPT_DRUM_CHANNEL,
137 TIM_OPT_DEFAULT_BANK,
163 TIM_OPT_REALTIME_LOAD,
169 TIM_OPT_INTERPOLATION,
171 TIM_OPT_OUTPUT_STEREO,
172 TIM_OPT_OUTPUT_SIGNED,
173 TIM_OPT_OUTPUT_BITWIDTH,
174 TIM_OPT_OUTPUT_FORMAT,
182 TIM_OPT_AUDIO_BUFFER,
185 TIM_OPT_ADJUST_TEMPO,
188 TIM_OPT_VOLUME_CURVE,
197 TIM_OPT_LAST = TIM_OPT_PURE_INT
200 static const char *optcommands =
201 "4A:aB:b:C:c:D:d:E:eFfg:H:hI:i:jK:k:L:M:m:N:"
202 "O:o:P:p:Q:q:R:S:s:T:t:UV:vW:"
206 "x:Z:"; /* Only GJlnruXYyz are remain... */
207 static const struct option longopts[] = {
208 { "volume", required_argument, NULL, TIM_OPT_VOLUME },
209 { "drum-power", required_argument, NULL, TIM_OPT_DRUM_POWER },
210 { "no-volume-compensation", no_argument, NULL, TIM_OPT_DRUM_POWER },
211 { "volume-compensation", optional_argument, NULL, TIM_OPT_VOLUME_COMP },
212 { "no-anti-alias", no_argument, NULL, TIM_OPT_ANTI_ALIAS },
213 { "anti-alias", optional_argument, NULL, TIM_OPT_ANTI_ALIAS },
214 { "buffer-fragments", required_argument, NULL, TIM_OPT_BUFFER_FRAGS },
215 { "control-ratio", required_argument, NULL, TIM_OPT_CONTROL_RATIO },
216 { "config-file", required_argument, NULL, TIM_OPT_CONFIG_FILE },
217 { "drum-channel", required_argument, NULL, TIM_OPT_DRUM_CHANNEL },
218 { "interface-path", required_argument, NULL, TIM_OPT_IFACE_PATH },
219 { "ext", required_argument, NULL, TIM_OPT_EXT },
220 { "no-mod-wheel", no_argument, NULL, TIM_OPT_MOD_WHEEL },
221 { "mod-wheel", optional_argument, NULL, TIM_OPT_MOD_WHEEL },
222 { "no-portamento", no_argument, NULL, TIM_OPT_PORTAMENTO },
223 { "portamento", optional_argument, NULL, TIM_OPT_PORTAMENTO },
224 { "no-vibrato", no_argument, NULL, TIM_OPT_VIBRATO },
225 { "vibrato", optional_argument, NULL, TIM_OPT_VIBRATO },
226 { "no-ch-pressure", no_argument, NULL, TIM_OPT_CH_PRESS },
227 { "ch-pressure", optional_argument, NULL, TIM_OPT_CH_PRESS },
228 { "no-mod-envelope", no_argument, NULL, TIM_OPT_MOD_ENV },
229 { "mod-envelope", optional_argument, NULL, TIM_OPT_MOD_ENV },
230 { "no-trace-text-meta", no_argument, NULL, TIM_OPT_TRACE_TEXT },
231 { "trace-text-meta", optional_argument, NULL, TIM_OPT_TRACE_TEXT },
232 { "no-overlap-voice", no_argument, NULL, TIM_OPT_OVERLAP },
233 { "overlap-voice", optional_argument, NULL, TIM_OPT_OVERLAP },
234 { "no-temper-control", no_argument, NULL, TIM_OPT_TEMPER_CTRL },
235 { "temper-control", optional_argument, NULL, TIM_OPT_TEMPER_CTRL },
236 { "default-mid", required_argument, NULL, TIM_OPT_DEFAULT_MID },
237 { "system-mid", required_argument, NULL, TIM_OPT_SYSTEM_MID },
238 { "default-bank", required_argument, NULL, TIM_OPT_DEFAULT_BANK },
239 { "force-bank", required_argument, NULL, TIM_OPT_FORCE_BANK },
240 { "default-program", required_argument, NULL, TIM_OPT_DEFAULT_PGM },
241 { "force-program", required_argument, NULL, TIM_OPT_FORCE_PGM },
242 { "delay", required_argument, NULL, TIM_OPT_DELAY },
243 { "chorus", required_argument, NULL, TIM_OPT_CHORUS },
244 { "reverb", required_argument, NULL, TIM_OPT_REVERB },
245 { "voice-lpf", required_argument, NULL, TIM_OPT_VOICE_LPF },
246 { "noise-shaping", required_argument, NULL, TIM_OPT_NS },
247 #ifndef FIXED_RESAMPLATION
248 { "resample", required_argument, NULL, TIM_OPT_RESAMPLE },
250 { "evil", required_argument, NULL, TIM_OPT_EVIL },
251 { "no-fast-panning", no_argument, NULL, TIM_OPT_FAST_PAN },
252 { "fast-panning", optional_argument, NULL, TIM_OPT_FAST_PAN },
253 { "no-fast-decay", no_argument, NULL, TIM_OPT_FAST_DECAY },
254 { "fast-decay", optional_argument, NULL, TIM_OPT_FAST_DECAY },
255 { "spectrogram", required_argument, NULL, TIM_OPT_SPECTROGRAM },
256 { "force-keysig", required_argument, NULL, TIM_OPT_KEYSIG },
257 { "help", optional_argument, NULL, TIM_OPT_HELP },
258 { "interface", required_argument, NULL, TIM_OPT_INTERFACE },
259 { "verbose", optional_argument, NULL, TIM_OPT_VERBOSE },
260 { "quiet", optional_argument, NULL, TIM_OPT_QUIET },
261 { "no-trace", no_argument, NULL, TIM_OPT_TRACE },
262 { "trace", optional_argument, NULL, TIM_OPT_TRACE },
263 { "no-loop", no_argument, NULL, TIM_OPT_LOOP },
264 { "loop", optional_argument, NULL, TIM_OPT_LOOP },
265 { "no-random", no_argument, NULL, TIM_OPT_RANDOM },
266 { "random", optional_argument, NULL, TIM_OPT_RANDOM },
267 { "no-sort", no_argument, NULL, TIM_OPT_SORT },
268 { "sort", optional_argument, NULL, TIM_OPT_SORT },
270 { "no-background", no_argument, NULL, TIM_OPT_BACKGROUND },
271 { "background", optional_argument, NULL, TIM_OPT_BACKGROUND },
272 { "realtime-priority", required_argument, NULL, TIM_OPT_RT_PRIO },
273 { "sequencer-ports", required_argument, NULL, TIM_OPT_SEQ_PORTS },
275 { "no-realtime-load", no_argument, NULL, TIM_OPT_REALTIME_LOAD },
276 { "realtime-load", optional_argument, NULL, TIM_OPT_REALTIME_LOAD },
277 { "adjust-key", required_argument, NULL, TIM_OPT_ADJUST_KEY },
278 { "voice-queue", required_argument, NULL, TIM_OPT_VOICE_QUEUE },
279 { "patch-path", required_argument, NULL, TIM_OPT_PATCH_PATH },
280 { "pcm-file", required_argument, NULL, TIM_OPT_PCM_FILE },
281 { "decay-time", required_argument, NULL, TIM_OPT_DECAY_TIME },
282 { "interpolation", required_argument, NULL, TIM_OPT_INTERPOLATION },
283 { "output-mode", required_argument, NULL, TIM_OPT_OUTPUT_MODE },
284 { "output-stereo", no_argument, NULL, TIM_OPT_OUTPUT_STEREO },
285 { "output-mono", no_argument, NULL, TIM_OPT_OUTPUT_STEREO },
286 { "output-signed", no_argument, NULL, TIM_OPT_OUTPUT_SIGNED },
287 { "output-unsigned", no_argument, NULL, TIM_OPT_OUTPUT_SIGNED },
288 { "output-16bit", no_argument, NULL, TIM_OPT_OUTPUT_BITWIDTH },
289 { "output-24bit", no_argument, NULL, TIM_OPT_OUTPUT_BITWIDTH },
290 { "output-8bit", no_argument, NULL, TIM_OPT_OUTPUT_BITWIDTH },
291 { "output-linear", no_argument, NULL, TIM_OPT_OUTPUT_FORMAT },
292 { "output-ulaw", no_argument, NULL, TIM_OPT_OUTPUT_FORMAT },
293 { "output-alaw", no_argument, NULL, TIM_OPT_OUTPUT_FORMAT },
294 { "no-output-swab", no_argument, NULL, TIM_OPT_OUTPUT_SWAB },
295 { "output-swab", optional_argument, NULL, TIM_OPT_OUTPUT_SWAB },
296 { "output-file", required_argument, NULL, TIM_OPT_OUTPUT_FILE },
297 { "patch-file", required_argument, NULL, TIM_OPT_PATCH_FILE },
298 { "polyphony", required_argument, NULL, TIM_OPT_POLYPHONY },
299 { "no-polyphony-reduction", no_argument, NULL, TIM_OPT_POLY_REDUCE },
300 { "polyphony-reduction", optional_argument, NULL, TIM_OPT_POLY_REDUCE },
301 { "mute", required_argument, NULL, TIM_OPT_MUTE },
302 { "temper-mute", required_argument, NULL, TIM_OPT_TEMPER_MUTE },
303 { "audio-buffer", required_argument, NULL, TIM_OPT_AUDIO_BUFFER },
304 { "cache-size", required_argument, NULL, TIM_OPT_CACHE_SIZE },
305 { "sampling-freq", required_argument, NULL, TIM_OPT_SAMPLE_FREQ },
306 { "adjust-tempo", required_argument, NULL, TIM_OPT_ADJUST_TEMPO },
307 { "output-charset", required_argument, NULL, TIM_OPT_CHARSET },
308 { "no-unload-instruments", no_argument, NULL, TIM_OPT_UNLOAD_INST },
309 { "unload-instruments", optional_argument, NULL, TIM_OPT_UNLOAD_INST },
310 { "volume-curve", required_argument, NULL, TIM_OPT_VOLUME_CURVE },
311 { "version", no_argument, NULL, TIM_OPT_VERSION },
312 { "wrd", required_argument, NULL, TIM_OPT_WRD },
314 { "rcpcv-dll", required_argument, NULL, TIM_OPT_RCPCV_DLL },
316 { "config-string", required_argument, NULL, TIM_OPT_CONFIG_STR },
317 { "freq-table", required_argument, NULL, TIM_OPT_FREQ_TABLE },
318 { "pure-intonation", optional_argument, NULL, TIM_OPT_PURE_INT },
319 { "module", required_argument, NULL, TIM_OPT_MODULE },
320 { NULL, no_argument, NULL, '\0' }
322 #define INTERACTIVE_INTERFACE_IDS "kmqagrwAWP"
324 /* main interfaces (To be used another main) */
325 #if defined(main) || defined(ANOTHER_MAIN)
326 #define MAIN_INTERFACE
328 #define MAIN_INTERFACE static
331 MAIN_INTERFACE void timidity_start_initialize(void);
332 MAIN_INTERFACE int timidity_pre_load_configuration(void);
333 MAIN_INTERFACE int timidity_post_load_configuration(void);
334 MAIN_INTERFACE void timidity_init_player(void);
335 MAIN_INTERFACE int timidity_play_main(int nfiles, char **files);
336 MAIN_INTERFACE int got_a_configuration;
337 char *wrdt_open_opts = NULL;
338 char *opt_aq_max_buff = NULL,
339 *opt_aq_fill_buff = NULL;
340 void timidity_init_aq_buff(void);
341 int opt_control_ratio = 0; /* Save -C option */
343 int set_extension_modes(char *);
345 int set_play_mode(char *);
347 MAIN_INTERFACE int set_tim_opt_short(int, char *);
348 MAIN_INTERFACE int set_tim_opt_long(int, char *, int);
349 static inline int parse_opt_A(const char *);
350 static inline int parse_opt_drum_power(const char *);
351 static inline int parse_opt_volume_comp(const char *);
352 static inline int parse_opt_a(const char *);
353 static inline int parse_opt_B(const char *);
354 static inline int parse_opt_C(const char *);
355 static inline int parse_opt_c(char *);
356 static inline int parse_opt_D(const char *);
357 static inline int parse_opt_d(const char *);
358 static inline int parse_opt_E(char *);
359 static inline int parse_opt_mod_wheel(const char *);
360 static inline int parse_opt_portamento(const char *);
361 static inline int parse_opt_vibrato(const char *);
362 static inline int parse_opt_ch_pressure(const char *);
363 static inline int parse_opt_mod_env(const char *);
364 static inline int parse_opt_trace_text(const char *);
365 static inline int parse_opt_overlap_voice(const char *);
366 static inline int parse_opt_temper_control(const char *);
367 static inline int parse_opt_default_mid(char *);
368 static inline int parse_opt_system_mid(char *);
369 static inline int parse_opt_default_bank(const char *);
370 static inline int parse_opt_force_bank(const char *);
371 static inline int parse_opt_default_program(const char *);
372 static inline int parse_opt_force_program(const char *);
373 static inline int set_default_program(int);
374 static inline int parse_opt_delay(const char *);
375 static inline int parse_opt_chorus(const char *);
376 static inline int parse_opt_reverb(const char *);
377 static inline int parse_opt_voice_lpf(const char *);
378 static inline int parse_opt_noise_shaping(const char *);
379 static inline int parse_opt_resample(const char *);
380 static inline int parse_opt_e(const char *);
381 static inline int parse_opt_F(const char *);
382 static inline int parse_opt_f(const char *);
383 static inline int parse_opt_g(const char *);
384 static inline int parse_opt_H(const char *);
385 __attribute__((noreturn))
386 static inline int parse_opt_h(const char *);
388 static inline void list_dyna_interface(FILE *, char *, char *);
389 static inline char *dynamic_interface_info(int);
390 char *dynamic_interface_module(int);
392 static inline int parse_opt_i(const char *);
393 static inline int parse_opt_verbose(const char *);
394 static inline int parse_opt_quiet(const char *);
395 static inline int parse_opt_trace(const char *);
396 static inline int parse_opt_loop(const char *);
397 static inline int parse_opt_random(const char *);
398 static inline int parse_opt_sort(const char *);
400 static inline int parse_opt_background(const char *);
401 static inline int parse_opt_rt_prio(const char *);
402 static inline int parse_opt_seq_ports(const char *);
404 static inline int parse_opt_j(const char *);
405 static inline int parse_opt_K(const char *);
406 static inline int parse_opt_k(const char *);
407 static inline int parse_opt_L(char *);
408 static inline int parse_opt_M(const char *);
409 static inline int parse_opt_m(const char *);
410 static inline int parse_opt_N(const char *);
411 static inline int parse_opt_O(const char *);
412 static inline int parse_opt_output_stereo(const char *);
413 static inline int parse_opt_output_signed(const char *);
414 static inline int parse_opt_output_bitwidth(const char *);
415 static inline int parse_opt_output_format(const char *);
416 static inline int parse_opt_output_swab(const char *);
417 static inline int parse_opt_o(char *);
418 static inline int parse_opt_P(const char *);
419 static inline int parse_opt_p(const char *);
420 static inline int parse_opt_p1(const char *);
421 static inline int parse_opt_Q(const char *);
422 static inline int parse_opt_Q1(const char *);
423 static inline int parse_opt_q(const char *);
424 static inline int parse_opt_R(const char *);
425 static inline int parse_opt_S(const char *);
426 static inline int parse_opt_s(const char *);
427 static inline int parse_opt_T(const char *);
428 static inline int parse_opt_t(const char *);
429 static inline int parse_opt_U(const char *);
430 static inline int parse_opt_volume_curve(char *);
431 __attribute__((noreturn))
432 static inline int parse_opt_v(const char *);
433 static inline int parse_opt_W(char *);
435 static inline int parse_opt_w(const char *);
437 static inline int parse_opt_x(char *);
438 static inline void expand_escape_string(char *);
439 static inline int parse_opt_Z(char *);
440 static inline int parse_opt_Z1(const char *);
441 static inline int parse_opt_default_module(const char *);
442 __attribute__((noreturn))
443 static inline int parse_opt_fail(const char *);
444 static inline int set_value(int *, int, int, int, char *);
445 static inline int set_val_i32(int32 *, int32, int32, int32, char *);
446 static inline int set_channel_flag(ChannelBitMask *, int32, char *);
447 static inline int y_or_n_p(const char *);
448 static inline int set_flag(int32 *, int32, const char *);
449 static inline FILE *open_pager(void);
450 static inline void close_pager(FILE *);
451 static void interesting_message(void);
454 MAIN_INTERFACE char dynamic_interface_id;
455 #endif /* IA_DYNAMIC */
457 extern StringTable wrd_read_opts;
459 extern int SecondMode;
461 extern struct URL_module URL_module_file;
463 extern struct URL_module URL_module_dir;
464 #endif /* __MACOS__ */
465 #ifdef SUPPORT_SOCKET
466 extern struct URL_module URL_module_http;
467 extern struct URL_module URL_module_ftp;
468 extern struct URL_module URL_module_news;
469 extern struct URL_module URL_module_newsgroup;
470 #endif /* SUPPORT_SOCKET */
472 extern struct URL_module URL_module_pipe;
473 #endif /* HAVE_POPEN */
475 MAIN_INTERFACE struct URL_module *url_module_list[] =
480 #endif /* __MACOS__ */
481 #ifdef SUPPORT_SOCKET
485 &URL_module_newsgroup,
486 #endif /* SUPPORT_SOCKET */
487 #if !defined(__MACOS__) && defined(HAVE_POPEN)
490 #if defined(main) || defined(ANOTHER_MAIN)
491 /* You can put some other modules */
506 #ifndef SHARED_LIB_PATH
507 #define SHARED_LIB_PATH PKGLIBDIR
508 #endif /* SHARED_LIB_PATH */
509 static char *dynamic_lib_root = SHARED_LIB_PATH;
510 #endif /* IA_DYNAMIC */
513 #define MAXPATHLEN 1024
514 #endif /* MAXPATHLEN */
516 int free_instruments_afterwards=0;
518 char def_instr_name[256]="";
519 VOLATILE int intr = 0;
522 CRITICAL_SECTION critSect;
525 static BOOL WINAPI handler(DWORD dw)
527 #if defined(IA_WINSYN) || defined(IA_PORTMIDISYN)
528 if( ctl->id_character == 'W'
529 || ctl->id_character == 'P' )
531 rtsyn_midiports_close();
534 printf ("***BREAK" NLS); fflush(stdout);
541 int effect_lr_mode = -1;
547 int effect_lr_delay_msec = 25;
549 extern char* pcm_alternate_file;
550 /* NULL, "none": disabled (default)
551 * "auto": automatically selected
552 * filename: use the one.
556 extern double atof(const char *);
559 /*! copy bank and, if necessary, map appropriately */
560 static void copybank(ToneBank *to, ToneBank *from, int mapid, int bankmapfrom, int bankno)
562 ToneBankElement *toelm, *fromelm;
567 for(i = 0; i < 128; i++)
569 toelm = &to->tone[i];
570 fromelm = &from->tone[i];
571 if (fromelm->name == NULL)
573 copy_tone_bank_element(toelm, fromelm);
574 toelm->instrument = NULL;
575 if (mapid != INST_NO_MAP)
576 set_instrument_map(mapid, bankmapfrom, i, bankno, i);
580 /*! copy the whole mapped bank. returns 0 if no error. */
581 static int copymap(int mapto, int mapfrom, int isdrum)
583 ToneBank **tb = isdrum ? drumset : tonebank;
584 int i, bankfrom, bankto;
586 for(i = 0; i < 128; i++)
588 bankfrom = find_instrument_map_bank(isdrum, mapfrom, i);
589 if (bankfrom <= 0) /* not mapped */
591 bankto = alloc_instrument_map_bank(isdrum, mapto, i);
592 if (bankto == -1) /* failed */
594 copybank(tb[bankto], tb[bankfrom], mapto, i, bankto);
599 static float *config_parse_tune(const char *cp, int *num)
607 while ((p = strchr(p, ',')) != NULL)
610 tune_list = (float *) safe_malloc((*num) * sizeof(float));
612 for (i = 0, p = cp; i < *num; i++, p++) {
613 tune_list[i] = atof(p);
614 if (! (p = strchr(p, ',')))
620 static int16 *config_parse_int16(const char *cp, int *num)
628 while ((p = strchr(p, ',')) != NULL)
631 list = (int16 *) safe_malloc((*num) * sizeof(int16));
633 for (i = 0, p = cp; i < *num; i++, p++) {
635 if (! (p = strchr(p, ',')))
641 static int **config_parse_envelope(const char *cp, int *num)
649 while ((p = strchr(p, ',')) != NULL)
652 env_list = (int **) safe_malloc((*num) * sizeof(int *));
653 for (i = 0; i < *num; i++)
654 env_list[i] = (int *) safe_malloc(6 * sizeof(int));
656 for (i = 0; i < *num; i++)
657 for (j = 0; j < 6; j++)
660 for (i = 0, p = cp; i < *num; i++, p++) {
662 for (j = 0; j < 6; j++, p++) {
665 env_list[i][j] = atoi(p);
666 if (! (p = strchr(p, ':')))
677 static Quantity **config_parse_modulation(const char *name, int line, const char *cp, int *num, int mod_type)
679 const char *p, *px, *err;
680 char buf[128], *delim;
683 static const char * qtypestr[] = {"tremolo", "vibrato"};
684 static const uint16 qtypes[] = {
685 QUANTITY_UNIT_TYPE(TREMOLO_SWEEP), QUANTITY_UNIT_TYPE(TREMOLO_RATE), QUANTITY_UNIT_TYPE(DIRECT_INT),
686 QUANTITY_UNIT_TYPE(VIBRATO_SWEEP), QUANTITY_UNIT_TYPE(VIBRATO_RATE), QUANTITY_UNIT_TYPE(DIRECT_INT)
691 while ((p = strchr(p, ',')) != NULL)
694 mod_list = (Quantity **) safe_malloc((*num) * sizeof(Quantity *));
695 for (i = 0; i < *num; i++)
696 mod_list[i] = (Quantity *) safe_malloc(3 * sizeof(Quantity));
698 for (i = 0; i < *num; i++)
699 for (j = 0; j < 3; j++)
700 INIT_QUANTITY(mod_list[i][j]);
701 buf[sizeof buf - 1] = '\0';
703 for (i = 0, p = cp; i < *num; i++, p++) {
705 for (j = 0; j < 3; j++, p++) {
708 if ((delim = strpbrk(strncpy(buf, p, sizeof buf - 1), ":,")) != NULL)
710 if (*buf != '\0' && (err = string_to_quantity(buf, &mod_list[i][j], qtypes[mod_type * 3 + j])) != NULL) {
711 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: line %d: %s: parameter %d of item %d: %s (%s)",
712 name, line, qtypestr[mod_type], j+1, i+1, err, buf);
713 free_ptr_list(mod_list, *num);
718 if (! (p = strchr(p, ':')))
729 static int set_gus_patchconf_opts(char *name,
730 int line, char *opts, ToneBankElement *tone)
735 if (! (cp = strchr(opts, '='))) {
736 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
737 "%s: line %d: bad patch option %s", name, line, opts);
741 if (! strcmp(opts, "amp")) {
743 if ((k < 0 || k > MAX_AMPLIFICATION) || (*cp < '0' || *cp > '9')) {
744 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
745 "%s: line %d: amplification must be between 0 and %d",
746 name, line, MAX_AMPLIFICATION);
750 } else if (! strcmp(opts, "note")) {
752 if ((k < 0 || k > 127) || (*cp < '0' || *cp > '9')) {
753 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
754 "%s: line %d: note must be between 0 and 127",
759 tone->scltune = config_parse_int16("100", &tone->scltunenum);
760 } else if (! strcmp(opts, "pan")) {
761 if (! strcmp(cp, "center"))
763 else if (! strcmp(cp, "left"))
765 else if (! strcmp(cp, "right"))
768 k = ((atoi(cp) + 100) * 100) / 157;
769 if ((k < 0 || k > 127)
770 || (k == 0 && *cp != '-' && (*cp < '0' || *cp > '9'))) {
771 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
772 "%s: line %d: panning must be left, right, "
773 "center, or between -100 and 100",
779 } else if (! strcmp(opts, "tune"))
780 tone->tune = config_parse_tune(cp, &tone->tunenum);
781 else if (! strcmp(opts, "rate"))
782 tone->envrate = config_parse_envelope(cp, &tone->envratenum);
783 else if (! strcmp(opts, "offset"))
784 tone->envofs = config_parse_envelope(cp, &tone->envofsnum);
785 else if (! strcmp(opts, "keep")) {
786 if (! strcmp(cp, "env"))
787 tone->strip_envelope = 0;
788 else if (! strcmp(cp, "loop"))
789 tone->strip_loop = 0;
791 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
792 "%s: line %d: keep must be env or loop", name, line);
795 } else if (! strcmp(opts, "strip")) {
796 if (! strcmp(cp, "env"))
797 tone->strip_envelope = 1;
798 else if (! strcmp(cp, "loop"))
799 tone->strip_loop = 1;
800 else if (! strcmp(cp, "tail"))
801 tone->strip_tail = 1;
803 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
804 "%s: line %d: strip must be env, loop, or tail",
808 } else if (! strcmp(opts, "tremolo")) {
809 if ((tone->trem = config_parse_modulation(name,
810 line, cp, &tone->tremnum, 0)) == NULL)
812 } else if (! strcmp(opts, "vibrato")) {
813 if ((tone->vib = config_parse_modulation(name,
814 line, cp, &tone->vibnum, 1)) == NULL)
816 } else if (! strcmp(opts, "sclnote"))
817 tone->sclnote = config_parse_int16(cp, &tone->sclnotenum);
818 else if (! strcmp(opts, "scltune"))
819 tone->scltune = config_parse_int16(cp, &tone->scltunenum);
820 else if (! strcmp(opts, "comm")) {
825 p = tone->comment = safe_strdup(cp);
831 } else if (! strcmp(opts, "modrate"))
832 tone->modenvrate = config_parse_envelope(cp, &tone->modenvratenum);
833 else if (! strcmp(opts, "modoffset"))
834 tone->modenvofs = config_parse_envelope(cp, &tone->modenvofsnum);
835 else if (! strcmp(opts, "envkeyf"))
836 tone->envkeyf = config_parse_envelope(cp, &tone->envkeyfnum);
837 else if (! strcmp(opts, "envvelf"))
838 tone->envvelf = config_parse_envelope(cp, &tone->envvelfnum);
839 else if (! strcmp(opts, "modkeyf"))
840 tone->modenvkeyf = config_parse_envelope(cp, &tone->modenvkeyfnum);
841 else if (! strcmp(opts, "modvelf"))
842 tone->modenvvelf = config_parse_envelope(cp, &tone->modenvvelfnum);
843 else if (! strcmp(opts, "trempitch"))
844 tone->trempitch = config_parse_int16(cp, &tone->trempitchnum);
845 else if (! strcmp(opts, "tremfc"))
846 tone->tremfc = config_parse_int16(cp, &tone->tremfcnum);
847 else if (! strcmp(opts, "modpitch"))
848 tone->modpitch = config_parse_int16(cp, &tone->modpitchnum);
849 else if (! strcmp(opts, "modfc"))
850 tone->modfc = config_parse_int16(cp, &tone->modfcnum);
851 else if (! strcmp(opts, "fc"))
852 tone->fc = config_parse_int16(cp, &tone->fcnum);
853 else if (! strcmp(opts, "q"))
854 tone->reso = config_parse_int16(cp, &tone->resonum);
855 else if (! strcmp(opts, "fckeyf")) /* filter key-follow */
856 tone->key_to_fc = atoi(cp);
857 else if (! strcmp(opts, "fcvelf")) /* filter velocity-follow */
858 tone->vel_to_fc = atoi(cp);
859 else if (! strcmp(opts, "qvelf")) /* resonance velocity-follow */
860 tone->vel_to_resonance = atoi(cp);
862 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
863 "%s: line %d: bad patch option %s",
870 static void reinit_tone_bank_element(ToneBankElement *tone)
872 free_tone_bank_element(tone);
873 tone->note = tone->pan = -1;
874 tone->strip_loop = tone->strip_envelope = tone->strip_tail = -1;
877 tone->loop_timeout = 0;
878 tone->legato = tone->damper_mode = tone->key_to_fc = tone->vel_to_fc = 0;
879 tone->reverb_send = tone->chorus_send = tone->delay_send = -1;
880 tone->tva_level = -1;
881 tone->play_note = -1;
884 #define SET_GUS_PATCHCONF_COMMENT
885 static int set_gus_patchconf(char *name, int line,
886 ToneBankElement *tone, char *pat, char **opts)
889 #ifdef SET_GUS_PATCHCONF_COMMENT
890 char *old_name = NULL;
892 if(tone != NULL && tone->name != NULL)
893 old_name = safe_strdup(tone->name);
895 reinit_tone_bank_element(tone);
897 if(strcmp(pat, "%font") == 0) /* Font extention */
899 /* %font filename bank prog [note-to-use]
900 * %font filename 128 bank key
903 if(opts[0] == NULL || opts[1] == NULL || opts[2] == NULL ||
904 (atoi(opts[1]) == 128 && opts[3] == NULL))
906 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
907 "%s: line %d: Syntax error", name, line);
910 tone->name = safe_strdup(opts[0]);
912 if(atoi(opts[1]) == 128) /* drum */
914 tone->font_bank = 128;
915 tone->font_preset = atoi(opts[2]);
916 tone->font_keynote = atoi(opts[3]);
921 tone->font_bank = atoi(opts[1]);
922 tone->font_preset = atoi(opts[2]);
924 if(opts[3] && isdigit(opts[3][0]))
926 tone->font_keynote = atoi(opts[3]);
931 tone->font_keynote = -1;
936 else if(strcmp(pat, "%sample") == 0) /* Sample extention */
938 /* %sample filename */
942 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
943 "%s: line %d: Syntax error", name, line);
946 tone->name = safe_strdup(opts[0]);
953 tone->name = safe_strdup(pat);
956 for(j = 0; opts[j] != NULL; j++)
959 if((err = set_gus_patchconf_opts(name, line, opts[j], tone)) != 0)
962 #ifdef SET_GUS_PATCHCONF_COMMENT
963 if(tone->comment == NULL ||
964 (old_name != NULL && strcmp(old_name,tone->comment) == 0))
966 if(tone->comment != NULL )
968 tone->comment = safe_strdup(tone->name);
973 if(tone->comment == NULL)
974 tone->comment = safe_strdup(tone->name);
979 static int set_patchconf(char *name, int line, ToneBank *bank, char *w[], int dr, int mapid, int bankmapfrom, int bankno)
989 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
990 "%s: line %d: Drum number must be between "
994 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
995 "%s: line %d: Program must be between "
997 name, line, progbase, 127 + progbase);
1002 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1003 "%s: line %d: Must specify tone bank or drum set "
1004 "before assignment", name, line);
1008 if(set_gus_patchconf(name, line, &bank->tone[i], w[1], w + 2))
1010 if (mapid != INST_NO_MAP)
1011 set_instrument_map(mapid, bankmapfrom, i, bankno, i);
1020 static int mapnamecompare(const void *name, const void *entry)
1022 return strcmp((const char *)name, ((const MapNameEntry *)entry)->name);
1025 static int mapname2id(char *name, int *isdrum)
1027 static const MapNameEntry data[] = {
1028 /* sorted in alphabetical order */
1029 {"gm2", GM2_TONE_MAP, 0},
1030 {"gm2drum", GM2_DRUM_MAP, 1},
1031 {"sc55", SC_55_TONE_MAP, 0},
1032 {"sc55drum", SC_55_DRUM_MAP, 1},
1033 {"sc88", SC_88_TONE_MAP, 0},
1034 {"sc8850", SC_8850_TONE_MAP, 0},
1035 {"sc8850drum", SC_8850_DRUM_MAP, 1},
1036 {"sc88drum", SC_88_DRUM_MAP, 1},
1037 {"sc88pro", SC_88PRO_TONE_MAP, 0},
1038 {"sc88prodrum", SC_88PRO_DRUM_MAP, 1},
1039 {"xg", XG_NORMAL_MAP, 0},
1040 {"xgdrum", XG_DRUM_MAP, 1},
1041 {"xgsfx126", XG_SFX126_MAP, 1},
1042 {"xgsfx64", XG_SFX64_MAP, 0}
1044 const MapNameEntry *found;
1046 found = (MapNameEntry *)bsearch(name, data, sizeof data / sizeof data[0], sizeof data[0], mapnamecompare);
1049 *isdrum = found->isdrum;
1050 return found->mapid;
1055 /* string[0] should not be '#' */
1056 static int strip_trailing_comment(char *string, int next_token_index)
1058 if (string[next_token_index - 1] == '#' /* strip \1 in /^\S+(#*[ \t].*)/ */
1059 && (string[next_token_index] == ' ' || string[next_token_index] == '\t'))
1061 string[next_token_index] = '\0'; /* new c-string terminator */
1062 while(string[--next_token_index - 1] == '#')
1065 return next_token_index;
1068 #define MAXWORDS 130
1069 #define CHECKERRLIMIT \
1070 if(++errcnt >= 10) { \
1071 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, \
1072 "Too many errors... Give up read %s", name); \
1073 close_file(tf); return 1; }
1075 MAIN_INTERFACE int read_config_file(char *name, int self)
1077 struct timidity_file *tf;
1078 char tmp[1024], *w[MAXWORDS + 1], *cp;
1079 ToneBank *bank = NULL;
1080 int i, j, k, line = 0, words, errcnt = 0;
1081 static int rcf_count = 0;
1082 int dr = 0, bankno = 0, mapid = INST_NO_MAP, origbankno = 0x7FFFFFFF;
1083 int extension_flag, param_parse_err;
1087 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1088 "Probable source loop in configuration files");
1094 tf = open_with_mem(name, (int32)strlen(name), OF_VERBOSE);
1095 name = "(configuration)";
1098 tf = open_file(name, 1, OF_VERBOSE);
1103 while(tf_gets(tmp, sizeof(tmp), tf))
1106 if(strncmp(tmp, "#extension", 10) == 0) {
1116 while(isspace(tmp[i])) /* skip /^\s*(?#)/ */
1118 if (tmp[i] == '#' || tmp[i] == '\0') /* /^#|^$/ */
1120 j = strcspn(tmp + i, " \t\r\n\240");
1122 j = strlen(tmp + i);
1123 j = strip_trailing_comment(tmp + i, j);
1124 tmp[i + j] = '\0'; /* terminate the first token */
1127 words = param_parse_err = 0;
1128 while(words < MAXWORDS - 1) /* -1 : next arg */
1132 while(isspace(tmp[i])) /* skip /^\s*(?#)/ */
1135 || tmp[i] == '#') /* /\s#/ */
1137 if ((tmp[i] == '"' || tmp[i] == '\'')
1138 && (terminator = strchr(tmp + i + 1, tmp[i])) != NULL)
1140 if (!isspace(terminator[1]) && terminator[1] != '\0')
1142 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1143 "%s: line %d: there must be at least one whitespace between "
1144 "string terminator (%c) and the next parameter", name, line, tmp[i]);
1146 param_parse_err = 1;
1149 w[++words] = tmp + i + 1;
1150 i = terminator - tmp + 1;
1153 else /* not terminated */
1155 j = strcspn(tmp + i, " \t\r\n\240");
1157 j = strip_trailing_comment(tmp + i, j);
1158 w[++words] = tmp + i;
1160 if (tmp[i] != '\0') /* unless at the end-of-string (i.e. EOF) */
1161 tmp[i++] = '\0'; /* terminate the token */
1164 if (param_parse_err)
1169 * #extension [something...]
1172 /* #extension comm program comment */
1173 if(strcmp(w[0], "comm") == 0)
1179 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1180 "%s: line %d: syntax error", name, line);
1186 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1187 "%s: line %d: Must specify tone bank or drum "
1188 "set before assignment", name, line);
1193 if(i < 0 || i > 127)
1195 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1196 "%s: line %d: extension comm must be "
1197 "between 0 and 127", name, line);
1201 if(bank->tone[i].comment)
1202 free(bank->tone[i].comment);
1203 p = bank->tone[i].comment = safe_strdup(w[2]);
1206 if(*p == ',') *p = ' ';
1210 /* #extension timeout program sec */
1211 else if(strcmp(w[0], "timeout") == 0)
1215 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1216 "%s: line %d: syntax error", name, line);
1222 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1223 "%s: line %d: Must specify tone bank or drum set "
1224 "before assignment", name, line);
1229 if(i < 0 || i > 127)
1231 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1232 "%s: line %d: extension timeout "
1233 "must be between 0 and 127", name, line);
1237 bank->tone[i].loop_timeout = atoi(w[2]);
1239 /* #extension copydrumset drumset */
1240 else if(strcmp(w[0], "copydrumset") == 0)
1244 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1245 "%s: line %d: No copydrumset number given",
1251 if(i < 0 || i > 127)
1253 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1254 "%s: line %d: extension copydrumset "
1255 "must be between 0 and 127", name, line);
1261 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1262 "%s: line %d: Must specify tone bank or "
1263 "drum set before assignment", name, line);
1267 copybank(bank, drumset[i], mapid, origbankno, bankno);
1269 /* #extension copybank bank */
1270 else if(strcmp(w[0], "copybank") == 0)
1274 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1275 "%s: line %d: No copybank number given",
1281 if(i < 0 || i > 127)
1283 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1284 "%s: line %d: extension copybank "
1285 "must be between 0 and 127", name, line);
1291 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1292 "%s: line %d: Must specify tone bank or "
1293 "drum set before assignment", name, line);
1297 copybank(bank, tonebank[i], mapid, origbankno, bankno);
1299 /* #extension copymap tomapid frommapid */
1300 else if(strcmp(w[0], "copymap") == 0)
1303 int toisdrum, fromisdrum;
1307 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1308 "%s: line %d: syntax error", name, line);
1312 if ((mapto = mapname2id(w[1], &toisdrum)) == -1)
1314 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1315 "%s: line %d: Invalid map name: %s", name, line, w[1]);
1319 if ((mapfrom = mapname2id(w[2], &fromisdrum)) == -1)
1321 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1322 "%s: line %d: Invalid map name: %s", name, line, w[2]);
1326 if (toisdrum != fromisdrum)
1328 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1329 "%s: line %d: Map type should be matched", name, line);
1333 if (copymap(mapto, mapfrom, toisdrum))
1335 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1336 "%s: line %d: No free %s available to map",
1337 name, line, toisdrum ? "drum set" : "tone bank");
1342 /* #extension HTTPproxy hostname:port */
1343 else if(strcmp(w[0], "HTTPproxy") == 0)
1347 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1348 "%s: line %d: No proxy name given",
1353 /* If network is not supported, this extension is ignored. */
1354 #ifdef SUPPORT_SOCKET
1355 url_http_proxy_host = safe_strdup(w[1]);
1356 if((cp = strchr(url_http_proxy_host, ':')) == NULL)
1358 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1359 "%s: line %d: Syntax error", name, line);
1364 if((url_http_proxy_port = atoi(cp)) <= 0)
1366 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1367 "%s: line %d: Port number must be "
1368 "positive number", name, line);
1374 /* #extension FTPproxy hostname:port */
1375 else if(strcmp(w[0], "FTPproxy") == 0)
1379 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1380 "%s: line %d: No proxy name given",
1385 /* If network is not supported, this extension is ignored. */
1386 #ifdef SUPPORT_SOCKET
1387 url_ftp_proxy_host = safe_strdup(w[1]);
1388 if((cp = strchr(url_ftp_proxy_host, ':')) == NULL)
1390 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1391 "%s: line %d: Syntax error", name, line);
1396 if((url_ftp_proxy_port = atoi(cp)) <= 0)
1398 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1399 "%s: line %d: Port number "
1400 "must be positive number", name, line);
1406 /* #extension mailaddr somebody@someware.domain.com */
1407 else if(strcmp(w[0], "mailaddr") == 0)
1411 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1412 "%s: line %d: No mail address given",
1417 if(strchr(w[1], '@') == NULL) {
1418 ctl->cmsg(CMSG_WARNING, VERB_NOISY,
1419 "%s: line %d: Warning: Mail address %s is not valid",
1423 /* If network is not supported, this extension is ignored. */
1424 #ifdef SUPPORT_SOCKET
1425 user_mailaddr = safe_strdup(w[1]);
1426 #endif /* SUPPORT_SOCKET */
1428 /* #extension opt [-]{option}[optarg] */
1429 else if (strcmp(w[0], "opt") == 0) {
1430 int c, longind, err;
1431 char *p, *cmd, *arg;
1433 if (words != 2 && words != 3) {
1434 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1435 "%s: line %d: Syntax error", name, line);
1440 int optind_save = optind;
1442 c = getopt_long(words, w, optcommands, longopts, &longind);
1443 err = set_tim_opt_long(c, optarg, longind);
1444 optind = optind_save;
1446 /* backward compatibility */
1447 if ((p = strchr(optcommands, c = *(cmd = w[1]))) == NULL)
1450 if (*(p + 1) == ':')
1451 arg = (words == 2) ? cmd + 1 : w[2];
1454 err = set_tim_opt_short(c, arg);
1459 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1460 "%s: line %d: Invalid command line option",
1467 /* #extension undef program */
1468 else if(strcmp(w[0], "undef") == 0)
1472 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1473 "%s: line %d: No undef number given",
1479 if(i < 0 || i > 127)
1481 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1482 "%s: line %d: extension undef "
1483 "must be between 0 and 127", name, line);
1489 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1490 "%s: line %d: Must specify tone bank or "
1491 "drum set before assignment", name, line);
1495 free_tone_bank_element(&bank->tone[i]);
1497 /* #extension altassign numbers... */
1498 else if(strcmp(w[0], "altassign") == 0)
1504 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1505 "%s: line %d: Must specify tone bank or drum set "
1506 "before altassign", name, line);
1512 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1513 "%s: line %d: No alternate assignment", name, line);
1519 ctl->cmsg(CMSG_WARNING, VERB_NORMAL,
1520 "%s: line %d: Warning: Not a drumset altassign"
1526 bk = drumset[bankno];
1527 bk->alt = add_altassign_string(bk->alt, w + 1, words - 1);
1528 } /* #extension legato [program] [0 or 1] */
1529 else if(strcmp(w[0], "legato") == 0)
1533 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1534 "%s: line %d: syntax error", name, line);
1540 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1541 "%s: line %d: Must specify tone bank or drum set "
1542 "before assignment", name, line);
1547 if(i < 0 || i > 127)
1549 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1550 "%s: line %d: extension legato "
1551 "must be between 0 and 127", name, line);
1555 bank->tone[i].legato = atoi(w[2]);
1556 } /* #extension damper [program] [0 or 1] */
1557 else if(strcmp(w[0], "damper") == 0)
1561 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1562 "%s: line %d: syntax error", name, line);
1568 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1569 "%s: line %d: Must specify tone bank or drum set "
1570 "before assignment", name, line);
1575 if(i < 0 || i > 127)
1577 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1578 "%s: line %d: extension damper "
1579 "must be between 0 and 127", name, line);
1583 bank->tone[i].damper_mode = atoi(w[2]);
1584 } /* #extension rnddelay [program] [0 or 1] */
1585 else if(strcmp(w[0], "rnddelay") == 0)
1589 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1590 "%s: line %d: syntax error", name, line);
1596 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1597 "%s: line %d: Must specify tone bank or drum set "
1598 "before assignment", name, line);
1603 if(i < 0 || i > 127)
1605 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1606 "%s: line %d: extension rnddelay "
1607 "must be between 0 and 127", name, line);
1611 bank->tone[i].rnddelay = atoi(w[2]);
1612 } /* #extension level program tva_level */
1613 else if(strcmp(w[0], "level") == 0)
1617 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: line %d: syntax error", name, line);
1623 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1624 "%s: line %d: Must specify tone bank or drum set "
1625 "before assignment", name, line);
1630 if(i < 0 || i > 127)
1632 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1633 "%s: line %d: extension level "
1634 "must be between 0 and 127", name, line);
1640 if (string_to_7bit_range(cp, &j, &k))
1643 bank->tone[j++].tva_level = i;
1645 cp = strchr(cp, ',');
1646 } while(cp++ != NULL);
1647 } /* #extension reverbsend */
1648 else if(strcmp(w[0], "reverbsend") == 0)
1652 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: line %d: syntax error", name, line);
1658 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1659 "%s: line %d: Must specify tone bank or drum set "
1660 "before assignment", name, line);
1665 if(i < 0 || i > 127)
1667 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1668 "%s: line %d: extension reverbsend "
1669 "must be between 0 and 127", name, line);
1675 if (string_to_7bit_range(cp, &j, &k))
1678 bank->tone[j++].reverb_send = i;
1680 cp = strchr(cp, ',');
1681 } while(cp++ != NULL);
1682 } /* #extension chorussend */
1683 else if(strcmp(w[0], "chorussend") == 0)
1687 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: line %d: syntax error", name, line);
1693 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1694 "%s: line %d: Must specify tone bank or drum set "
1695 "before assignment", name, line);
1700 if(i < 0 || i > 127)
1702 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1703 "%s: line %d: extension chorussend "
1704 "must be between 0 and 127", name, line);
1710 if (string_to_7bit_range(cp, &j, &k))
1713 bank->tone[j++].chorus_send = i;
1715 cp = strchr(cp, ',');
1716 } while(cp++ != NULL);
1717 } /* #extension delaysend */
1718 else if(strcmp(w[0], "delaysend") == 0)
1722 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: line %d: syntax error", name, line);
1728 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1729 "%s: line %d: Must specify tone bank or drum set "
1730 "before assignment", name, line);
1735 if(i < 0 || i > 127)
1737 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1738 "%s: line %d: extension delaysend "
1739 "must be between 0 and 127", name, line);
1745 if (string_to_7bit_range(cp, &j, &k))
1748 bank->tone[j++].delay_send = i;
1750 cp = strchr(cp, ',');
1751 } while(cp++ != NULL);
1752 } /* #extension playnote */
1753 else if(strcmp(w[0], "playnote") == 0)
1757 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: line %d: syntax error", name, line);
1763 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1764 "%s: line %d: Must specify tone bank or drum set "
1765 "before assignment", name, line);
1770 if(i < 0 || i > 127)
1772 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1773 "%s: line %d: extension playnote"
1774 "must be between 0 and 127", name, line);
1780 if (string_to_7bit_range(cp, &j, &k))
1783 bank->tone[j++].play_note = i;
1785 cp = strchr(cp, ',');
1786 } while(cp++ != NULL);
1788 else if(!strcmp(w[0], "soundfont"))
1790 int order, cutoff, isremove, reso, amp;
1795 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1796 "%s: line %d: No soundfont file given",
1803 order = cutoff = reso = amp = -1;
1805 for(j = 2; j < words; j++)
1807 if(strcmp(w[j], "remove") == 0)
1812 if(!(cp = strchr(w[j], '=')))
1814 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1815 "%s: line %d: bad patch option %s",
1822 if(!strcmp(w[j], "order"))
1824 if(k < 0 || (*cp < '0' || *cp > '9'))
1826 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1827 "%s: line %d: order must be a digit",
1834 else if(!strcmp(w[j], "cutoff"))
1836 if(k < 0 || (*cp < '0' || *cp > '9'))
1838 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1839 "%s: line %d: cutoff must be a digit",
1846 else if(!strcmp(w[j], "reso"))
1848 if(k < 0 || (*cp < '0' || *cp > '9'))
1850 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1851 "%s: line %d: reso must be a digit",
1858 else if(!strcmp(w[j], "amp"))
1864 remove_soundfont(sf_file);
1866 add_soundfont(sf_file, order, cutoff, reso, amp);
1868 else if(!strcmp(w[0], "font"))
1870 int bank, preset, keynote;
1873 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1874 "%s: line %d: no font command", name, line);
1878 if(!strcmp(w[1], "exclude"))
1882 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1883 "%s: line %d: No bank/preset/key is given",
1890 preset = atoi(w[3]) - progbase;
1894 keynote = atoi(w[4]);
1897 if(exclude_soundfont(bank, preset, keynote))
1899 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1900 "%s: line %d: No soundfont is given",
1905 else if(!strcmp(w[1], "order"))
1910 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1911 "%s: line %d: No order/bank is given",
1919 preset = atoi(w[4]) - progbase;
1923 keynote = atoi(w[5]);
1926 if(order_soundfont(bank, preset, keynote, order))
1928 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1929 "%s: line %d: No soundfont is given",
1935 else if(!strcmp(w[0], "progbase"))
1937 if(words < 2 || *w[1] < '0' || *w[1] > '9')
1939 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1940 "%s: line %d: syntax error", name, line);
1944 progbase = atoi(w[1]);
1946 else if(!strcmp(w[0], "map")) /* map <name> set1 elem1 set2 elem2 */
1952 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1953 "%s: line %d: syntax error", name, line);
1957 if((arg[0] = mapname2id(w[1], &isdrum)) == -1)
1959 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1960 "%s: line %d: Invalid map name: %s", name, line, w[1]);
1964 for(i = 2; i < 6; i++)
1965 arg[i - 1] = atoi(w[i]);
1977 for(i = 1; i < 5; i++)
1978 if(arg[i] < 0 || arg[i] > 127)
1982 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1983 "%s: line %d: Invalid parameter", name, line);
1987 set_instrument_map(arg[0], arg[1], arg[2], arg[3], arg[4]);
1991 * Standard configurations
1993 else if(!strcmp(w[0], "dir"))
1997 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1998 "%s: line %d: No directory given", name, line);
2002 for(i = 1; i < words; i++)
2003 add_to_pathlist(w[i]);
2005 else if(!strcmp(w[0], "source"))
2009 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
2010 "%s: line %d: No file name given", name, line);
2014 for(i = 1; i < words; i++)
2018 status = read_config_file(w[i], 0);
2025 else if(status != 0)
2033 else if(!strcmp(w[0], "default"))
2037 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
2038 "%s: line %d: Must specify exactly one patch name",
2043 strncpy(def_instr_name, w[1], 255);
2044 def_instr_name[255] = '\0';
2045 default_instrument_name = def_instr_name;
2047 /* drumset [mapid] num */
2048 else if(!strcmp(w[0], "drumset"))
2050 int newmapid, isdrum, newbankno;
2054 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
2055 "%s: line %d: No drum set number given", name, line);
2059 if (words != 2 && !isdigit(*w[1]))
2061 if ((newmapid = mapname2id(w[1], &isdrum)) == -1 || !isdrum)
2063 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
2064 "%s: line %d: Invalid drum set map name: %s", name, line, w[1]);
2069 memmove(&w[1], &w[2], sizeof w[0] * words);
2072 newmapid = INST_NO_MAP;
2073 i = atoi(w[1]) - progbase;
2074 if(i < 0 || i > 127)
2076 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
2077 "%s: line %d: Drum set must be between %d and %d",
2079 progbase, progbase + 127);
2085 i = alloc_instrument_map_bank(1, newmapid, i);
2088 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
2089 "%s: line %d: No free drum set available to map",
2100 origbankno = newbankno;
2105 if(words < 4 || *w[2] < '0' || *w[2] > '9')
2107 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
2108 "%s: line %d: syntax error", name, line);
2112 if (set_patchconf(name, line, drumset[i], &w[2], 1, newmapid, newbankno, i))
2119 /* bank [mapid] num */
2120 else if(!strcmp(w[0], "bank"))
2122 int newmapid, isdrum, newbankno;
2126 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
2127 "%s: line %d: No bank number given", name, line);
2131 if (words != 2 && !isdigit(*w[1]))
2133 if ((newmapid = mapname2id(w[1], &isdrum)) == -1 || isdrum)
2135 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
2136 "%s: line %d: Invalid bank map name: %s", name, line, w[1]);
2141 memmove(&w[1], &w[2], sizeof w[0] * words);
2144 newmapid = INST_NO_MAP;
2146 if(i < 0 || i > 127)
2148 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
2149 "%s: line %d: Tone bank must be between 0 and 127",
2156 i = alloc_instrument_map_bank(0, newmapid, i);
2159 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
2160 "%s: line %d: No free tone bank available to map",
2171 origbankno = newbankno;
2176 if(words < 4 || *w[2] < '0' || *w[2] > '9')
2178 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
2179 "%s: line %d: syntax error", name, line);
2183 if (set_patchconf(name, line, tonebank[i], &w[2], 0, newmapid, newbankno, i))
2192 if(words < 2 || *w[0] < '0' || *w[0] > '9')
2196 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
2197 "%s: line %d: syntax error", name, line);
2201 if (set_patchconf(name, line, bank, w, dr, mapid, origbankno, bankno))
2210 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
2211 "Can't read %s: %s", name, strerror(errno));
2218 #ifdef SUPPORT_SOCKET
2220 #if defined(__W32__) && !defined(MAIL_NAME)
2221 #define MAIL_NAME "anonymous"
2222 #endif /* __W32__ */
2225 #define get_username() MAIL_NAME
2226 #else /* MAIL_NAME */
2228 static char *get_username(void)
2231 struct passwd *pass;
2239 if((p = getenv("USER")) != NULL)
2241 if((p = getenv("LOGIN")) != NULL)
2243 if((p = getenv("LOGNAME")) != NULL)
2246 pass = getpwuid(getuid());
2249 return pass->pw_name;
2251 #endif /* MAIL_NAME */
2253 static void init_mail_addr(void)
2257 sprintf(addr, "%s%s", get_username(), MAIL_DOMAIN);
2258 user_mailaddr = safe_strdup(addr);
2260 #endif /* SUPPORT_SOCKET */
2262 static int read_user_config_file(void)
2270 home = getenv("HOME");
2272 home = getenv("home");
2275 ctl->cmsg(CMSG_INFO, VERB_NOISY,
2276 "Warning: HOME environment is not defined.");
2279 /* .timidity.cfg or timidity.cfg */
2280 sprintf(path, "%s" PATH_STRING "timidity.cfg", home);
2281 if((opencheck = open(path, 0)) < 0)
2283 sprintf(path, "%s" PATH_STRING "_timidity.cfg", home);
2284 if((opencheck = open(path, 0)) < 0)
2286 sprintf(path, "%s" PATH_STRING ".timidity.cfg", home);
2287 if((opencheck = open(path, 0)) < 0)
2289 ctl->cmsg(CMSG_INFO, VERB_NOISY, "%s: %s",
2290 path, strerror(errno));
2297 return read_config_file(path, 0);
2299 home = getenv("HOME");
2302 ctl->cmsg(CMSG_INFO, VERB_NOISY,
2303 "Warning: HOME environment is not defined.");
2306 sprintf(path, "%s" PATH_STRING ".timidity.cfg", home);
2308 if((opencheck = open(path, 0)) < 0)
2310 ctl->cmsg(CMSG_INFO, VERB_NOISY, "%s: %s",
2311 path, strerror(errno));
2316 return read_config_file(path, 0);
2317 #endif /* __W32__ */
2320 MAIN_INTERFACE void tmdy_free_config(void)
2323 free_instrument_map();
2324 clean_up_pathlist();
2327 int set_extension_modes(char *flag)
2329 return parse_opt_E(flag);
2332 int set_ctl(char *cp)
2334 return parse_opt_i(cp);
2337 int set_play_mode(char *cp)
2339 return parse_opt_O(cp);
2342 int set_wrd(char *w)
2344 return parse_opt_W(w);
2348 int opt_evil_mode = 0;
2350 int opt_rcpcv_dll = 0;
2351 #endif /* SMFCONV */
2352 #endif /* __W32__ */
2353 static int try_config_again = 0;
2354 int32 opt_output_rate = 0;
2355 static char *opt_output_name = NULL;
2356 static StringTable opt_config_string;
2357 #ifdef SUPPORT_SOUNDSPEC
2358 static double spectrogram_update_sec = 0.0;
2359 #endif /* SUPPORT_SOUNDSPEC */
2360 int opt_buffer_fragments = -1;
2362 MAIN_INTERFACE int set_tim_opt_short(int c, char *optarg)
2368 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
2369 "-4 option is obsoleted. Please use -N");
2372 if (*optarg != ',' && *optarg != 'a')
2373 err += parse_opt_A(optarg);
2374 if (strchr(optarg, ','))
2375 err += parse_opt_drum_power(strchr(optarg, ',') + 1);
2376 if (strchr(optarg, 'a'))
2377 opt_amp_compensation = 1;
2380 antialiasing_allowed = 1;
2383 return parse_opt_B(optarg);
2385 return parse_opt_C(optarg);
2387 return parse_opt_c(optarg);
2389 return parse_opt_D(optarg);
2391 return parse_opt_d(optarg);
2393 return parse_opt_E(optarg);
2395 return parse_opt_e(optarg);
2397 adjust_panning_immediately = (adjust_panning_immediately) ? 0 : 1;
2400 fast_decay = (fast_decay) ? 0 : 1;
2403 return parse_opt_g(optarg);
2405 return parse_opt_H(optarg);
2407 return parse_opt_h(optarg);
2409 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
2410 "-I option is obsoleted. Please use -Ei");
2413 return parse_opt_i(optarg);
2415 opt_realtime_playing = (opt_realtime_playing) ? 0 : 1;
2418 return parse_opt_K(optarg);
2420 return parse_opt_k(optarg);
2422 return parse_opt_L(optarg);
2424 return parse_opt_M(optarg);
2426 return parse_opt_m(optarg);
2428 return parse_opt_N(optarg);
2430 return parse_opt_O(optarg);
2432 return parse_opt_o(optarg);
2434 return parse_opt_P(optarg);
2437 err += parse_opt_p(optarg);
2438 if (strchr(optarg, 'a'))
2439 auto_reduce_polyphony = (auto_reduce_polyphony) ? 0 : 1;
2442 return parse_opt_Q(optarg);
2444 return parse_opt_q(optarg);
2446 return parse_opt_R(optarg);
2448 return parse_opt_S(optarg);
2450 return parse_opt_s(optarg);
2452 return parse_opt_T(optarg);
2454 return parse_opt_t(optarg);
2456 free_instruments_afterwards = 1;
2459 return parse_opt_volume_curve(optarg);
2461 return parse_opt_v(optarg);
2463 return parse_opt_W(optarg);
2466 return parse_opt_w(optarg);
2469 return parse_opt_x(optarg);
2471 if (strncmp(optarg, "pure", 4))
2472 return parse_opt_Z(optarg);
2474 return parse_opt_Z1(optarg + 4);
2481 /* -------- getopt_long -------- */
2482 MAIN_INTERFACE int set_tim_opt_long(int c, char *optarg, int index)
2484 const struct option *the_option = &(longopts[index]);
2487 if (c == '?') /* getopt_long failed parsing */
2488 parse_opt_fail(optarg);
2489 else if (c < TIM_OPT_FIRST)
2490 return set_tim_opt_short(c, optarg);
2491 if (! strncmp(the_option->name, "no-", 3))
2492 arg = "no"; /* `reverse' switch */
2496 case TIM_OPT_VOLUME:
2497 return parse_opt_A(arg);
2498 case TIM_OPT_DRUM_POWER:
2499 return parse_opt_drum_power(arg);
2500 case TIM_OPT_VOLUME_COMP:
2501 return parse_opt_volume_comp(arg);
2502 case TIM_OPT_ANTI_ALIAS:
2503 return parse_opt_a(arg);
2504 case TIM_OPT_BUFFER_FRAGS:
2505 return parse_opt_B(arg);
2506 case TIM_OPT_CONTROL_RATIO:
2507 return parse_opt_C(arg);
2508 case TIM_OPT_CONFIG_FILE:
2509 return parse_opt_c(arg);
2510 case TIM_OPT_DRUM_CHANNEL:
2511 return parse_opt_D(arg);
2512 case TIM_OPT_IFACE_PATH:
2513 return parse_opt_d(arg);
2515 return parse_opt_E(arg);
2516 case TIM_OPT_MOD_WHEEL:
2517 return parse_opt_mod_wheel(arg);
2518 case TIM_OPT_PORTAMENTO:
2519 return parse_opt_portamento(arg);
2520 case TIM_OPT_VIBRATO:
2521 return parse_opt_vibrato(arg);
2522 case TIM_OPT_CH_PRESS:
2523 return parse_opt_ch_pressure(arg);
2524 case TIM_OPT_MOD_ENV:
2525 return parse_opt_mod_env(arg);
2526 case TIM_OPT_TRACE_TEXT:
2527 return parse_opt_trace_text(arg);
2528 case TIM_OPT_OVERLAP:
2529 return parse_opt_overlap_voice(arg);
2530 case TIM_OPT_TEMPER_CTRL:
2531 return parse_opt_temper_control(arg);
2532 case TIM_OPT_DEFAULT_MID:
2533 return parse_opt_default_mid(arg);
2534 case TIM_OPT_SYSTEM_MID:
2535 return parse_opt_system_mid(arg);
2536 case TIM_OPT_DEFAULT_BANK:
2537 return parse_opt_default_bank(arg);
2538 case TIM_OPT_FORCE_BANK:
2539 return parse_opt_force_bank(arg);
2540 case TIM_OPT_DEFAULT_PGM:
2541 return parse_opt_default_program(arg);
2542 case TIM_OPT_FORCE_PGM:
2543 return parse_opt_force_program(arg);
2545 return parse_opt_delay(arg);
2546 case TIM_OPT_CHORUS:
2547 return parse_opt_chorus(arg);
2548 case TIM_OPT_REVERB:
2549 return parse_opt_reverb(arg);
2550 case TIM_OPT_VOICE_LPF:
2551 return parse_opt_voice_lpf(arg);
2553 return parse_opt_noise_shaping(arg);
2554 #ifndef FIXED_RESAMPLATION
2555 case TIM_OPT_RESAMPLE:
2556 return parse_opt_resample(arg);
2559 return parse_opt_e(arg);
2560 case TIM_OPT_FAST_PAN:
2561 return parse_opt_F(arg);
2562 case TIM_OPT_FAST_DECAY:
2563 return parse_opt_f(arg);
2564 case TIM_OPT_SPECTROGRAM:
2565 return parse_opt_g(arg);
2566 case TIM_OPT_KEYSIG:
2567 return parse_opt_H(arg);
2569 return parse_opt_h(arg);
2570 case TIM_OPT_INTERFACE:
2571 return parse_opt_i(arg);
2572 case TIM_OPT_VERBOSE:
2573 return parse_opt_verbose(arg);
2575 return parse_opt_quiet(arg);
2577 return parse_opt_trace(arg);
2579 return parse_opt_loop(arg);
2580 case TIM_OPT_RANDOM:
2581 return parse_opt_random(arg);
2583 return parse_opt_sort(arg);
2585 case TIM_OPT_BACKGROUND:
2586 return parse_opt_background(arg);
2587 case TIM_OPT_RT_PRIO:
2588 return parse_opt_rt_prio(arg);
2589 case TIM_OPT_SEQ_PORTS:
2590 return parse_opt_seq_ports(arg);
2592 case TIM_OPT_REALTIME_LOAD:
2593 return parse_opt_j(arg);
2594 case TIM_OPT_ADJUST_KEY:
2595 return parse_opt_K(arg);
2596 case TIM_OPT_VOICE_QUEUE:
2597 return parse_opt_k(arg);
2598 case TIM_OPT_PATCH_PATH:
2599 return parse_opt_L(arg);
2600 case TIM_OPT_PCM_FILE:
2601 return parse_opt_M(arg);
2602 case TIM_OPT_DECAY_TIME:
2603 return parse_opt_m(arg);
2604 case TIM_OPT_INTERPOLATION:
2605 return parse_opt_N(arg);
2606 case TIM_OPT_OUTPUT_MODE:
2607 return parse_opt_O(arg);
2608 case TIM_OPT_OUTPUT_STEREO:
2609 if (! strcmp(the_option->name, "output-mono"))
2610 /* --output-mono == --output-stereo=no */
2612 return parse_opt_output_stereo(arg);
2613 case TIM_OPT_OUTPUT_SIGNED:
2614 if (! strcmp(the_option->name, "output-unsigned"))
2615 /* --output-unsigned == --output-signed=no */
2617 return parse_opt_output_signed(arg);
2618 case TIM_OPT_OUTPUT_BITWIDTH:
2619 if (! strcmp(the_option->name, "output-16bit"))
2621 else if (! strcmp(the_option->name, "output-24bit"))
2623 else if (! strcmp(the_option->name, "output-8bit"))
2625 return parse_opt_output_bitwidth(arg);
2626 case TIM_OPT_OUTPUT_FORMAT:
2627 if (! strcmp(the_option->name, "output-linear"))
2629 else if (! strcmp(the_option->name, "output-ulaw"))
2631 else if (! strcmp(the_option->name, "output-alaw"))
2633 return parse_opt_output_format(arg);
2634 case TIM_OPT_OUTPUT_SWAB:
2635 return parse_opt_output_swab(arg);
2636 case TIM_OPT_OUTPUT_FILE:
2637 return parse_opt_o(arg);
2638 case TIM_OPT_PATCH_FILE:
2639 return parse_opt_P(arg);
2640 case TIM_OPT_POLYPHONY:
2641 return parse_opt_p(arg);
2642 case TIM_OPT_POLY_REDUCE:
2643 return parse_opt_p1(arg);
2645 return parse_opt_Q(arg);
2646 case TIM_OPT_TEMPER_MUTE:
2647 return parse_opt_Q1(arg);
2648 case TIM_OPT_AUDIO_BUFFER:
2649 return parse_opt_q(arg);
2650 case TIM_OPT_CACHE_SIZE:
2651 return parse_opt_S(arg);
2652 case TIM_OPT_SAMPLE_FREQ:
2653 return parse_opt_s(arg);
2654 case TIM_OPT_ADJUST_TEMPO:
2655 return parse_opt_T(arg);
2656 case TIM_OPT_CHARSET:
2657 return parse_opt_t(arg);
2658 case TIM_OPT_UNLOAD_INST:
2659 return parse_opt_U(arg);
2660 case TIM_OPT_VOLUME_CURVE:
2661 return parse_opt_volume_curve(arg);
2662 case TIM_OPT_VERSION:
2663 return parse_opt_v(arg);
2665 return parse_opt_W(arg);
2667 case TIM_OPT_RCPCV_DLL:
2668 return parse_opt_w(arg);
2670 case TIM_OPT_CONFIG_STR:
2671 return parse_opt_x(arg);
2672 case TIM_OPT_FREQ_TABLE:
2673 return parse_opt_Z(arg);
2674 case TIM_OPT_PURE_INT:
2675 return parse_opt_Z1(arg);
2676 case TIM_OPT_MODULE:
2677 return parse_opt_default_module(arg);
2679 ctl->cmsg(CMSG_FATAL, VERB_NORMAL,
2680 "[BUG] Inconceivable case branch %d", c);
2685 static inline int parse_opt_A(const char *arg)
2687 /* amplify volume by n percent */
2688 return set_val_i32(&lification, atoi(arg), 0, MAX_AMPLIFICATION,
2692 static inline int parse_opt_drum_power(const char *arg)
2695 return set_val_i32(&opt_drum_power, atoi(arg), 0, MAX_AMPLIFICATION,
2699 static inline int parse_opt_volume_comp(const char *arg)
2701 /* --[no-]volume-compensation */
2702 opt_amp_compensation = y_or_n_p(arg);
2706 static inline int parse_opt_a(const char *arg)
2708 antialiasing_allowed = y_or_n_p(arg);
2712 static inline int parse_opt_B(const char *arg)
2714 /* --buffer-fragments */
2719 if (set_value(&opt_buffer_fragments, atoi(arg), 0, 1000,
2720 "Buffer Fragments (num)"))
2724 if ((p = strchr(arg, ',')) != NULL) {
2725 if (set_value(&audio_buffer_bits, atoi(++p), 1, AUDIO_BUFFER_BITS,
2726 "Buffer Fragments (bit)"))
2732 static inline int parse_opt_C(const char *arg)
2734 if (set_val_i32(&control_ratio, atoi(arg), 0, MAX_CONTROL_RATIO,
2737 opt_control_ratio = control_ratio;
2741 static inline int parse_opt_c(char *arg)
2743 if (read_config_file(arg, 0))
2745 got_a_configuration = 1;
2749 static inline int parse_opt_D(const char *arg)
2751 return set_channel_flag(&default_drumchannels, atoi(arg), "Drum channel");
2754 static inline int parse_opt_d(const char *arg)
2756 /* dynamic lib root */
2758 if (dynamic_lib_root)
2759 free(dynamic_lib_root);
2760 dynamic_lib_root = safe_strdup(arg);
2763 ctl->cmsg(CMSG_WARNING, VERB_NOISY, "-d option is not supported");
2765 #endif /* IA_DYNAMIC */
2768 static inline int parse_opt_E(char *arg)
2770 /* undocumented option --ext */
2776 opt_modulation_wheel = 1;
2779 opt_modulation_wheel = 0;
2788 opt_nrpn_vibrato = 1;
2791 opt_nrpn_vibrato = 0;
2794 opt_channel_pressure = 1;
2797 opt_channel_pressure = 0;
2800 opt_modulation_envelope = 1;
2803 opt_modulation_envelope = 0;
2806 opt_trace_text_meta_event = 1;
2809 opt_trace_text_meta_event = 0;
2812 opt_overlap_voice_allow = 1;
2815 opt_overlap_voice_allow = 0;
2818 opt_temper_control = 1;
2821 opt_temper_control = 0;
2824 if (parse_opt_default_mid(arg + 1))
2829 if (parse_opt_system_mid(arg + 1))
2834 if (parse_opt_default_bank(arg + 1))
2836 while (isdigit(*(arg + 1)))
2840 if (parse_opt_force_bank(arg + 1))
2842 while (isdigit(*(arg + 1)))
2846 if (parse_opt_default_program(arg + 1))
2848 while (isdigit(*(arg + 1)) || *(arg + 1) == '/')
2852 if (parse_opt_force_program(arg + 1))
2854 while (isdigit(*(arg + 1)) || *(arg + 1) == '/')
2858 if (strncmp(arg + 1, "delay=", 6) == 0) {
2859 if (parse_opt_delay(arg + 7))
2861 } else if (strncmp(arg + 1, "chorus=", 7) == 0) {
2862 if (parse_opt_chorus(arg + 8))
2864 } else if (strncmp(arg + 1, "reverb=", 7) == 0) {
2865 if (parse_opt_reverb(arg + 8))
2867 } else if (strncmp(arg + 1, "ns=", 3) == 0) {
2868 if (parse_opt_noise_shaping(arg + 4))
2870 #ifndef FIXED_RESAMPLATION
2871 } else if (strncmp(arg + 1, "resamp=", 7) == 0) {
2872 if (parse_opt_resample(arg + 8))
2877 ctl->cmsg(CMSG_ERROR,
2878 VERB_NORMAL, "-E%s: unsupported effect", arg);
2883 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
2884 "-E: Illegal mode `%c'", *arg);
2893 static inline int parse_opt_mod_wheel(const char *arg)
2895 /* --[no-]mod-wheel */
2896 opt_modulation_wheel = y_or_n_p(arg);
2900 static inline int parse_opt_portamento(const char *arg)
2902 /* --[no-]portamento */
2903 opt_portamento = y_or_n_p(arg);
2907 static inline int parse_opt_vibrato(const char *arg)
2909 /* --[no-]vibrato */
2910 opt_nrpn_vibrato = y_or_n_p(arg);
2914 static inline int parse_opt_ch_pressure(const char *arg)
2916 /* --[no-]ch-pressure */
2917 opt_channel_pressure = y_or_n_p(arg);
2921 static inline int parse_opt_mod_env(const char *arg)
2923 /* --[no-]mod-envelope */
2924 opt_modulation_envelope = y_or_n_p(arg);
2928 static inline int parse_opt_trace_text(const char *arg)
2930 /* --[no-]trace-text-meta */
2931 opt_trace_text_meta_event = y_or_n_p(arg);
2935 static inline int parse_opt_overlap_voice(const char *arg)
2937 /* --[no-]overlap-voice */
2938 opt_overlap_voice_allow = y_or_n_p(arg);
2942 static inline int parse_opt_temper_control(const char *arg)
2944 /* --[no-]temper-control */
2945 opt_temper_control = y_or_n_p(arg);
2949 static inline int parse_opt_default_mid(char *arg)
2952 int val = str2mID(arg);
2955 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Manufacture ID: Illegal value");
2958 opt_default_mid = val;
2962 static inline int parse_opt_system_mid(char *arg)
2965 int val = str2mID(arg);
2968 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Manufacture ID: Illegal value");
2971 opt_system_mid = val;
2975 static inline int parse_opt_default_bank(const char *arg)
2977 /* --default-bank */
2978 if (set_value(&default_tonebank, atoi(arg), 0, 0x7f, "Bank number"))
2980 special_tonebank = -1;
2984 static inline int parse_opt_force_bank(const char *arg)
2987 if (set_value(&special_tonebank, atoi(arg), 0, 0x7f, "Bank number"))
2992 static inline int parse_opt_default_program(const char *arg)
2994 /* --default-program */
2998 if (set_value(&prog, atoi(arg), 0, 0x7f, "Program number"))
3000 if ((p = strchr(arg, '/')) != NULL) {
3001 if (set_value(&i, atoi(++p), 1, MAX_CHANNELS, "Program channel"))
3003 default_program[i - 1] = prog;
3005 for (i = 0; i < MAX_CHANNELS; i++)
3006 default_program[i] = prog;
3010 static inline int parse_opt_force_program(const char *arg)
3012 /* --force-program */
3016 if (set_value(&def_prog, atoi(arg), 0, 0x7f, "Program number"))
3019 set_default_program(def_prog);
3020 if ((p = strchr(arg, '/')) != NULL) {
3021 if (set_value(&i, atoi(++p), 1, MAX_CHANNELS, "Program channel"))
3023 default_program[i - 1] = SPECIAL_PROGRAM;
3025 for (i = 0; i < MAX_CHANNELS; i++)
3026 default_program[i] = SPECIAL_PROGRAM;
3030 static inline int set_default_program(int prog)
3035 bank = (special_tonebank >= 0) ? special_tonebank : default_tonebank;
3036 if ((ip = play_midi_load_instrument(0, bank, prog)) == NULL)
3038 default_instrument = ip;
3042 static inline int parse_opt_delay(const char *arg)
3049 case 'd': /* disable */
3050 effect_lr_mode = -1;
3052 case 'l': /* left */
3055 case 'r': /* right */
3058 case 'b': /* both */
3062 if ((p = strchr(arg, ',')) != NULL)
3063 if ((effect_lr_delay_msec = atoi(++p)) < 0) {
3064 effect_lr_delay_msec = 0;
3065 effect_lr_mode = -1;
3066 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Invalid delay parameter.");
3072 static inline int parse_opt_chorus(const char *arg)
3079 case 'd': /* disable */
3080 opt_chorus_control = 0;
3081 opt_surround_chorus = 0;
3084 case 'n': /* normal */
3086 case 's': /* surround */
3087 opt_surround_chorus = (*arg == '2' || *arg == 's') ? 1 : 0;
3088 if ((p = strchr(arg, ',')) != NULL) {
3089 if (set_value(&opt_chorus_control, atoi(++p), 0, 0x7f,
3092 opt_chorus_control = -opt_chorus_control;
3094 opt_chorus_control = 1;
3097 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Invalid chorus parameter.");
3103 static inline int parse_opt_reverb(const char *arg)
3108 /* option action opt_reverb_control
3109 * reverb=0 no reverb 0
3110 * reverb=1 old reverb 1
3111 * reverb=1,n set reverb level to n (-1 to -127)
3112 * reverb=2 "global" old reverb 2
3113 * reverb=2,n set reverb level to n (-1 to -127) - 128
3114 * reverb=3 new reverb 3
3115 * reverb=3,n set reverb level to n (-1 to -127) - 256
3116 * reverb=4 "global" new reverb 4
3117 * reverb=4,n set reverb level to n (-1 to -127) - 384
3119 * I think "global" was meant to apply a single global reverb,
3120 * without applying any reverb to the channels. The do_effects()
3121 * function in effects.c looks like a good way to do this.
3123 * This is NOT the "correct" way to implement global reverb, we should
3124 * really make a new variable just for that. But if opt_reverb_control
3125 * is already used in a similar fashion, rather than creating a new
3126 * variable for setting the channel reverb levels, then I guess
3127 * maybe this isn't so bad.... It would be nice to create new
3128 * variables for both global reverb and channel reverb level settings
3129 * in the future, but this will do for now.
3134 case 'd': /* disable */
3135 opt_reverb_control = 0;
3138 case 'n': /* normal */
3139 if ((p = strchr(arg, ',')) != NULL) {
3140 if (set_value(&opt_reverb_control, atoi(++p), 1, 0x7f,
3143 opt_reverb_control = -opt_reverb_control;
3145 opt_reverb_control = 1;
3148 case 'g': /* global */
3149 if ((p = strchr(arg, ',')) != NULL) {
3150 if (set_value(&opt_reverb_control, atoi(++p), 1, 0x7f,
3153 opt_reverb_control = -opt_reverb_control - 128;
3155 opt_reverb_control = 2;
3158 case 'f': /* freeverb */
3159 if ((p = strchr(arg, ',')) != NULL) {
3160 if (set_value(&opt_reverb_control, atoi(++p), 1, 0x7f,
3163 opt_reverb_control = -opt_reverb_control - 256;
3165 opt_reverb_control = 3;
3168 case 'G': /* global freeverb */
3169 if ((p = strchr(arg, ',')) != NULL) {
3170 if (set_value(&opt_reverb_control, atoi(++p), 1, 0x7f,
3173 opt_reverb_control = -opt_reverb_control - 384;
3175 opt_reverb_control = 4;
3178 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Invalid reverb parameter.");
3184 static inline int parse_opt_voice_lpf(const char *arg)
3189 case 'd': /* disable */
3193 case 'c': /* chamberlin */
3197 case 'm': /* moog */
3201 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Invalid voice LPF type %s", arg);
3207 /* Noise Shaping filter from
3208 * Kunihiko IMAI <imai@leo.ec.t.kanazawa-u.ac.jp>
3210 static inline int parse_opt_noise_shaping(const char *arg)
3212 /* --noise-shaping */
3213 if (set_value(&noise_sharp_type, atoi(arg), 0, 4, "Noise shaping type"))
3218 static inline int parse_opt_resample(const char *arg)
3223 case 'd': /* disable */
3224 set_current_resampler(RESAMPLE_NONE);
3227 case 'l': /* linear */
3228 set_current_resampler(RESAMPLE_LINEAR);
3231 case 'c': /* cspline */
3232 set_current_resampler(RESAMPLE_CSPLINE);
3235 case 'L': /* lagrange */
3236 set_current_resampler(RESAMPLE_LAGRANGE);
3239 case 'n': /* newton */
3240 set_current_resampler(RESAMPLE_NEWTON);
3243 case 'g': /* guass */
3244 set_current_resampler(RESAMPLE_GAUSS);
3247 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Invalid resample type %s", arg);
3253 static inline int parse_opt_e(const char *arg)
3260 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "-e option is not supported");
3262 #endif /* __W32__ */
3265 static inline int parse_opt_F(const char *arg)
3267 adjust_panning_immediately = y_or_n_p(arg);
3271 static inline int parse_opt_f(const char *arg)
3273 fast_decay = y_or_n_p(arg);
3277 static inline int parse_opt_g(const char *arg)
3279 #ifdef SUPPORT_SOUNDSPEC
3280 spectrogram_update_sec = atof(arg);
3281 if (spectrogram_update_sec <= 0) {
3282 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
3283 "Invalid -g argument: `%s'", arg);
3286 view_soundspec_flag = 1;
3289 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "-g option is not supported");
3291 #endif /* SUPPORT_SOUNDSPEC */
3294 static inline int parse_opt_H(const char *arg)
3296 /* force keysig (number of sharp/flat) */
3299 if (set_value(&keysig, atoi(arg), -7, 7,
3300 "Force keysig (number of sHarp(+)/flat(-))"))
3302 opt_force_keysig = keysig;
3306 __attribute__((noreturn))
3307 static inline int parse_opt_h(const char *arg)
3309 static char *help_list[] = {
3310 "TiMidity++ version %s (C) 1999-2003 Masanao Izumo <mo@goice.co.jp>",
3311 "The original version (C) 1995 Tuukka Toivonen <tt@cgs.fi>",
3312 "TiMidity is free software and comes with ABSOLUTELY NO WARRANTY.",
3315 "Win32 version by Davide Moretti <dave@rimini.com>",
3316 " and Daisuke Aoki <dai@y7.net>",
3318 #endif /* __W32__ */
3320 " %s [options] filename [...]",
3322 #ifndef __W32__ /*does not work in Windows */
3323 " Use \"-\" as filename to read a MIDI file from stdin",
3327 " -A n,m --volume=n, --drum-power=m",
3328 " Amplify volume by n percent (may cause clipping),",
3329 " and amplify drum power by m percent",
3330 " (a) --[no-]volume-compensation",
3331 " Toggle amplify compensation (disabled by default)",
3332 " -a --[no-]anti-alias",
3333 " Enable the anti-aliasing filter",
3334 " -B n,m --buffer-fragments=n,m",
3335 " Set number of buffer fragments(n), and buffer size(2^m)",
3336 " -C n --control-ratio=n",
3337 " Set ratio of sampling and control frequencies",
3338 " -c file --config-file=file",
3339 " Read extra configuration file",
3340 " -D n --drum-channel=n",
3341 " Play drums on channel n",
3343 " -d path --interface-path=path",
3344 " Set dynamic interface module directory",
3345 #endif /* IA_DYNAMIC */
3346 " -E mode --ext=mode",
3347 " TiMidity sequencer extensional modes:",
3348 " mode = w/W : Enable/Disable Modulation wheel",
3349 " p/P : Enable/Disable Portamento",
3350 " v/V : Enable/Disable NRPN Vibrato",
3351 " s/S : Enable/Disable Channel pressure",
3352 " e/E : Enable/Disable Modulation Envelope",
3353 " t/T : Enable/Disable Trace Text Meta Event at playing",
3354 " o/O : Enable/Disable Overlapped voice",
3355 " z/Z : Enable/Disable Temperament control",
3356 " m<HH>: Define default Manufacture ID <HH> in two hex",
3357 " M<HH>: Define system Manufacture ID <HH> in two hex",
3358 " b<n>: Use tone bank <n> as the default",
3359 " B<n>: Always use tone bank <n>",
3360 " i<n/m>: Use program <n> on channel <m> as the default",
3361 " I<n/m>: Always use program <n> on channel <m>",
3362 " F<args>: For effect. See below for effect options",
3364 #ifdef MODULATION_WHEEL_ALLOW
3368 #endif /* MODULATION_WHEEL_ALLOW */
3369 #ifdef PORTAMENTO_ALLOW
3373 #endif /* PORTAMENTO_ALLOW */
3374 #ifdef NRPN_VIBRATO_ALLOW
3378 #endif /* NRPN_VIBRATO_ALLOW */
3379 #ifdef GM_CHANNEL_PRESSURE_ALLOW
3383 #endif /* GM_CHANNEL_PRESSURE_ALLOW */
3384 #ifdef MODULATION_ENVELOPE_ALLOW
3388 #endif /* MODULATION_ENVELOPE_ALLOW */
3389 #ifdef ALWAYS_TRACE_TEXT_META_EVENT
3393 #endif /* ALWAYS_TRACE_TEXT_META_EVENT */
3394 #ifdef OVERLAP_VOICE_ALLOW
3398 #endif /* OVERLAP_VOICE_ALLOW */
3399 #ifdef TEMPER_CONTROL_ALLOW
3403 #endif /* TEMPER_CONTROL_ALLOW */
3407 " Increase thread priority (evil) - be careful!",
3409 " -F --[no-]fast-panning",
3410 " Disable/Enable fast panning (toggle on/off, default is on)",
3411 " -f --[no-]fast-decay",
3418 "fast decay mode (toggle)",
3419 #ifdef SUPPORT_SOUNDSPEC
3420 " -g sec --spectrogram=sec",
3421 " Open Sound-Spectrogram Window",
3422 #endif /* SUPPORT_SOUNDSPEC */
3423 " -H n --force-keysig=n",
3424 " Force keysig number of sHarp(+)/flat(-) (-7..7)",
3426 " Display this help message",
3427 " -i mode --interface=mode",
3428 " Select user interface (see below for list)",
3430 " --realtime-priority=n (for alsaseq only)",
3431 " Set the realtime priority (0-100)",
3432 " --sequencer-ports=n (for alsaseq only)",
3433 " Set the number of opened sequencer ports (default is 4)",
3435 " -j --[no-]realtime-load",
3436 " Realtime load instrument (toggle on/off)",
3437 " -K n --adjust-key=n",
3438 " Adjust key by n half tone (-24..24)",
3439 " -k msec --voice-queue=msec",
3440 " Specify audio queue time limit to reduce voice",
3441 " -L path --patch-path=path",
3442 " Append dir to search path",
3443 " -M name --pcm-file=name",
3444 " Specify PCM filename (*.wav or *.aiff) to be played or:",
3445 " \"auto\" : Play *.mid.wav or *.mid.aiff",
3446 " \"none\" : Disable this feature (default)",
3447 " -m msec --decay-time=msec",
3448 " Minimum time for a full volume sustained note to decay,",
3450 " -N n --interpolation=n",
3451 " Set the interpolation parameter (depends on -EFresamp option)",
3452 " Linear interpolation is used if audio queue < 99%%",
3453 " cspline, lagrange:",
3454 " Toggle 4-point interpolation (default on)",
3456 " n'th order Newton polynomial interpolation, n=1-57 odd",
3458 " n+1 point Gauss-like interpolation, n=1-34 (default 25)",
3459 " -O mode --output-mode=mode",
3460 " Select output mode and format (see below for list)",
3461 " -o file --output-file=file",
3462 " Output to another file (or device/server) (Use \"-\" for stdout)",
3463 " -P file --patch-file=file",
3464 " Use patch file for all programs",
3465 " -p n --polyphony=n",
3466 " Allow n-voice polyphony. Optional auto polyphony reduction",
3467 " (a) --[no-]polyphony-reduction",
3468 " Toggle automatic polyphony reduction. Enabled by default",
3469 " -Q n[,...] --mute=n[,...]",
3470 " Ignore channel n (0: ignore all, -n: resume channel n)",
3471 " (t) --temper-mute=n[,...]",
3472 " Quiet temperament type n (0..3: preset, 4..7: user-defined)",
3473 " -q sec/n --audio-buffer=sec/n",
3474 " Specify audio buffer in seconds",
3475 " sec: Maxmum buffer, n: Filled to start (default is 5.0/100%%)",
3476 " (size of 100%% equals device buffer size)",
3477 " -R msec Pseudo reveb effect (set every instrument's release to msec)",
3478 " if n=0, n is set to 800",
3479 " -S n --cache-size=n",
3480 " Cache size (0 means no cache)",
3481 " -s freq --sampling-freq=freq",
3482 " Set sampling frequency to freq (Hz or kHz)",
3483 " -T n --adjust-tempo=n",
3484 " Adjust tempo to n%%,",
3485 " 120=play MOD files with an NTSC Amiga's timing",
3486 " -t code --output-charset=code",
3487 " Output text language code:",
3488 " code=auto : Auto conversion by `LANG' environment variable",
3490 " ascii : Convert unreadable characters to '.' (0x2e)",
3491 " nocnv : No conversion",
3492 " 1251 : Convert from windows-1251 to koi8-r",
3496 " sjis : shift JIS",
3497 #endif /* JAPANESE */
3498 " -U --[no-]unload-instruments",
3499 " Unload instruments from memory between MIDI files",
3500 " -V power --volume-curve=power",
3501 " Define the velocity/volume/expression curve",
3502 " amp = vol^power (auto: 0, linear: 1, ideal: ~1.661, GS: ~2)",
3504 " Display TiMidity version information",
3505 " -W mode --wrd=mode",
3506 " Select WRD interface (see below for list)",
3508 " -w mode --rcpcv-dll=mode",
3509 " Windows extensional modes:",
3510 " mode=r/R : Enable/Disable rcpcv.dll",
3511 #endif /* __W32__ */
3512 " -x str --config-string=str",
3513 " Read configuration str from command line argument",
3514 " -Z file --freq-table=file",
3515 " Load frequency table (Use \"pure\" for pure intonation)",
3516 " pure<n>(m) --pure-intonation=n(m)",
3517 " Initial keysig number <n> of sharp(+)/flat(-) (-7..7)",
3518 " 'm' stands for minor mode",
3520 " Simulate behavior of specific synthesizer module by n",
3521 " n=0 : TiMidity++ Default (default)",
3522 " 1-15 : GS family",
3523 " 16-31 : XG family",
3524 " 32-111 : SoundBlaster and other systhesizer modules",
3525 " 112-127 : TiMidity++ specification purposes",
3528 static char *help_args[3];
3532 ControlMode *cmp, **cmpp;
3534 PlayMode *pmp, **pmpp;
3535 WRDTracer *wlp, **wlpp;
3538 help_args[0] = timidity_version;
3539 help_args[1] = program_name;
3540 help_args[2] = NULL;
3541 for (i = 0, j = 0; (h = help_list[i]) != NULL; i++) {
3542 if (strchr(h, '%')) {
3543 if (*(strchr(h, '%') + 1) != '%')
3544 fprintf(fp, h, help_args[j++]);
3552 fputs("Effect options (-EF, --ext=F option):" NLS
3553 " -EFdelay=d Disable delay effect (default)" NLS
3554 " -EFdelay=l Enable Left delay" NLS
3555 " [,msec] `msec' is optional to specify left-right delay time" NLS
3556 " -EFdelay=r Enable Right delay" NLS
3557 " [,msec] `msec' is optional to specify left-right delay time" NLS
3558 " -EFdelay=b Enable rotate Both left and right" NLS
3559 " [,msec] `msec' is optional to specify left-right delay time" NLS
3560 " -EFchorus=d Disable MIDI chorus effect control" NLS
3561 " -EFchorus=n Enable Normal MIDI chorus effect control" NLS
3562 " [,level] `level' is optional to specify chorus level [0..127]" NLS
3564 " -EFchorus=s Surround sound, chorus detuned to a lesser degree" NLS
3565 " [,level] `level' is optional to specify chorus level [0..127]" NLS
3566 " -EFreverb=d Disable MIDI reverb effect control" NLS
3567 " -EFreverb=n Enable Normal MIDI reverb effect control" NLS
3568 " [,level] `level' is optional to specify reverb level [1..127]" NLS
3569 " -EFreverb=g Global reverb effect" NLS
3570 " [,level] `level' is optional to specify reverb level [1..127]" NLS
3571 " -EFreverb=f Enable Freeverb MIDI reverb effect control (default)" NLS
3572 " [,level] `level' is optional to specify reverb level [1..127]" NLS
3573 " -EFreverb=G Global Freeverb effect" NLS
3574 " [,level] `level' is optional to specify reverb level [1..127]" NLS
3575 " -EFvlpf=d Disable voice LPF" NLS
3576 " -EFvlpf=c Enable Chamberlin resonant LPF (12dB/oct) (default)" NLS
3577 " -EFvlpf=m Enable Moog resonant lowpass VCF (24dB/oct)" NLS
3578 " -EFns=n Enable the n th degree (type) noise shaping filter" NLS
3579 " n:[0..4] (for 8-bit linear encoding, default is 4)" NLS
3580 " n:[0..4] (for 16-bit linear encoding, default is 4)" NLS, fp);
3581 #ifndef FIXED_RESAMPLATION
3583 " -EFresamp=d Disable resamplation" NLS
3584 " -EFresamp=l Enable Linear resample algorithm" NLS
3585 " -EFresamp=c Enable C-spline resample algorithm" NLS
3586 " -EFresamp=L Enable Lagrange resample algorithm" NLS
3587 " -EFresamp=n Enable Newton resample algorithm" NLS
3588 " -EFresamp=g Enable Gauss-like resample algorithm (default)" NLS
3589 " -EFresamp affects the behavior of -N option" NLS, fp);
3592 fputs("Alternative TiMidity sequencer extensional mode long options:" NLS
3593 " --[no-]mod-wheel" NLS
3594 " --[no-]portamento" NLS
3595 " --[no-]vibrato" NLS
3596 " --[no-]ch-pressure" NLS
3597 " --[no-]mod-envelope" NLS
3598 " --[no-]trace-text-meta" NLS
3599 " --[no-]overlap-voice" NLS
3600 " --[no-]temper-control" NLS
3601 " --default-mid=<HH>" NLS
3602 " --system-mid=<HH>" NLS
3603 " --default-bank=n" NLS
3604 " --force-bank=n" NLS
3605 " --default-program=n/m" NLS
3606 " --force-program=n/m" NLS
3607 " --delay=(d|l|r|b)[,msec]" NLS
3608 " --chorus=(d|n|s)[,level]" NLS
3609 " --reverb=(d|n|g|f|G)[,level]" NLS
3610 " --voice-lpf=(d|c|m)" NLS
3611 " --noise-shaping=n" NLS, fp);
3612 #ifndef FIXED_RESAMPLATION
3613 fputs(" --resample=(d|l|c|L|n|g)" NLS, fp);
3616 fputs("Available interfaces (-i, --interface option):" NLS, fp);
3617 for (cmpp = ctl_list; (cmp = *cmpp) != NULL; cmpp++)
3619 if (cmp->id_character != dynamic_interface_id)
3620 fprintf(fp, " -i%c %s" NLS,
3621 cmp->id_character, cmp->id_name);
3623 fprintf(fp, " -i%c %s" NLS,
3624 cmp->id_character, cmp->id_name);
3625 #endif /* IA_DYNAMIC */
3627 fprintf(fp, "Supported dynamic load interfaces (%s):" NLS,
3629 memset(mark, 0, sizeof(mark));
3630 for (cmpp = ctl_list; (cmp = *cmpp) != NULL; cmpp++)
3631 mark[(int) cmp->id_character] = 1;
3632 if (dynamic_interface_id != 0)
3633 mark[(int) dynamic_interface_id] = 0;
3634 list_dyna_interface(fp, dynamic_lib_root, mark);
3635 #endif /* IA_DYNAMIC */
3637 fputs("Interface options (append to -i? option):" NLS
3638 " `v' more verbose (cumulative)" NLS
3639 " `q' quieter (cumulative)" NLS
3640 " `t' trace playing" NLS
3641 " `l' loop playing (some interface ignore this option)" NLS
3642 " `r' randomize file list arguments before playing" NLS
3643 " `s' sorting file list arguments before playing" NLS, fp);
3645 fputs(" `D' daemonize TiMidity++ in background "
3646 "(for alsaseq only)" NLS, fp);
3649 fputs("Alternative interface long options:" NLS
3654 " --[no-]random" NLS
3655 " --[no-]sort" NLS, fp);
3657 fputs(" --[no-]background" NLS, fp);
3660 fputs("Available output modes (-O, --output-mode option):" NLS, fp);
3661 for (pmpp = play_mode_list; (pmp = *pmpp) != NULL; pmpp++)
3662 fprintf(fp, " -O%c %s" NLS,
3663 pmp->id_character, pmp->id_name);
3665 fputs("Output format options (append to -O? option):" NLS
3667 " `M' monophonic" NLS
3668 " `s' signed output" NLS
3669 " `u' unsigned output" NLS
3670 " `1' 16-bit sample width" NLS
3671 " `2' 24-bit sample width" NLS
3672 " `8' 8-bit sample width" NLS
3673 " `l' linear encoding" NLS
3674 " `U' U-Law encoding" NLS
3675 " `A' A-Law encoding" NLS
3676 " `x' byte-swapped output" NLS, fp);
3678 fputs("Alternative output format long options:" NLS
3679 " --output-stereo" NLS
3680 " --output-mono" NLS
3681 " --output-signed" NLS
3682 " --output-unsigned" NLS
3683 " --output-16bit" NLS
3684 " --output-24bit" NLS
3685 " --output-8bit" NLS
3686 " --output-linear" NLS
3687 " --output-ulaw" NLS
3688 " --output-alaw" NLS
3689 " --[no-]output-swab" NLS, fp);
3691 fputs("Available WRD interfaces (-W, --wrd option):" NLS, fp);
3692 for (wlpp = wrdt_list; (wlp = *wlpp) != NULL; wlpp++)
3693 fprintf(fp, " -W%c %s" NLS, wlp->id, wlp->name);
3700 static inline void list_dyna_interface(FILE *fp, char *path, char *mark)
3703 char fname[BUFSIZ], *info;
3706 if ((url = url_dir_open(path)) == NULL)
3708 while (url_gets(url, fname, sizeof(fname)) != NULL)
3709 if (strncmp(fname, "interface_", 10) == 0) {
3714 if ((info = dynamic_interface_info(id)) == NULL)
3715 info = dynamic_interface_module(id);
3717 fprintf(fp, " -i%c %s" NLS, id, info);
3722 static inline char *dynamic_interface_info(int id)
3724 static char libinfo[MAXPATHLEN];
3728 sprintf(libinfo, "%s" PATH_STRING "interface_%c.txt",
3729 dynamic_lib_root, id);
3730 if ((fd = open(libinfo, 0)) < 0)
3732 n = read(fd, libinfo, sizeof(libinfo) - 1);
3737 if ((nl = strchr(libinfo, '\n')) == libinfo)
3741 if (*(nl - 1) == '\r')
3747 char *dynamic_interface_module(int id)
3749 static char shared_library[MAXPATHLEN];
3752 sprintf(shared_library, "%s" PATH_STRING "interface_%c%s",
3753 dynamic_lib_root, id, SHARED_LIB_EXT);
3754 if ((fd = open(shared_library, 0)) < 0)
3757 return shared_library;
3759 #endif /* IA_DYNAMIC */
3761 static inline int parse_opt_i(const char *arg)
3763 /* interface mode */
3764 ControlMode *cmp, **cmpp;
3767 for (cmpp = ctl_list; (cmp = *cmpp) != NULL; cmpp++) {
3768 if (cmp->id_character == *arg) {
3771 #if defined(IA_W32GUI) || defined(IA_W32G_SYN)
3773 cmp->trace_playing = 0;
3775 #endif /* IA_W32GUI */
3779 if (cmp->id_character == dynamic_interface_id
3780 && dynamic_interface_module(*arg)) {
3781 /* Dynamic interface loader */
3784 if (dynamic_interface_id != *arg) {
3785 cmp->id_character = dynamic_interface_id = *arg;
3787 cmp->trace_playing = 0;
3792 #endif /* IA_DYNAMIC */
3795 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
3796 "Interface `%c' is not compiled in.", *arg);
3807 case 't': /* toggle */
3808 cmp->trace_playing = (cmp->trace_playing) ? 0 : 1;
3811 cmp->flags ^= CTLF_LIST_LOOP;
3814 cmp->flags ^= CTLF_LIST_RANDOM;
3817 cmp->flags ^= CTLF_LIST_SORT;
3820 cmp->flags ^= CTLF_AUTOSTART;
3823 cmp->flags ^= CTLF_AUTOEXIT;
3826 cmp->flags ^= CTLF_DRAG_START;
3829 cmp->flags ^= CTLF_AUTOUNIQ;
3832 cmp->flags ^= CTLF_AUTOREFINE;
3835 cmp->flags ^= CTLF_NOT_CONTINUE;
3839 cmp->flags ^= CTLF_DAEMONIZE;
3843 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
3844 "Unknown interface option `%c'", *arg);
3850 static inline int parse_opt_verbose(const char *arg)
3853 ctl->verbosity += (arg) ? atoi(arg) : 1;
3857 static inline int parse_opt_quiet(const char *arg)
3860 ctl->verbosity -= (arg) ? atoi(arg) : 1;
3864 static inline int parse_opt_trace(const char *arg)
3867 ctl->trace_playing = y_or_n_p(arg);
3871 static inline int parse_opt_loop(const char *arg)
3874 return set_flag(&(ctl->flags), CTLF_LIST_LOOP, arg);
3877 static inline int parse_opt_random(const char *arg)
3880 return set_flag(&(ctl->flags), CTLF_LIST_RANDOM, arg);
3883 static inline int parse_opt_sort(const char *arg)
3886 return set_flag(&(ctl->flags), CTLF_LIST_SORT, arg);
3890 static inline int parse_opt_background(const char *arg)
3892 /* --[no-]background */
3893 return set_flag(&(ctl->flags), CTLF_DAEMONIZE, arg);
3896 static inline int parse_opt_rt_prio(const char *arg)
3898 /* --realtime-priority */
3899 if (set_value(&opt_realtime_priority, atoi(arg), 0, 100,
3900 "Realtime priority"))
3905 static inline int parse_opt_seq_ports(const char *arg)
3907 /* --sequencer-ports */
3908 if (set_value(&opt_sequencer_ports, atoi(arg), 1, 16,
3909 "Number of sequencer ports"))
3915 static inline int parse_opt_j(const char *arg)
3917 opt_realtime_playing = y_or_n_p(arg);
3921 static inline int parse_opt_K(const char *arg)
3924 if (set_value(&key_adjust, atoi(arg), -24, 24, "Key adjust"))
3929 static inline int parse_opt_k(const char *arg)
3931 reduce_voice_threshold = atoi(arg);
3935 static inline int parse_opt_L(char *arg)
3937 add_to_pathlist(arg);
3938 try_config_again = 1;
3942 static inline int parse_opt_M(const char *arg)
3944 if (pcm_alternate_file)
3945 free(pcm_alternate_file);
3946 pcm_alternate_file = safe_strdup(arg);
3950 static inline int parse_opt_m(const char *arg)
3952 min_sustain_time = atoi(arg);
3953 if (min_sustain_time < 0)
3954 min_sustain_time = 0;
3958 static inline int parse_opt_N(const char *arg)
3962 switch (get_current_resampler()) {
3963 case RESAMPLE_CSPLINE:
3964 case RESAMPLE_LAGRANGE:
3965 no_4point_interpolation = y_or_n_p(arg);
3967 case RESAMPLE_NEWTON:
3968 case RESAMPLE_GAUSS:
3969 if (! (val = atoi(arg)))
3970 /* set to linear interpolation for compatibility */
3971 set_current_resampler(RESAMPLE_LINEAR);
3972 else if (set_resampler_parm(val)) {
3973 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Invalid -N value");
3981 static inline int parse_opt_O(const char *arg)
3984 PlayMode *pmp, **pmpp;
3987 for (pmpp = play_mode_list; (pmp = *pmpp) != NULL; pmpp++)
3988 if (pmp->id_character == *arg) {
3994 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
3995 "Playmode `%c' is not compiled in.", *arg);
4000 case 'S': /* stereo */
4001 pmp->encoding &= ~PE_MONO;
4004 pmp->encoding |= PE_MONO;
4007 pmp->encoding |= PE_SIGNED;
4008 pmp->encoding &= ~(PE_ULAW | PE_ALAW);
4011 pmp->encoding &= ~PE_SIGNED;
4012 pmp->encoding &= ~(PE_ULAW | PE_ALAW);
4014 case '1': /* 1 for 16-bit */
4015 pmp->encoding |= PE_16BIT;
4016 pmp->encoding &= ~(PE_24BIT | PE_ULAW | PE_ALAW);
4018 case '2': /* 2 for 24-bit */
4019 pmp->encoding |= PE_24BIT;
4020 pmp->encoding &= ~(PE_16BIT | PE_ULAW | PE_ALAW);
4023 pmp->encoding &= ~(PE_16BIT | PE_24BIT);
4025 case 'l': /* linear */
4026 pmp->encoding &= ~(PE_ULAW | PE_ALAW);
4028 case 'U': /* uLaw */
4029 pmp->encoding |= PE_ULAW;
4030 pmp->encoding &= ~(PE_SIGNED
4031 | PE_16BIT | PE_24BIT | PE_ALAW | PE_BYTESWAP);
4033 case 'A': /* aLaw */
4034 pmp->encoding |= PE_ALAW;
4035 pmp->encoding &= ~(PE_SIGNED
4036 | PE_16BIT | PE_24BIT | PE_ULAW | PE_BYTESWAP);
4039 pmp->encoding ^= PE_BYTESWAP; /* toggle */
4040 pmp->encoding &= ~(PE_ULAW | PE_ALAW);
4043 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
4044 "Unknown format modifier `%c'", *arg);
4050 static inline int parse_opt_output_stereo(const char *arg)
4052 /* --output-stereo, --output-mono */
4054 /* I first thought --mono should be the syntax sugar to
4055 * --stereo=no, but the source said stereo should be !PE_MONO,
4056 * not mono should be !PE_STEREO. Perhaps I took a wrong
4059 play_mode->encoding &= ~PE_MONO;
4061 play_mode->encoding |= PE_MONO;
4065 static inline int parse_opt_output_signed(const char *arg)
4067 /* --output-singed, --output-unsigned */
4068 if (set_flag(&(play_mode->encoding), PE_SIGNED, arg))
4070 play_mode->encoding &= ~(PE_ULAW | PE_ALAW);
4074 static inline int parse_opt_output_bitwidth(const char *arg)
4076 /* --output-16bit, --output-24bit, --output-8bit */
4078 case '1': /* 16bit */
4079 play_mode->encoding |= PE_16BIT;
4080 play_mode->encoding &= ~(PE_24BIT | PE_ULAW | PE_ALAW);
4082 case '2': /* 24bit */
4083 play_mode->encoding |= PE_24BIT;
4084 play_mode->encoding &= ~(PE_16BIT | PE_ULAW | PE_ALAW);
4086 case '8': /* 8bit */
4087 play_mode->encoding &= ~(PE_16BIT | PE_24BIT);
4090 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Invalid output bitwidth %s", arg);
4095 static inline int parse_opt_output_format(const char *arg)
4097 /* --output-linear, --output-ulaw, --output-alaw */
4099 case 'l': /* linear */
4100 play_mode->encoding &= ~(PE_ULAW | PE_ALAW);
4102 case 'u': /* uLaw */
4103 play_mode->encoding |= PE_ULAW;
4104 play_mode->encoding &=
4105 ~(PE_SIGNED | PE_16BIT | PE_24BIT | PE_ALAW | PE_BYTESWAP);
4107 case 'a': /* aLaw */
4108 play_mode->encoding |= PE_ALAW;
4109 play_mode->encoding &=
4110 ~(PE_SIGNED | PE_16BIT | PE_24BIT | PE_ULAW | PE_BYTESWAP);
4113 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Invalid output format %s", arg);
4118 static inline int parse_opt_output_swab(const char *arg)
4120 /* --[no-]output-swab */
4121 if (set_flag(&(play_mode->encoding), PE_BYTESWAP, arg))
4123 play_mode->encoding &= ~(PE_ULAW | PE_ALAW);
4127 static inline int parse_opt_o(char *arg)
4129 if (opt_output_name)
4130 free(opt_output_name);
4131 opt_output_name = safe_strdup(url_expand_home_dir(arg));
4135 static inline int parse_opt_P(const char *arg)
4137 /* set overriding instrument */
4138 strncpy(def_instr_name, arg, sizeof(def_instr_name) - 1);
4139 def_instr_name[sizeof(def_instr_name) - 1] = '\0';
4143 static inline int parse_opt_p(const char *arg)
4145 if (set_value(&voices, atoi(arg), 1,
4146 MAX_SAFE_MALLOC_SIZE / sizeof(Voice), "Polyphony"))
4148 max_voices = voices;
4152 static inline int parse_opt_p1(const char *arg)
4154 /* --[no-]polyphony-reduction */
4155 auto_reduce_polyphony = y_or_n_p(arg);
4159 static inline int parse_opt_Q(const char *arg)
4161 const char *p = arg;
4163 if (strchr(arg, 't'))
4164 /* backward compatibility */
4165 return parse_opt_Q1(arg);
4166 if (set_channel_flag(&quietchannels, atoi(arg), "Quiet channel"))
4168 while ((p = strchr(p, ',')) != NULL)
4169 if (set_channel_flag(&quietchannels, atoi(++p), "Quiet channel"))
4174 static inline int parse_opt_Q1(const char *arg)
4178 const char *p = arg;
4180 if (set_value(&prog, atoi(arg), 0, 7, "Temperament program number"))
4182 temper_type_mute |= 1 << prog;
4183 while ((p = strchr(p, ',')) != NULL) {
4184 if (set_value(&prog, atoi(++p), 0, 7, "Temperament program number"))
4186 temper_type_mute |= 1 << prog;
4191 static inline int parse_opt_q(const char *arg)
4193 char *max_buff = safe_strdup(arg);
4194 char *fill_buff = strchr(max_buff, '/');
4196 if (fill_buff != max_buff) {
4197 if (opt_aq_max_buff)
4198 free(opt_aq_max_buff);
4199 opt_aq_max_buff = max_buff;
4203 if (opt_aq_fill_buff)
4204 free(opt_aq_fill_buff);
4205 opt_aq_fill_buff = ++fill_buff;
4210 static inline int parse_opt_R(const char *arg)
4212 /* I think pseudo reverb can now be retired... Computers are
4213 * enough fast to do a full reverb, don't they?
4215 if (atoi(arg) == -1) /* reset */
4218 if (set_val_i32(&modify_release, atoi(arg), 0, MAX_MREL,
4221 if (modify_release == 0)
4222 modify_release = DEFAULT_MREL;
4227 static inline int parse_opt_S(const char *arg)
4229 int suffix = arg[strlen(arg) - 1];
4245 allocate_cache_size = atof(arg) * figure;
4249 static inline int parse_opt_s(const char *arg)
4254 if ((freq = atoi(arg)) < 100)
4255 freq = atof(arg) * 1000 + 0.5;
4256 return set_val_i32(&opt_output_rate, freq,
4257 MIN_OUTPUT_RATE, MAX_OUTPUT_RATE, "Resampling frequency");
4260 static inline int parse_opt_T(const char *arg)
4265 if (set_value(&adjust, atoi(arg), 10, 400, "Tempo adjust"))
4267 tempo_adjust = 100.0 / adjust;
4271 static inline int parse_opt_t(const char *arg)
4273 if (output_text_code)
4274 free(output_text_code);
4275 output_text_code = safe_strdup(arg);
4279 static inline int parse_opt_U(const char *arg)
4281 free_instruments_afterwards = y_or_n_p(arg);
4285 static inline int parse_opt_volume_curve(char *arg)
4287 if (atof(arg) < 0) {
4288 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
4289 "Volume curve power must be >= 0", *arg);
4292 if (atof(arg) != 0) {
4293 init_user_vol_table(atof(arg));
4294 opt_user_volume_curve = 1;
4299 __attribute__((noreturn))
4300 static inline int parse_opt_v(const char *arg)
4302 const char *version_list[] = {
4303 "TiMidity++ version ", timidity_version, NLS,
4305 "Copyright (C) 1999-2003 Masanao Izumo <mo@goice.co.jp>", NLS,
4306 "Copyright (C) 1995 Tuukka Toivonen <tt@cgs.fi>", NLS,
4309 "Win32 version by Davide Moretti <dmoretti@iper.net>", NLS,
4310 " and Daisuke Aoki <dai@y7.net>", NLS,
4312 #endif /* __W32__ */
4313 "This program is distributed in the hope that it will be useful,", NLS,
4314 "but WITHOUT ANY WARRANTY; without even the implied warranty of", NLS,
4315 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the", NLS,
4316 "GNU General Public License for more details.", NLS,
4318 FILE *fp = open_pager();
4321 for (i = 0; i < sizeof(version_list) / sizeof(char *); i++)
4322 fputs(version_list[i], fp);
4327 static inline int parse_opt_W(char *arg)
4329 WRDTracer *wlp, **wlpp;
4331 if (*arg == 'R') { /* for WRD reader options */
4332 put_string_table(&wrd_read_opts, arg + 1, strlen(arg + 1));
4335 for (wlpp = wrdt_list; (wlp = *wlpp) != NULL; wlpp++)
4336 if (wlp->id == *arg) {
4339 free(wrdt_open_opts);
4340 wrdt_open_opts = safe_strdup(arg + 1);
4343 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
4344 "WRD Tracer `%c' is not compiled in.", *arg);
4349 static inline int parse_opt_w(const char *arg)
4362 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
4363 "-w%c option is not supported", *arg);
4365 #endif /* SMFCONV */
4367 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "-w: Illegal mode `%c'", *arg);
4371 #endif /* __W32__ */
4373 static inline int parse_opt_x(char *arg)
4375 StringTableNode *st;
4377 if ((st = put_string_table(&opt_config_string,
4378 arg, strlen(arg))) != NULL)
4379 expand_escape_string(st->string);
4383 static inline void expand_escape_string(char *s)
4389 for (t = s; *s; s++)
4426 static inline int parse_opt_Z(char *arg)
4428 /* load frequency table */
4429 return load_table(arg);
4432 static inline int parse_opt_Z1(const char *arg)
4434 /* --pure-intonation */
4437 opt_pure_intonation = 1;
4439 if (set_value(&keysig, atoi(arg), -7, 7,
4440 "Initial keysig (number of #(+)/b(-)[m(minor)])"))
4442 opt_init_keysig = keysig;
4443 if (strchr(arg, 'm'))
4444 opt_init_keysig += 16;
4449 static inline int parse_opt_default_module(const char *arg)
4451 opt_default_module = atoi(arg);
4452 if (opt_default_module < 0)
4453 opt_default_module = 0;
4457 __attribute__((noreturn))
4458 static inline int parse_opt_fail(const char *arg)
4460 /* getopt_long failed to recognize any options */
4461 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
4462 "Could not understand option : try --help");
4466 static inline int set_value(int *param, int i, int low, int high, char *name)
4470 if (set_val_i32(&val, i, low, high, name))
4476 static inline int set_val_i32(int32 *param,
4477 int32 i, int32 low, int32 high, char *name)
4479 if (i < low || i > high) {
4480 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
4481 "%s must be between %ld and %ld", name, low, high);
4488 static inline int set_channel_flag(ChannelBitMask *flags, int32 i, char *name)
4491 FILL_CHANNELMASK(*flags);
4493 } else if (abs(i) > MAX_CHANNELS) {
4494 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
4495 "%s must be between (-)1 and (-)%d, or 0",
4496 name, MAX_CHANNELS);
4500 SET_CHANNELMASK(*flags, i - 1);
4502 UNSET_CHANNELMASK(*flags, -i - 1);
4506 static inline int y_or_n_p(const char *arg)
4526 static inline int set_flag(int32 *fields, int32 bitmask, const char *arg)
4531 *fields &= ~bitmask;
4535 static inline FILE *open_pager(void)
4537 #if ! defined(__MACOS__) && defined(HAVE_POPEN) && defined(HAVE_ISATTY) \
4538 && ! defined(IA_W32GUI) && ! defined(IA_W32G_SYN)
4541 if (isatty(1) && (pager = getenv("PAGER")) != NULL)
4542 return popen(pager, "w");
4547 static inline void close_pager(FILE *fp)
4549 #if ! defined(__MACOS__) && defined(HAVE_POPEN) && defined(HAVE_ISATTY) \
4550 && ! defined(IA_W32GUI) && ! defined(IA_W32G_SYN)
4556 static void interesting_message(void)
4559 "TiMidity++ version %s -- MIDI to WAVE converter and player" NLS
4560 "Copyright (C) 1999-2003 Masanao Izumo <mo@goice.co.jp>" NLS
4561 "Copyright (C) 1995 Tuukka Toivonen <tt@cgs.fi>" NLS
4564 "Win32 version by Davide Moretti <dmoretti@iper.net>" NLS
4565 " and Daisuke Aoki <dai@y7.net>" NLS
4567 #endif /* __W32__ */
4568 "This program is free software; you can redistribute it and/or modify" NLS
4569 "it under the terms of the GNU General Public License as published by" NLS
4570 "the Free Software Foundation; either version 2 of the License, or" NLS
4571 "(at your option) any later version." NLS
4573 "This program is distributed in the hope that it will be useful," NLS
4574 "but WITHOUT ANY WARRANTY; without even the implied warranty of" NLS
4575 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the" NLS
4576 "GNU General Public License for more details." NLS
4578 "You should have received a copy of the GNU General Public License" NLS
4579 "along with this program; if not, write to the Free Software" NLS
4580 "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA" NLS
4581 NLS, timidity_version);
4584 /* -------- functions for getopt_long ends here --------- */
4587 static RETSIGTYPE sigterm_exit(int sig)
4591 /* NOTE: Here, fprintf is dangerous because it is not re-enterance
4592 * function. It is possible coredump if the signal is called in printf's.
4595 write(2, "Terminated sig=0x", 17);
4596 s[0] = "0123456789abcdef"[(sig >> 4) & 0xf];
4597 s[1] = "0123456789abcdef"[sig & 0xf];
4603 #endif /* HAVE_SIGNAL */
4605 static void timidity_arc_error_handler(char *error_message)
4607 extern int open_file_noise_mode;
4608 if(open_file_noise_mode)
4609 ctl->cmsg(CMSG_WARNING, VERB_NORMAL, "%s", error_message);
4612 MAIN_INTERFACE void timidity_start_initialize(void)
4615 static int drums[] = DEFAULT_DRUMCHANNELS;
4616 static int is_first = 1;
4617 #if defined(__FreeBSD__) && !defined(__alpha__)
4619 #elif defined(__NetBSD__) || defined(__OpenBSD__)
4623 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
4624 fpexp = fpgetmask();
4625 fpsetmask(fpexp & ~(FP_X_INV|FP_X_DZ));
4628 if(!output_text_code)
4629 output_text_code = safe_strdup(OUTPUT_TEXT_CODE);
4630 if(!opt_aq_max_buff)
4631 opt_aq_max_buff = safe_strdup("5.0");
4632 if(!opt_aq_fill_buff)
4633 opt_aq_fill_buff = safe_strdup("100%");
4635 /* Check the byte order */
4637 #ifdef LITTLE_ENDIAN
4638 if(*(char *)&i != 1)
4640 if(*(char *)&i == 1)
4643 fprintf(stderr, "Byte order is miss configured.\n");
4647 for(i = 0; i < MAX_CHANNELS; i++)
4649 memset(&(channel[i]), 0, sizeof(Channel));
4652 CLEAR_CHANNELMASK(quietchannels);
4653 CLEAR_CHANNELMASK(default_drumchannels);
4655 for(i = 0; drums[i] > 0; i++)
4656 SET_CHANNELMASK(default_drumchannels, drums[i] - 1);
4657 #if MAX_CHANNELS > 16
4658 for(i = 16; i < MAX_CHANNELS; i++)
4659 if(IS_SET_CHANNELMASK(default_drumchannels, i & 0xF))
4660 SET_CHANNELMASK(default_drumchannels, i);
4663 if(program_name == NULL)
4664 program_name = "TiMidity";
4665 uudecode_unquote_html = 1;
4666 for(i = 0; i < MAX_CHANNELS; i++)
4668 default_program[i] = DEFAULT_PROGRAM;
4669 memset(channel[i].drums, 0, sizeof(channel[i].drums));
4671 arc_error_handler = timidity_arc_error_handler;
4673 if(play_mode == NULL)
4678 output_id = getenv("TIMIDITY_OUTPUT_ID");
4679 #ifdef TIMIDITY_OUTPUT_ID
4680 if(output_id == NULL)
4681 output_id = TIMIDITY_OUTPUT_ID;
4682 #endif /* TIMIDITY_OUTPUT_ID */
4683 if(output_id != NULL)
4685 for(i = 0; play_mode_list[i]; i++)
4686 if(play_mode_list[i]->id_character == *output_id)
4688 if (! play_mode_list[i]->detect ||
4689 play_mode_list[i]->detect()) {
4690 play_mode = play_mode_list[i];
4697 if (play_mode == NULL) {
4698 /* try to detect the first available device */
4699 for(i = 0; play_mode_list[i]; i++) {
4700 /* check only the devices with detect callback */
4701 if (play_mode_list[i]->detect) {
4702 if (play_mode_list[i]->detect()) {
4703 play_mode = play_mode_list[i];
4710 if (play_mode == NULL) {
4711 fprintf(stderr, "Couldn't open output device" NLS);
4715 if(is_first) /* initialize once time */
4717 got_a_configuration = 0;
4719 #ifdef SUPPORT_SOCKET
4721 if(url_user_agent == NULL)
4724 (char *)safe_malloc(10 + strlen(timidity_version));
4725 strcpy(url_user_agent, "TiMidity-");
4726 strcat(url_user_agent, timidity_version);
4728 #endif /* SUPPORT_SOCKET */
4730 for(i = 0; url_module_list[i]; i++)
4731 url_add_module(url_module_list[i]);
4732 init_string_table(&opt_config_string);
4734 init_freq_table_tuning();
4735 init_freq_table_pytha();
4736 init_freq_table_meantone();
4737 init_freq_table_pureint();
4738 init_freq_table_user();
4742 init_gm2_pan_table();
4743 init_attack_vol_table();
4744 init_sb_vol_table();
4745 init_modenv_vol_table();
4746 init_def_vol_table();
4747 init_gs_vol_table();
4748 init_perceived_vol_table();
4749 init_gm2_vol_table();
4750 #ifdef SUPPORT_SOCKET
4751 url_news_connection_cache(URL_NEWS_CONN_CACHE);
4752 #endif /* SUPPORT_SOCKET */
4753 for(i = 0; i < NSPECIAL_PATCH; i++)
4754 special_patch[i] = NULL;
4756 int_rand(-1); /* initialize random seed */
4757 int_rand(42); /* the 1st number generated is not very random */
4758 ML_RegisterAllLoaders ();
4764 MAIN_INTERFACE int timidity_pre_load_configuration(void)
4766 #if defined(__W32__)
4772 #if defined ( IA_W32GUI ) || defined ( IA_W32G_SYN )
4773 extern char *ConfigFile;
4774 if(!ConfigFile[0]) {
4775 GetWindowsDirectory(ConfigFile, 1023 - 13);
4776 strcat(ConfigFile, "\\TIMIDITY.CFG");
4778 strncpy(local, ConfigFile, sizeof(local) - 1);
4781 GetWindowsDirectory(local, 1023 - 13);
4782 strcat(local, "\\TIMIDITY.CFG");
4785 /* First, try read system configuration file.
4786 * Default is C:\WINDOWS\TIMIDITY.CFG
4788 if((check = open(local, 0)) >= 0)
4791 if(!read_config_file(local, 0)) {
4792 got_a_configuration = 1;
4797 /* Next, try read configuration file which is in the
4798 * TiMidity directory.
4800 if(GetModuleFileName(NULL, local, 1023))
4803 if(strp = strrchr(local, '\\'))
4806 strcat(local,"TIMIDITY.CFG");
4807 if((check = open(local, 0)) >= 0)
4810 if(!read_config_file(local, 0)) {
4811 got_a_configuration = 1;
4820 if(!read_config_file(CONFIG_FILE, 0)) {
4821 got_a_configuration = 1;
4826 /* Try read configuration file which is in the
4827 * $HOME (or %HOME% for DOS) directory.
4828 * Please setup each user preference in $HOME/.timidity.cfg
4829 * (or %HOME%/timidity.cfg for DOS)
4832 if(read_user_config_file())
4833 ctl->cmsg(CMSG_INFO, VERB_NOISY,
4834 "Warning: Can't read ~/.timidity.cfg correctly");
4838 MAIN_INTERFACE int timidity_post_load_configuration(void)
4843 if(!got_a_configuration)
4845 if(try_config_again && !read_config_file(CONFIG_FILE, 0))
4846 got_a_configuration = 1;
4849 if(opt_config_string.nstring > 0)
4851 char **config_string_list;
4854 config_string_list = make_string_array(&opt_config_string);
4855 if(config_string_list != NULL)
4857 for(i = 0; config_string_list[i]; i++)
4859 if(!read_config_file(config_string_list[i], 1))
4860 got_a_configuration = 1;
4864 free(config_string_list[0]);
4865 free(config_string_list);
4869 if(!got_a_configuration)
4874 MAIN_INTERFACE void timidity_init_player(void)
4876 /* Allocate voice[] */
4877 voice = (Voice *) safe_realloc(voice, max_voices * sizeof(Voice));
4878 memset(voice, 0, max_voices * sizeof(Voice));
4880 /* Set play mode parameters */
4881 if(opt_output_rate != 0)
4882 play_mode->rate = opt_output_rate;
4883 else if(play_mode->rate == 0)
4884 play_mode->rate = DEFAULT_RATE;
4887 COPY_CHANNELMASK(drumchannels, default_drumchannels);
4888 COPY_CHANNELMASK(drumchannel_mask, default_drumchannel_mask);
4890 if(opt_buffer_fragments != -1)
4892 if(play_mode->flag & PF_BUFF_FRAGM_OPT)
4893 play_mode->extra_param[0] = opt_buffer_fragments;
4895 ctl->cmsg(CMSG_WARNING, VERB_NORMAL,
4896 "%s: -B option is ignored", play_mode->id_name);
4899 #ifdef SUPPORT_SOUNDSPEC
4900 if(view_soundspec_flag)
4903 soundspec_setinterval(spectrogram_update_sec);
4905 #endif /* SOUNDSPEC */
4908 void timidity_init_aq_buff(void)
4910 double time1, /* max buffer */
4911 time2, /* init filled */
4912 base; /* buffer of device driver */
4914 if(!IS_STREAM_TRACE)
4915 return; /* Ignore */
4917 time1 = atof(opt_aq_max_buff);
4918 time2 = atof(opt_aq_fill_buff);
4919 base = (double)aq_get_dev_queuesize() / play_mode->rate;
4920 if(strchr(opt_aq_max_buff, '%'))
4922 time1 = base * (time1 - 100) / 100.0;
4926 if(strchr(opt_aq_fill_buff, '%'))
4927 time2 = base * time2 / 100.0;
4928 aq_set_soft_queue(time1, time2);
4931 MAIN_INTERFACE int timidity_play_main(int nfiles, char **files)
4933 int need_stdin = 0, need_stdout = 0;
4935 int output_fail = 0;
4937 if(nfiles == 0 && !strchr(INTERACTIVE_INTERFACE_IDS, ctl->id_character))
4942 play_mode->name = opt_output_name;
4943 if(!strcmp(opt_output_name, "-"))
4947 for(i = 0; i < nfiles; i++)
4948 if (!strcmp(files[i], "-"))
4951 if(ctl->open(need_stdin, need_stdout))
4953 fprintf(stderr, "Couldn't open %s (`%c')" NLS,
4954 ctl->id_name, ctl->id_character);
4955 play_mode->close_output();
4959 if(wrdt->open(wrdt_open_opts))
4961 fprintf(stderr, "Couldn't open WRD Tracer: %s (`%c')" NLS,
4962 wrdt->name, wrdt->id);
4963 play_mode->close_output();
4968 #ifdef BORLANDC_EXCEPTION
4971 #endif /* BORLANDC_EXCEPTION */
4975 signal(SIGTERM, sigterm_exit);
4977 SetConsoleCtrlHandler(handler, TRUE);
4979 ctl->cmsg(CMSG_INFO, VERB_DEBUG_SILLY,
4980 "Initialize for Critical Section");
4981 InitializeCriticalSection(&critSect);
4983 if(!SetThreadPriority(GetCurrentThread(),
4984 THREAD_PRIORITY_ABOVE_NORMAL))
4985 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
4986 "Error raising process priority");
4991 signal(SIGINT, sigterm_exit);
4992 signal(SIGTERM, sigterm_exit);
4994 signal(SIGPIPE, sigterm_exit); /* Handle broken pipe */
4995 #endif /* SIGPIPE */
4996 #endif /* HAVE_SIGNAL */
5000 /* Open output device */
5001 ctl->cmsg(CMSG_INFO, VERB_DEBUG_SILLY,
5002 "Open output: %c, %s",
5003 play_mode->id_character,
5004 play_mode->id_name);
5006 if (play_mode->flag & PF_PCM_STREAM) {
5007 play_mode->extra_param[1] = aq_calc_fragsize();
5008 ctl->cmsg(CMSG_INFO, VERB_DEBUG_SILLY,
5009 "requesting fragment size: %d",
5010 play_mode->extra_param[1]);
5012 #if !defined ( IA_W32GUI ) && !defined ( IA_W32G_SYN )
5013 if(play_mode->open_output() < 0)
5015 ctl->cmsg(CMSG_FATAL, VERB_NORMAL,
5016 "Couldn't open %s (`%c')",
5017 play_mode->id_name, play_mode->id_character);
5022 #endif /* IA_W32GUI */
5025 control_ratio = play_mode->rate / CONTROLS_PER_SECOND;
5026 if(control_ratio < 1)
5028 else if (control_ratio > MAX_CONTROL_RATIO)
5029 control_ratio = MAX_CONTROL_RATIO;
5032 init_load_soundfont();
5036 timidity_init_aq_buff();
5038 if(allocate_cache_size > 0)
5039 resamp_cache_reset();
5042 set_default_program(def_prog);
5043 if (*def_instr_name)
5044 set_default_instrument(def_instr_name);
5046 if(ctl->flags & CTLF_LIST_RANDOM)
5047 randomize_string_list(files, nfiles);
5048 else if(ctl->flags & CTLF_LIST_SORT)
5049 sort_pathname(files, nfiles);
5051 /* Return only when quitting */
5052 ctl->cmsg(CMSG_INFO, VERB_DEBUG_SILLY,
5053 "pass_playing_list() nfiles=%d", nfiles);
5055 ctl->pass_playing_list(nfiles, files);
5062 #endif /* XP_UNIX */
5064 play_mode->close_output();
5068 DeleteCriticalSection (&critSect);
5071 #ifdef BORLANDC_EXCEPTION
5073 fprintf(stderr, "\nError!!!\nUnexpected Exception Occured!\n");
5074 if(play_mode->fd != -1)
5076 play_mode->purge_output();
5077 play_mode->close_output();
5081 DeleteCriticalSection (&critSect);
5084 #endif /* BORLANDC_EXCEPTION */
5086 #ifdef SUPPORT_SOUNDSPEC
5087 if(view_soundspec_flag)
5089 #endif /* SUPPORT_SOUNDSPEC */
5091 free_archive_files();
5092 #ifdef SUPPORT_SOCKET
5093 url_news_connection_cache(URL_NEWS_CLOSE_CACHE);
5094 #endif /* SUPPORT_SOCKET */
5100 int w32gSecondTiMidity(int opt, int argc, char **argv);
5101 int w32gSecondTiMidityExit(void);
5102 int w32gLoadDefaultPlaylist(void);
5103 int w32gSaveDefaultPlaylist(void);
5104 extern int volatile save_playlist_once_before_exit_flag;
5105 #endif /* IA_W32GUI */
5107 #if defined ( IA_W32GUI ) || defined ( IA_W32G_SYN )
5108 static int CoInitializeOK = 0;
5112 #ifdef __W32__ /* Windows */
5113 #if ( (!defined(IA_W32GUI) || defined(__CYGWIN32__) || defined(__MINGW32__)) && !defined(IA_W32G_SYN) )
5114 /* Cygwin or Console */
5115 int __cdecl main(int argc, char **argv)
5117 /* _MSC_VER, _BORLANDC_ */
5118 int win_main(int argc, char **argv)
5121 int main(int argc, char **argv)
5130 #if defined(DANGEROUS_RENICE) && !defined(__W32__) && !defined(main)
5132 * THIS CODES MUST EXECUT BEGINNING OF MAIN FOR SECURITY.
5133 * DONT PUT ANY CODES ABOVE.
5135 #include <sys/resource.h>
5138 extern int setpriority(int which, id_t who, int prio);
5139 extern int setreuid(int ruid, int euid);
5143 if(setpriority(PRIO_PROCESS, 0, DANGEROUS_RENICE) < 0)
5145 perror("setpriority");
5146 fprintf(stderr, "Couldn't set priority to %d.", DANGEROUS_RENICE);
5151 #if defined(REDIRECT_STDOUT)
5152 memcpy(stdout, fopen(REDIRECT_STDOUT, "a+"), sizeof(FILE));
5153 printf("TiMidity++ start\n");fflush(stdout);
5158 static int maincnt = 0;
5163 while(argv[0][0] == '-') {
5167 ctl->pass_playing_list(argc, argv);
5176 argv[0] = "netscape";
5177 #endif /* XP_UNIX */
5178 dynamic_interface_id = 0;
5179 dl_init(argc, argv);
5181 #endif /* IA_DYNAMIC */
5183 if((program_name=pathsep_strrchr(argv[0]))) program_name++;
5184 else program_name=argv[0];
5186 if(strncmp(program_name,"timidity",8) == 0);
5187 else if(strncmp(program_name,"kmidi",5) == 0) set_ctl("q");
5188 else if(strncmp(program_name,"tkmidi",6) == 0) set_ctl("k");
5189 else if(strncmp(program_name,"gtkmidi",6) == 0) set_ctl("g");
5190 else if(strncmp(program_name,"xmmidi",6) == 0) set_ctl("m");
5191 else if(strncmp(program_name,"xawmidi",7) == 0) set_ctl("a");
5192 else if(strncmp(program_name,"xskinmidi",9) == 0) set_ctl("i");
5194 if(argc == 1 && !strchr(INTERACTIVE_INTERFACE_IDS, ctl->id_character))
5196 interesting_message();
5200 timidity_start_initialize();
5201 #if defined ( IA_W32GUI ) || defined ( IA_W32G_SYN )
5202 if(CoInitialize(NULL)==S_OK)
5207 /* Secondary TiMidity Execute */
5208 /* FirstLoadIniFile(); */
5209 if(w32gSecondTiMidity(SecondMode,argc,argv)==FALSE){
5214 for(c = 1; c < argc; c++)
5216 if(is_directory(argv[c]))
5219 p = (char *)safe_malloc(strlen(argv[c]) + 2);
5227 if((err = timidity_pre_load_configuration()) != 0)
5230 optind = longind = 0;
5231 while ((c = getopt_long(argc, argv, optcommands, longopts, &longind)) > 0)
5232 if ((err = set_tim_opt_long(c, optarg, longind)) != 0)
5235 initialize_resampler_coeffs();
5237 err += timidity_post_load_configuration();
5239 /* If there were problems, give up now */
5240 if(err || (optind >= argc &&
5241 !strchr(INTERACTIVE_INTERFACE_IDS, ctl->id_character)))
5243 if(!got_a_configuration)
5249 memset(config1, 0, sizeof(config1));
5250 memset(config2, 0, sizeof(config2));
5251 #if defined ( IA_W32GUI ) || defined ( IA_W32G_SYN )
5253 extern char *ConfigFile;
5254 strncpy(config1, ConfigFile, sizeof(config1) - 1);
5258 GetWindowsDirectory(config1, 1023 - 13);
5259 strcat(config1, "\\TIMIDITY.CFG");
5262 if(GetModuleFileName(NULL, config2, 1023))
5265 config2[1023] = '\0';
5266 if(strp = strrchr(config2, '\\'))
5269 strcat(config2,"TIMIDITY.CFG");
5273 ctl->cmsg(CMSG_FATAL, VERB_NORMAL,
5274 "%s: Can't read any configuration file.\nPlease check "
5275 "%s or %s", program_name, config1, config2);
5277 ctl->cmsg(CMSG_FATAL, VERB_NORMAL,
5278 "%s: Can't read any configuration file.\nPlease check "
5279 CONFIG_FILE, program_name);
5280 #endif /* __W32__ */
5284 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
5285 "Try %s -h for help", program_name);
5288 #if !defined ( IA_W32GUI ) && !defined ( IA_W32G_SYN ) /* Try to continue if it is Windows version */
5289 return 1; /* problems with command line */
5293 timidity_init_player();
5295 nfiles = argc - optind;
5296 files = argv + optind;
5297 if(nfiles > 0 && ctl->id_character != 'r' && ctl->id_character != 'A' && ctl->id_character != 'W' && ctl->id_character != 'P')
5298 files = expand_file_archives(files, &nfiles);
5299 if(dumb_error_count)
5303 main_ret = timidity_play_main(nfiles, files);
5307 #endif /* IA_W32G_SYN */
5309 w32gLoadDefaultPlaylist();
5310 main_ret = timidity_play_main(nfiles, files);
5311 if(save_playlist_once_before_exit_flag) {
5312 save_playlist_once_before_exit_flag = 0;
5313 w32gSaveDefaultPlaylist();
5315 w32gSecondTiMidityExit();
5318 #endif /* IA_W32GUI */
5319 free_instruments(0);
5320 free_global_mblock();
5321 free_all_midi_file_info();
5325 free_effect_buffers();
5326 for (i = 0; i < MAX_CHANNELS; i++) {free_drum_effect(i);}
5329 #endif /* __MACOS__ */