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