OSDN Git Service

2fea88d83a5b88f0b3bfd6b3d9db56bb6516e8cd
[timidity41/timidity41.git] / timidity / timidity.c
1 /*
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>
5
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.
10
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.
15
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
19 */
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif /* HAVE_CONFIG_H */
24 #include <stdio.h>
25 #ifdef STDC_HEADERS
26 #include <stdlib.h>
27 #include <ctype.h>
28 #include <stddef.h>
29 #endif
30 #ifndef NO_STRING_H
31 #include <string.h>
32 #else
33 #include <strings.h>
34 #endif
35 #ifdef __W32__
36 #include <windows.h>
37 #include <io.h>
38 #include <shlobj.h>
39 #endif
40 #ifdef HAVE_UNISTD_H
41 #include <unistd.h>
42 #endif /* HAVE_UNISTD_H */
43 #include <fcntl.h> /* for open */
44
45 #ifdef HAVE_STDBOOL_H
46 #include <stdbool.h>
47 #endif
48
49 #ifndef __bool_true_false_are_defined
50 # ifdef bool
51 #  undef bool
52 # endif
53 # ifdef ture
54 #  undef ture
55 # endif
56 # ifdef false
57 #  undef false
58 # endif
59 # define bool int
60 # define false ((bool)0)
61 # define true (!false)
62 # define __bool_true_false_are_defined true
63 #endif /* C99 _Bool hack */
64
65 #ifdef BORLANDC_EXCEPTION
66 #include <excpt.h>
67 #endif /* BORLANDC_EXCEPTION */
68 #include <signal.h>
69
70 #if defined(__FreeBSD__) && !defined(__alpha__)
71 #include <floatingpoint.h> /* For FP exceptions */
72 #endif
73 #if defined(__NetBSD__) || defined(__OpenBSD__)
74 #include <ieeefp.h> /* For FP exceptions */
75 #endif
76
77 #include "interface.h"
78 #include "timidity.h"
79 #include "utils/tmdy_getopt.h"
80 #include "common.h"
81 #include "instrum.h"
82 #include "playmidi.h"
83 #include "readmidi.h"
84 #include "output.h"
85 #include "controls.h"
86 #include "tables.h"
87 #include "miditrace.h"
88 #include "reverb.h"
89 #ifdef SUPPORT_SOUNDSPEC
90 #include "soundspec.h"
91 #endif /* SUPPORT_SOUNDSPEC */
92 #include "resample.h"
93 #include "recache.h"
94 #include "arc.h"
95 #include "strtab.h"
96 #include "wrd.h"
97 #define DEFINE_GLOBALS
98 #include "mid.defs"
99 #include "aq.h"
100 #include "mix.h"
101 #include "unimod.h"
102 #include "quantity.h"
103
104 #ifdef IA_W32GUI
105 #include "w32g.h"
106 #include "w32g_utl.h"
107 #endif
108
109 #ifndef __GNUC__
110 #define __attribute__(x) /* ignore */
111 #endif
112
113 /* option enums */
114 enum {
115         TIM_OPT_FIRST = 256,
116         /* first entry */
117         TIM_OPT_VOLUME = TIM_OPT_FIRST,
118         TIM_OPT_DRUM_POWER,
119         TIM_OPT_VOLUME_COMP,
120         TIM_OPT_ANTI_ALIAS,
121         TIM_OPT_BUFFER_FRAGS,
122         TIM_OPT_CONTROL_RATIO,
123         TIM_OPT_CONFIG_FILE,
124         TIM_OPT_DRUM_CHANNEL,
125         TIM_OPT_IFACE_PATH,
126         TIM_OPT_EXT,
127         TIM_OPT_MOD_WHEEL,
128         TIM_OPT_PORTAMENTO,
129         TIM_OPT_VIBRATO,
130         TIM_OPT_CH_PRESS,
131         TIM_OPT_MOD_ENV,
132         TIM_OPT_TRACE_TEXT,
133         TIM_OPT_OVERLAP,
134         TIM_OPT_TEMPER_CTRL,
135         TIM_OPT_DEFAULT_MID,
136         TIM_OPT_SYSTEM_MID,
137         TIM_OPT_DEFAULT_BANK,
138         TIM_OPT_FORCE_BANK,
139         TIM_OPT_DEFAULT_PGM,
140         TIM_OPT_FORCE_PGM,
141         TIM_OPT_DELAY,
142         TIM_OPT_CHORUS,
143         TIM_OPT_REVERB,
144         TIM_OPT_VOICE_LPF,
145         TIM_OPT_NS,
146         TIM_OPT_RESAMPLE,
147         TIM_OPT_EVIL,
148         TIM_OPT_FAST_PAN,
149         TIM_OPT_FAST_DECAY,
150         TIM_OPT_SPECTROGRAM,
151         TIM_OPT_KEYSIG,
152         TIM_OPT_HELP,
153         TIM_OPT_INTERFACE,
154         TIM_OPT_VERBOSE,
155         TIM_OPT_QUIET,
156         TIM_OPT_TRACE,
157         TIM_OPT_LOOP,
158         TIM_OPT_RANDOM,
159         TIM_OPT_SORT,
160         TIM_OPT_BACKGROUND,
161         TIM_OPT_RT_PRIO,
162         TIM_OPT_SEQ_PORTS,
163         TIM_OPT_REALTIME_LOAD,
164         TIM_OPT_ADJUST_KEY,
165         TIM_OPT_VOICE_QUEUE,
166         TIM_OPT_PATCH_PATH,
167         TIM_OPT_PCM_FILE,
168         TIM_OPT_DECAY_TIME,
169         TIM_OPT_INTERPOLATION,
170         TIM_OPT_OUTPUT_MODE,
171         TIM_OPT_OUTPUT_STEREO,
172         TIM_OPT_OUTPUT_SIGNED,
173         TIM_OPT_OUTPUT_BITWIDTH,
174         TIM_OPT_OUTPUT_FORMAT,
175         TIM_OPT_OUTPUT_SWAB,
176         TIM_OPT_OUTPUT_FILE,
177         TIM_OPT_PATCH_FILE,
178         TIM_OPT_POLYPHONY,
179         TIM_OPT_POLY_REDUCE,
180         TIM_OPT_MUTE,
181         TIM_OPT_TEMPER_MUTE,
182         TIM_OPT_AUDIO_BUFFER,
183         TIM_OPT_CACHE_SIZE,
184         TIM_OPT_SAMPLE_FREQ,
185         TIM_OPT_ADJUST_TEMPO,
186         TIM_OPT_CHARSET,
187         TIM_OPT_UNLOAD_INST,
188         TIM_OPT_VOLUME_CURVE,
189         TIM_OPT_VERSION,
190         TIM_OPT_WRD,
191         TIM_OPT_RCPCV_DLL,
192         TIM_OPT_CONFIG_STR,
193         TIM_OPT_FREQ_TABLE,
194         TIM_OPT_PURE_INT,
195         TIM_OPT_MODULE,
196         /* last entry */
197         TIM_OPT_LAST = TIM_OPT_PURE_INT
198 };
199
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:"
203 #ifdef __W32__
204                 "w:"
205 #endif
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 },
249 #endif
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 },
269 #ifdef IA_ALSASEQ
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 },
274 #endif
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 },
313 #ifdef __W32__
314         { "rcpcv-dll",              required_argument, NULL, TIM_OPT_RCPCV_DLL },
315 #endif
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'     }
321 };
322 #define INTERACTIVE_INTERFACE_IDS "kmqagrwAWP"
323
324 /* main interfaces (To be used another main) */
325 #if defined(main) || defined(ANOTHER_MAIN)
326 #define MAIN_INTERFACE
327 #else
328 #define MAIN_INTERFACE static
329 #endif /* main */
330
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 */
342
343 int set_extension_modes(char *);
344 int set_ctl(char *);
345 int set_play_mode(char *);
346 int set_wrd(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 *);
387 #ifdef IA_DYNAMIC
388 static inline void list_dyna_interface(FILE *, char *, char *);
389 static inline char *dynamic_interface_info(int);
390 char *dynamic_interface_module(int);
391 #endif
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 *);
399 #ifdef IA_ALSASEQ
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 *);
403 #endif
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 *);
434 #ifdef __W32__
435 static inline int parse_opt_w(const char *);
436 #endif
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);
452
453 #ifdef IA_DYNAMIC
454 MAIN_INTERFACE char dynamic_interface_id;
455 #endif /* IA_DYNAMIC */
456
457 extern StringTable wrd_read_opts;
458
459 extern int SecondMode;
460
461 extern struct URL_module URL_module_file;
462 #ifndef __MACOS__
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 */
471 #ifdef HAVE_POPEN
472 extern struct URL_module URL_module_pipe;
473 #endif /* HAVE_POPEN */
474
475 MAIN_INTERFACE struct URL_module *url_module_list[] =
476 {
477     &URL_module_file,
478 #ifndef __MACOS__
479     &URL_module_dir,
480 #endif /* __MACOS__ */
481 #ifdef SUPPORT_SOCKET
482     &URL_module_http,
483     &URL_module_ftp,
484     &URL_module_news,
485     &URL_module_newsgroup,
486 #endif /* SUPPORT_SOCKET */
487 #if !defined(__MACOS__) && defined(HAVE_POPEN)
488     &URL_module_pipe,
489 #endif
490 #if defined(main) || defined(ANOTHER_MAIN)
491     /* You can put some other modules */
492     NULL,
493     NULL,
494     NULL,
495     NULL,
496     NULL,
497     NULL,
498     NULL,
499     NULL,
500 #endif /* main */
501     NULL
502 };
503
504 #ifdef IA_DYNAMIC
505 #include "dlutils.h"
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 */
511
512 #ifndef MAXPATHLEN
513 #define MAXPATHLEN 1024
514 #endif /* MAXPATHLEN */
515
516 int free_instruments_afterwards=0;
517 int def_prog = -1;
518 char def_instr_name[256]="";
519 VOLATILE int intr = 0;
520
521 #ifdef __W32__
522 CRITICAL_SECTION critSect;
523
524 #pragma argsused
525 static BOOL WINAPI handler(DWORD dw)
526 {
527 #if defined(IA_WINSYN) || defined(IA_PORTMIDISYN)
528         if( ctl->id_character == 'W' 
529                 || ctl->id_character == 'P' )
530         {
531         rtsyn_midiports_close();
532         }
533 #endif  
534     printf ("***BREAK" NLS); fflush(stdout);
535     intr++;
536     return TRUE;
537 }
538 #endif
539
540
541 int effect_lr_mode = -1;
542 /* 0: left delay
543  * 1: right delay
544  * 2: rotate
545  * -1: not use
546  */
547 int effect_lr_delay_msec = 25;
548
549 extern char* pcm_alternate_file;
550 /* NULL, "none": disabled (default)
551  * "auto":       automatically selected
552  * filename:     use the one.
553  */
554
555 #ifndef atof
556 extern double atof(const char *);
557 #endif
558
559 /*! copy bank and, if necessary, map appropriately */
560 static void copybank(ToneBank *to, ToneBank *from, int mapid, int bankmapfrom, int bankno)
561 {
562         ToneBankElement *toelm, *fromelm;
563         int i;
564
565         if (from == NULL)
566                 return;
567         for(i = 0; i < 128; i++)
568         {
569                 toelm = &to->tone[i];
570                 fromelm = &from->tone[i];
571                 if (fromelm->name == NULL)
572                     continue;
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);
577         }
578 }
579
580 /*! copy the whole mapped bank. returns 0 if no error. */
581 static int copymap(int mapto, int mapfrom, int isdrum)
582 {
583         ToneBank **tb = isdrum ? drumset : tonebank;
584         int i, bankfrom, bankto;
585         
586         for(i = 0; i < 128; i++)
587         {
588                 bankfrom = find_instrument_map_bank(isdrum, mapfrom, i);
589                 if (bankfrom <= 0) /* not mapped */
590                         continue;
591                 bankto = alloc_instrument_map_bank(isdrum, mapto, i);
592                 if (bankto == -1) /* failed */
593                         return 1;
594                 copybank(tb[bankto], tb[bankfrom], mapto, i, bankto);
595         }
596         return 0;
597 }
598
599 static float *config_parse_tune(const char *cp, int *num)
600 {
601         const char *p;
602         float *tune_list;
603         int i;
604         
605         /* count num */
606         *num = 1, p = cp;
607         while ((p = strchr(p, ',')) != NULL)
608                 (*num)++, p++;
609         /* alloc */
610         tune_list = (float *) safe_malloc((*num) * sizeof(float));
611         /* regist */
612         for (i = 0, p = cp; i < *num; i++, p++) {
613                 tune_list[i] = atof(p);
614                 if (! (p = strchr(p, ',')))
615                         break;
616         }
617         return tune_list;
618 }
619
620 static int16 *config_parse_int16(const char *cp, int *num)
621 {
622         const char *p;
623         int16 *list;
624         int i;
625         
626         /* count num */
627         *num = 1, p = cp;
628         while ((p = strchr(p, ',')) != NULL)
629                 (*num)++, p++;
630         /* alloc */
631         list = (int16 *) safe_malloc((*num) * sizeof(int16));
632         /* regist */
633         for (i = 0, p = cp; i < *num; i++, p++) {
634                 list[i] = atoi(p);
635                 if (! (p = strchr(p, ',')))
636                         break;
637         }
638         return list;
639 }
640
641 static int **config_parse_envelope(const char *cp, int *num)
642 {
643         const char *p, *px;
644         int **env_list;
645         int i, j;
646         
647         /* count num */
648         *num = 1, p = cp;
649         while ((p = strchr(p, ',')) != NULL)
650                 (*num)++, p++;
651         /* alloc */
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));
655         /* init */
656         for (i = 0; i < *num; i++)
657                 for (j = 0; j < 6; j++)
658                         env_list[i][j] = -1;
659         /* regist */
660         for (i = 0, p = cp; i < *num; i++, p++) {
661                 px = strchr(p, ',');
662                 for (j = 0; j < 6; j++, p++) {
663                         if (*p == ':')
664                                 continue;
665                         env_list[i][j] = atoi(p);
666                         if (! (p = strchr(p, ':')))
667                                 break;
668                         if (px && p > px)
669                                 break;
670                 }
671                 if (! (p = px))
672                         break;
673         }
674         return env_list;
675 }
676
677 static Quantity **config_parse_modulation(const char *name, int line, const char *cp, int *num, int mod_type)
678 {
679         const char *p, *px, *err;
680         char buf[128], *delim;
681         Quantity **mod_list;
682         int i, j;
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)
687         };
688         
689         /* count num */
690         *num = 1, p = cp;
691         while ((p = strchr(p, ',')) != NULL)
692                 (*num)++, p++;
693         /* alloc */
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));
697         /* init */
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';
702         /* regist */
703         for (i = 0, p = cp; i < *num; i++, p++) {
704                 px = strchr(p, ',');
705                 for (j = 0; j < 3; j++, p++) {
706                         if (*p == ':')
707                                 continue;
708                         if ((delim = strpbrk(strncpy(buf, p, sizeof buf - 1), ":,")) != NULL)
709                                 *delim = '\0';
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);
714                                 mod_list = NULL;
715                                 *num = 0;
716                                 return NULL;
717                         }
718                         if (! (p = strchr(p, ':')))
719                                 break;
720                         if (px && p > px)
721                                 break;
722                 }
723                 if (! (p = px))
724                         break;
725         }
726         return mod_list;
727 }
728
729 static int set_gus_patchconf_opts(char *name,
730                 int line, char *opts, ToneBankElement *tone)
731 {
732         char *cp;
733         int k;
734         
735         if (! (cp = strchr(opts, '='))) {
736                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
737                                 "%s: line %d: bad patch option %s", name, line, opts);
738                 return 1;
739         }
740         *cp++ = 0;
741         if (! strcmp(opts, "amp")) {
742                 k = atoi(cp);
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);
747                         return 1;
748                 }
749                 tone->amp = k;
750         } else if (! strcmp(opts, "note")) {
751                 k = atoi(cp);
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",
755                                         name, line);
756                         return 1;
757                 }
758                 tone->note = k;
759                 tone->scltune = config_parse_int16("100", &tone->scltunenum);
760         } else if (! strcmp(opts, "pan")) {
761                 if (! strcmp(cp, "center"))
762                         k = 64;
763                 else if (! strcmp(cp, "left"))
764                         k = 0;
765                 else if (! strcmp(cp, "right"))
766                         k = 127;
767                 else {
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",
774                                                 name, line);
775                                 return 1;
776                         }
777                 }
778                 tone->pan = k;
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;
790                 else {
791                         ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
792                                         "%s: line %d: keep must be env or loop", name, line);
793                         return 1;
794                 }
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;
802                 else {
803                         ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
804                                         "%s: line %d: strip must be env, loop, or tail",
805                                         name, line);
806                         return 1;
807                 }
808         } else if (! strcmp(opts, "tremolo")) {
809                 if ((tone->trem = config_parse_modulation(name,
810                                 line, cp, &tone->tremnum, 0)) == NULL)
811                         return 1;
812         } else if (! strcmp(opts, "vibrato")) {
813                 if ((tone->vib = config_parse_modulation(name,
814                                 line, cp, &tone->vibnum, 1)) == NULL)
815                         return 1;
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")) {
821                 char *p;
822                 
823                 if (tone->comment)
824                         free(tone->comment);
825                 p = tone->comment = safe_strdup(cp);
826                 while (*p) {
827                         if (*p == ',')
828                                 *p = ' ';
829                         p++;
830                 }
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);
861         else {
862                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
863                                 "%s: line %d: bad patch option %s",
864                                 name, line, opts);
865                 return 1;
866         }
867         return 0;
868 }
869
870 static void reinit_tone_bank_element(ToneBankElement *tone)
871 {
872         free_tone_bank_element(tone);
873         tone->note = tone->pan = -1;
874         tone->strip_loop = tone->strip_envelope = tone->strip_tail = -1;
875         tone->amp = -1;
876         tone->rnddelay = 0;
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;
882 }
883
884 #define SET_GUS_PATCHCONF_COMMENT
885 static int set_gus_patchconf(char *name, int line,
886                              ToneBankElement *tone, char *pat, char **opts)
887 {
888     int j;
889 #ifdef SET_GUS_PATCHCONF_COMMENT
890                 char *old_name = NULL;
891
892                 if(tone != NULL && tone->name != NULL)
893                         old_name = safe_strdup(tone->name);
894 #endif
895     reinit_tone_bank_element(tone);
896
897     if(strcmp(pat, "%font") == 0) /* Font extention */
898     {
899         /* %font filename bank prog [note-to-use]
900          * %font filename 128 bank key
901          */
902
903         if(opts[0] == NULL || opts[1] == NULL || opts[2] == NULL ||
904            (atoi(opts[1]) == 128 && opts[3] == NULL))
905         {
906             ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
907                       "%s: line %d: Syntax error", name, line);
908             return 1;
909         }
910         tone->name = safe_strdup(opts[0]);
911         tone->instype = 1;
912         if(atoi(opts[1]) == 128) /* drum */
913         {
914             tone->font_bank = 128;
915             tone->font_preset = atoi(opts[2]);
916             tone->font_keynote = atoi(opts[3]);
917             opts += 4;
918         }
919         else
920         {
921             tone->font_bank = atoi(opts[1]);
922             tone->font_preset = atoi(opts[2]);
923
924             if(opts[3] && isdigit(opts[3][0]))
925             {
926                 tone->font_keynote = atoi(opts[3]);
927                 opts += 4;
928             }
929             else
930             {
931                 tone->font_keynote = -1;
932                 opts += 3;
933             }
934         }
935     }
936     else if(strcmp(pat, "%sample") == 0) /* Sample extention */
937     {
938         /* %sample filename */
939
940         if(opts[0] == NULL)
941         {
942             ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
943                       "%s: line %d: Syntax error", name, line);
944             return 1;
945         }
946         tone->name = safe_strdup(opts[0]);
947         tone->instype = 2;
948         opts++;
949     }
950     else
951     {
952         tone->instype = 0;
953         tone->name = safe_strdup(pat);
954     }
955
956     for(j = 0; opts[j] != NULL; j++)
957     {
958         int err;
959         if((err = set_gus_patchconf_opts(name, line, opts[j], tone)) != 0)
960             return err;
961     }
962 #ifdef SET_GUS_PATCHCONF_COMMENT
963                 if(tone->comment == NULL ||
964                         (old_name != NULL && strcmp(old_name,tone->comment) == 0))
965                 {
966                         if(tone->comment != NULL )
967                                 free(tone->comment);
968                         tone->comment = safe_strdup(tone->name);
969                 }
970                 if(old_name != NULL)
971                         free(old_name);
972 #else
973     if(tone->comment == NULL)
974         tone->comment = safe_strdup(tone->name);
975 #endif
976     return 0;
977 }
978
979 static int set_patchconf(char *name, int line, ToneBank *bank, char *w[], int dr, int mapid, int bankmapfrom, int bankno)
980 {
981     int i;
982     
983     i = atoi(w[0]);
984     if(!dr)
985         i -= progbase;
986     if(i < 0 || i > 127)
987     {
988         if(dr)
989             ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
990                       "%s: line %d: Drum number must be between "
991                       "0 and 127",
992                       name, line);
993         else
994             ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
995                       "%s: line %d: Program must be between "
996                       "%d and %d",
997                       name, line, progbase, 127 + progbase);
998         return 1;
999     }
1000     if(!bank)
1001     {
1002         ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1003                   "%s: line %d: Must specify tone bank or drum set "
1004                   "before assignment", name, line);
1005         return 1;
1006     }
1007
1008     if(set_gus_patchconf(name, line, &bank->tone[i], w[1], w + 2))
1009         return 1;
1010     if (mapid != INST_NO_MAP)
1011         set_instrument_map(mapid, bankmapfrom, i, bankno, i);
1012     return 0;
1013 }
1014
1015 typedef struct {
1016         const char *name;
1017         int mapid, isdrum;
1018 } MapNameEntry;
1019
1020 static int mapnamecompare(const void *name, const void *entry)
1021 {
1022         return strcmp((const char *)name, ((const MapNameEntry *)entry)->name);
1023 }
1024
1025 static int mapname2id(char *name, int *isdrum)
1026 {
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}
1043         };
1044         const MapNameEntry *found;
1045         
1046         found = (MapNameEntry *)bsearch(name, data, sizeof data / sizeof data[0], sizeof data[0], mapnamecompare);
1047         if (found != NULL)
1048         {
1049                 *isdrum = found->isdrum;
1050                 return found->mapid;
1051         }
1052         return -1;
1053 }
1054
1055 /* string[0] should not be '#' */
1056 static int strip_trailing_comment(char *string, int next_token_index)
1057 {
1058     if (string[next_token_index - 1] == '#'     /* strip \1 in /^\S+(#*[ \t].*)/ */
1059         && (string[next_token_index] == ' ' || string[next_token_index] == '\t'))
1060     {
1061         string[next_token_index] = '\0';        /* new c-string terminator */
1062         while(string[--next_token_index - 1] == '#')
1063             ;
1064     }
1065     return next_token_index;
1066 }
1067
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; }
1074
1075 MAIN_INTERFACE int read_config_file(char *name, int self)
1076 {
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;
1084
1085     if(rcf_count > 50)
1086     {
1087         ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1088                   "Probable source loop in configuration files");
1089         return 2;
1090     }
1091
1092     if(self)
1093     {
1094         tf = open_with_mem(name, (int32)strlen(name), OF_VERBOSE);
1095         name = "(configuration)";
1096     }
1097     else
1098         tf = open_file(name, 1, OF_VERBOSE);
1099     if(tf == NULL)
1100         return 1;
1101
1102     errno = 0;
1103     while(tf_gets(tmp, sizeof(tmp), tf))
1104     {
1105         line++;
1106         if(strncmp(tmp, "#extension", 10) == 0) {
1107             extension_flag = 1;
1108             i = 10;
1109         }
1110         else
1111         {
1112             extension_flag = 0;
1113             i = 0;
1114         }
1115
1116         while(isspace(tmp[i]))                  /* skip /^\s*(?#)/ */
1117             i++;
1118         if (tmp[i] == '#' || tmp[i] == '\0')    /* /^#|^$/ */
1119             continue;
1120         j = strcspn(tmp + i, " \t\r\n\240");
1121         if (j == 0)
1122                 j = strlen(tmp + i);
1123         j = strip_trailing_comment(tmp + i, j);
1124         tmp[i + j] = '\0';                      /* terminate the first token */
1125         w[0] = tmp + i;
1126         i += j + 1;
1127         words = param_parse_err = 0;
1128         while(words < MAXWORDS - 1)             /* -1 : next arg */
1129         {
1130             char *terminator;
1131
1132             while(isspace(tmp[i]))              /* skip /^\s*(?#)/ */
1133                 i++;
1134             if (tmp[i] == '\0'
1135                     || tmp[i] == '#')           /* /\s#/ */
1136                 break;
1137             if ((tmp[i] == '"' || tmp[i] == '\'')
1138                     && (terminator = strchr(tmp + i + 1, tmp[i])) != NULL)
1139             {
1140                 if (!isspace(terminator[1]) && terminator[1] != '\0')
1141                 {
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]);
1145                     CHECKERRLIMIT;
1146                     param_parse_err = 1;
1147                     break;
1148                 }
1149                 w[++words] = tmp + i + 1;
1150                 i = terminator - tmp + 1;
1151                 *terminator = '\0';
1152             }
1153             else        /* not terminated */
1154             {
1155                 j = strcspn(tmp + i, " \t\r\n\240");
1156                 if (j > 0)
1157                     j = strip_trailing_comment(tmp + i, j);
1158                 w[++words] = tmp + i;
1159                 i += j;
1160                 if (tmp[i] != '\0')             /* unless at the end-of-string (i.e. EOF) */
1161                     tmp[i++] = '\0';            /* terminate the token */
1162             }
1163         }
1164         if (param_parse_err)
1165             continue;
1166         w[++words] = NULL;
1167
1168         /*
1169          * #extension [something...]
1170          */
1171
1172         /* #extension comm program comment */
1173         if(strcmp(w[0], "comm") == 0)
1174         {
1175             char *p;
1176
1177             if(words != 3)
1178             {
1179                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1180                           "%s: line %d: syntax error", name, line);
1181                 CHECKERRLIMIT;
1182                 continue;
1183             }
1184             if(!bank)
1185             {
1186                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1187                           "%s: line %d: Must specify tone bank or drum "
1188                           "set before assignment", name, line);
1189                 CHECKERRLIMIT;
1190                 continue;
1191             }
1192             i = atoi(w[1]);
1193             if(i < 0 || i > 127)
1194             {
1195                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1196                           "%s: line %d: extension comm must be "
1197                           "between 0 and 127", name, line);
1198                 CHECKERRLIMIT;
1199                 continue;
1200             }
1201             if(bank->tone[i].comment)
1202                 free(bank->tone[i].comment);
1203             p = bank->tone[i].comment = safe_strdup(w[2]);
1204             while(*p)
1205             {
1206                 if(*p == ',') *p = ' ';
1207                 p++;
1208             }
1209         }
1210         /* #extension timeout program sec */
1211         else if(strcmp(w[0], "timeout") == 0)
1212         {
1213             if(words != 3)
1214             {
1215                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1216                           "%s: line %d: syntax error", name, line);
1217                 CHECKERRLIMIT;
1218                 continue;
1219             }
1220             if(!bank)
1221             {
1222                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1223                           "%s: line %d: Must specify tone bank or drum set "
1224                           "before assignment", name, line);
1225                 CHECKERRLIMIT;
1226                 continue;
1227             }
1228             i = atoi(w[1]);
1229             if(i < 0 || i > 127)
1230             {
1231                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1232                           "%s: line %d: extension timeout "
1233                           "must be between 0 and 127", name, line);
1234                 CHECKERRLIMIT;
1235                 continue;
1236             }
1237             bank->tone[i].loop_timeout = atoi(w[2]);
1238         }
1239         /* #extension copydrumset drumset */
1240         else if(strcmp(w[0], "copydrumset") == 0)
1241         {
1242             if(words < 2)
1243             {
1244                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1245                           "%s: line %d: No copydrumset number given",
1246                           name, line);
1247                 CHECKERRLIMIT;
1248                 continue;
1249             }
1250             i = atoi(w[1]);
1251             if(i < 0 || i > 127)
1252             {
1253                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1254                           "%s: line %d: extension copydrumset "
1255                           "must be between 0 and 127", name, line);
1256                 CHECKERRLIMIT;
1257                 continue;
1258             }
1259             if(!bank)
1260             {
1261                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1262                           "%s: line %d: Must specify tone bank or "
1263                           "drum set before assignment", name, line);
1264                 CHECKERRLIMIT;
1265                 continue;
1266             }
1267             copybank(bank, drumset[i], mapid, origbankno, bankno);
1268         }
1269         /* #extension copybank bank */
1270         else if(strcmp(w[0], "copybank") == 0)
1271         {
1272             if(words < 2)
1273             {
1274                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1275                           "%s: line %d: No copybank number given",
1276                           name, line);
1277                 CHECKERRLIMIT;
1278                 continue;
1279             }
1280             i = atoi(w[1]);
1281             if(i < 0 || i > 127)
1282             {
1283                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1284                           "%s: line %d: extension copybank "
1285                           "must be between 0 and 127", name, line);
1286                 CHECKERRLIMIT;
1287                 continue;
1288             }
1289             if(!bank)
1290             {
1291                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1292                           "%s: line %d: Must specify tone bank or "
1293                           "drum set before assignment", name, line);
1294                 CHECKERRLIMIT;
1295                 continue;
1296             }
1297             copybank(bank, tonebank[i], mapid, origbankno, bankno);
1298         }
1299         /* #extension copymap tomapid frommapid */
1300         else if(strcmp(w[0], "copymap") == 0)
1301         {
1302             int mapto, mapfrom;
1303             int toisdrum, fromisdrum;
1304
1305             if(words != 3)
1306             {
1307                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1308                           "%s: line %d: syntax error", name, line);
1309                 CHECKERRLIMIT;
1310                 continue;
1311             }
1312             if ((mapto = mapname2id(w[1], &toisdrum)) == -1)
1313             {
1314                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1315                           "%s: line %d: Invalid map name: %s", name, line, w[1]);
1316                 CHECKERRLIMIT;
1317                 continue;
1318             }
1319             if ((mapfrom = mapname2id(w[2], &fromisdrum)) == -1)
1320             {
1321                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1322                           "%s: line %d: Invalid map name: %s", name, line, w[2]);
1323                 CHECKERRLIMIT;
1324                 continue;
1325             }
1326             if (toisdrum != fromisdrum)
1327             {
1328                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1329                           "%s: line %d: Map type should be matched", name, line);
1330                 CHECKERRLIMIT;
1331                 continue;
1332             }
1333             if (copymap(mapto, mapfrom, toisdrum))
1334             {
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");
1338                 CHECKERRLIMIT;
1339                 continue;
1340             }
1341         }
1342         /* #extension HTTPproxy hostname:port */
1343         else if(strcmp(w[0], "HTTPproxy") == 0)
1344         {
1345             if(words < 2)
1346             {
1347                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1348                           "%s: line %d: No proxy name given",
1349                           name, line);
1350                 CHECKERRLIMIT;
1351                 continue;
1352             }
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)
1357             {
1358                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1359                           "%s: line %d: Syntax error", name, line);
1360                 CHECKERRLIMIT;
1361                 continue;
1362             }
1363             *cp++ = '\0';
1364             if((url_http_proxy_port = atoi(cp)) <= 0)
1365             {
1366                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1367                           "%s: line %d: Port number must be "
1368                           "positive number", name, line);
1369                 CHECKERRLIMIT;
1370                 continue;
1371             }
1372 #endif
1373         }
1374         /* #extension FTPproxy hostname:port */
1375         else if(strcmp(w[0], "FTPproxy") == 0)
1376         {
1377             if(words < 2)
1378             {
1379                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1380                           "%s: line %d: No proxy name given",
1381                           name, line);
1382                 CHECKERRLIMIT;
1383                 continue;
1384             }
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)
1389             {
1390                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1391                           "%s: line %d: Syntax error", name, line);
1392                 CHECKERRLIMIT;
1393                 continue;
1394             }
1395             *cp++ = '\0';
1396             if((url_ftp_proxy_port = atoi(cp)) <= 0)
1397             {
1398                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1399                           "%s: line %d: Port number "
1400                           "must be positive number", name, line);
1401                 CHECKERRLIMIT;
1402                 continue;
1403             }
1404 #endif
1405         }
1406         /* #extension mailaddr somebody@someware.domain.com */
1407         else if(strcmp(w[0], "mailaddr") == 0)
1408         {
1409             if(words < 2)
1410             {
1411                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1412                           "%s: line %d: No mail address given",
1413                           name, line);
1414                 CHECKERRLIMIT;
1415                 continue;
1416             }
1417             if(strchr(w[1], '@') == NULL) {
1418                 ctl->cmsg(CMSG_WARNING, VERB_NOISY,
1419                           "%s: line %d: Warning: Mail address %s is not valid",
1420                           name, line);
1421             }
1422
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 */
1427         }
1428         /* #extension opt [-]{option}[optarg] */
1429         else if (strcmp(w[0], "opt") == 0) {
1430                 int c, longind, err;
1431                 char *p, *cmd, *arg;
1432                 
1433                 if (words != 2 && words != 3) {
1434                         ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1435                                         "%s: line %d: Syntax error", name, line);
1436                         CHECKERRLIMIT;
1437                         continue;
1438                 }
1439                 if (*w[1] == '-') {
1440                         int optind_save = optind;
1441                         optind = 0;
1442                         c = getopt_long(words, w, optcommands, longopts, &longind);
1443                         err = set_tim_opt_long(c, optarg, longind);
1444                         optind = optind_save;
1445                 } else {
1446                         /* backward compatibility */
1447                         if ((p = strchr(optcommands, c = *(cmd = w[1]))) == NULL)
1448                                 err = 1;
1449                         else {
1450                                 if (*(p + 1) == ':')
1451                                         arg = (words == 2) ? cmd + 1 : w[2];
1452                                 else
1453                                         arg = "";
1454                                 err = set_tim_opt_short(c, arg);
1455                         }
1456                 }
1457                 if (err) {
1458                         /* error */
1459                         ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1460                                         "%s: line %d: Invalid command line option",
1461                                         name, line);
1462                         errcnt += err - 1;
1463                         CHECKERRLIMIT;
1464                         continue;
1465                 }
1466         }
1467         /* #extension undef program */
1468         else if(strcmp(w[0], "undef") == 0)
1469         {
1470             if(words < 2)
1471             {
1472                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1473                           "%s: line %d: No undef number given",
1474                           name, line);
1475                 CHECKERRLIMIT;
1476                 continue;
1477             }
1478             i = atoi(w[1]);
1479             if(i < 0 || i > 127)
1480             {
1481                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1482                           "%s: line %d: extension undef "
1483                           "must be between 0 and 127", name, line);
1484                 CHECKERRLIMIT;
1485                 continue;
1486             }
1487             if(!bank)
1488             {
1489                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1490                           "%s: line %d: Must specify tone bank or "
1491                           "drum set before assignment", name, line);
1492                 CHECKERRLIMIT;
1493                 continue;
1494             }
1495             free_tone_bank_element(&bank->tone[i]);
1496         }
1497         /* #extension altassign numbers... */
1498         else if(strcmp(w[0], "altassign") == 0)
1499         {
1500             ToneBank *bk;
1501
1502             if(!bank)
1503             {
1504                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1505                           "%s: line %d: Must specify tone bank or drum set "
1506                           "before altassign", name, line);
1507                 CHECKERRLIMIT;
1508                 continue;
1509             }
1510             if(words < 2)
1511             {
1512                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1513                           "%s: line %d: No alternate assignment", name, line);
1514                 CHECKERRLIMIT;
1515                 continue;
1516             }
1517
1518             if(!dr) {
1519                 ctl->cmsg(CMSG_WARNING, VERB_NORMAL,
1520                           "%s: line %d: Warning: Not a drumset altassign"
1521                           " (ignored)",
1522                           name, line);
1523                 continue;
1524             }
1525
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)
1530         {
1531             if(words != 3)
1532             {
1533                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1534                           "%s: line %d: syntax error", name, line);
1535                 CHECKERRLIMIT;
1536                 continue;
1537             }
1538             if(!bank)
1539             {
1540                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1541                           "%s: line %d: Must specify tone bank or drum set "
1542                           "before assignment", name, line);
1543                 CHECKERRLIMIT;
1544                 continue;
1545             }
1546             i = atoi(w[1]);
1547             if(i < 0 || i > 127)
1548             {
1549                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1550                           "%s: line %d: extension legato "
1551                           "must be between 0 and 127", name, line);
1552                 CHECKERRLIMIT;
1553                 continue;
1554             }
1555             bank->tone[i].legato = atoi(w[2]);
1556         }       /* #extension damper [program] [0 or 1] */
1557         else if(strcmp(w[0], "damper") == 0)
1558         {
1559             if(words != 3)
1560             {
1561                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1562                           "%s: line %d: syntax error", name, line);
1563                 CHECKERRLIMIT;
1564                 continue;
1565             }
1566             if(!bank)
1567             {
1568                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1569                           "%s: line %d: Must specify tone bank or drum set "
1570                           "before assignment", name, line);
1571                 CHECKERRLIMIT;
1572                 continue;
1573             }
1574             i = atoi(w[1]);
1575             if(i < 0 || i > 127)
1576             {
1577                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1578                           "%s: line %d: extension damper "
1579                           "must be between 0 and 127", name, line);
1580                 CHECKERRLIMIT;
1581                 continue;
1582             }
1583             bank->tone[i].damper_mode = atoi(w[2]);
1584         }       /* #extension rnddelay [program] [0 or 1] */
1585         else if(strcmp(w[0], "rnddelay") == 0)
1586         {
1587             if(words != 3)
1588             {
1589                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1590                           "%s: line %d: syntax error", name, line);
1591                 CHECKERRLIMIT;
1592                 continue;
1593             }
1594             if(!bank)
1595             {
1596                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1597                           "%s: line %d: Must specify tone bank or drum set "
1598                           "before assignment", name, line);
1599                 CHECKERRLIMIT;
1600                 continue;
1601             }
1602             i = atoi(w[1]);
1603             if(i < 0 || i > 127)
1604             {
1605                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1606                           "%s: line %d: extension rnddelay "
1607                           "must be between 0 and 127", name, line);
1608                 CHECKERRLIMIT;
1609                 continue;
1610             }
1611             bank->tone[i].rnddelay = atoi(w[2]);
1612         }       /* #extension level program tva_level */
1613         else if(strcmp(w[0], "level") == 0)
1614         {
1615             if(words != 3)
1616             {
1617                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: line %d: syntax error", name, line);
1618                 CHECKERRLIMIT;
1619                 continue;
1620             }
1621             if(!bank)
1622             {
1623                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1624                           "%s: line %d: Must specify tone bank or drum set "
1625                           "before assignment", name, line);
1626                 CHECKERRLIMIT;
1627                 continue;
1628             }
1629                 i = atoi(w[2]);
1630                 if(i < 0 || i > 127)
1631                 {
1632                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1633                           "%s: line %d: extension level "
1634                           "must be between 0 and 127", name, line);
1635                 CHECKERRLIMIT;
1636                 continue;
1637                 }
1638                 cp = w[1];
1639                 do {
1640                         if (string_to_7bit_range(cp, &j, &k))
1641                         {
1642                                 while (j <= k)
1643                                         bank->tone[j++].tva_level = i;
1644                         }
1645                         cp = strchr(cp, ',');
1646                 } while(cp++ != NULL);
1647         }       /* #extension reverbsend */
1648         else if(strcmp(w[0], "reverbsend") == 0)
1649         {
1650             if(words != 3)
1651             {
1652                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: line %d: syntax error", name, line);
1653                 CHECKERRLIMIT;
1654                 continue;
1655             }
1656             if(!bank)
1657             {
1658                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1659                           "%s: line %d: Must specify tone bank or drum set "
1660                           "before assignment", name, line);
1661                 CHECKERRLIMIT;
1662                 continue;
1663             }
1664                 i = atoi(w[2]);
1665                 if(i < 0 || i > 127)
1666                 {
1667                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1668                           "%s: line %d: extension reverbsend "
1669                           "must be between 0 and 127", name, line);
1670                 CHECKERRLIMIT;
1671                 continue;
1672                 }
1673                 cp = w[1];
1674                 do {
1675                         if (string_to_7bit_range(cp, &j, &k))
1676                         {
1677                                 while (j <= k)
1678                                         bank->tone[j++].reverb_send = i;
1679                         }
1680                         cp = strchr(cp, ',');
1681                 } while(cp++ != NULL);
1682         }       /* #extension chorussend */
1683         else if(strcmp(w[0], "chorussend") == 0)
1684         {
1685             if(words != 3)
1686             {
1687                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: line %d: syntax error", name, line);
1688                 CHECKERRLIMIT;
1689                 continue;
1690             }
1691             if(!bank)
1692             {
1693                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1694                           "%s: line %d: Must specify tone bank or drum set "
1695                           "before assignment", name, line);
1696                 CHECKERRLIMIT;
1697                 continue;
1698             }
1699                 i = atoi(w[2]);
1700                 if(i < 0 || i > 127)
1701                 {
1702                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1703                           "%s: line %d: extension chorussend "
1704                           "must be between 0 and 127", name, line);
1705                 CHECKERRLIMIT;
1706                 continue;
1707                 }
1708                 cp = w[1];
1709                 do {
1710                         if (string_to_7bit_range(cp, &j, &k))
1711                         {
1712                                 while (j <= k)
1713                                         bank->tone[j++].chorus_send = i;
1714                         }
1715                         cp = strchr(cp, ',');
1716                 } while(cp++ != NULL);
1717         }       /* #extension delaysend */
1718         else if(strcmp(w[0], "delaysend") == 0)
1719         {
1720             if(words != 3)
1721             {
1722                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: line %d: syntax error", name, line);
1723                 CHECKERRLIMIT;
1724                 continue;
1725             }
1726             if(!bank)
1727             {
1728                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1729                           "%s: line %d: Must specify tone bank or drum set "
1730                           "before assignment", name, line);
1731                 CHECKERRLIMIT;
1732                 continue;
1733             }
1734                 i = atoi(w[2]);
1735                 if(i < 0 || i > 127)
1736                 {
1737                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1738                           "%s: line %d: extension delaysend "
1739                           "must be between 0 and 127", name, line);
1740                 CHECKERRLIMIT;
1741                 continue;
1742                 }
1743                 cp = w[1];
1744                 do {
1745                         if (string_to_7bit_range(cp, &j, &k))
1746                         {
1747                                 while (j <= k)
1748                                         bank->tone[j++].delay_send = i;
1749                         }
1750                         cp = strchr(cp, ',');
1751                 } while(cp++ != NULL);
1752         }       /* #extension playnote */
1753         else if(strcmp(w[0], "playnote") == 0)
1754         {
1755             if(words != 3)
1756             {
1757                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: line %d: syntax error", name, line);
1758                 CHECKERRLIMIT;
1759                 continue;
1760             }
1761             if(!bank)
1762             {
1763                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1764                           "%s: line %d: Must specify tone bank or drum set "
1765                           "before assignment", name, line);
1766                 CHECKERRLIMIT;
1767                 continue;
1768             }
1769                 i = atoi(w[2]);
1770                 if(i < 0 || i > 127)
1771                 {
1772                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1773                           "%s: line %d: extension playnote"
1774                           "must be between 0 and 127", name, line);
1775                 CHECKERRLIMIT;
1776                 continue;
1777                 }
1778                 cp = w[1];
1779                 do {
1780                         if (string_to_7bit_range(cp, &j, &k))
1781                         {
1782                                 while (j <= k)
1783                                         bank->tone[j++].play_note = i;
1784                         }
1785                         cp = strchr(cp, ',');
1786                 } while(cp++ != NULL);
1787         }
1788         else if(!strcmp(w[0], "soundfont"))
1789         {
1790             int order, cutoff, isremove, reso, amp;
1791             char *sf_file;
1792
1793             if(words < 2)
1794             {
1795                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1796                           "%s: line %d: No soundfont file given",
1797                           name, line);
1798                 CHECKERRLIMIT;
1799                 continue;
1800             }
1801
1802             sf_file = w[1];
1803             order = cutoff = reso = amp = -1;
1804             isremove = 0;
1805             for(j = 2; j < words; j++)
1806             {
1807                 if(strcmp(w[j], "remove") == 0)
1808                 {
1809                     isremove = 1;
1810                     break;
1811                 }
1812                 if(!(cp = strchr(w[j], '=')))
1813                 {
1814                     ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1815                               "%s: line %d: bad patch option %s",
1816                               name, line, w[j]);
1817                     CHECKERRLIMIT;
1818                     break;
1819                 }
1820                 *cp++=0;
1821                 k = atoi(cp);
1822                 if(!strcmp(w[j], "order"))
1823                 {
1824                     if(k < 0 || (*cp < '0' || *cp > '9'))
1825                     {
1826                         ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1827                                   "%s: line %d: order must be a digit",
1828                                   name, line);
1829                         CHECKERRLIMIT;
1830                         break;
1831                     }
1832                     order = k;
1833                 }
1834                 else if(!strcmp(w[j], "cutoff"))
1835                 {
1836                     if(k < 0 || (*cp < '0' || *cp > '9'))
1837                     {
1838                         ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1839                                   "%s: line %d: cutoff must be a digit",
1840                                   name, line);
1841                         CHECKERRLIMIT;
1842                         break;
1843                     }
1844                     cutoff = k;
1845                 }
1846                 else if(!strcmp(w[j], "reso"))
1847                 {
1848                     if(k < 0 || (*cp < '0' || *cp > '9'))
1849                     {
1850                         ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1851                                   "%s: line %d: reso must be a digit",
1852                                   name, line);
1853                         CHECKERRLIMIT;
1854                         break;
1855                     }
1856                     reso = k;
1857                 }
1858                 else if(!strcmp(w[j], "amp"))
1859                 {
1860                     amp = k;
1861                 }
1862             }
1863             if(isremove)
1864                 remove_soundfont(sf_file);
1865             else
1866                 add_soundfont(sf_file, order, cutoff, reso, amp);
1867         }
1868         else if(!strcmp(w[0], "font"))
1869         {
1870             int bank, preset, keynote;
1871             if(words < 2)
1872             {
1873                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1874                           "%s: line %d: no font command", name, line);
1875                 CHECKERRLIMIT;
1876                 continue;
1877             }
1878             if(!strcmp(w[1], "exclude"))
1879             {
1880                 if(words < 3)
1881                 {
1882                     ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1883                               "%s: line %d: No bank/preset/key is given",
1884                               name, line);
1885                     CHECKERRLIMIT;
1886                     continue;
1887                 }
1888                 bank = atoi(w[2]);
1889                 if(words >= 4)
1890                     preset = atoi(w[3]) - progbase;
1891                 else
1892                     preset = -1;
1893                 if(words >= 5)
1894                     keynote = atoi(w[4]);
1895                 else
1896                     keynote = -1;
1897                 if(exclude_soundfont(bank, preset, keynote))
1898                 {
1899                     ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1900                               "%s: line %d: No soundfont is given",
1901                               name, line);
1902                     CHECKERRLIMIT;
1903                 }
1904             }
1905             else if(!strcmp(w[1], "order"))
1906             {
1907                 int order;
1908                 if(words < 4)
1909                 {
1910                     ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1911                               "%s: line %d: No order/bank is given",
1912                               name, line);
1913                     CHECKERRLIMIT;
1914                     continue;
1915                 }
1916                 order = atoi(w[2]);
1917                 bank = atoi(w[3]);
1918                 if(words >= 5)
1919                     preset = atoi(w[4]) - progbase;
1920                 else
1921                     preset = -1;
1922                 if(words >= 6)
1923                     keynote = atoi(w[5]);
1924                 else
1925                     keynote = -1;
1926                 if(order_soundfont(bank, preset, keynote, order))
1927                 {
1928                     ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1929                               "%s: line %d: No soundfont is given",
1930                               name, line);
1931                     CHECKERRLIMIT;
1932                 }
1933             }
1934         }
1935         else if(!strcmp(w[0], "progbase"))
1936         {
1937             if(words < 2 || *w[1] < '0' || *w[1] > '9')
1938             {
1939                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1940                           "%s: line %d: syntax error", name, line);
1941                 CHECKERRLIMIT;
1942                 continue;
1943             }
1944             progbase = atoi(w[1]);
1945         }
1946         else if(!strcmp(w[0], "map")) /* map <name> set1 elem1 set2 elem2 */
1947         {
1948             int arg[5], isdrum;
1949
1950             if(words != 6)
1951             {
1952                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1953                           "%s: line %d: syntax error", name, line);
1954                 CHECKERRLIMIT;
1955                 continue;
1956             }
1957             if((arg[0] = mapname2id(w[1], &isdrum)) == -1)
1958             {
1959                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1960                           "%s: line %d: Invalid map name: %s", name, line, w[1]);
1961                 CHECKERRLIMIT;
1962                 continue;
1963             }
1964             for(i = 2; i < 6; i++)
1965                 arg[i - 1] = atoi(w[i]);
1966             if(isdrum)
1967             {
1968                 arg[1] -= progbase;
1969                 arg[3] -= progbase;
1970             }
1971             else
1972             {
1973                 arg[2] -= progbase;
1974                 arg[4] -= progbase;
1975             }
1976
1977             for(i = 1; i < 5; i++)
1978                 if(arg[i] < 0 || arg[i] > 127)
1979                     break;
1980             if(i != 5)
1981             {
1982                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1983                           "%s: line %d: Invalid parameter", name, line);
1984                 CHECKERRLIMIT;
1985                 continue;
1986             }
1987             set_instrument_map(arg[0], arg[1], arg[2], arg[3], arg[4]);
1988         }
1989
1990         /*
1991          * Standard configurations
1992          */
1993         else if(!strcmp(w[0], "dir"))
1994         {
1995             if(words < 2)
1996             {
1997                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1998                           "%s: line %d: No directory given", name, line);
1999                 CHECKERRLIMIT;
2000                 continue;
2001             }
2002             for(i = 1; i < words; i++)
2003                 add_to_pathlist(w[i]);
2004         }
2005         else if(!strcmp(w[0], "source"))
2006         {
2007             if(words < 2)
2008             {
2009                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
2010                           "%s: line %d: No file name given", name, line);
2011                 CHECKERRLIMIT;
2012                 continue;
2013             }
2014             for(i = 1; i < words; i++)
2015             {
2016                 int status;
2017                 rcf_count++;
2018                 status = read_config_file(w[i], 0);
2019                 rcf_count--;
2020                 if(status == 2)
2021                 {
2022                     close_file(tf);
2023                     return 2;
2024                 }
2025                 else if(status != 0)
2026                 {
2027
2028                     CHECKERRLIMIT;
2029                     continue;
2030                 }
2031             }
2032         }
2033         else if(!strcmp(w[0], "default"))
2034         {
2035             if(words != 2)
2036             {
2037                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
2038                           "%s: line %d: Must specify exactly one patch name",
2039                           name, line);
2040                 CHECKERRLIMIT;
2041                 continue;
2042             }
2043             strncpy(def_instr_name, w[1], 255);
2044             def_instr_name[255] = '\0';
2045             default_instrument_name = def_instr_name;
2046         }
2047         /* drumset [mapid] num */
2048         else if(!strcmp(w[0], "drumset"))
2049         {
2050             int newmapid, isdrum, newbankno;
2051             
2052             if(words < 2)
2053             {
2054                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
2055                           "%s: line %d: No drum set number given", name, line);
2056                 CHECKERRLIMIT;
2057                 continue;
2058             }
2059             if (words != 2 && !isdigit(*w[1]))
2060             {
2061                 if ((newmapid = mapname2id(w[1], &isdrum)) == -1 || !isdrum)
2062                 {
2063                     ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
2064                           "%s: line %d: Invalid drum set map name: %s", name, line, w[1]);
2065                     CHECKERRLIMIT;
2066                     continue;
2067                 }
2068                 words--;
2069                 memmove(&w[1], &w[2], sizeof w[0] * words);
2070             }
2071             else
2072                 newmapid = INST_NO_MAP;
2073             i = atoi(w[1]) - progbase;
2074             if(i < 0 || i > 127)
2075             {
2076                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
2077                           "%s: line %d: Drum set must be between %d and %d",
2078                           name, line,
2079                           progbase, progbase + 127);
2080                 CHECKERRLIMIT;
2081                 continue;
2082             }
2083
2084             newbankno = i;
2085             i = alloc_instrument_map_bank(1, newmapid, i);
2086             if (i == -1)
2087             {
2088                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
2089                           "%s: line %d: No free drum set available to map",
2090                           name, line);
2091                 CHECKERRLIMIT;
2092                 continue;
2093             }
2094
2095             if(words == 2)
2096             {
2097                 bank = drumset[i];
2098                 bankno = i;
2099                 mapid = newmapid;
2100                 origbankno = newbankno;
2101                 dr = 1;
2102             }
2103             else
2104             {
2105                 if(words < 4 || *w[2] < '0' || *w[2] > '9')
2106                 {
2107                     ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
2108                               "%s: line %d: syntax error", name, line);
2109                     CHECKERRLIMIT;
2110                     continue;
2111                 }
2112                 if (set_patchconf(name, line, drumset[i], &w[2], 1, newmapid, newbankno, i))
2113                 {
2114                     CHECKERRLIMIT;
2115                     continue;
2116                 }
2117             }
2118         }
2119         /* bank [mapid] num */
2120         else if(!strcmp(w[0], "bank"))
2121         {
2122             int newmapid, isdrum, newbankno;
2123             
2124             if(words < 2)
2125             {
2126                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
2127                           "%s: line %d: No bank number given", name, line);
2128                 CHECKERRLIMIT;
2129                 continue;
2130             }
2131             if (words != 2 && !isdigit(*w[1]))
2132             {
2133                 if ((newmapid = mapname2id(w[1], &isdrum)) == -1 || isdrum)
2134                 {
2135                     ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
2136                           "%s: line %d: Invalid bank map name: %s", name, line, w[1]);
2137                     CHECKERRLIMIT;
2138                     continue;
2139                 }
2140                 words--;
2141                 memmove(&w[1], &w[2], sizeof w[0] * words);
2142             }
2143             else
2144                 newmapid = INST_NO_MAP;
2145             i = atoi(w[1]);
2146             if(i < 0 || i > 127)
2147             {
2148                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
2149                           "%s: line %d: Tone bank must be between 0 and 127",
2150                           name, line);
2151                 CHECKERRLIMIT;
2152                 continue;
2153             }
2154
2155             newbankno = i;
2156             i = alloc_instrument_map_bank(0, newmapid, i);
2157             if (i == -1)
2158             {
2159                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
2160                           "%s: line %d: No free tone bank available to map",
2161                           name, line);
2162                 CHECKERRLIMIT;
2163                 continue;
2164             }
2165
2166             if(words == 2)
2167             {
2168                 bank = tonebank[i];
2169                 bankno = i;
2170                 mapid = newmapid;
2171                 origbankno = newbankno;
2172                 dr = 0;
2173             }
2174             else
2175             {
2176                 if(words < 4 || *w[2] < '0' || *w[2] > '9')
2177                 {
2178                     ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
2179                               "%s: line %d: syntax error", name, line);
2180                     CHECKERRLIMIT;
2181                     continue;
2182                 }
2183                 if (set_patchconf(name, line, tonebank[i], &w[2], 0, newmapid, newbankno, i))
2184                 {
2185                     CHECKERRLIMIT;
2186                     continue;
2187                 }
2188             }
2189         }
2190         else
2191         {
2192             if(words < 2 || *w[0] < '0' || *w[0] > '9')
2193             {
2194                 if(extension_flag)
2195                     continue;
2196                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
2197                           "%s: line %d: syntax error", name, line);
2198                 CHECKERRLIMIT;
2199                 continue;
2200             }
2201             if (set_patchconf(name, line, bank, w, dr, mapid, origbankno, bankno))
2202             {
2203                 CHECKERRLIMIT;
2204                 continue;
2205             }
2206         }
2207     }
2208     if(errno)
2209     {
2210         ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
2211                   "Can't read %s: %s", name, strerror(errno));
2212         errcnt++;
2213     }
2214     close_file(tf);
2215     return errcnt != 0;
2216 }
2217
2218 #ifdef SUPPORT_SOCKET
2219
2220 #if defined(__W32__) && !defined(MAIL_NAME)
2221 #define MAIL_NAME "anonymous"
2222 #endif /* __W32__ */
2223
2224 #ifdef MAIL_NAME
2225 #define get_username() MAIL_NAME
2226 #else /* MAIL_NAME */
2227 #include <pwd.h>
2228 static char *get_username(void)
2229 {
2230     char *p;
2231     struct passwd *pass;
2232
2233     /* USER
2234      * LOGIN
2235      * LOGNAME
2236      * getpwnam()
2237      */
2238
2239     if((p = getenv("USER")) != NULL)
2240         return p;
2241     if((p = getenv("LOGIN")) != NULL)
2242         return p;
2243     if((p = getenv("LOGNAME")) != NULL)
2244         return p;
2245
2246     pass = getpwuid(getuid());
2247     if(pass == NULL)
2248         return "nobody";
2249     return pass->pw_name;
2250 }
2251 #endif /* MAIL_NAME */
2252
2253 static void init_mail_addr(void)
2254 {
2255     char addr[BUFSIZ];
2256
2257     sprintf(addr, "%s%s", get_username(), MAIL_DOMAIN);
2258     user_mailaddr = safe_strdup(addr);
2259 }
2260 #endif /* SUPPORT_SOCKET */
2261
2262 static int read_user_config_file(void)
2263 {
2264     char *home;
2265     char path[BUFSIZ];
2266     int opencheck;
2267
2268 #ifdef __W32__
2269 /* HOME or home */
2270     home = getenv("HOME");
2271     if(home == NULL)
2272         home = getenv("home");
2273     if(home == NULL)
2274     {
2275         ctl->cmsg(CMSG_INFO, VERB_NOISY,
2276                   "Warning: HOME environment is not defined.");
2277         return 0;
2278     }
2279 /* .timidity.cfg or timidity.cfg */
2280     sprintf(path, "%s" PATH_STRING "timidity.cfg", home);
2281     if((opencheck = open(path, 0)) < 0)
2282     {
2283         sprintf(path, "%s" PATH_STRING "_timidity.cfg", home);
2284         if((opencheck = open(path, 0)) < 0)
2285         {
2286             sprintf(path, "%s" PATH_STRING ".timidity.cfg", home);
2287             if((opencheck = open(path, 0)) < 0)
2288             {
2289                 ctl->cmsg(CMSG_INFO, VERB_NOISY, "%s: %s",
2290                           path, strerror(errno));
2291                 return 0;
2292             }
2293         }
2294     }
2295
2296     close(opencheck);
2297     return read_config_file(path, 0);
2298 #else
2299     home = getenv("HOME");
2300     if(home == NULL)
2301     {
2302         ctl->cmsg(CMSG_INFO, VERB_NOISY,
2303                   "Warning: HOME environment is not defined.");
2304         return 0;
2305     }
2306     sprintf(path, "%s" PATH_STRING ".timidity.cfg", home);
2307
2308     if((opencheck = open(path, 0)) < 0)
2309     {
2310         ctl->cmsg(CMSG_INFO, VERB_NOISY, "%s: %s",
2311                   path, strerror(errno));
2312         return 0;
2313     }
2314
2315     close(opencheck);
2316     return read_config_file(path, 0);
2317 #endif /* __W32__ */
2318 }
2319
2320 MAIN_INTERFACE void tmdy_free_config(void)
2321 {
2322         free_tone_bank();
2323         free_instrument_map();
2324         clean_up_pathlist();
2325 }
2326
2327 int set_extension_modes(char *flag)
2328 {
2329         return parse_opt_E(flag);
2330 }
2331
2332 int set_ctl(char *cp)
2333 {
2334         return parse_opt_i(cp);
2335 }
2336
2337 int set_play_mode(char *cp)
2338 {
2339         return parse_opt_O(cp);
2340 }
2341
2342 int set_wrd(char *w)
2343 {
2344         return parse_opt_W(w);
2345 }
2346
2347 #ifdef __W32__
2348 int opt_evil_mode = 0;
2349 #ifdef SMFCONV
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;
2361
2362 MAIN_INTERFACE int set_tim_opt_short(int c, char *optarg)
2363 {
2364         int err = 0;
2365         
2366         switch (c) {
2367         case '4':
2368                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
2369                                 "-4 option is obsoleted.  Please use -N");
2370                 return 1;
2371         case 'A':
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;
2378                 return err;
2379         case 'a':
2380                 antialiasing_allowed = 1;
2381                 break;
2382         case 'B':
2383                 return parse_opt_B(optarg);
2384         case 'C':
2385                 return parse_opt_C(optarg);
2386         case 'c':
2387                 return parse_opt_c(optarg);
2388         case 'D':
2389                 return parse_opt_D(optarg);
2390         case 'd':
2391                 return parse_opt_d(optarg);
2392         case 'E':
2393                 return parse_opt_E(optarg);
2394         case 'e':
2395                 return parse_opt_e(optarg);
2396         case 'F':
2397                 adjust_panning_immediately = (adjust_panning_immediately) ? 0 : 1;
2398                 break;
2399         case 'f':
2400                 fast_decay = (fast_decay) ? 0 : 1;
2401                 break;
2402         case 'g':
2403                 return parse_opt_g(optarg);
2404         case 'H':
2405                 return parse_opt_H(optarg);
2406         case 'h':
2407                 return parse_opt_h(optarg);
2408         case 'I':
2409                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
2410                                 "-I option is obsoleted.  Please use -Ei");
2411                 return 1;
2412         case 'i':
2413                 return parse_opt_i(optarg);
2414         case 'j':
2415                 opt_realtime_playing = (opt_realtime_playing) ? 0 : 1;
2416                 break;
2417         case 'K':
2418                 return parse_opt_K(optarg);
2419         case 'k':
2420                 return parse_opt_k(optarg);
2421         case 'L':
2422                 return parse_opt_L(optarg);
2423         case 'M':
2424                 return parse_opt_M(optarg);
2425         case 'm':
2426                 return parse_opt_m(optarg);
2427         case 'N':
2428                 return parse_opt_N(optarg);
2429         case 'O':
2430                 return parse_opt_O(optarg);
2431         case 'o':
2432                 return parse_opt_o(optarg);
2433         case 'P':
2434                 return parse_opt_P(optarg);
2435         case 'p':
2436                 if (*optarg != 'a')
2437                         err += parse_opt_p(optarg);
2438                 if (strchr(optarg, 'a'))
2439                         auto_reduce_polyphony = (auto_reduce_polyphony) ? 0 : 1;
2440                 return err;
2441         case 'Q':
2442                 return parse_opt_Q(optarg);
2443         case 'q':
2444                 return parse_opt_q(optarg);
2445         case 'R':
2446                 return parse_opt_R(optarg);
2447         case 'S':
2448                 return parse_opt_S(optarg);
2449         case 's':
2450                 return parse_opt_s(optarg);
2451         case 'T':
2452                 return parse_opt_T(optarg);
2453         case 't':
2454                 return parse_opt_t(optarg);
2455         case 'U':
2456                 free_instruments_afterwards = 1;
2457                 break;
2458         case 'V':
2459                 return parse_opt_volume_curve(optarg);
2460         case 'v':
2461                 return parse_opt_v(optarg);
2462         case 'W':
2463                 return parse_opt_W(optarg);
2464 #ifdef __W32__
2465         case 'w':
2466                 return parse_opt_w(optarg);
2467 #endif
2468         case 'x':
2469                 return parse_opt_x(optarg);
2470         case 'Z':
2471                 if (strncmp(optarg, "pure", 4))
2472                         return parse_opt_Z(optarg);
2473                 else
2474                         return parse_opt_Z1(optarg + 4);
2475         default:
2476                 return 1;
2477         }
2478         return 0;
2479 }
2480
2481 /* -------- getopt_long -------- */
2482 MAIN_INTERFACE int set_tim_opt_long(int c, char *optarg, int index)
2483 {
2484         const struct option *the_option = &(longopts[index]);
2485         char *arg;
2486         
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 */
2493         else
2494                 arg = optarg;
2495         switch (c) {
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);
2514         case TIM_OPT_EXT:
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);
2544         case TIM_OPT_DELAY:
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);
2552         case TIM_OPT_NS:
2553                 return parse_opt_noise_shaping(arg);
2554 #ifndef FIXED_RESAMPLATION
2555         case TIM_OPT_RESAMPLE:
2556                 return parse_opt_resample(arg);
2557 #endif
2558         case TIM_OPT_EVIL:
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);
2568         case TIM_OPT_HELP:
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);
2574         case TIM_OPT_QUIET:
2575                 return parse_opt_quiet(arg);
2576         case TIM_OPT_TRACE:
2577                 return parse_opt_trace(arg);
2578         case TIM_OPT_LOOP:
2579                 return parse_opt_loop(arg);
2580         case TIM_OPT_RANDOM:
2581                 return parse_opt_random(arg);
2582         case TIM_OPT_SORT:
2583                 return parse_opt_sort(arg);
2584 #ifdef IA_ALSASEQ
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);
2591 #endif
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 */
2611                         arg = "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 */
2616                         arg = "no";
2617                 return parse_opt_output_signed(arg);
2618         case TIM_OPT_OUTPUT_BITWIDTH:
2619                 if (! strcmp(the_option->name, "output-16bit"))
2620                         arg = "16bit";
2621                 else if (! strcmp(the_option->name, "output-24bit"))
2622                         arg = "24bit";
2623                 else if (! strcmp(the_option->name, "output-8bit"))
2624                         arg = "8bit";
2625                 return parse_opt_output_bitwidth(arg);
2626         case TIM_OPT_OUTPUT_FORMAT:
2627                 if (! strcmp(the_option->name, "output-linear"))
2628                         arg = "linear";
2629                 else if (! strcmp(the_option->name, "output-ulaw"))
2630                         arg = "ulaw";
2631                 else if (! strcmp(the_option->name, "output-alaw"))
2632                         arg = "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);
2644         case TIM_OPT_MUTE:
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);
2664         case TIM_OPT_WRD:
2665                 return parse_opt_W(arg);
2666 #ifdef __W32__
2667         case TIM_OPT_RCPCV_DLL:
2668                 return parse_opt_w(arg);
2669 #endif
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);
2678         default:
2679                 ctl->cmsg(CMSG_FATAL, VERB_NORMAL,
2680                                 "[BUG] Inconceivable case branch %d", c);
2681                 abort();
2682         }
2683 }
2684
2685 static inline int parse_opt_A(const char *arg)
2686 {
2687         /* amplify volume by n percent */
2688         return set_val_i32(&amplification, atoi(arg), 0, MAX_AMPLIFICATION,
2689                         "Amplification");
2690 }
2691
2692 static inline int parse_opt_drum_power(const char *arg)
2693 {
2694         /* --drum-power */
2695         return set_val_i32(&opt_drum_power, atoi(arg), 0, MAX_AMPLIFICATION,
2696                         "Drum power");
2697 }
2698
2699 static inline int parse_opt_volume_comp(const char *arg)
2700 {
2701         /* --[no-]volume-compensation */
2702         opt_amp_compensation = y_or_n_p(arg);
2703         return 0;
2704 }
2705
2706 static inline int parse_opt_a(const char *arg)
2707 {
2708         antialiasing_allowed = y_or_n_p(arg);
2709         return 0;
2710 }
2711
2712 static inline int parse_opt_B(const char *arg)
2713 {
2714         /* --buffer-fragments */
2715         const char *p;
2716         
2717         /* num */
2718         if (*arg != ',') {
2719                 if (set_value(&opt_buffer_fragments, atoi(arg), 0, 1000,
2720                                 "Buffer Fragments (num)"))
2721                         return 1;
2722         }
2723         /* bits */
2724         if ((p = strchr(arg, ',')) != NULL) {
2725                 if (set_value(&audio_buffer_bits, atoi(++p), 1, AUDIO_BUFFER_BITS,
2726                                 "Buffer Fragments (bit)"))
2727                         return 1;
2728         }
2729         return 0;
2730 }
2731
2732 static inline int parse_opt_C(const char *arg)
2733 {
2734         if (set_val_i32(&control_ratio, atoi(arg), 0, MAX_CONTROL_RATIO,
2735                         "Control ratio"))
2736                 return 1;
2737         opt_control_ratio = control_ratio;
2738         return 0;
2739 }
2740
2741 static inline int parse_opt_c(char *arg)
2742 {
2743         if (read_config_file(arg, 0))
2744                 return 1;
2745         got_a_configuration = 1;
2746         return 0;
2747 }
2748
2749 static inline int parse_opt_D(const char *arg)
2750 {
2751         return set_channel_flag(&default_drumchannels, atoi(arg), "Drum channel");
2752 }
2753
2754 static inline int parse_opt_d(const char *arg)
2755 {
2756         /* dynamic lib root */
2757 #ifdef IA_DYNAMIC
2758         if (dynamic_lib_root)
2759                 free(dynamic_lib_root);
2760         dynamic_lib_root = safe_strdup(arg);
2761         return 0;
2762 #else
2763         ctl->cmsg(CMSG_WARNING, VERB_NOISY, "-d option is not supported");
2764         return 1;
2765 #endif  /* IA_DYNAMIC */
2766 }
2767
2768 static inline int parse_opt_E(char *arg)
2769 {
2770         /* undocumented option --ext */
2771         int err = 0;
2772         
2773         while (*arg) {
2774                 switch (*arg) {
2775                 case 'w':
2776                         opt_modulation_wheel = 1;
2777                         break;
2778                 case 'W':
2779                         opt_modulation_wheel = 0;
2780                         break;
2781                 case 'p':
2782                         opt_portamento = 1;
2783                         break;
2784                 case 'P':
2785                         opt_portamento = 0;
2786                         break;
2787                 case 'v':
2788                         opt_nrpn_vibrato = 1;
2789                         break;
2790                 case 'V':
2791                         opt_nrpn_vibrato = 0;
2792                         break;
2793                 case 's':
2794                         opt_channel_pressure = 1;
2795                         break;
2796                 case 'S':
2797                         opt_channel_pressure = 0;
2798                         break;
2799                 case 'e':
2800                         opt_modulation_envelope = 1;
2801                         break;
2802                 case 'E':
2803                         opt_modulation_envelope = 0;
2804                         break;
2805                 case 't':
2806                         opt_trace_text_meta_event = 1;
2807                         break;
2808                 case 'T':
2809                         opt_trace_text_meta_event = 0;
2810                         break;
2811                 case 'o':
2812                         opt_overlap_voice_allow = 1;
2813                         break;
2814                 case 'O':
2815                         opt_overlap_voice_allow = 0;
2816                         break;
2817                 case 'z':
2818                         opt_temper_control = 1;
2819                         break;
2820                 case 'Z':
2821                         opt_temper_control = 0;
2822                         break;
2823                 case 'm':
2824                         if (parse_opt_default_mid(arg + 1))
2825                                 err++;
2826                         arg += 2;
2827                         break;
2828                 case 'M':
2829                         if (parse_opt_system_mid(arg + 1))
2830                                 err++;
2831                         arg += 2;
2832                         break;
2833                 case 'b':
2834                         if (parse_opt_default_bank(arg + 1))
2835                                 err++;
2836                         while (isdigit(*(arg + 1)))
2837                                 arg++;
2838                         break;
2839                 case 'B':
2840                         if (parse_opt_force_bank(arg + 1))
2841                                 err++;
2842                         while (isdigit(*(arg + 1)))
2843                                 arg++;
2844                         break;
2845                 case 'i':
2846                         if (parse_opt_default_program(arg + 1))
2847                                 err++;
2848                         while (isdigit(*(arg + 1)) || *(arg + 1) == '/')
2849                                 arg++;
2850                         break;
2851                 case 'I':
2852                         if (parse_opt_force_program(arg + 1))
2853                                 err++;
2854                         while (isdigit(*(arg + 1)) || *(arg + 1) == '/')
2855                                 arg++;
2856                         break;
2857                 case 'F':
2858                         if (strncmp(arg + 1, "delay=", 6) == 0) {
2859                                 if (parse_opt_delay(arg + 7))
2860                                         err++;
2861                         } else if (strncmp(arg + 1, "chorus=", 7) == 0) {
2862                                 if (parse_opt_chorus(arg + 8))
2863                                         err++;
2864                         } else if (strncmp(arg + 1, "reverb=", 7) == 0) {
2865                                 if (parse_opt_reverb(arg + 8))
2866                                         err++;
2867                         } else if (strncmp(arg + 1, "ns=", 3) == 0) {
2868                                 if (parse_opt_noise_shaping(arg + 4))
2869                                         err++;
2870 #ifndef FIXED_RESAMPLATION
2871                         } else if (strncmp(arg + 1, "resamp=", 7) == 0) {
2872                                 if (parse_opt_resample(arg + 8))
2873                                         err++;
2874 #endif
2875                         }
2876                         if (err) {
2877                                 ctl->cmsg(CMSG_ERROR,
2878                                                 VERB_NORMAL, "-E%s: unsupported effect", arg);
2879                                 return err;
2880                         }
2881                         return err;
2882                 default:
2883                         ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
2884                                         "-E: Illegal mode `%c'", *arg);
2885                         err++;
2886                         break;
2887                 }
2888                 arg++;
2889         }
2890         return err;
2891 }
2892
2893 static inline int parse_opt_mod_wheel(const char *arg)
2894 {
2895         /* --[no-]mod-wheel */
2896         opt_modulation_wheel = y_or_n_p(arg);
2897         return 0;
2898 }
2899
2900 static inline int parse_opt_portamento(const char *arg)
2901 {
2902         /* --[no-]portamento */
2903         opt_portamento = y_or_n_p(arg);
2904         return 0;
2905 }
2906
2907 static inline int parse_opt_vibrato(const char *arg)
2908 {
2909         /* --[no-]vibrato */
2910         opt_nrpn_vibrato = y_or_n_p(arg);
2911         return 0;
2912 }
2913
2914 static inline int parse_opt_ch_pressure(const char *arg)
2915 {
2916         /* --[no-]ch-pressure */
2917         opt_channel_pressure = y_or_n_p(arg);
2918         return 0;
2919 }
2920
2921 static inline int parse_opt_mod_env(const char *arg)
2922 {
2923         /* --[no-]mod-envelope */
2924         opt_modulation_envelope = y_or_n_p(arg);
2925         return 0;
2926 }
2927
2928 static inline int parse_opt_trace_text(const char *arg)
2929 {
2930         /* --[no-]trace-text-meta */
2931         opt_trace_text_meta_event = y_or_n_p(arg);
2932         return 0;
2933 }
2934
2935 static inline int parse_opt_overlap_voice(const char *arg)
2936 {
2937         /* --[no-]overlap-voice */
2938         opt_overlap_voice_allow = y_or_n_p(arg);
2939         return 0;
2940 }
2941
2942 static inline int parse_opt_temper_control(const char *arg)
2943 {
2944         /* --[no-]temper-control */
2945         opt_temper_control = y_or_n_p(arg);
2946         return 0;
2947 }
2948
2949 static inline int parse_opt_default_mid(char *arg)
2950 {
2951         /* --default-mid */
2952         int val = str2mID(arg);
2953         
2954         if (! val) {
2955                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Manufacture ID: Illegal value");
2956                 return 1;
2957         }
2958         opt_default_mid = val;
2959         return 0;
2960 }
2961
2962 static inline int parse_opt_system_mid(char *arg)
2963 {
2964         /* --system-mid */
2965         int val = str2mID(arg);
2966         
2967         if (! val) {
2968                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Manufacture ID: Illegal value");
2969                 return 1;
2970         }
2971         opt_system_mid = val;
2972         return 0;
2973 }
2974
2975 static inline int parse_opt_default_bank(const char *arg)
2976 {
2977         /* --default-bank */
2978         if (set_value(&default_tonebank, atoi(arg), 0, 0x7f, "Bank number"))
2979                 return 1;
2980         special_tonebank = -1;
2981         return 0;
2982 }
2983
2984 static inline int parse_opt_force_bank(const char *arg)
2985 {
2986         /* --force-bank */
2987         if (set_value(&special_tonebank, atoi(arg), 0, 0x7f, "Bank number"))
2988                 return 1;
2989         return 0;
2990 }
2991
2992 static inline int parse_opt_default_program(const char *arg)
2993 {
2994         /* --default-program */
2995         int prog, i;
2996         const char *p;
2997         
2998         if (set_value(&prog, atoi(arg), 0, 0x7f, "Program number"))
2999                 return 1;
3000         if ((p = strchr(arg, '/')) != NULL) {
3001                 if (set_value(&i, atoi(++p), 1, MAX_CHANNELS, "Program channel"))
3002                         return 1;
3003                 default_program[i - 1] = prog;
3004         } else
3005                 for (i = 0; i < MAX_CHANNELS; i++)
3006                         default_program[i] = prog;
3007         return 0;
3008 }
3009
3010 static inline int parse_opt_force_program(const char *arg)
3011 {
3012         /* --force-program */
3013         const char *p;
3014         int i;
3015         
3016         if (set_value(&def_prog, atoi(arg), 0, 0x7f, "Program number"))
3017                 return 1;
3018         if (ctl->opened)
3019                 set_default_program(def_prog);
3020         if ((p = strchr(arg, '/')) != NULL) {
3021                 if (set_value(&i, atoi(++p), 1, MAX_CHANNELS, "Program channel"))
3022                         return 1;
3023                 default_program[i - 1] = SPECIAL_PROGRAM;
3024         } else
3025                 for (i = 0; i < MAX_CHANNELS; i++)
3026                         default_program[i] = SPECIAL_PROGRAM;
3027         return 0;
3028 }
3029
3030 static inline int set_default_program(int prog)
3031 {
3032         int bank;
3033         Instrument *ip;
3034         
3035         bank = (special_tonebank >= 0) ? special_tonebank : default_tonebank;
3036         if ((ip = play_midi_load_instrument(0, bank, prog)) == NULL)
3037                 return 1;
3038         default_instrument = ip;
3039         return 0;
3040 }
3041
3042 static inline int parse_opt_delay(const char *arg)
3043 {
3044         /* --delay */
3045         const char *p;
3046         
3047         switch (*arg) {
3048         case '0':
3049         case 'd':       /* disable */
3050                 effect_lr_mode = -1;
3051                 return 0;
3052         case 'l':       /* left */
3053                 effect_lr_mode = 0;
3054                 break;
3055         case 'r':       /* right */
3056                 effect_lr_mode = 1;
3057                 break;
3058         case 'b':       /* both */
3059                 effect_lr_mode = 2;
3060                 break;
3061         }
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.");
3067                         return 1;
3068                 }
3069         return 0;
3070 }
3071
3072 static inline int parse_opt_chorus(const char *arg)
3073 {
3074         /* --chorus */
3075         const char *p;
3076         
3077         switch (*arg) {
3078         case '0':
3079         case 'd':       /* disable */
3080                 opt_chorus_control = 0;
3081                 opt_surround_chorus = 0;
3082                 break;
3083         case '1':
3084         case 'n':       /* normal */
3085         case '2':
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,
3090                                         "Chorus level"))
3091                                 return 1;
3092                         opt_chorus_control = -opt_chorus_control;
3093                 } else
3094                         opt_chorus_control = 1;
3095                 break;
3096         default:
3097                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Invalid chorus parameter.");
3098                 return 1;
3099         }
3100         return 0;
3101 }
3102
3103 static inline int parse_opt_reverb(const char *arg)
3104 {
3105         /* --reverb */
3106         const char *p;
3107         
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
3118          * 
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.
3122          * 
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.
3130          */
3131         
3132         switch (*arg) {
3133         case '0':
3134         case 'd':       /* disable */
3135                 opt_reverb_control = 0;
3136                 break;
3137         case '1':
3138         case 'n':       /* normal */
3139                 if ((p = strchr(arg, ',')) != NULL) {
3140                         if (set_value(&opt_reverb_control, atoi(++p), 1, 0x7f,
3141                                         "Reverb level"))
3142                                 return 1;
3143                         opt_reverb_control = -opt_reverb_control;
3144                 } else
3145                         opt_reverb_control = 1;
3146                 break;
3147         case '2':
3148         case 'g':       /* global */
3149                 if ((p = strchr(arg, ',')) != NULL) {
3150                         if (set_value(&opt_reverb_control, atoi(++p), 1, 0x7f,
3151                                         "Reverb level"))
3152                                 return 1;
3153                         opt_reverb_control = -opt_reverb_control - 128;
3154                 } else
3155                         opt_reverb_control = 2;
3156                 break;
3157         case '3':
3158         case 'f':       /* freeverb */
3159                 if ((p = strchr(arg, ',')) != NULL) {
3160                         if (set_value(&opt_reverb_control, atoi(++p), 1, 0x7f,
3161                                         "Reverb level"))
3162                                 return 1;
3163                         opt_reverb_control = -opt_reverb_control - 256;
3164                 } else
3165                         opt_reverb_control = 3;
3166                 break;
3167         case '4':
3168         case 'G':       /* global freeverb */
3169                 if ((p = strchr(arg, ',')) != NULL) {
3170                         if (set_value(&opt_reverb_control, atoi(++p), 1, 0x7f,
3171                                         "Reverb level"))
3172                                 return 1;
3173                         opt_reverb_control = -opt_reverb_control - 384;
3174                 } else
3175                         opt_reverb_control = 4;
3176                 break;
3177         default:
3178                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Invalid reverb parameter.");
3179                 return 1;
3180         }
3181         return 0;
3182 }
3183
3184 static inline int parse_opt_voice_lpf(const char *arg)
3185 {
3186         /* --voice-lpf */
3187         switch (*arg) {
3188         case '0':
3189         case 'd':       /* disable */
3190                 opt_lpf_def = 0;
3191                 break;
3192         case '1':
3193         case 'c':       /* chamberlin */
3194                 opt_lpf_def = 1;
3195                 break;
3196         case '2':
3197         case 'm':       /* moog */
3198                 opt_lpf_def = 2;
3199                 break;
3200         default:
3201                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Invalid voice LPF type %s", arg);
3202                 return 1;
3203         }
3204         return 0;
3205 }
3206
3207 /* Noise Shaping filter from
3208  * Kunihiko IMAI <imai@leo.ec.t.kanazawa-u.ac.jp>
3209  */
3210 static inline int parse_opt_noise_shaping(const char *arg)
3211 {
3212         /* --noise-shaping */
3213         if (set_value(&noise_sharp_type, atoi(arg), 0, 4, "Noise shaping type"))
3214                 return 1;
3215         return 0;
3216 }
3217
3218 static inline int parse_opt_resample(const char *arg)
3219 {
3220         /* --resample */
3221         switch (*arg) {
3222         case '0':
3223         case 'd':       /* disable */
3224                 set_current_resampler(RESAMPLE_NONE);
3225                 break;
3226         case '1':
3227         case 'l':       /* linear */
3228                 set_current_resampler(RESAMPLE_LINEAR);
3229                 break;
3230         case '2':
3231         case 'c':       /* cspline */
3232                 set_current_resampler(RESAMPLE_CSPLINE);
3233                 break;
3234         case '3':
3235         case 'L':       /* lagrange */
3236                 set_current_resampler(RESAMPLE_LAGRANGE);
3237                 break;
3238         case '4':
3239         case 'n':       /* newton */
3240                 set_current_resampler(RESAMPLE_NEWTON);
3241                 break;
3242         case '5':
3243         case 'g':       /* guass */
3244                 set_current_resampler(RESAMPLE_GAUSS);
3245                 break;
3246         default:
3247                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Invalid resample type %s", arg);
3248                 return 1;
3249         }
3250         return 0;
3251 }
3252
3253 static inline int parse_opt_e(const char *arg)
3254 {
3255         /* evil */
3256 #ifdef __W32__
3257         opt_evil_mode = 1;
3258         return 0;
3259 #else
3260         ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "-e option is not supported");
3261         return 1;
3262 #endif /* __W32__ */
3263 }
3264
3265 static inline int parse_opt_F(const char *arg)
3266 {
3267         adjust_panning_immediately = y_or_n_p(arg);
3268         return 0;
3269 }
3270
3271 static inline int parse_opt_f(const char *arg)
3272 {
3273         fast_decay = y_or_n_p(arg);
3274         return 0;
3275 }
3276
3277 static inline int parse_opt_g(const char *arg)
3278 {
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);
3284                 return 1;
3285         }
3286         view_soundspec_flag = 1;
3287         return 0;
3288 #else
3289         ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "-g option is not supported");
3290         return 1;
3291 #endif  /* SUPPORT_SOUNDSPEC */
3292 }
3293
3294 static inline int parse_opt_H(const char *arg)
3295 {
3296         /* force keysig (number of sharp/flat) */
3297         int keysig;
3298         
3299         if (set_value(&keysig, atoi(arg), -7, 7,
3300                         "Force keysig (number of sHarp(+)/flat(-))"))
3301                 return 1;
3302         opt_force_keysig = keysig;
3303         return 0;
3304 }
3305
3306 __attribute__((noreturn))
3307 static inline int parse_opt_h(const char *arg)
3308 {
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.",
3313 "",
3314 #ifdef __W32__
3315 "Win32 version by Davide Moretti <dave@rimini.com>",
3316 "              and Daisuke Aoki <dai@y7.net>",
3317 "",
3318 #endif /* __W32__ */
3319 "Usage:",
3320 "  %s [options] filename [...]",
3321 "",
3322 #ifndef __W32__         /*does not work in Windows */
3323 "  Use \"-\" as filename to read a MIDI file from stdin",
3324 "",
3325 #endif
3326 "Options:",
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",
3342 #ifdef IA_DYNAMIC
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",
3363 "                   default: -E "
3364 #ifdef MODULATION_WHEEL_ALLOW
3365 "w"
3366 #else
3367 "W"
3368 #endif /* MODULATION_WHEEL_ALLOW */
3369 #ifdef PORTAMENTO_ALLOW
3370 "p"
3371 #else
3372 "P"
3373 #endif /* PORTAMENTO_ALLOW */
3374 #ifdef NRPN_VIBRATO_ALLOW
3375 "v"
3376 #else
3377 "V"
3378 #endif /* NRPN_VIBRATO_ALLOW */
3379 #ifdef GM_CHANNEL_PRESSURE_ALLOW
3380 "s"
3381 #else
3382 "S"
3383 #endif /* GM_CHANNEL_PRESSURE_ALLOW */
3384 #ifdef MODULATION_ENVELOPE_ALLOW
3385 "e"
3386 #else
3387 "E"
3388 #endif /* MODULATION_ENVELOPE_ALLOW */
3389 #ifdef ALWAYS_TRACE_TEXT_META_EVENT
3390 "t"
3391 #else
3392 "T"
3393 #endif /* ALWAYS_TRACE_TEXT_META_EVENT */
3394 #ifdef OVERLAP_VOICE_ALLOW
3395 "o"
3396 #else
3397 "O"
3398 #endif /* OVERLAP_VOICE_ALLOW */
3399 #ifdef TEMPER_CONTROL_ALLOW
3400 "z"
3401 #else
3402 "Z"
3403 #endif /* TEMPER_CONTROL_ALLOW */
3404 ,
3405 #ifdef __W32__
3406 "  -e         --evil",
3407 "               Increase thread priority (evil) - be careful!",
3408 #endif
3409 "  -F         --[no-]fast-panning",
3410 "               Disable/Enable fast panning (toggle on/off, default is on)",
3411 "  -f         --[no-]fast-decay",
3412 "               "
3413 #ifdef FAST_DECAY
3414 "Disable "
3415 #else
3416 "Enable "
3417 #endif
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)",
3425 "  -h         --help",
3426 "               Display this help message",
3427 "  -i mode    --interface=mode",
3428 "               Select user interface (see below for list)",
3429 #ifdef IA_ALSASEQ
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)",
3434 #endif
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,",
3449 "                 0 disables",
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)",
3455 "                 newton:",
3456 "                   n'th order Newton polynomial interpolation, n=1-57 odd",
3457 "                 gauss:",
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",
3489 "                              (UNIX only)",
3490 "                      ascii : Convert unreadable characters to '.' (0x2e)",
3491 "                      nocnv : No conversion",
3492 "                      1251  : Convert from windows-1251 to koi8-r",
3493 #ifdef JAPANESE
3494 "                      euc   : EUC-japan",
3495 "                      jis   : JIS",
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)",
3503 "  -v         --version",
3504 "               Display TiMidity version information",
3505 "  -W mode    --wrd=mode",
3506 "               Select WRD interface (see below for list)",
3507 #ifdef __W32__
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",
3519 "  --module=n",
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",
3526                 NULL
3527         };
3528         static char *help_args[3];
3529         FILE *fp;
3530         int i, j;
3531         char *h;
3532         ControlMode *cmp, **cmpp;
3533         char mark[128];
3534         PlayMode *pmp, **pmpp;
3535         WRDTracer *wlp, **wlpp;
3536         
3537         fp = open_pager();
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++]);
3545                         else
3546                                 fprintf(fp, h);
3547                 } else
3548                         fputs(h, fp);
3549                 fputs(NLS, fp);
3550         }
3551         fputs(NLS, fp);
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
3563 "                 (default)" 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
3582         fputs(
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);
3590 #endif
3591         fputs(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);
3614 #endif
3615         fputs(NLS, fp);
3616         fputs("Available interfaces (-i, --interface option):" NLS, fp);
3617         for (cmpp = ctl_list; (cmp = *cmpp) != NULL; cmpp++)
3618 #ifdef IA_DYNAMIC
3619                 if (cmp->id_character != dynamic_interface_id)
3620                         fprintf(fp, "  -i%c          %s" NLS,
3621                                         cmp->id_character, cmp->id_name);
3622 #else
3623                 fprintf(fp, "  -i%c          %s" NLS,
3624                                 cmp->id_character, cmp->id_name);
3625 #endif  /* IA_DYNAMIC */
3626 #ifdef IA_DYNAMIC
3627         fprintf(fp, "Supported dynamic load interfaces (%s):" NLS,
3628                         dynamic_lib_root);
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 */
3636         fputs(NLS, fp);
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);
3644 #ifdef IA_ALSASEQ
3645         fputs("  `D'          daemonize TiMidity++ in background "
3646                         "(for alsaseq only)" NLS, fp);
3647 #endif
3648         fputs(NLS, fp);
3649         fputs("Alternative interface long options:" NLS
3650 "  --verbose=n" NLS
3651 "  --quiet=n" NLS
3652 "  --[no-]trace" NLS
3653 "  --[no-]loop" NLS
3654 "  --[no-]random" NLS
3655 "  --[no-]sort" NLS, fp);
3656 #ifdef IA_ALSASEQ
3657         fputs("  --[no-]background" NLS, fp);
3658 #endif
3659         fputs(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);
3664         fputs(NLS, fp);
3665         fputs("Output format options (append to -O? option):" NLS
3666 "  `S'          stereo" 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);
3677         fputs(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);
3690         fputs(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);
3694         fputs(NLS, fp);
3695         close_pager(fp);
3696         exit(EXIT_SUCCESS);
3697 }
3698
3699 #ifdef IA_DYNAMIC
3700 static inline void list_dyna_interface(FILE *fp, char *path, char *mark)
3701 {
3702         URL url;
3703         char fname[BUFSIZ], *info;
3704         int id;
3705         
3706         if ((url = url_dir_open(path)) == NULL)
3707                 return;
3708         while (url_gets(url, fname, sizeof(fname)) != NULL)
3709                 if (strncmp(fname, "interface_", 10) == 0) {
3710                         id = fname[10];
3711                         if (mark[id])
3712                                 continue;
3713                         mark[id] = 1;
3714                         if ((info = dynamic_interface_info(id)) == NULL)
3715                                 info = dynamic_interface_module(id);
3716                         if (info != NULL)
3717                                 fprintf(fp, "  -i%c          %s" NLS, id, info);
3718                 }
3719         url_close(url);
3720 }
3721
3722 static inline char *dynamic_interface_info(int id)
3723 {
3724         static char libinfo[MAXPATHLEN];
3725         int fd, n;
3726         char *nl;
3727         
3728         sprintf(libinfo, "%s" PATH_STRING "interface_%c.txt",
3729                         dynamic_lib_root, id);
3730         if ((fd = open(libinfo, 0)) < 0)
3731                 return NULL;
3732         n = read(fd, libinfo, sizeof(libinfo) - 1);
3733         close(fd);
3734         if (n <= 0)
3735                 return NULL;
3736         libinfo[n] = '\0';
3737         if ((nl = strchr(libinfo, '\n')) == libinfo)
3738                 return NULL;
3739         if (nl != NULL) {
3740                 *nl = '\0';
3741                 if (*(nl - 1) == '\r')
3742                         *(nl - 1) = '\0';
3743         }
3744         return libinfo;
3745 }
3746
3747 char *dynamic_interface_module(int id)
3748 {
3749         static char shared_library[MAXPATHLEN];
3750         int fd;
3751         
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)
3755                 return NULL;
3756         close(fd);
3757         return shared_library;
3758 }
3759 #endif  /* IA_DYNAMIC */
3760
3761 static inline int parse_opt_i(const char *arg)
3762 {
3763         /* interface mode */
3764         ControlMode *cmp, **cmpp;
3765         int found = 0;
3766         
3767         for (cmpp = ctl_list; (cmp = *cmpp) != NULL; cmpp++) {
3768                 if (cmp->id_character == *arg) {
3769                         found = 1;
3770                         ctl = cmp;
3771 #if defined(IA_W32GUI) || defined(IA_W32G_SYN)
3772                         cmp->verbosity = 1;
3773                         cmp->trace_playing = 0;
3774                         cmp->flags = 0;
3775 #endif  /* IA_W32GUI */
3776                         break;
3777                 }
3778 #ifdef IA_DYNAMIC
3779                 if (cmp->id_character == dynamic_interface_id
3780                                 && dynamic_interface_module(*arg)) {
3781                         /* Dynamic interface loader */
3782                         found = 1;
3783                         ctl = cmp;
3784                         if (dynamic_interface_id != *arg) {
3785                                 cmp->id_character = dynamic_interface_id = *arg;
3786                                 cmp->verbosity = 1;
3787                                 cmp->trace_playing = 0;
3788                                 cmp->flags = 0;
3789                         }
3790                         break;
3791                 }
3792 #endif  /* IA_DYNAMIC */
3793         }
3794         if (! found) {
3795                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
3796                                 "Interface `%c' is not compiled in.", *arg);
3797                 return 1;
3798         }
3799         while (*(++arg))
3800                 switch (*arg) {
3801                 case 'v':
3802                         cmp->verbosity++;
3803                         break;
3804                 case 'q':
3805                         cmp->verbosity--;
3806                         break;
3807                 case 't':       /* toggle */
3808                         cmp->trace_playing = (cmp->trace_playing) ? 0 : 1;
3809                         break;
3810                 case 'l':
3811                         cmp->flags ^= CTLF_LIST_LOOP;
3812                         break;
3813                 case 'r':
3814                         cmp->flags ^= CTLF_LIST_RANDOM;
3815                         break;
3816                 case 's':
3817                         cmp->flags ^= CTLF_LIST_SORT;
3818                         break;
3819                 case 'a':
3820                         cmp->flags ^= CTLF_AUTOSTART;
3821                         break;
3822                 case 'x':
3823                         cmp->flags ^= CTLF_AUTOEXIT;
3824                         break;
3825                 case 'd':
3826                         cmp->flags ^= CTLF_DRAG_START;
3827                         break;
3828                 case 'u':
3829                         cmp->flags ^= CTLF_AUTOUNIQ;
3830                         break;
3831                 case 'R':
3832                         cmp->flags ^= CTLF_AUTOREFINE;
3833                         break;
3834                 case 'C':
3835                         cmp->flags ^= CTLF_NOT_CONTINUE;
3836                         break;
3837 #ifdef IA_ALSASEQ
3838                 case 'D':
3839                         cmp->flags ^= CTLF_DAEMONIZE;
3840                         break;
3841 #endif
3842                 default:
3843                         ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
3844                                         "Unknown interface option `%c'", *arg);
3845                         return 1;
3846                 }
3847         return 0;
3848 }
3849
3850 static inline int parse_opt_verbose(const char *arg)
3851 {
3852         /* --verbose */
3853         ctl->verbosity += (arg) ? atoi(arg) : 1;
3854         return 0;
3855 }
3856
3857 static inline int parse_opt_quiet(const char *arg)
3858 {
3859         /* --quiet */
3860         ctl->verbosity -= (arg) ? atoi(arg) : 1;
3861         return 0;
3862 }
3863
3864 static inline int parse_opt_trace(const char *arg)
3865 {
3866         /* --[no-]trace */
3867         ctl->trace_playing = y_or_n_p(arg);
3868         return 0;
3869 }
3870
3871 static inline int parse_opt_loop(const char *arg)
3872 {
3873         /* --[no-]loop */
3874         return set_flag(&(ctl->flags), CTLF_LIST_LOOP, arg);
3875 }
3876
3877 static inline int parse_opt_random(const char *arg)
3878 {
3879         /* --[no-]random */
3880         return set_flag(&(ctl->flags), CTLF_LIST_RANDOM, arg);
3881 }
3882
3883 static inline int parse_opt_sort(const char *arg)
3884 {
3885         /* --[no-]sort */
3886         return set_flag(&(ctl->flags), CTLF_LIST_SORT, arg);
3887 }
3888
3889 #ifdef IA_ALSASEQ
3890 static inline int parse_opt_background(const char *arg)
3891 {
3892         /* --[no-]background */
3893         return set_flag(&(ctl->flags), CTLF_DAEMONIZE, arg);
3894 }
3895
3896 static inline int parse_opt_rt_prio(const char *arg)
3897 {
3898         /* --realtime-priority */
3899         if (set_value(&opt_realtime_priority, atoi(arg), 0, 100,
3900                         "Realtime priority"))
3901                 return 1;
3902         return 0;
3903 }
3904
3905 static inline int parse_opt_seq_ports(const char *arg)
3906 {
3907         /* --sequencer-ports */
3908         if (set_value(&opt_sequencer_ports, atoi(arg), 1, 16,
3909                         "Number of sequencer ports"))
3910                 return 1;
3911         return 0;
3912 }
3913 #endif
3914
3915 static inline int parse_opt_j(const char *arg)
3916 {
3917         opt_realtime_playing = y_or_n_p(arg);
3918         return 0;
3919 }
3920
3921 static inline int parse_opt_K(const char *arg)
3922 {
3923         /* key adjust */
3924         if (set_value(&key_adjust, atoi(arg), -24, 24, "Key adjust"))
3925                 return 1;
3926         return 0;
3927 }
3928
3929 static inline int parse_opt_k(const char *arg)
3930 {
3931         reduce_voice_threshold = atoi(arg);
3932         return 0;
3933 }
3934
3935 static inline int parse_opt_L(char *arg)
3936 {
3937         add_to_pathlist(arg);
3938         try_config_again = 1;
3939         return 0;
3940 }
3941
3942 static inline int parse_opt_M(const char *arg)
3943 {
3944         if (pcm_alternate_file)
3945                 free(pcm_alternate_file);
3946         pcm_alternate_file = safe_strdup(arg);
3947         return 0;
3948 }
3949
3950 static inline int parse_opt_m(const char *arg)
3951 {
3952         min_sustain_time = atoi(arg);
3953         if (min_sustain_time < 0)
3954                 min_sustain_time = 0;
3955         return 0;
3956 }
3957
3958 static inline int parse_opt_N(const char *arg)
3959 {
3960         int val;
3961         
3962         switch (get_current_resampler()) {
3963         case RESAMPLE_CSPLINE:
3964         case RESAMPLE_LAGRANGE:
3965                 no_4point_interpolation = y_or_n_p(arg);
3966                 break;
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");
3974                         return 1;
3975                 }
3976                 break;
3977         }
3978         return 0;
3979 }
3980
3981 static inline int parse_opt_O(const char *arg)
3982 {
3983         /* output mode */
3984         PlayMode *pmp, **pmpp;
3985         int found = 0;
3986         
3987         for (pmpp = play_mode_list; (pmp = *pmpp) != NULL; pmpp++)
3988                 if (pmp->id_character == *arg) {
3989                         found = 1;
3990                         play_mode = pmp;
3991                         break;
3992                 }
3993         if (! found) {
3994                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
3995                                 "Playmode `%c' is not compiled in.", *arg);
3996                 return 1;
3997         }
3998         while (*(++arg))
3999                 switch (*arg) {
4000                 case 'S':       /* stereo */
4001                         pmp->encoding &= ~PE_MONO;
4002                         break;
4003                 case 'M':
4004                         pmp->encoding |= PE_MONO;
4005                         break;
4006                 case 's':
4007                         pmp->encoding |= PE_SIGNED;
4008                         pmp->encoding &= ~(PE_ULAW | PE_ALAW);
4009                         break;
4010                 case 'u':
4011                         pmp->encoding &= ~PE_SIGNED;
4012                         pmp->encoding &= ~(PE_ULAW | PE_ALAW);
4013                         break;
4014                 case '1':       /* 1 for 16-bit */
4015                         pmp->encoding |= PE_16BIT;
4016                         pmp->encoding &= ~(PE_24BIT | PE_ULAW | PE_ALAW);
4017                         break;
4018                 case '2':       /* 2 for 24-bit */
4019                         pmp->encoding |= PE_24BIT;
4020                         pmp->encoding &= ~(PE_16BIT | PE_ULAW | PE_ALAW);
4021                         break;
4022                 case '8':
4023                         pmp->encoding &= ~(PE_16BIT | PE_24BIT);
4024                         break;
4025                 case 'l':       /* linear */
4026                         pmp->encoding &= ~(PE_ULAW | PE_ALAW);
4027                         break;
4028                 case 'U':       /* uLaw */
4029                         pmp->encoding |= PE_ULAW;
4030                         pmp->encoding &= ~(PE_SIGNED
4031                                         | PE_16BIT | PE_24BIT | PE_ALAW | PE_BYTESWAP);
4032                         break;
4033                 case 'A':       /* aLaw */
4034                         pmp->encoding |= PE_ALAW;
4035                         pmp->encoding &= ~(PE_SIGNED
4036                                         | PE_16BIT | PE_24BIT | PE_ULAW | PE_BYTESWAP);
4037                         break;
4038                 case 'x':
4039                         pmp->encoding ^= PE_BYTESWAP;   /* toggle */
4040                         pmp->encoding &= ~(PE_ULAW | PE_ALAW);
4041                         break;
4042                 default:
4043                         ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
4044                                         "Unknown format modifier `%c'", *arg);
4045                         return 1;
4046                 }
4047         return 0;
4048 }
4049
4050 static inline int parse_opt_output_stereo(const char *arg)
4051 {
4052         /* --output-stereo, --output-mono */
4053         if (y_or_n_p(arg))
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
4057                  * choice? -- mput
4058                  */
4059                 play_mode->encoding &= ~PE_MONO;
4060         else
4061                 play_mode->encoding |= PE_MONO;
4062         return 0;
4063 }
4064
4065 static inline int parse_opt_output_signed(const char *arg)
4066 {
4067         /* --output-singed, --output-unsigned */
4068         if (set_flag(&(play_mode->encoding), PE_SIGNED, arg))
4069                 return 1;
4070         play_mode->encoding &= ~(PE_ULAW | PE_ALAW);
4071         return 0;
4072 }
4073
4074 static inline int parse_opt_output_bitwidth(const char *arg)
4075 {
4076         /* --output-16bit, --output-24bit, --output-8bit */
4077         switch (*arg) {
4078         case '1':       /* 16bit */
4079                 play_mode->encoding |= PE_16BIT;
4080                 play_mode->encoding &= ~(PE_24BIT | PE_ULAW | PE_ALAW);
4081                 return 0;
4082         case '2':       /* 24bit */
4083                 play_mode->encoding |= PE_24BIT;
4084                 play_mode->encoding &= ~(PE_16BIT | PE_ULAW | PE_ALAW);
4085                 return 0;
4086         case '8':       /* 8bit */
4087                 play_mode->encoding &= ~(PE_16BIT | PE_24BIT);
4088                 return 0;
4089         default:
4090                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Invalid output bitwidth %s", arg);
4091                 return 1;
4092         }
4093 }
4094
4095 static inline int parse_opt_output_format(const char *arg)
4096 {
4097         /* --output-linear, --output-ulaw, --output-alaw */
4098         switch (*arg) {
4099         case 'l':       /* linear */
4100                 play_mode->encoding &= ~(PE_ULAW | PE_ALAW);
4101                 return 0;
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);
4106                 return 0;
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);
4111                 return 0;
4112         default:
4113                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Invalid output format %s", arg);
4114                 return 1;
4115         }
4116 }
4117
4118 static inline int parse_opt_output_swab(const char *arg)
4119 {
4120         /* --[no-]output-swab */
4121         if (set_flag(&(play_mode->encoding), PE_BYTESWAP, arg))
4122                 return 1;
4123         play_mode->encoding &= ~(PE_ULAW | PE_ALAW);
4124         return 0;
4125 }
4126
4127 static inline int parse_opt_o(char *arg)
4128 {
4129         if (opt_output_name)
4130                 free(opt_output_name);
4131         opt_output_name = safe_strdup(url_expand_home_dir(arg));
4132         return 0;
4133 }
4134
4135 static inline int parse_opt_P(const char *arg)
4136 {
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';
4140         return 0;
4141 }
4142
4143 static inline int parse_opt_p(const char *arg)
4144 {
4145         if (set_value(&voices, atoi(arg), 1,
4146                         MAX_SAFE_MALLOC_SIZE / sizeof(Voice), "Polyphony"))
4147                 return 1;
4148         max_voices = voices;
4149         return 0;
4150 }
4151
4152 static inline int parse_opt_p1(const char *arg)
4153 {
4154         /* --[no-]polyphony-reduction */
4155         auto_reduce_polyphony = y_or_n_p(arg);
4156         return 0;
4157 }
4158
4159 static inline int parse_opt_Q(const char *arg)
4160 {
4161         const char *p = arg;
4162         
4163         if (strchr(arg, 't'))
4164                 /* backward compatibility */
4165                 return parse_opt_Q1(arg);
4166         if (set_channel_flag(&quietchannels, atoi(arg), "Quiet channel"))
4167                 return 1;
4168         while ((p = strchr(p, ',')) != NULL)
4169                 if (set_channel_flag(&quietchannels, atoi(++p), "Quiet channel"))
4170                         return 1;
4171         return 0;
4172 }
4173
4174 static inline int parse_opt_Q1(const char *arg)
4175 {
4176         /* --temper-mute */
4177         int prog;
4178         const char *p = arg;
4179         
4180         if (set_value(&prog, atoi(arg), 0, 7, "Temperament program number"))
4181                 return 1;
4182         temper_type_mute |= 1 << prog;
4183         while ((p = strchr(p, ',')) != NULL) {
4184                 if (set_value(&prog, atoi(++p), 0, 7, "Temperament program number"))
4185                         return 1;
4186                 temper_type_mute |= 1 << prog;
4187         }
4188         return 0;
4189 }
4190
4191 static inline int parse_opt_q(const char *arg)
4192 {
4193         char *max_buff = safe_strdup(arg);
4194         char *fill_buff = strchr(max_buff, '/');
4195         
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;
4200         }
4201         if (fill_buff) {
4202                 *fill_buff = '\0';
4203                 if (opt_aq_fill_buff)
4204                         free(opt_aq_fill_buff);
4205                 opt_aq_fill_buff = ++fill_buff;
4206         }
4207         return 0;
4208 }
4209
4210 static inline int parse_opt_R(const char *arg)
4211 {
4212         /* I think pseudo reverb can now be retired... Computers are
4213          * enough fast to do a full reverb, don't they?
4214          */
4215         if (atoi(arg) == -1)    /* reset */
4216                 modify_release = 0;
4217         else {
4218                 if (set_val_i32(&modify_release, atoi(arg), 0, MAX_MREL,
4219                                 "Modify Release"))
4220                         return 1;
4221                 if (modify_release == 0)
4222                         modify_release = DEFAULT_MREL;
4223         }
4224         return 0;
4225 }
4226
4227 static inline int parse_opt_S(const char *arg)
4228 {
4229         int suffix = arg[strlen(arg) - 1];
4230         int32 figure;
4231         
4232         switch (suffix) {
4233         case 'M':
4234         case 'm':
4235                 figure = 1 << 20;
4236                 break;
4237         case 'K':
4238         case 'k':
4239                 figure = 1 << 10;
4240                 break;
4241         default:
4242                 figure = 1;
4243                 break;
4244         }
4245         allocate_cache_size = atof(arg) * figure;
4246         return 0;
4247 }
4248
4249 static inline int parse_opt_s(const char *arg)
4250 {
4251         /* sampling rate */
4252         int32 freq;
4253
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");
4258 }
4259
4260 static inline int parse_opt_T(const char *arg)
4261 {
4262         /* tempo adjust */
4263         int adjust;
4264         
4265         if (set_value(&adjust, atoi(arg), 10, 400, "Tempo adjust"))
4266                 return 1;
4267         tempo_adjust = 100.0 / adjust;
4268         return 0;
4269 }
4270
4271 static inline int parse_opt_t(const char *arg)
4272 {
4273         if (output_text_code)
4274                 free(output_text_code);
4275         output_text_code = safe_strdup(arg);
4276         return 0;
4277 }
4278
4279 static inline int parse_opt_U(const char *arg)
4280 {
4281         free_instruments_afterwards = y_or_n_p(arg);
4282         return 0;
4283 }
4284
4285 static inline int parse_opt_volume_curve(char *arg)
4286 {
4287         if (atof(arg) < 0) {
4288                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
4289                                 "Volume curve power must be >= 0", *arg);
4290                 return 1;
4291         }
4292         if (atof(arg) != 0) {
4293                 init_user_vol_table(atof(arg));
4294                 opt_user_volume_curve = 1;
4295         }
4296         return 0;
4297 }
4298
4299 __attribute__((noreturn))
4300 static inline int parse_opt_v(const char *arg)
4301 {
4302         const char *version_list[] = {
4303                 "TiMidity++ version ", timidity_version, NLS,
4304                 NLS,
4305                 "Copyright (C) 1999-2003 Masanao Izumo <mo@goice.co.jp>", NLS,
4306                 "Copyright (C) 1995 Tuukka Toivonen <tt@cgs.fi>", NLS,
4307                 NLS,
4308 #ifdef __W32__
4309                 "Win32 version by Davide Moretti <dmoretti@iper.net>", NLS,
4310                 "              and Daisuke Aoki <dai@y7.net>", NLS,
4311                 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,
4317         };
4318         FILE *fp = open_pager();
4319         int i;
4320         
4321         for (i = 0; i < sizeof(version_list) / sizeof(char *); i++)
4322                 fputs(version_list[i], fp);
4323         close_pager(fp);
4324         exit(EXIT_SUCCESS);
4325 }
4326
4327 static inline int parse_opt_W(char *arg)
4328 {
4329         WRDTracer *wlp, **wlpp;
4330         
4331         if (*arg == 'R') {      /* for WRD reader options */
4332                 put_string_table(&wrd_read_opts, arg + 1, strlen(arg + 1));
4333                 return 0;
4334         }
4335         for (wlpp = wrdt_list; (wlp = *wlpp) != NULL; wlpp++)
4336                 if (wlp->id == *arg) {
4337                         wrdt = wlp;
4338                         if (wrdt_open_opts)
4339                                 free(wrdt_open_opts);
4340                         wrdt_open_opts = safe_strdup(arg + 1);
4341                         return 0;
4342                 }
4343         ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
4344                         "WRD Tracer `%c' is not compiled in.", *arg);
4345         return 1;
4346 }
4347
4348 #ifdef __W32__
4349 static inline int parse_opt_w(const char *arg)
4350 {
4351         switch (*arg) {
4352 #ifdef SMFCONV
4353         case 'r':
4354                 opt_rcpcv_dll = 1;
4355                 return 0:
4356         case 'R':
4357                 opt_rcpcv_dll = 0;
4358                 return 0;
4359 #else
4360         case 'r':
4361         case 'R':
4362                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
4363                                 "-w%c option is not supported", *arg);
4364                 return 1;
4365 #endif  /* SMFCONV */
4366         default:
4367                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "-w: Illegal mode `%c'", *arg);
4368                 return 1;
4369         }
4370 }
4371 #endif  /* __W32__ */
4372
4373 static inline int parse_opt_x(char *arg)
4374 {
4375         StringTableNode *st;
4376         
4377         if ((st = put_string_table(&opt_config_string,
4378                         arg, strlen(arg))) != NULL)
4379                 expand_escape_string(st->string);
4380         return 0;
4381 }
4382
4383 static inline void expand_escape_string(char *s)
4384 {
4385         char *t = s;
4386         
4387         if (s == NULL)
4388                 return;
4389         for (t = s; *s; s++)
4390                 if (*s == '\\') {
4391                         switch (*++s) {
4392                         case 'a':
4393                                 *t++ = '\a';
4394                                 break;
4395                         case 'b':
4396                                 *t++ = '\b';
4397                                 break;
4398                         case 't':
4399                                 *t++ = '\t';
4400                                 break;
4401                         case 'n':
4402                                 *t++ = '\n';
4403                                 break;
4404                         case 'f':
4405                                 *t++ = '\f';
4406                                 break;
4407                         case 'v':
4408                                 *t++ = '\v';
4409                                 break;
4410                         case 'r':
4411                                 *t++ = '\r';
4412                                 break;
4413                         case '\\':
4414                                 *t++ = '\\';
4415                                 break;
4416                         default:
4417                                 if (! (*t++ = *s))
4418                                         return;
4419                                 break;
4420                         }
4421                 } else
4422                         *t++ = *s;
4423         *t = *s;
4424 }
4425
4426 static inline int parse_opt_Z(char *arg)
4427 {
4428         /* load frequency table */
4429         return load_table(arg);
4430 }
4431
4432 static inline int parse_opt_Z1(const char *arg)
4433 {
4434         /* --pure-intonation */
4435         int keysig;
4436         
4437         opt_pure_intonation = 1;
4438         if (*arg) {
4439                 if (set_value(&keysig, atoi(arg), -7, 7,
4440                                 "Initial keysig (number of #(+)/b(-)[m(minor)])"))
4441                         return 1;
4442                 opt_init_keysig = keysig;
4443                 if (strchr(arg, 'm'))
4444                         opt_init_keysig += 16;
4445         }
4446         return 0;
4447 }
4448
4449 static inline int parse_opt_default_module(const char *arg)
4450 {
4451         opt_default_module = atoi(arg);
4452         if (opt_default_module < 0)
4453                 opt_default_module = 0;
4454         return 0;
4455 }
4456
4457 __attribute__((noreturn))
4458 static inline int parse_opt_fail(const char *arg)
4459 {
4460         /* getopt_long failed to recognize any options */
4461         ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
4462                         "Could not understand option : try --help");
4463         exit(EXIT_FAILURE);
4464 }
4465
4466 static inline int set_value(int *param, int i, int low, int high, char *name)
4467 {
4468         int32 val;
4469         
4470         if (set_val_i32(&val, i, low, high, name))
4471                 return 1;
4472         *param = val;
4473         return 0;
4474 }
4475
4476 static inline int set_val_i32(int32 *param,
4477                 int32 i, int32 low, int32 high, char *name)
4478 {
4479         if (i < low || i > high) {
4480                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
4481                                 "%s must be between %ld and %ld", name, low, high);
4482                 return 1;
4483         }
4484         *param = i;
4485         return 0;
4486 }
4487
4488 static inline int set_channel_flag(ChannelBitMask *flags, int32 i, char *name)
4489 {
4490         if (i == 0) {
4491                 FILL_CHANNELMASK(*flags);
4492                 return 0;
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);
4497                 return 1;
4498         }
4499         if (i > 0)
4500                 SET_CHANNELMASK(*flags, i - 1);
4501         else
4502                 UNSET_CHANNELMASK(*flags, -i - 1);
4503         return 0;
4504 }
4505
4506 static inline int y_or_n_p(const char *arg)
4507 {
4508         if (arg) {
4509                 switch (arg[0]) {
4510                 case 'y':
4511                 case 'Y':
4512                 case 't':
4513                 case 'T':
4514                         return 1;
4515                 case 'n':
4516                 case 'N':
4517                 case 'f':
4518                 case 'F':
4519                 default:
4520                         return 0;
4521                 }
4522         } else
4523                 return 1;
4524 }
4525
4526 static inline int set_flag(int32 *fields, int32 bitmask, const char *arg)
4527 {
4528         if (y_or_n_p(arg))
4529                 *fields |= bitmask;
4530         else
4531                 *fields &= ~bitmask;
4532         return 0;
4533 }
4534
4535 static inline FILE *open_pager(void)
4536 {
4537 #if ! defined(__MACOS__) && defined(HAVE_POPEN) && defined(HAVE_ISATTY) \
4538                 && ! defined(IA_W32GUI) && ! defined(IA_W32G_SYN)
4539         char *pager;
4540         
4541         if (isatty(1) && (pager = getenv("PAGER")) != NULL)
4542                 return popen(pager, "w");
4543 #endif
4544         return stdout;
4545 }
4546
4547 static inline void close_pager(FILE *fp)
4548 {
4549 #if ! defined(__MACOS__) && defined(HAVE_POPEN) && defined(HAVE_ISATTY) \
4550                 && ! defined(IA_W32GUI) && ! defined(IA_W32G_SYN)
4551         if (fp != stdout)
4552                 pclose(fp);
4553 #endif
4554 }
4555
4556 static void interesting_message(void)
4557 {
4558         printf(
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
4562                         NLS
4563 #ifdef __W32__
4564 "Win32 version by Davide Moretti <dmoretti@iper.net>" NLS
4565 "              and Daisuke Aoki <dai@y7.net>" NLS
4566                         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
4572                         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
4577                         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);
4582 }
4583
4584 /* -------- functions for getopt_long ends here --------- */
4585
4586 #ifdef HAVE_SIGNAL
4587 static RETSIGTYPE sigterm_exit(int sig)
4588 {
4589     char s[4];
4590
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.
4593      */
4594
4595     write(2, "Terminated sig=0x", 17);
4596     s[0] = "0123456789abcdef"[(sig >> 4) & 0xf];
4597     s[1] = "0123456789abcdef"[sig & 0xf];
4598     s[2] = '\n';
4599     write(2, s, 3);
4600
4601     safe_exit(1);
4602 }
4603 #endif /* HAVE_SIGNAL */
4604
4605 static void timidity_arc_error_handler(char *error_message)
4606 {
4607     extern int open_file_noise_mode;
4608     if(open_file_noise_mode)
4609         ctl->cmsg(CMSG_WARNING, VERB_NORMAL, "%s", error_message);
4610 }
4611
4612 MAIN_INTERFACE void timidity_start_initialize(void)
4613 {
4614     int i;
4615     static int drums[] = DEFAULT_DRUMCHANNELS;
4616     static int is_first = 1;
4617 #if defined(__FreeBSD__) && !defined(__alpha__)
4618     fp_except_t fpexp;
4619 #elif defined(__NetBSD__) || defined(__OpenBSD__)
4620     fp_except fpexp;
4621 #endif
4622
4623 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
4624     fpexp = fpgetmask();
4625     fpsetmask(fpexp & ~(FP_X_INV|FP_X_DZ));
4626 #endif
4627
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%");
4634
4635     /* Check the byte order */
4636     i = 1;
4637 #ifdef LITTLE_ENDIAN
4638     if(*(char *)&i != 1)
4639 #else
4640     if(*(char *)&i == 1)
4641 #endif
4642     {
4643         fprintf(stderr, "Byte order is miss configured.\n");
4644         exit(1);
4645     }
4646
4647     for(i = 0; i < MAX_CHANNELS; i++)
4648     {
4649         memset(&(channel[i]), 0, sizeof(Channel));
4650     }
4651
4652     CLEAR_CHANNELMASK(quietchannels);
4653     CLEAR_CHANNELMASK(default_drumchannels);
4654
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);
4661 #endif
4662
4663     if(program_name == NULL)
4664         program_name = "TiMidity";
4665     uudecode_unquote_html = 1;
4666     for(i = 0; i < MAX_CHANNELS; i++)
4667     {
4668         default_program[i] = DEFAULT_PROGRAM;
4669         memset(channel[i].drums, 0, sizeof(channel[i].drums));
4670     }
4671     arc_error_handler = timidity_arc_error_handler;
4672
4673     if(play_mode == NULL)
4674     {
4675         char *output_id;
4676         int i;
4677
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)
4684         {
4685             for(i = 0; play_mode_list[i]; i++)
4686                 if(play_mode_list[i]->id_character == *output_id)
4687                 {
4688                     if (! play_mode_list[i]->detect ||
4689                         play_mode_list[i]->detect()) {
4690                         play_mode = play_mode_list[i];
4691                         break;
4692                     }
4693                 }
4694         }
4695     }
4696
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];
4704                     break;
4705                 }
4706             }
4707         }
4708     }
4709     
4710     if (play_mode == NULL) {
4711         fprintf(stderr, "Couldn't open output device" NLS);
4712         exit(1);
4713     }
4714
4715     if(is_first) /* initialize once time */
4716     {
4717         got_a_configuration = 0;
4718
4719 #ifdef SUPPORT_SOCKET
4720         init_mail_addr();
4721         if(url_user_agent == NULL)
4722         {
4723             url_user_agent =
4724                 (char *)safe_malloc(10 + strlen(timidity_version));
4725             strcpy(url_user_agent, "TiMidity-");
4726             strcat(url_user_agent, timidity_version);
4727         }
4728 #endif /* SUPPORT_SOCKET */
4729
4730         for(i = 0; url_module_list[i]; i++)
4731             url_add_module(url_module_list[i]);
4732         init_string_table(&opt_config_string);
4733         init_freq_table();
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();
4739         init_bend_fine();
4740         init_bend_coarse();
4741         init_tables();
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;
4755         init_midi_trace();
4756         int_rand(-1);   /* initialize random seed */
4757         int_rand(42);   /* the 1st number generated is not very random */
4758         ML_RegisterAllLoaders ();
4759     }
4760
4761     is_first = 0;
4762 }
4763
4764 MAIN_INTERFACE int timidity_pre_load_configuration(void)
4765 {
4766 #if defined(__W32__)
4767     /* Windows */
4768     char *strp;
4769     int check;
4770     char local[1024];
4771
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");
4777     }
4778     strncpy(local, ConfigFile, sizeof(local) - 1);
4779 #else
4780     /* !IA_W32GUI */
4781     GetWindowsDirectory(local, 1023 - 13);
4782     strcat(local, "\\TIMIDITY.CFG");
4783 #endif
4784
4785     /* First, try read system configuration file.
4786      * Default is C:\WINDOWS\TIMIDITY.CFG
4787      */
4788     if((check = open(local, 0)) >= 0)
4789     {
4790         close(check);
4791         if(!read_config_file(local, 0)) {
4792             got_a_configuration = 1;
4793                 return 0;
4794         }
4795     }
4796
4797     /* Next, try read configuration file which is in the
4798      * TiMidity directory.
4799      */
4800     if(GetModuleFileName(NULL, local, 1023))
4801     {
4802         local[1023] = '\0';
4803         if(strp = strrchr(local, '\\'))
4804         {
4805             *(++strp)='\0';
4806             strcat(local,"TIMIDITY.CFG");
4807             if((check = open(local, 0)) >= 0)
4808             {
4809                 close(check);
4810                 if(!read_config_file(local, 0)) {
4811                     got_a_configuration = 1;
4812                         return 0;
4813                 }
4814             }
4815         }
4816     }
4817
4818 #else
4819     /* UNIX */
4820     if(!read_config_file(CONFIG_FILE, 0)) {
4821                 got_a_configuration = 1;
4822                 return 0;
4823         }
4824 #endif
4825
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)
4830      */
4831
4832     if(read_user_config_file())
4833         ctl->cmsg(CMSG_INFO, VERB_NOISY,
4834                   "Warning: Can't read ~/.timidity.cfg correctly");
4835     return 0;
4836 }
4837
4838 MAIN_INTERFACE int timidity_post_load_configuration(void)
4839 {
4840     int cmderr;
4841
4842     cmderr = 0;
4843     if(!got_a_configuration)
4844     {
4845         if(try_config_again && !read_config_file(CONFIG_FILE, 0))
4846             got_a_configuration = 1;
4847     }
4848
4849     if(opt_config_string.nstring > 0)
4850     {
4851         char **config_string_list;
4852         int i;
4853
4854         config_string_list = make_string_array(&opt_config_string);
4855         if(config_string_list != NULL)
4856         {
4857             for(i = 0; config_string_list[i]; i++)
4858             {
4859                 if(!read_config_file(config_string_list[i], 1))
4860                     got_a_configuration = 1;
4861                 else
4862                     cmderr++;
4863             }
4864             free(config_string_list[0]);
4865             free(config_string_list);
4866         }
4867     }
4868
4869     if(!got_a_configuration)
4870         cmderr++;
4871     return cmderr;
4872 }
4873
4874 MAIN_INTERFACE void timidity_init_player(void)
4875 {
4876     /* Allocate voice[] */
4877     voice = (Voice *) safe_realloc(voice, max_voices * sizeof(Voice));
4878         memset(voice, 0, max_voices * sizeof(Voice));
4879
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;
4885
4886     /* save defaults */
4887     COPY_CHANNELMASK(drumchannels, default_drumchannels);
4888     COPY_CHANNELMASK(drumchannel_mask, default_drumchannel_mask);
4889
4890     if(opt_buffer_fragments != -1)
4891     {
4892         if(play_mode->flag & PF_BUFF_FRAGM_OPT)
4893             play_mode->extra_param[0] = opt_buffer_fragments;
4894         else
4895             ctl->cmsg(CMSG_WARNING, VERB_NORMAL,
4896                       "%s: -B option is ignored", play_mode->id_name);
4897     }
4898
4899 #ifdef SUPPORT_SOUNDSPEC
4900     if(view_soundspec_flag)
4901     {
4902         open_soundspec();
4903         soundspec_setinterval(spectrogram_update_sec);
4904     }
4905 #endif /* SOUNDSPEC */
4906 }
4907
4908 void timidity_init_aq_buff(void)
4909 {
4910     double time1, /* max buffer */
4911            time2, /* init filled */
4912            base;  /* buffer of device driver */
4913
4914     if(!IS_STREAM_TRACE)
4915         return; /* Ignore */
4916
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, '%'))
4921     {
4922         time1 = base * (time1 - 100) / 100.0;
4923         if(time1 < 0)
4924             time1 = 0;
4925     }
4926     if(strchr(opt_aq_fill_buff, '%'))
4927         time2 = base * time2 / 100.0;
4928     aq_set_soft_queue(time1, time2);
4929 }
4930
4931 MAIN_INTERFACE int timidity_play_main(int nfiles, char **files)
4932 {
4933     int need_stdin = 0, need_stdout = 0;
4934     int i;
4935     int output_fail = 0;
4936
4937     if(nfiles == 0 && !strchr(INTERACTIVE_INTERFACE_IDS, ctl->id_character))
4938         return 0;
4939
4940     if(opt_output_name)
4941     {
4942         play_mode->name = opt_output_name;
4943         if(!strcmp(opt_output_name, "-"))
4944             need_stdout = 1;
4945     }
4946
4947     for(i = 0; i < nfiles; i++)
4948         if (!strcmp(files[i], "-"))
4949             need_stdin = 1;
4950
4951     if(ctl->open(need_stdin, need_stdout))
4952     {
4953         fprintf(stderr, "Couldn't open %s (`%c')" NLS,
4954                 ctl->id_name, ctl->id_character);
4955         play_mode->close_output();
4956         return 3;
4957     }
4958
4959     if(wrdt->open(wrdt_open_opts))
4960     {
4961         fprintf(stderr, "Couldn't open WRD Tracer: %s (`%c')" NLS,
4962                 wrdt->name, wrdt->id);
4963         play_mode->close_output();
4964         ctl->close();
4965         return 1;
4966     }
4967
4968 #ifdef BORLANDC_EXCEPTION
4969     __try
4970     {
4971 #endif /* BORLANDC_EXCEPTION */
4972 #ifdef __W32__
4973
4974 #ifdef HAVE_SIGNAL
4975         signal(SIGTERM, sigterm_exit);
4976 #endif
4977         SetConsoleCtrlHandler(handler, TRUE);
4978
4979         ctl->cmsg(CMSG_INFO, VERB_DEBUG_SILLY,
4980                   "Initialize for Critical Section");
4981         InitializeCriticalSection(&critSect);
4982         if(opt_evil_mode)
4983             if(!SetThreadPriority(GetCurrentThread(),
4984                                   THREAD_PRIORITY_ABOVE_NORMAL))
4985                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
4986                           "Error raising process priority");
4987
4988 #else
4989         /* UNIX */
4990 #ifdef HAVE_SIGNAL
4991         signal(SIGINT, sigterm_exit);
4992         signal(SIGTERM, sigterm_exit);
4993 #ifdef SIGPIPE
4994         signal(SIGPIPE, sigterm_exit);    /* Handle broken pipe */
4995 #endif /* SIGPIPE */
4996 #endif /* HAVE_SIGNAL */
4997
4998 #endif
4999
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);
5005
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]);
5011         }
5012 #if !defined ( IA_W32GUI ) && !defined ( IA_W32G_SYN )
5013         if(play_mode->open_output() < 0)
5014         {
5015             ctl->cmsg(CMSG_FATAL, VERB_NORMAL,
5016                       "Couldn't open %s (`%c')",
5017                       play_mode->id_name, play_mode->id_character);
5018             output_fail = 1;
5019             ctl->close();
5020             return 2;
5021         }
5022 #endif /* IA_W32GUI */
5023         if(!control_ratio)
5024         {
5025             control_ratio = play_mode->rate / CONTROLS_PER_SECOND;
5026             if(control_ratio < 1)
5027                 control_ratio = 1;
5028             else if (control_ratio > MAX_CONTROL_RATIO)
5029                 control_ratio = MAX_CONTROL_RATIO;
5030         }
5031
5032         init_load_soundfont();
5033         if(!output_fail)
5034         {
5035             aq_setup();
5036             timidity_init_aq_buff();
5037         }
5038         if(allocate_cache_size > 0)
5039             resamp_cache_reset();
5040
5041         if (def_prog >= 0)
5042                 set_default_program(def_prog);
5043         if (*def_instr_name)
5044                 set_default_instrument(def_instr_name);
5045
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);
5050
5051         /* Return only when quitting */
5052         ctl->cmsg(CMSG_INFO, VERB_DEBUG_SILLY,
5053                   "pass_playing_list() nfiles=%d", nfiles);
5054
5055         ctl->pass_playing_list(nfiles, files);
5056
5057         if(intr)
5058             aq_flush(1);
5059
5060 #ifdef XP_UNIX
5061         return 0;
5062 #endif /* XP_UNIX */
5063
5064         play_mode->close_output();
5065         ctl->close();
5066         wrdt->close();
5067 #ifdef __W32__
5068         DeleteCriticalSection (&critSect);
5069 #endif
5070
5071 #ifdef BORLANDC_EXCEPTION
5072     } __except(1) {
5073         fprintf(stderr, "\nError!!!\nUnexpected Exception Occured!\n");
5074         if(play_mode->fd != -1)
5075         {
5076                 play_mode->purge_output();
5077                 play_mode->close_output();
5078         }
5079         ctl->close();
5080         wrdt->close();
5081         DeleteCriticalSection (&critSect);
5082         exit(EXIT_FAILURE);
5083     }
5084 #endif /* BORLANDC_EXCEPTION */
5085
5086 #ifdef SUPPORT_SOUNDSPEC
5087     if(view_soundspec_flag)
5088         close_soundspec();
5089 #endif /* SUPPORT_SOUNDSPEC */
5090
5091     free_archive_files();
5092 #ifdef SUPPORT_SOCKET
5093     url_news_connection_cache(URL_NEWS_CLOSE_CACHE);
5094 #endif /* SUPPORT_SOCKET */
5095
5096     return 0;
5097 }
5098
5099 #ifdef IA_W32GUI
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 */
5106
5107 #if defined ( IA_W32GUI ) || defined ( IA_W32G_SYN )
5108 static int CoInitializeOK = 0;
5109 #endif
5110
5111 #ifndef __MACOS__
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)
5116 #else
5117 /* _MSC_VER, _BORLANDC_ */
5118 int win_main(int argc, char **argv)
5119 #endif
5120 #else /* UNIX */
5121 int main(int argc, char **argv)
5122 #endif
5123 {
5124     int c, err, i;
5125     int nfiles;
5126     char **files;
5127     int main_ret;
5128     int longind;
5129
5130 #if defined(DANGEROUS_RENICE) && !defined(__W32__) && !defined(main)
5131     /*
5132      * THIS CODES MUST EXECUT BEGINNING OF MAIN FOR SECURITY.
5133      * DONT PUT ANY CODES ABOVE.
5134      */
5135 #include <sys/resource.h>
5136     int uid;
5137 #ifdef sun
5138     extern int setpriority(int which, id_t who, int prio);
5139     extern int setreuid(int ruid, int euid);
5140 #endif
5141
5142     uid = getuid();
5143     if(setpriority(PRIO_PROCESS, 0, DANGEROUS_RENICE) < 0)
5144     {
5145         perror("setpriority");
5146         fprintf(stderr, "Couldn't set priority to %d.", DANGEROUS_RENICE);
5147     }
5148     setreuid(uid, uid);
5149 #endif
5150
5151 #if defined(REDIRECT_STDOUT)
5152     memcpy(stdout, fopen(REDIRECT_STDOUT, "a+"), sizeof(FILE));
5153     printf("TiMidity++ start\n");fflush(stdout);
5154 #endif
5155
5156 #ifdef main
5157     {
5158         static int maincnt = 0;
5159         if(maincnt++ > 0)
5160         {
5161             argv++;
5162             argc--;
5163             while(argv[0][0] == '-') {
5164                 argv++;
5165                 argc--;
5166             }
5167             ctl->pass_playing_list(argc, argv);
5168             return 0;
5169         }
5170     }
5171 #endif
5172
5173 #ifdef IA_DYNAMIC
5174     {
5175 #ifdef XP_UNIX
5176         argv[0] = "netscape";
5177 #endif /* XP_UNIX */
5178         dynamic_interface_id = 0;
5179         dl_init(argc, argv);
5180     }
5181 #endif /* IA_DYNAMIC */
5182
5183     if((program_name=pathsep_strrchr(argv[0]))) program_name++;
5184     else program_name=argv[0];
5185
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");
5193
5194     if(argc == 1 && !strchr(INTERACTIVE_INTERFACE_IDS, ctl->id_character))
5195     {
5196         interesting_message();
5197         return 0;
5198     }
5199
5200     timidity_start_initialize();
5201 #if defined ( IA_W32GUI ) || defined ( IA_W32G_SYN )
5202     if(CoInitialize(NULL)==S_OK)
5203       CoInitializeOK = 1;
5204     w32g_initialize();
5205
5206 #ifdef IA_W32GUI
5207         /* Secondary TiMidity Execute */
5208         /*      FirstLoadIniFile(); */
5209         if(w32gSecondTiMidity(SecondMode,argc,argv)==FALSE){
5210                 return 0;
5211         }
5212 #endif
5213         
5214     for(c = 1; c < argc; c++)
5215     {
5216         if(is_directory(argv[c]))
5217         {
5218             char *p;
5219             p = (char *)safe_malloc(strlen(argv[c]) + 2);
5220             strcpy(p, argv[c]);
5221             directory_form(p);
5222             argv[c] = p;
5223         }
5224     }
5225 #endif
5226
5227     if((err = timidity_pre_load_configuration()) != 0)
5228         return err;
5229
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)
5233             break;
5234
5235     initialize_resampler_coeffs();
5236
5237     err += timidity_post_load_configuration();
5238
5239     /* If there were problems, give up now */
5240     if(err || (optind >= argc &&
5241                !strchr(INTERACTIVE_INTERFACE_IDS, ctl->id_character)))
5242     {
5243         if(!got_a_configuration)
5244         {
5245 #ifdef __W32__
5246             char config1[1024];
5247             char config2[1024];
5248
5249             memset(config1, 0, sizeof(config1));
5250             memset(config2, 0, sizeof(config2));
5251 #if defined ( IA_W32GUI ) || defined ( IA_W32G_SYN )
5252             {
5253                 extern char *ConfigFile;
5254                 strncpy(config1, ConfigFile, sizeof(config1) - 1);
5255             }
5256 #else
5257             /* !IA_W32GUI */
5258             GetWindowsDirectory(config1, 1023 - 13);
5259             strcat(config1, "\\TIMIDITY.CFG");
5260 #endif
5261
5262             if(GetModuleFileName(NULL, config2, 1023))
5263             {
5264                 char *strp;
5265                 config2[1023] = '\0';
5266                 if(strp = strrchr(config2, '\\'))
5267                 {
5268                     *(++strp)='\0';
5269                     strcat(config2,"TIMIDITY.CFG");
5270                 }
5271             }
5272
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);
5276 #else
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__ */
5281         }
5282         else
5283         {
5284             ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
5285                       "Try %s -h for help", program_name);
5286         }
5287
5288 #if !defined ( IA_W32GUI ) && !defined ( IA_W32G_SYN ) /* Try to continue if it is Windows version */
5289         return 1; /* problems with command line */
5290 #endif
5291     }
5292
5293     timidity_init_player();
5294
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)
5300         sleep(1);
5301
5302 #ifndef IA_W32GUI
5303     main_ret = timidity_play_main(nfiles, files);
5304 #ifdef IA_W32G_SYN
5305     if(CoInitializeOK)
5306       CoUninitialize();
5307 #endif /* IA_W32G_SYN */
5308 #else
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();
5314         }
5315     w32gSecondTiMidityExit();
5316     if(CoInitializeOK)
5317       CoUninitialize();
5318 #endif /* IA_W32GUI */
5319     free_instruments(0);
5320     free_global_mblock();
5321     free_all_midi_file_info();
5322         free_userdrum();
5323         free_userinst();
5324     tmdy_free_config();
5325         free_effect_buffers();
5326         for (i = 0; i < MAX_CHANNELS; i++) {free_drum_effect(i);}
5327     return main_ret;
5328 }
5329 #endif /* __MACOS__ */