1 #include "config.h"
2 #include <windows.h>
3 #include <sys/stat.h>
4 #include <io.h>
5
6 #ifndef __bool_true_false_are_defined
7 # ifdef bool
8 # undef bool
9 # endif
10 # ifdef ture
11 # undef ture
12 # endif
13 # ifdef false
14 # undef false
15 # endif
16 # define bool int
17 # define false ((bool)0)
18 # define true (!false)
19 # define __bool_true_false_are_defined true
20 #endif
21 /* C99 _Bool hack */
22
23 #include "arc.h"
24 #include "tmdy_getopt.h"
25 #include "rtsyn.h"
26
27 /* MAIN_INTERFACE */
28 extern void timidity_start_initialize(void);
29 extern int timidity_pre_load_configuration(void);
30 extern int timidity_post_load_configuration(void);
31 extern void timidity_init_player(void);
32 extern void timidity_init_aq_buff(void);
33 extern int set_tim_opt_long(int, char *, int);
34
35 extern void tmdy_free_config(void);
36
37 extern const char *optcommands;
38 extern const struct option longopts[];
39
40 #define INTERACTIVE_INTERFACE_IDS "kmqagrwAWP"
41
42 extern int got_a_configuration;
43
44 extern int def_prog;
45 extern char def_instr_name[256];
46
47 extern CRITICAL_SECTION critSect;
48 extern int opt_evil_mode;
49
50
51
52
53
54 #include "timiwp_timidity.h"
55
56
handler(DWORD dw)57 static BOOL WINAPI handler(DWORD dw)
58 {
59 // printf ("***BREAK" NLS); fflush(stdout);
60 intr++;
61 return TRUE;
62 }
63
sigterm_exit(int sig)64 static RETSIGTYPE sigterm_exit(int sig)
65 {
66 char s[4];
67
68 /* NOTE: Here, fprintf is dangerous because it is not re-enterance
69 * function. It is possible coredump if the signal is called in printf's.
70 */
71 /*
72 write(2, "Terminated sig=0x", 17);
73 s[0] = "0123456789abcdef"[(sig >> 4) & 0xf];
74 s[1] = "0123456789abcdef"[sig & 0xf];
75 s[2] = '\n';
76 write(2, s, 3);
77 */
78 safe_exit(1);
79 }
80
directory_p(const char * path)81 static inline bool directory_p(const char* path)
82 {
83 struct stat st;
84 if(stat(path, &st) != -1) return S_ISDIR(st.st_mode);
85 return false;
86 }
87
canonicalize_path(char * path)88 static inline void canonicalize_path(char* path)
89 {
90 int len = strlen(path);
91 if(!len || path[len-1]==PATH_SEP) return;
92 path[len] = PATH_SEP;
93 path[len+1] = '\0';
94 }
95
96
97
98
99
timiwp_main_ini(int argc,char ** argv)100 int timiwp_main_ini(int argc, char **argv)
101 {
102 int c, err;
103 int nfiles;
104 char **files;
105 int main_ret;
106 int longind;
107
108
109 program_name=argv[0];
110 timidity_start_initialize();
111
112 for(c = 1; c < argc; c++)
113 {
114 if(directory_p(argv[c]))
115 {
116 char *p;
117 p = (char *)safe_malloc(strlen(argv[c]) + 2);
118 strcpy(p, argv[c]);
119 canonicalize_path(p);
120 free(argv[c]);
121 argv[c] = p;
122 }
123 }
124
125 #if !defined(IA_WINSYN) && !defined(IA_PORTMIDISYN) && !defined(IA_W32G_SYN)
126 if((err = timidity_pre_load_configuration()) != 0)
127 return err;
128 #else
129 opt_sf_close_each_file = 0;
130 #endif
131
132 optind = longind = 0;
133 #if defined(__MINGW32__) || defined(__CYGWIN__)
134 optreset=1;
135 #endif
136 while ((c = getopt_long(argc, argv, optcommands, longopts, &longind)) > 0)
137 if ((err = set_tim_opt_long(c, optarg, longind)) != 0)
138 break;
139
140 #if defined(IA_WINSYN) || defined(IA_PORTMIDISYN) || defined(IA_W32G_SYN)
141 if(got_a_configuration != 1){
142 if((err = timidity_pre_load_configuration()) != 0)
143 return err;
144 }
145 #endif
146
147 err += timidity_post_load_configuration();
148
149 /* If there were problems, give up now */
150 if(err || (optind >= argc &&
151 !strchr(INTERACTIVE_INTERFACE_IDS, ctl->id_character)))
152 {
153 if(!got_a_configuration)
154 {
155 char config1[1024];
156 char config2[1024];
157
158 memset(config1, 0, sizeof(config1));
159 memset(config2, 0, sizeof(config2));
160 GetWindowsDirectory(config1, 1023 - 13);
161 strcat(config1, "\\TIMIDITY.CFG");
162 if(GetModuleFileName(NULL, config2, 1023))
163 {
164 char *strp;
165 config2[1023] = '\0';
166 if(strp = strrchr(config2, '\\'))
167 {
168 *(++strp)='\0';
169 strncat(config2,"TIMIDITY.CFG",sizeof(config2)-strlen(config2)-1);
170 }
171 }
172
173 ctl->cmsg(CMSG_FATAL, VERB_NORMAL,
174 "%s: Can't read any configuration file.\nPlease check "
175 "%s or %s", program_name, config1, config2);
176
177 }
178 else
179 {
180 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
181 "Try %s -h for help", program_name);
182 }
183
184 }
185
186
187 timidity_init_player();
188
189 nfiles = argc - optind;
190 files = argv + optind;
191 if(nfiles > 0 && ctl->id_character != 'r' && ctl->id_character != 'A' && ctl->id_character != 'W' && ctl->id_character != 'P')
192 files = expand_file_archives(files, &nfiles);
193 if(dumb_error_count)
194 Sleep(1);
195
196 main_ret = timiwp_play_main_ini(nfiles, files);
197
198 return main_ret;
199
200 }
201
timiwp_main_close(void)202 int timiwp_main_close(void)
203 {
204 int i;
205 #if 0
206 timiwp_play_main_close();
207
208 free_instruments(0);
209 free_global_mblock();
210 free_all_midi_file_info();
211 free_userdrum();
212 free_userinst();
213 tmdy_free_config();
214 free_effect_buffers();
215 for (i = 0; i < MAX_CHANNELS; i++) {free_drum_effect(i);}
216 #endif
217 #ifdef SUPPORT_SOCKET
218 if (url_user_agent)
219 free(url_user_agent);
220 if (url_http_proxy_host)
221 free(url_http_proxy_host);
222 if (url_ftp_proxy_host)
223 free(url_ftp_proxy_host);
224 if (user_mailaddr)
225 free(user_mailaddr);
226 #endif
227 #if 0
228 if (pcm_alternate_file)
229 free(pcm_alternate_file);
230 if (opt_output_name)
231 free(opt_output_name);
232 if (opt_aq_max_buff)
233 free(opt_aq_max_buff);
234 if (opt_aq_fill_buff && opt_aq_fill_buff_free_needed)
235 free(opt_aq_fill_buff);
236 if (output_text_code)
237 free(output_text_code);
238 if (wrdt_open_opts)
239 free(wrdt_open_opts);
240 if (nfiles > 0
241 && ctl->id_character != 'r' && ctl->id_character != 'A'
242 && ctl->id_character != 'W' && ctl->id_character != 'N' && ctl->id_character != 'P') {
243 free(files_nbuf);
244 free(files);
245 }
246 #endif
247 //#if 0
248 free_soft_queue();
249 free_instruments(0);
250 free_soundfonts();
251 free_cache_data();
252 free_wrd();
253 free_readmidi();
254
255 free_global_mblock();
256 tmdy_free_config();
257 free_reverb_buffer();
258
259 free_effect_buffers();
260 free(voice);
261 free_gauss_table();
262 for (i = 0; i < MAX_CHANNELS; i++)
263 free_drum_effect(i);
264 return 0;
265 }
266
267
set_default_program(int prog)268 static inline int set_default_program(int prog)
269 {
270 int bank;
271 Instrument *ip;
272
273 bank = (special_tonebank >= 0) ? special_tonebank : default_tonebank;
274 if ((ip = play_midi_load_instrument(0, bank, prog)) == NULL)
275 return 1;
276 default_instrument = ip;
277 return 0;
278 }
279
timiwp_play_main_ini(int nfiles,char ** files)280 int timiwp_play_main_ini(int nfiles, char **files)
281 {
282 int output_fail = 0;
283
284
285 if(ctl->open(0, 0))
286 {
287 /* fprintf(stderr, "Couldn't open %s (`%c')" NLS,
288 ctl->id_name, ctl->id_character);
289 */
290 play_mode->close_output();
291 return 3;
292 }
293
294
295 signal(SIGTERM, sigterm_exit);
296 SetConsoleCtrlHandler(handler, TRUE);
297
298 ctl->cmsg(CMSG_INFO, VERB_DEBUG_SILLY,
299 "Initialize for Critical Section");
300 InitializeCriticalSection(&critSect);
301 if(opt_evil_mode)
302 if(!SetThreadPriority(GetCurrentThread(),
303 THREAD_PRIORITY_ABOVE_NORMAL))
304 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
305 "Error raising process priority");
306
307
308 /* Open output device */
309 ctl->cmsg(CMSG_INFO, VERB_DEBUG_SILLY,
310 "Open output: %c, %s",
311 play_mode->id_character,
312 play_mode->id_name);
313
314 if (play_mode->flag & PF_PCM_STREAM) {
315 play_mode->extra_param[1] = aq_calc_fragsize();
316 ctl->cmsg(CMSG_INFO, VERB_DEBUG_SILLY,
317 "requesting fragment size: %d",
318 play_mode->extra_param[1]);
319 }
320 if(play_mode->open_output() < 0)
321 {
322 ctl->cmsg(CMSG_FATAL, VERB_NORMAL,
323 "Couldn't open %s (`%c')",
324 play_mode->id_name, play_mode->id_character);
325 output_fail = 1;
326 ctl->close();
327 return 2;
328 }
329
330 if(!control_ratio)
331 {
332 control_ratio = play_mode->rate / CONTROLS_PER_SECOND;
333 if(control_ratio < 1)
334 control_ratio = 1;
335 else if (control_ratio > MAX_CONTROL_RATIO)
336 control_ratio = MAX_CONTROL_RATIO;
337 }
338
339 init_load_soundfont();
340 if(!output_fail)
341 {
342 aq_setup();
343 timidity_init_aq_buff();
344 }
345 if(allocate_cache_size > 0)
346 resamp_cache_reset();
347
348 if (def_prog >= 0)
349 set_default_program(def_prog);
350 if (*def_instr_name)
351 set_default_instrument(def_instr_name);
352
353 return 0;
354 }
355
356
timiwp_play_main_close(void)357 int timiwp_play_main_close (void)
358 {
359
360 if(intr)
361 aq_flush(1);
362 play_mode->close_output();
363 ctl->close();
364 DeleteCriticalSection (&critSect);
365 free_archive_files();
366
367 return 0;
368 }
369
370
371
372