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>
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.
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.
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
21 Copyright (c) 2003-2005 Keishi Suenaga <s_keishi@mutt.freemail.ne.jp>
23 I referenced following sources.
24 alsaseq_c.c - ALSA sequencer server interface
25 Copyright (c) 2000 Takashi Iwai <tiwai@suse.de>
31 #endif /* HAVE_CONFIG_H */
32 #include "interface.h"
40 #include <sys/types.h>
41 #ifdef TIME_WITH_SYS_TIME
52 #include "server_defs.h"
71 extern int32 current_sample;
76 int rtsyn_system_mode = DEFAULT_SYSTEM_MODE;
77 double rtsyn_latency = RTSYN_LATENCY; //ratency (sec)
79 static int rtsyn_played = 0;
80 static double rtsyn_start_time;
81 static int32 rtsyn_start_sample;
82 static double last_event_time;
83 static double last_calc_time;
84 static int set_time_first=2;
85 extern int volatile stream_max_compute; // play_event()
\82Ì compute_data()
\82Å
\8cv
\8eZ
\82ð
\8b\96\82·
\8dÅ
\91å
\8e\9e\8aÔ
88 static int active_sensing_flag=0;
89 static double active_sensing_time=0;
95 static char sysex_resets[EX_RESET_NO][11]={
96 '\xf0','\x7e','\x7f','\x09','\x00','\xf7','\x00','\x00','\x00','\x00','\x00',
97 '\xf0','\x7e','\x7f','\x09','\x01','\xf7','\x00','\x00','\x00','\x00','\x00',
98 '\xf0','\x7e','\x7f','\x09','\x03','\xf7','\x00','\x00','\x00','\x00','\x00',
99 '\xf0','\x41','\x10','\x42','\x12','\x40','\x00','\x7f','\x00','\x41','\xf7',
100 '\xf0','\x41','\x10','\x42','\x12','\x00','\x00','\x7f','\x00','\x01','\xf7',
101 '\xf0','\x41','\x10','\x42','\x12','\x00','\x00','\x7f','\x01','\x00','\xf7',
102 '\xf0','\x43','\x10','\x4c','\x00','\x00','\x7E','\x00','\xf7','\x00','\x00' };
104 #define EX_RESET_NO 9
105 static char sysex_resets[EX_RESET_NO][11]={
106 '\xf0','\x7e','\x7f','\x09','\x00','\xf7','\x00','\x00','\x00','\x00','\x00', //gm off
107 '\xf0','\x7e','\x7f','\x09','\x01','\xf7','\x00','\x00','\x00','\x00','\x00', //gm1
108 '\xf0','\x7e','\x7f','\x09','\x02','\xf7','\x00','\x00','\x00','\x00','\x00', //gm off
109 '\xf0','\x7e','\x7f','\x09','\x03','\xf7','\x00','\x00','\x00','\x00','\x00', //gm2
110 '\xf0','\x41','\x10','\x42','\x12','\x40','\x00','\x7f','\x00','\x41','\xf7', //GS
111 '\xf0','\x41','\x10','\x42','\x12','\x40','\x00','\x7f','\x7f','\x41','\xf7', //GS off
112 '\xf0','\x41','\x10','\x42','\x12','\x00','\x00','\x7f','\x00','\x01','\xf7', //88
113 '\xf0','\x41','\x10','\x42','\x12','\x00','\x00','\x7f','\x01','\x00','\xf7', //88
114 '\xf0','\x43','\x10','\x4c','\x00','\x00','\x7E','\x00','\xf7','\x00','\x00' //XG on
118 void rtsyn_seq_set_time(MidiEvent *ev, double event_time);
121 void rtsyn_gm_reset(){
124 rtsyn_server_reset();
127 rtsyn_play_event(&ev);
132 void rtsyn_gs_reset(){
135 rtsyn_server_reset();
138 rtsyn_play_event(&ev);
142 void rtsyn_xg_reset(){
145 rtsyn_server_reset();
149 rtsyn_play_event(&ev);
153 void rtsyn_normal_reset(){
156 rtsyn_server_reset();
158 ev.a=rtsyn_system_mode;
159 rtsyn_play_event(&ev);
161 void rtsyn_gm_modeset(){
164 rtsyn_server_reset();
165 rtsyn_system_mode=GM_SYSTEM_MODE;
168 rtsyn_play_event(&ev);
169 change_system_mode(rtsyn_system_mode);
173 void rtsyn_gs_modeset(){
176 rtsyn_server_reset();
177 rtsyn_system_mode=GS_SYSTEM_MODE;
180 rtsyn_play_event(&ev);
181 change_system_mode(rtsyn_system_mode);
185 void rtsyn_xg_modeset(){
188 rtsyn_server_reset();
189 rtsyn_system_mode=XG_SYSTEM_MODE;
192 rtsyn_play_event(&ev);
193 change_system_mode(rtsyn_system_mode);
197 void rtsyn_normal_modeset(){
200 rtsyn_server_reset();
201 rtsyn_system_mode=DEFAULT_SYSTEM_MODE;
204 rtsyn_play_event(&ev);
205 change_system_mode(rtsyn_system_mode);
208 double rtsyn_set_latency(double latency){
209 if(latency < 1.0 / TICKTIME_HZ * 3.0) latency = 1.0 / TICKTIME_HZ * 4.0;
210 rtsyn_latency = latency;
214 void rtsyn_init(void){
218 opt_realtime_playing = 1; /* Enable loading patch while playing */
219 allocate_cache_size = 0; /* Don't use pre-calclated samples */
220 auto_reduce_polyphony = 0;
221 opt_sf_close_each_file = 0;
223 aq_set_soft_queue(rtsyn_latency*(double)1.01, 0.0);
224 i = current_keysig + ((current_keysig < 8) ? 7 : -9), j = 0;
226 i += (i < 7) ? 5 : -7, j++;
227 j += note_key_offset, j -= floor(j / 12.0) * 12;
228 current_freq_table = j;
231 rtsyn_system_mode=DEFAULT_SYSTEM_MODE;
232 change_system_mode(rtsyn_system_mode);
234 ev.a=GS_SYSTEM_MODE; //GM is mor better ???
235 rtsyn_play_event(&ev);
238 void rtsyn_close(void){
239 rtsyn_stop_playing();
241 free_global_mblock();
244 void rtsyn_play_event_time(MidiEvent *ev, double event_time){
246 double current_event_time, buf_time;
250 gch = GLOBAL_CHANNEL_EVENT_TYPE(ev->type);
251 if(gch || !IS_SET_CHANNELMASK(quietchannels, ev->channel) ){
253 max_compute = rtsyn_latency * 1000.0;
254 max_compute = (stream_max_compute > max_compute) ? stream_max_compute : max_compute;
255 if ( (event_time - last_event_time) > (double)max_compute/1000.0){
257 current_sample = (double)(play_mode->rate) * get_current_calender_time()+0.5;
258 rtsyn_start_time=get_current_calender_time();
259 rtsyn_start_sample=current_sample;
260 last_event_time=rtsyn_start_time;
263 if( (event_time - last_event_time) > 1.0/(double)TICKTIME_HZ ) {
264 buf_time = last_event_time + 1.0/(double)TICKTIME_HZ;
265 rtsyn_seq_set_time(&nev, buf_time);
267 aq_fill_nonblocking();
269 while( event_time > buf_time + 1.0/(double)TICKTIME_HZ){
270 buf_time = buf_time + 1.0/(double)TICKTIME_HZ;
271 rtsyn_seq_set_time(&nev, buf_time);
273 aq_fill_nonblocking();
275 rtsyn_seq_set_time(ev,event_time);
277 aq_fill_nonblocking();
278 last_event_time = (event_time > last_event_time) ? event_time : last_event_time ;
281 rtsyn_seq_set_time(ev, event_time);
283 aq_fill_nonblocking();
284 last_event_time = (event_time > last_event_time) ? event_time : last_event_time ;
292 void rtsyn_play_event(MidiEvent *ev){
293 rtsyn_play_event_time(ev, get_current_calender_time());
297 void rtsyn_reset(void){
298 rtsyn_server_reset();
301 void rtsyn_server_reset(void){
303 play_mode->close_output(); // PM_REQ_PLAY_START wlll called in playmidi_stream_init()
304 play_mode->open_output(); // but w32_a.c does not have it.
305 readmidi_read_init();
306 playmidi_stream_init();
307 change_system_mode(rtsyn_system_mode);
308 if (free_instruments_afterwards){
310 free_global_mblock(); /* free unused memory */
312 free_special_patch(-1);
313 reduce_voice_threshold = 0; // * Disable auto reduction voice *
314 auto_reduce_polyphony = 0;
316 rtsyn_start_time=get_current_calender_time();
317 rtsyn_start_sample=current_sample;
318 last_event_time=rtsyn_start_time + rtsyn_latency;
319 last_calc_time = rtsyn_start_time;
322 void rtsyn_stop_playing(void)
330 rtsyn_play_event_time(&ev, rtsyn_latency + get_current_calender_time());
331 sleep( rtsyn_latency * 1000.0);
337 void rtsyn_seq_set_time(MidiEvent *ev, double event_time)
339 double currenttime, time_div;
341 time_div = event_time - rtsyn_start_time;
342 ev->time = rtsyn_start_sample
343 +(int32) ((double)(play_mode->rate) * time_div+0.5);
347 void rtsyn_play_calculate(){
349 double currenet_event_time, current_time;
351 current_time = get_current_calender_time();
352 currenet_event_time = current_time + rtsyn_latency;
354 if( (rtsyn_played == 0) && (currenet_event_time > last_calc_time + 1.0/(double)TICKTIME_HZ) /* event buffer is empty */
355 || (current_time + 1.0/(double)TICKTIME_HZ*2.0 > last_event_time) /* near miss */
358 rtsyn_play_event_time(&ev, currenet_event_time);
359 last_calc_time=currenet_event_time;
364 if(active_sensing_flag==~0 && (get_current_calender_time() > active_sensing_time+0.5)){
365 //normaly acitive sensing expiering time is 330ms(>300ms) but this loop is heavy
366 play_mode->close_output();
367 play_mode->open_output();
368 ctl->cmsg( CMSG_ERROR, VERB_NORMAL,"Active Sensing Expired\n");
369 rtsyn_server_reset();
370 active_sensing_flag=0;
374 int rtsyn_play_one_data (int port, int32 dwParam1, double event_time){
377 event_time = event_time + rtsyn_latency;
379 ev.channel = dwParam1 & 0x0000000f;
380 ev.channel = ev.channel+port*16;
381 ev.a = (dwParam1 >> 8) & 0xff;
382 ev.b = (dwParam1 >> 16) & 0xff;
383 switch ((int) (dwParam1 & 0x000000f0)) {
385 ev.type = ME_NOTEOFF;
386 // rtsyn_play_event(&ev);
389 ev.type = (ev.b) ? ME_NOTEON : ME_NOTEOFF;
390 // rtsyn_play_event(&ev);
393 ev.type = ME_KEYPRESSURE;
394 // rtsyn_play_event(&ev);
397 if (! convert_midi_control_change(ev.channel, ev.a, ev.b, &ev))
401 ev.type = ME_PROGRAM;
402 // rtsyn_play_event(&ev);
405 ev.type = ME_CHANNEL_PRESSURE;
406 // rtsyn_play_event(&ev);
409 ev.type = ME_PITCHWHEEL;
410 // rtsyn_play_event(&ev);
413 #ifdef IA_PORTMIDISYN
414 if ( (dwParam1 & 0x000000ff) == 0xf0) {
419 if ((dwParam1 & 0x000000ff) == 0xf2) {
420 ev.type = ME_PROGRAM;
421 // rtsyn_play_event(&ev);
424 if ((dwParam1 & 0x000000ff) == 0xf1)
425 //MIDI Time Code Qtr. Frame (not need)
426 printf("MIDI Time Code Qtr\n");
427 if ((dwParam1 & 0x000000ff) == 0xf3)
428 //Song Select(Song #) (not need)
429 if ((dwParam1 & 0x000000ff) == 0xf6)
430 //Tune request (not need)
431 printf("Tune request\n");
432 if ((dwParam1 & 0x000000ff) == 0xf8)
433 //Timing Clock (not need)
434 printf("Timing Clock\n");
435 if ((dwParam1&0x000000ff)==0xfa)
437 if ((dwParam1 & 0x000000ff) == 0xfb)
439 if ((dwParam1 & 0x000000ff) == 0xfc) {
444 if ((dwParam1 & 0x000000ff) == 0xfe) {
446 // printf("Active Sensing\n");
447 active_sensing_flag = ~0;
448 active_sensing_time = get_current_calender_time();
450 if ((dwParam1 & 0x000000ff) == 0xff) {
452 printf("System Reset\n");
456 // printf("Unsup/ed event %d\n", aevp->type);
459 if (ev.type != ME_NONE) {
460 rtsyn_play_event_time(&ev, event_time);
466 void rtsyn_play_one_sysex (char *sysexbuffer, int exlen, double event_time ){
471 event_time = event_time + rtsyn_latency;
473 if(sysexbuffer[exlen-1] == '\xf7'){ // I don't konw why this need
474 for(i=0;i<EX_RESET_NO;i++){
476 for(j=0;(j<exlen)&&(j<11);j++){
477 if(chk==0 && sysex_resets[i][j]!=sysexbuffer[j]){
482 rtsyn_server_reset();
487 printf("SyeEx length=%x bytes \n", exlen);
488 for(i=0;i<exlen;i++){
489 printf("%x ",sysexbuffer[i]);
493 if(parse_sysex_event(sysexbuffer+1,exlen-1,&ev)){
494 if(ev.type==ME_RESET && rtsyn_system_mode!=DEFAULT_SYSTEM_MODE){
495 ev.a=rtsyn_system_mode;
496 change_system_mode(rtsyn_system_mode);
497 rtsyn_play_event_time(&ev, event_time);
499 rtsyn_play_event_time(&ev, event_time);
502 if(ne=parse_sysex_event_multi(sysexbuffer+1,exlen-1, evm)){
503 for (i = 0; i < ne; i++){
504 rtsyn_play_event_time(&evm[i], event_time);