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