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 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 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 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 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 } 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 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 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 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 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 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 248 void rtsyn_close(void){ 249 rtsyn_stop_playing(); 250 free_instruments(0); 251 playmidi_stream_free(); 252 free_global_mblock(); 253 } 254 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 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 } 305 void rtsyn_play_event(MidiEvent *ev){ 306 rtsyn_play_event_time(ev, get_current_calender_time()); 307 } 308 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 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 337 void rtsyn_reset(void){ 338 rtsyn_wot_reset(); 339 rtsyn_tmr_reset(); 340 } 341 342 void rtsyn_server_reset(void){ 343 rtsyn_wot_reset(); 344 if(rtsyn_sample_time_mode !=1){ 345 rtsyn_tmr_reset(); 346 } 347 } 348 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 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 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 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 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