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     rtsyn_common.c
21         Copyright (c) 2003-2005  Keishi Suenaga <s_keishi@mutt.freemail.ne.jp>
22 
23     I referenced following sources.
24         alsaseq_c.c - ALSA sequencer server interface
25             Copyright (c) 2000  Takashi Iwai <tiwai@suse.de>
26         readmidi.c
27 */
28 
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif /* HAVE_CONFIG_H */
32 #include "interface.h"
33 
34 #ifdef __POCC__
35 #include <sys/types.h>
36 #endif //for off_t
37 
38 #include <stdio.h>
39 
40 #include <stdarg.h>
41 #ifdef HAVE_UNISTD_H
42 #include <unistd.h>
43 #endif
44 #include <sys/types.h>
45 #ifdef TIME_WITH_SYS_TIME
46 #include <sys/time.h>
47 #endif
48 #ifndef NO_STRING_H
49 #include <string.h>
50 #else
51 #include <strings.h>
52 #endif
53 #include <math.h>
54 #include <signal.h>
55 
56 #include "server_defs.h"
57 
58 #ifdef __W32__
59 #include <windows.h>
60 #endif
61 
62 #include "timidity.h"
63 #include "common.h"
64 #include "controls.h"
65 #include "instrum.h"
66 #include "playmidi.h"
67 #include "readmidi.h"
68 #include "recache.h"
69 #include "output.h"
70 #include "aq.h"
71 #include "timer.h"
72 
73 #include "rtsyn.h"
74 
75 extern int32 current_sample;
76 extern void reset_midi(int playing);
77 
78 //int seq_quit;
79 
80 int rtsyn_system_mode = DEFAULT_SYSTEM_MODE;
81 double rtsyn_latency = RTSYN_LATENCY;   //ratency (sec)
82 int32 rtsyn_start_sample;
83 int rtsyn_sample_time_mode = 0;
84 
85 static int rtsyn_played = 0;
86 static double rtsyn_start_time;
87 static double last_event_time;
88 static double last_calc_time;
89 static int set_time_first=2;
90 extern int volatile stream_max_compute;	// play_event() �� compute_data() �Ōv�Z�������ő厞��
91 
92 //acitive sensing
93 static int active_sensing_flag=0;
94 static double active_sensing_time=0;
95 
96 //timer interrupt
97 
98 /*
99 #define EX_RESET_NO 7
100 static char sysex_resets[EX_RESET_NO][11]={
101 		'\xf0','\x7e','\x7f','\x09','\x00','\xf7','\x00','\x00','\x00','\x00','\x00',
102 		'\xf0','\x7e','\x7f','\x09','\x01','\xf7','\x00','\x00','\x00','\x00','\x00',
103 		'\xf0','\x7e','\x7f','\x09','\x03','\xf7','\x00','\x00','\x00','\x00','\x00',
104 		'\xf0','\x41','\x10','\x42','\x12','\x40','\x00','\x7f','\x00','\x41','\xf7',
105 		'\xf0','\x41','\x10','\x42','\x12','\x00','\x00','\x7f','\x00','\x01','\xf7',
106 		'\xf0','\x41','\x10','\x42','\x12','\x00','\x00','\x7f','\x01','\x00','\xf7',
107 		'\xf0','\x43','\x10','\x4c','\x00','\x00','\x7E','\x00','\xf7','\x00','\x00' };
108 */
109 /*
110 #define EX_RESET_NO 9
111 static char sysex_resets[EX_RESET_NO][11]={
112 	'\xf0','\x7e','\x7f','\x09','\x00','\xf7','\x00','\x00','\x00','\x00','\x00', //gm off
113 	'\xf0','\x7e','\x7f','\x09','\x01','\xf7','\x00','\x00','\x00','\x00','\x00', //gm1
114 	'\xf0','\x7e','\x7f','\x09','\x02','\xf7','\x00','\x00','\x00','\x00','\x00', //gm off
115 	'\xf0','\x7e','\x7f','\x09','\x03','\xf7','\x00','\x00','\x00','\x00','\x00', //gm2
116 	'\xf0','\x41','\x10','\x42','\x12','\x40','\x00','\x7f','\x00','\x41','\xf7', //GS
117 	'\xf0','\x41','\x10','\x42','\x12','\x40','\x00','\x7f','\x7f','\x41','\xf7', //GS off
118 	'\xf0','\x41','\x10','\x42','\x12','\x00','\x00','\x7f','\x00','\x01','\xf7', //88
119 	'\xf0','\x41','\x10','\x42','\x12','\x00','\x00','\x7f','\x01','\x00','\xf7', //88
120 	'\xf0','\x43','\x10','\x4c','\x00','\x00','\x7E','\x00','\xf7','\x00','\x00'  //XG on
121 	};
122 */
123 
124 void rtsyn_seq_set_time(MidiEvent *ev, double event_time);
125 
126 
rtsyn_gm_reset()127 void rtsyn_gm_reset(){
128 	MidiEvent ev;
129 
130 	rtsyn_server_reset();
131 	ev.type=ME_RESET;
132 	ev.a=GM_SYSTEM_MODE;
133 	rtsyn_play_event(&ev);
134 
135 }
136 
137 
rtsyn_gs_reset()138 void rtsyn_gs_reset(){
139 	MidiEvent ev;
140 
141 	rtsyn_server_reset();
142 	ev.type=ME_RESET;
143 	ev.a=GS_SYSTEM_MODE;
144 	rtsyn_play_event(&ev);
145 }
146 
147 
rtsyn_xg_reset()148 void rtsyn_xg_reset(){
149 	MidiEvent ev;
150 
151 	rtsyn_server_reset();
152 	ev.type=ME_RESET;
153 	ev.a=XG_SYSTEM_MODE;
154 	ev.time=0;
155 	rtsyn_play_event(&ev);
156 }
157 
158 
rtsyn_normal_reset()159 void rtsyn_normal_reset(){
160 	MidiEvent ev;
161 
162 	rtsyn_server_reset();
163 	ev.type=ME_RESET;
164 	ev.a=rtsyn_system_mode;
165 	rtsyn_play_event(&ev);
166 }
rtsyn_gm_modeset()167 void rtsyn_gm_modeset(){
168 	MidiEvent ev;
169 
170 	rtsyn_server_reset();
171 	rtsyn_system_mode=GM_SYSTEM_MODE;
172 	ev.type=ME_RESET;
173 	ev.a=GM_SYSTEM_MODE;
174 	rtsyn_play_event(&ev);
175 	change_system_mode(rtsyn_system_mode);
176 	reset_midi(1);
177 }
178 
179 
rtsyn_gs_modeset()180 void rtsyn_gs_modeset(){
181 	MidiEvent ev;
182 
183 	rtsyn_server_reset();
184 	rtsyn_system_mode=GS_SYSTEM_MODE;
185 	ev.type=ME_RESET;
186 	ev.a=GS_SYSTEM_MODE;
187 	rtsyn_play_event(&ev);
188 	change_system_mode(rtsyn_system_mode);
189 	reset_midi(1);
190 }
191 
192 
rtsyn_xg_modeset()193 void rtsyn_xg_modeset(){
194 	MidiEvent ev;
195 
196 	rtsyn_server_reset();
197 	rtsyn_system_mode=XG_SYSTEM_MODE;
198 	ev.type=ME_RESET;
199 	ev.a=XG_SYSTEM_MODE;
200 	rtsyn_play_event(&ev);
201 	change_system_mode(rtsyn_system_mode);
202 	reset_midi(1);
203 }
204 
205 
rtsyn_normal_modeset()206 void rtsyn_normal_modeset(){
207 	MidiEvent ev;
208 
209 	rtsyn_server_reset();
210 	rtsyn_system_mode=DEFAULT_SYSTEM_MODE;
211 	ev.type=ME_RESET;
212 	ev.a=GS_SYSTEM_MODE;
213 	rtsyn_play_event(&ev);
214 	change_system_mode(rtsyn_system_mode);
215 	reset_midi(1);
216 }
217 
rtsyn_set_latency(double latency)218 double rtsyn_set_latency(double latency){
219 	if(latency < 1.0 / TICKTIME_HZ * 3.0) latency = 1.0 / TICKTIME_HZ * 4.0;
220 	rtsyn_latency = latency;
221 	return latency;
222 }
223 
rtsyn_init(void)224 void rtsyn_init(void){
225 	int i,j;
226 	MidiEvent ev;
227 		/* set constants */
228 	opt_realtime_playing = 1; /* Enable loading patch while playing */
229 	allocate_cache_size = 0; /* Don't use pre-calclated samples */
230 	auto_reduce_polyphony = 0;
231 	opt_sf_close_each_file = 0;
232 
233 	if(ctl->id_character != 'N')
234 	  aq_set_soft_queue(rtsyn_latency*(double)1.01, 0.0);
235 	i = current_keysig + ((current_keysig < 8) ? 7 : -9), j = 0;
236 	while (i != 7)
237 		i += (i < 7) ? 5 : -7, j++;
238 	j += note_key_offset, j -= floor(j / 12.0) * 12;
239 	current_freq_table = j;
240 
241 	rtsyn_reset();
242 	play_mode->open_output();
243 	rtsyn_system_mode=DEFAULT_SYSTEM_MODE;
244 	change_system_mode(rtsyn_system_mode);
245 	reset_midi(0);
246 }
247 
rtsyn_close(void)248 void rtsyn_close(void){
249 	rtsyn_stop_playing();
250 	free_instruments(0);
251 	playmidi_stream_free();
252 	free_global_mblock();
253 }
254 
rtsyn_play_event_sample(MidiEvent * ev,int32 event_sample_time)255 rtsyn_play_event_sample(MidiEvent *ev, int32 event_sample_time){
256 	ev->time=event_sample_time;
257 	play_event(ev);
258 	if(rtsyn_sample_time_mode != 1)
259 	  aq_fill_nonblocking();
260 }
261 
rtsyn_play_event_time(MidiEvent * ev,double event_time)262 void rtsyn_play_event_time(MidiEvent *ev, double event_time){
263 	int gch;
264 	double current_event_time, buf_time;
265 	int32 max_compute;
266 	MidiEvent nev;
267 
268 		max_compute = rtsyn_latency * 1000.0;
269 		max_compute = (stream_max_compute > max_compute) ? stream_max_compute : max_compute;
270 		if ( (event_time - last_event_time) > (double)max_compute/1000.0){
271 				kill_all_voices();
272 				current_sample = (double)(play_mode->rate) * get_current_calender_time()+0.5;
273 				rtsyn_start_time=get_current_calender_time();
274 				rtsyn_start_sample=current_sample;
275 				last_event_time=rtsyn_start_time;
276 		}else{
277 				nev.type = ME_NONE;
278 			if( (event_time - last_event_time) > 1.0/(double)TICKTIME_HZ ) {
279 				buf_time = last_event_time + 1.0/(double)TICKTIME_HZ;
280 				rtsyn_seq_set_time(&nev, buf_time);
281 				play_event(&nev);
282 				aq_fill_nonblocking();
283 
284 				while( event_time > buf_time + 1.0/(double)TICKTIME_HZ){
285 					buf_time = buf_time + 1.0/(double)TICKTIME_HZ;
286 					rtsyn_seq_set_time(&nev, buf_time);
287 					play_event(&nev);
288 					aq_fill_nonblocking();
289 				}
290 			}
291 				gch = GLOBAL_CHANNEL_EVENT_TYPE(ev->type);
292 				if(gch || !IS_SET_CHANNELMASK(quietchannels, ev->channel) ){
293 					rtsyn_seq_set_time(ev,event_time);
294 					play_event(ev);
295 					aq_fill_nonblocking();
296 					last_event_time = (event_time  > last_event_time) ? event_time : last_event_time ;
297 				}
298 			}
299 //		}
300 //		}
301 		rtsyn_played = 1;
302 
303 
304 }
rtsyn_play_event(MidiEvent * ev)305 void rtsyn_play_event(MidiEvent *ev){
306 	rtsyn_play_event_time(ev, get_current_calender_time());
307 }
308 
rtsyn_wot_reset(void)309 void rtsyn_wot_reset(void){
310 	int i;
311 	kill_all_voices();
312 	if (free_instruments_afterwards){
313 		free_instruments(0);
314 	}
315 	aq_flush(1);
316 //	play_mode->close_output();	// PM_REQ_PLAY_START wlll called in playmidi_stream_init()
317 //	play_mode->open_output();	// but w32_a.c does not have it.
318 	play_mode->acntl(PM_REQ_FLUSH, NULL);
319 
320 	readmidi_read_init();
321 	playmidi_stream_init();
322 	change_system_mode(rtsyn_system_mode);
323 	reset_midi(1);
324 	reduce_voice_threshold = 0; // * Disable auto reduction voice *
325 	auto_reduce_polyphony = 0;
326 }
327 
rtsyn_tmr_reset(void)328 void rtsyn_tmr_reset(void){
329     	if(ctl->id_character == 'N')
330         	current_sample = 0;
331 		rtsyn_start_time=get_current_calender_time();
332 		rtsyn_start_sample=current_sample;
333 		last_event_time=rtsyn_start_time + rtsyn_latency;
334 		last_calc_time  = rtsyn_start_time;
335 }
336 
rtsyn_reset(void)337 void rtsyn_reset(void){
338 	rtsyn_wot_reset();
339 	rtsyn_tmr_reset();
340 }
341 
rtsyn_server_reset(void)342 void rtsyn_server_reset(void){
343 	rtsyn_wot_reset();
344 	if(rtsyn_sample_time_mode !=1){
345 		rtsyn_tmr_reset();
346 	}
347 }
348 
rtsyn_stop_playing(void)349 void rtsyn_stop_playing(void)
350 {
351 	if(upper_voices) {
352 		MidiEvent ev;
353 		ev.type = ME_EOT;
354 		ev.time = 0;
355 		ev.a = 0;
356 		ev.b = 0;
357 		rtsyn_play_event_time(&ev, rtsyn_latency + get_current_calender_time());
358 		sleep( rtsyn_latency * 1000.0);
359 		aq_flush(0);
360 	}
361 }
362 
363 
rtsyn_seq_set_time(MidiEvent * ev,double event_time)364 void rtsyn_seq_set_time(MidiEvent *ev, double event_time)
365 {
366 	double currenttime, time_div;
367 
368 	time_div = event_time  - rtsyn_start_time;
369 	ev->time = rtsyn_start_sample
370 		+(int32) ((double)(play_mode->rate) * time_div+0.5);
371 }
372 
373 
rtsyn_play_calculate()374 void rtsyn_play_calculate(){
375 	MidiEvent ev;
376 	double currenet_event_time, current_time;
377 
378 	current_time = get_current_calender_time();
379 	currenet_event_time = current_time + rtsyn_latency;
380 
381 	if( (rtsyn_played == 0)  && (currenet_event_time > last_calc_time + 1.0/(double)TICKTIME_HZ) /* event buffer is empty */
382 		||  (current_time + 1.0/(double)TICKTIME_HZ*2.0 > last_event_time) /* near miss */
383 	){
384 		ev.type = ME_NONE;
385 		rtsyn_play_event_time(&ev, currenet_event_time);
386 		last_calc_time=currenet_event_time;
387 	}
388 	rtsyn_played = 0;
389 
390 
391 	if(active_sensing_flag==~0 && (get_current_calender_time() > active_sensing_time+0.5)){
392 //normaly acitive sensing expiering time is 330ms(>300ms) but this loop is heavy
393 		play_mode->close_output();
394 		play_mode->open_output();
395 		ctl->cmsg(  CMSG_ERROR, VERB_NORMAL,"Active Sensing Expired\n");
396 		rtsyn_server_reset();
397 		active_sensing_flag=0;
398 	}
399 }
400 
rtsyn_play_one_data(int port,int32 dwParam1,double event_time)401 int rtsyn_play_one_data (int port, int32 dwParam1, double event_time){
402 	MidiEvent ev;
403 
404 	if(rtsyn_sample_time_mode != 1){
405 		event_time += rtsyn_latency;
406 	}
407 	ev.type = ME_NONE;
408 	ev.channel = dwParam1 & 0x0000000f;
409 	ev.channel = ev.channel+port*16;
410 	ev.a = (dwParam1 >> 8) & 0xff;
411 	ev.b = (dwParam1 >> 16) & 0xff;
412 	switch ((int) (dwParam1 & 0x000000f0)) {
413 	case 0x80:
414 		ev.type = ME_NOTEOFF;
415 //		rtsyn_play_event(&ev);
416 		break;
417 	case 0x90:
418 		ev.type = (ev.b) ? ME_NOTEON : ME_NOTEOFF;
419 //		rtsyn_play_event(&ev);
420 		break;
421 	case 0xa0:
422 		ev.type = ME_KEYPRESSURE;
423 //		rtsyn_play_event(&ev);
424 		break;
425 	case 0xb0:
426 		if (! convert_midi_control_change(ev.channel, ev.a, ev.b, &ev))
427 		ev.type = ME_NONE;
428 		break;
429 	case 0xc0:
430 		ev.type = ME_PROGRAM;
431 //		rtsyn_play_event(&ev);
432 		break;
433 	case 0xd0:
434 		ev.type = ME_CHANNEL_PRESSURE;
435 //		rtsyn_play_event(&ev);
436 		break;
437 	case 0xe0:
438 		ev.type = ME_PITCHWHEEL;
439 //		rtsyn_play_event(&ev);
440 		break;
441 	case 0xf0:
442 #ifdef IA_PORTMIDISYN
443 		if ( (dwParam1 & 0x000000ff) == 0xf0) {
444 			//SysEx
445 			return 1;
446 		}
447 #endif
448 		if ((dwParam1 & 0x000000ff) == 0xf2) {
449 			ev.type = ME_PROGRAM;
450 //			rtsyn_play_event(&ev);
451 		}
452 #if 0
453 		if ((dwParam1 & 0x000000ff) == 0xf1)
454 			//MIDI Time Code Qtr. Frame (not need)
455 			printf("MIDI Time Code Qtr\n");
456 		if ((dwParam1 & 0x000000ff) == 0xf3)
457 			//Song Select(Song #) (not need)
458 #endif
459 		if ((dwParam1 & 0x000000ff) == 0xf6){
460 			//Tune request  but use to make TiMidity++  to calculate.
461 			if(rtsyn_sample_time_mode == 1){
462 				ev.type = ME_NONE;
463 				rtsyn_play_event_sample(&ev, event_time);
464 				aq_fill_nonblocking();
465 				//aq_soft_flush();
466 			}else{
467 				//printf("Tune request\n");
468 			}
469 		}
470 #if 0
471 		if ((dwParam1 & 0x000000ff) == 0xf8)
472 			//Timing Clock (not need)
473 			printf("Timing Clock\n");
474 		if ((dwParam1&0x000000ff)==0xfa)
475 			//Start
476 		if ((dwParam1 & 0x000000ff) == 0xfb)
477 			//Continue
478 		if ((dwParam1 & 0x000000ff) == 0xfc) {
479 			//Stop
480 			printf("Stop\n");
481 		}
482 #endif
483 		if ((dwParam1 & 0x000000ff) == 0xfe) {
484 			//Active Sensing
485 //			printf("Active Sensing\n");
486 			active_sensing_flag = ~0;
487 			active_sensing_time = get_current_calender_time();
488 		}
489 		if ((dwParam1 & 0x000000ff) == 0xff) {
490 			//System Reset  use for TiMidity++  timer  reset
491 			if(rtsyn_sample_time_mode == 1){
492 				rtsyn_tmr_reset();
493 			}else{
494 				//printf("System Reset\n");
495 			}
496 		}
497 		break;
498 	default:
499 //		printf("Unsup/ed event %d\n", aevp->type);
500 		break;
501 	}
502 	if (ev.type != ME_NONE) {
503 		if(rtsyn_sample_time_mode != 1){
504 				rtsyn_play_event_time(&ev, event_time);
505 		}else{
506 				rtsyn_play_event_sample(&ev, event_time);
507 		}
508 	}
509 	return 0;
510 }
511 
512 
rtsyn_play_one_sysex(char * sysexbuffer,int exlen,double event_time)513 void rtsyn_play_one_sysex (char *sysexbuffer, int exlen, double event_time ){
514 	int i,j,chk,ne;
515 	MidiEvent ev;
516 	MidiEvent evm[260];
517 
518 	if(rtsyn_sample_time_mode != 1){
519 		event_time += rtsyn_latency;
520 	}
521 
522 	if( (sysexbuffer[0] != '\xf0') && (sysexbuffer[0] != '\xf7') ) return ;
523 
524 /* // this is bad check  someone send SysEx f0xxxxxxxxxxx without xf7 format.
525 	if(   ((sysexbuffer[0] != '\xf0') && (sysexbuffer[0] != '\xf7')) ||
526 	((sysexbuffer[0] == '\xf0') && (sysexbuffer[exlen-1] != '\xf7'))  ) return ;
527 */
528 
529 /*
530 	for(i=0;i<EX_RESET_NO;i++){
531 		chk=0;
532 		for(j=0;(j<exlen)&&(j<11);j++){
533 			if(chk==0 && sysex_resets[i][j]!=sysexbuffer[j]){
534 				chk=~0;
535 			}
536 		}
537 		if(chk==0){
538 			 rtsyn_server_reset();
539 		}
540 	}
541 */
542 /*
543 		printf("SyeEx length=%x bytes \n", exlen);
544 		for(i=0;i<exlen;i++){
545 			printf("%x ",sysexbuffer[i]);
546 		}
547 		printf("\n");
548 */
549 	if(parse_sysex_event(sysexbuffer+1,exlen-1,&ev)){
550 		if(ev.type==ME_RESET)  rtsyn_server_reset();
551 		if(ev.type==ME_RESET && rtsyn_system_mode!=DEFAULT_SYSTEM_MODE){
552 			ev.a=rtsyn_system_mode;
553 			change_system_mode(rtsyn_system_mode);
554 			if(rtsyn_sample_time_mode != 1){
555 				rtsyn_play_event_time(&ev, event_time);
556 			}else{
557 				rtsyn_play_event_sample(&ev, event_time);
558 			}
559 		}else{
560 			if(rtsyn_sample_time_mode != 1){
561 				rtsyn_play_event_time(&ev, event_time);
562 			}else{
563 				rtsyn_play_event_sample(&ev, event_time);
564 			}
565 		}
566 	}
567 	if(ne=parse_sysex_event_multi(sysexbuffer+1,exlen-1, evm)){
568 		for (i = 0; i < ne; i++){
569 			if(rtsyn_sample_time_mode != 1){
570 				rtsyn_play_event_time(&(evm[i]), event_time);
571 			}else{
572 				rtsyn_play_event_sample(&(evm[i]), event_time);
573 			}
574 		}
575 	}
576 
577 }
578