OSDN Git Service

Import UnkoTim212
[timidity41/timidity41.git] / interface / rtsyn_common.c
index 4b6f60e..6156a7a 100644 (file)
 #endif /* HAVE_CONFIG_H */
 #include "interface.h"
 
+#ifdef __POCC__
+#include <sys/types.h>
+#endif //for off_t
+
 #include <stdio.h>
 
 #include <stdarg.h>
 #include "rtsyn.h"
 
 extern int32 current_sample;
+extern void reset_midi(int playing);
 
-
-//int seq_quit;
+int seq_quit = ~0;
 
 int rtsyn_system_mode = DEFAULT_SYSTEM_MODE;
 double rtsyn_latency = RTSYN_LATENCY;   //ratency (sec)
+int32 rtsyn_start_sample;
+int rtsyn_sample_time_mode = 0;
+int rtsyn_skip_aq = 0;
+double max_compute = RTSYN_LATENCY;    // play_event() \82Ì compute_data() \82Å\8cv\8eZ\82ð\8b\96\82·\8dÅ\91å\8e\9e\8aÔ
 
 static int rtsyn_played = 0;
 static double rtsyn_start_time;
-static int32 rtsyn_start_sample;
 static double last_event_time;
 static double last_calc_time;
 static int set_time_first=2;
-extern int volatile stream_max_compute;        // play_event() \82Ì compute_data() \82Å\8cv\8eZ\82ð\8b\96\82·\8dÅ\91å\8e\9e\8aÔ
 
 //acitive sensing
 static int active_sensing_flag=0;
@@ -90,7 +96,7 @@ static double active_sensing_time=0;
 
 //timer interrupt
 
-
+/*
 #define EX_RESET_NO 7
 static char sysex_resets[EX_RESET_NO][11]={
                '\xf0','\x7e','\x7f','\x09','\x00','\xf7','\x00','\x00','\x00','\x00','\x00',
@@ -100,6 +106,7 @@ static char sysex_resets[EX_RESET_NO][11]={
                '\xf0','\x41','\x10','\x42','\x12','\x00','\x00','\x7f','\x00','\x01','\xf7',
                '\xf0','\x41','\x10','\x42','\x12','\x00','\x00','\x7f','\x01','\x00','\xf7',
                '\xf0','\x43','\x10','\x4c','\x00','\x00','\x7E','\x00','\xf7','\x00','\x00' };
+*/
 /*
 #define EX_RESET_NO 9
 static char sysex_resets[EX_RESET_NO][11]={
@@ -150,6 +157,53 @@ void rtsyn_xg_reset(){
 }
 
 
+
+void rtsyn_gm2_reset(){
+       MidiEvent ev;
+
+       rtsyn_server_reset();
+       ev.type=ME_RESET;
+       ev.a=GM2_SYSTEM_MODE;
+       ev.time=0;
+       rtsyn_play_event(&ev);
+}
+
+
+
+void rtsyn_sd_reset(){
+       MidiEvent ev;
+
+       rtsyn_server_reset();
+       ev.type=ME_RESET;
+       ev.a=SD_SYSTEM_MODE;
+       ev.time=0;
+       rtsyn_play_event(&ev);
+}
+
+
+void rtsyn_kg_reset(){
+       MidiEvent ev;
+
+       rtsyn_server_reset();
+       ev.type=ME_RESET;
+       ev.a=KG_SYSTEM_MODE;
+       ev.time=0;
+       rtsyn_play_event(&ev);
+}
+
+
+
+void rtsyn_cm_reset(){
+       MidiEvent ev;
+
+       rtsyn_server_reset();
+       ev.type=ME_RESET;
+       ev.a=CM_SYSTEM_MODE;
+       ev.time=0;
+       rtsyn_play_event(&ev);
+}
+
+
 void rtsyn_normal_reset(){
        MidiEvent ev;
 
@@ -167,6 +221,7 @@ void rtsyn_gm_modeset(){
        ev.a=GM_SYSTEM_MODE;
        rtsyn_play_event(&ev);
        change_system_mode(rtsyn_system_mode);
+       reset_midi(1);
 }
 
 
@@ -179,6 +234,7 @@ void rtsyn_gs_modeset(){
        ev.a=GS_SYSTEM_MODE;
        rtsyn_play_event(&ev);
        change_system_mode(rtsyn_system_mode);
+       reset_midi(1);
 }
 
 
@@ -191,6 +247,61 @@ void rtsyn_xg_modeset(){
        ev.a=XG_SYSTEM_MODE;
        rtsyn_play_event(&ev);
        change_system_mode(rtsyn_system_mode);
+       reset_midi(1);
+}
+
+
+void rtsyn_gm2_modeset(){
+       MidiEvent ev;
+
+       rtsyn_server_reset();
+       rtsyn_system_mode=GM2_SYSTEM_MODE;
+       ev.type=ME_RESET;
+       ev.a=GM2_SYSTEM_MODE;
+       rtsyn_play_event(&ev);
+       change_system_mode(rtsyn_system_mode);
+       reset_midi(1);
+}
+
+
+void rtsyn_sd_modeset(){
+       MidiEvent ev;
+
+       rtsyn_server_reset();
+       rtsyn_system_mode=SD_SYSTEM_MODE;
+       ev.type=ME_RESET;
+       ev.a=SD_SYSTEM_MODE;
+       rtsyn_play_event(&ev);
+       change_system_mode(rtsyn_system_mode);
+       reset_midi(1);
+}
+
+
+
+void rtsyn_kg_modeset(){
+       MidiEvent ev;
+
+       rtsyn_server_reset();
+       rtsyn_system_mode=KG_SYSTEM_MODE;
+       ev.type=ME_RESET;
+       ev.a=KG_SYSTEM_MODE;
+       rtsyn_play_event(&ev);
+       change_system_mode(rtsyn_system_mode);
+       reset_midi(1);
+}
+
+
+
+void rtsyn_cm_modeset(){
+       MidiEvent ev;
+
+       rtsyn_server_reset();
+       rtsyn_system_mode=CM_SYSTEM_MODE;
+       ev.type=ME_RESET;
+       ev.a=CM_SYSTEM_MODE;
+       rtsyn_play_event(&ev);
+       change_system_mode(rtsyn_system_mode);
+       reset_midi(1);
 }
 
 
@@ -203,14 +314,21 @@ void rtsyn_normal_modeset(){
        ev.a=GS_SYSTEM_MODE;
        rtsyn_play_event(&ev);
        change_system_mode(rtsyn_system_mode);
+       reset_midi(1);
 }
 
 double rtsyn_set_latency(double latency){
-       if(latency < 1.0 / TICKTIME_HZ * 3.0) latency = 1.0 / TICKTIME_HZ * 4.0;
+       if(latency < 1.0 / TICKTIME_HZ * 4.0)
+               latency = 1.0 / TICKTIME_HZ * 4.0;
        rtsyn_latency = latency;
        return latency;
 }
 
+void rtsyn_set_skip_aq(int flg)
+{
+       rtsyn_skip_aq = flg ? 1 : 0;
+}
+
 void rtsyn_init(void){
        int i,j;
        MidiEvent ev;
@@ -219,114 +337,168 @@ void rtsyn_init(void){
        allocate_cache_size = 0; /* Don't use pre-calclated samples */
        auto_reduce_polyphony = 0;
        opt_sf_close_each_file = 0;
-       
-       aq_set_soft_queue(rtsyn_latency*(double)1.01, 0.0);
+
+       if (play_mode->flag & PF_PCM_STREAM) {
+               play_mode->extra_param[1] = aq_calc_fragsize();
+               ctl->cmsg(CMSG_INFO, VERB_DEBUG_SILLY,
+                         "requesting fragment size: %d",
+                         play_mode->extra_param[1]);
+       }       
+       if(ctl->id_character != 'N')
+               if(rtsyn_skip_aq) // c212 add
+                 aq_set_soft_queue(0.0, 0.0); // skip audio queue
+               else
+                 aq_set_soft_queue(rtsyn_latency, 0.0);
+       max_compute = (double)stream_max_compute * DIV_1000; //rtsyn_latency * 1000.0;
+       max_compute = (rtsyn_latency > max_compute) ? rtsyn_latency : max_compute;
        i = current_keysig + ((current_keysig < 8) ? 7 : -9), j = 0;
        while (i != 7)
                i += (i < 7) ? 5 : -7, j++;
-       j += note_key_offset, j -= floor(j / 12.0) * 12;
+       j += note_key_offset, j -= floor(j * DIV_12) * 12;
        current_freq_table = j;
        
+       if(play_mode && play_mode->acntl)
+         play_mode->acntl(PM_REQ_PLAY_END, NULL);
+       if(play_mode && play_mode->close_output)
+         play_mode->close_output();
+       
+       current_file_info = get_midi_file_info("Output.mid", 1);
+       
+       if(play_mode && play_mode->open_output)
+         play_mode->open_output();
+       
+       aq_setup();
+       
+       if(play_mode && play_mode->acntl)
+         play_mode->acntl(PM_REQ_PLAY_START, NULL);
+       
        rtsyn_reset();
        rtsyn_system_mode=DEFAULT_SYSTEM_MODE;
        change_system_mode(rtsyn_system_mode);
-       ev.type=ME_RESET;
-       ev.a=GS_SYSTEM_MODE; //GM is mor better ???
-       rtsyn_play_event(&ev);
+
+       reset_midi(0);
 }
 
 void rtsyn_close(void){
        rtsyn_stop_playing();
+       if(play_mode && play_mode->acntl)
+         play_mode->acntl(PM_REQ_PLAY_END, NULL);
        free_instruments(0);
+       playmidi_stream_free();
        free_global_mblock();
 }
 
+void rtsyn_play_event_sample(MidiEvent *ev, int32 event_sample_time){
+       ev->time=event_sample_time;
+       play_event(ev);
+       if(rtsyn_sample_time_mode != 1)
+         aq_fill_nonblocking();
+}
+
 void rtsyn_play_event_time(MidiEvent *ev, double event_time){
        int gch;
        double current_event_time, buf_time;
-       int32 max_compute;
        MidiEvent nev;
 
-       gch = GLOBAL_CHANNEL_EVENT_TYPE(ev->type);
-       if(gch || !IS_SET_CHANNELMASK(quietchannels, ev->channel) ){
-
-               max_compute = rtsyn_latency * 1000.0;
-               max_compute = (stream_max_compute > max_compute) ? stream_max_compute : max_compute;
-               if ( (event_time - last_event_time) > (double)max_compute/1000.0){
-                               kill_all_voices();
-                               current_sample = (double)(play_mode->rate) * get_current_calender_time()+0.5;
-                               rtsyn_start_time=get_current_calender_time();
-                               rtsyn_start_sample=current_sample;
-                               last_event_time=rtsyn_start_time;
-               }else{
-                               nev.type = ME_NONE;
-                       if( (event_time - last_event_time) > 1.0/(double)TICKTIME_HZ ) {
-                               buf_time = last_event_time + 1.0/(double)TICKTIME_HZ;
+       if ( (event_time - last_event_time) > max_compute){
+                       kill_all_voices();
+                       current_sample = (double)(play_mode->rate) * get_current_calender_time()+0.5;
+                       rtsyn_start_time=get_current_calender_time();
+                       rtsyn_start_sample=current_sample;
+                       last_event_time=rtsyn_start_time;
+       }else{
+                       nev.type = ME_NONE;
+               if( (event_time - last_event_time) > 1.0/(double)TICKTIME_HZ ) {
+                       buf_time = last_event_time + 1.0/(double)TICKTIME_HZ;
+                       rtsyn_seq_set_time(&nev, buf_time);
+                       play_event(&nev);
+                       aq_fill_nonblocking();
+                               
+                       while( event_time > buf_time + 1.0/(double)TICKTIME_HZ){
+                               buf_time = buf_time + 1.0/(double)TICKTIME_HZ;
                                rtsyn_seq_set_time(&nev, buf_time);
                                play_event(&nev);
                                aq_fill_nonblocking();
-                               
-                               while( event_time > buf_time + 1.0/(double)TICKTIME_HZ){
-                                       buf_time = buf_time + 1.0/(double)TICKTIME_HZ;
-                                       rtsyn_seq_set_time(&nev, buf_time);
-                                       play_event(&nev);
-                                       aq_fill_nonblocking();
-                               }
+                       }
+               }
+                       gch = GLOBAL_CHANNEL_EVENT_TYPE(ev->type);
+                       if(gch || !IS_SET_CHANNELMASK(quietchannels, ev->channel) ){
                                rtsyn_seq_set_time(ev,event_time);
                                play_event(ev);
                                aq_fill_nonblocking();
                                last_event_time = (event_time  > last_event_time) ? event_time : last_event_time ;
-               
-                       }else{
-                               rtsyn_seq_set_time(ev, event_time);
-                               play_event(ev);
-                               aq_fill_nonblocking();
-                               last_event_time = (event_time  > last_event_time) ? event_time : last_event_time ;
                        }
                }
 //             }
-               rtsyn_played = 1;
-       }
+//             }
+       rtsyn_played = 1;
+
 
 }
 void rtsyn_play_event(MidiEvent *ev){
        rtsyn_play_event_time(ev, get_current_calender_time());
 }
 
-
-void rtsyn_reset(void){
-               rtsyn_server_reset();
-}
-
-void rtsyn_server_reset(void){
+void rtsyn_wot_reset(void){
+       int i;
+       kill_all_voices();
+       if (free_instruments_afterwards){
+               free_instruments(0);
+       }
        aq_flush(1);
-       play_mode->close_output();      // PM_REQ_PLAY_START wlll called in playmidi_stream_init()
-       play_mode->open_output();       // but w32_a.c does not have it.
+//     play_mode->close_output();      // PM_REQ_PLAY_START wlll called in playmidi_stream_init()
+//     play_mode->open_output();       // but w32_a.c does not have it.
+       play_mode->acntl(PM_REQ_FLUSH, NULL);
+
        readmidi_read_init();
        playmidi_stream_init();
-       if (free_instruments_afterwards)
-               free_instruments(0);
+       change_system_mode(rtsyn_system_mode);
+       reset_midi(1);
        reduce_voice_threshold = 0; // * Disable auto reduction voice *
+///r
+       reduce_quality_threshold = 0;
+       reduce_polyphony_threshold = 0;
        auto_reduce_polyphony = 0;
-       
-       rtsyn_start_time=get_current_calender_time();
-       rtsyn_start_sample=current_sample;
-       last_event_time=rtsyn_start_time + rtsyn_latency;
-       last_calc_time  = rtsyn_start_time;
+}
+
+void rtsyn_tmr_reset(void){
+       if(ctl->id_character == 'N')
+               current_sample = 0;     
+               rtsyn_start_time=get_current_calender_time();
+               rtsyn_start_sample=current_sample;
+               last_event_time=rtsyn_start_time + rtsyn_latency;
+               last_calc_time  = rtsyn_start_time;
+}
+
+void rtsyn_reset(void){
+       rtsyn_wot_reset();
+       rtsyn_tmr_reset();
+}
+
+void rtsyn_server_reset(void){
+       rtsyn_wot_reset();
+       if(rtsyn_sample_time_mode !=1){
+               rtsyn_tmr_reset();
+       }
 }
 
 void rtsyn_stop_playing(void)
 {
        if(upper_voices) {
+               const double tail = (rtsyn_latency > 0.1) ? 0.1 : rtsyn_latency;
+
                MidiEvent ev;
                ev.type = ME_EOT;
                ev.time = 0;
                ev.a = 0;
                ev.b = 0;
-               rtsyn_play_event_time(&ev, rtsyn_latency + get_current_calender_time());
-               sleep( rtsyn_latency * 1000.0);
+               rtsyn_play_event_time(&ev, tail + get_current_calender_time());
+               sleep(tail * 10.0);
+       //      rtsyn_play_event_time(&ev, rtsyn_latency + get_current_calender_time());
+       //      sleep(rtsyn_latency * 1000.0);
                aq_flush(0);
        }
+       trace_flush();
 }
 
 
@@ -369,11 +541,13 @@ void rtsyn_play_calculate(){
        
 int rtsyn_play_one_data (int port, int32 dwParam1, double event_time){
        MidiEvent ev;
-
-       event_time = event_time + rtsyn_latency;
+       
+       if(rtsyn_sample_time_mode != 1){
+               event_time += rtsyn_latency;
+       }
        ev.type = ME_NONE;
        ev.channel = dwParam1 & 0x0000000f;
-       ev.channel = ev.channel+port*16;
+       ev.channel = ev.channel+(port<<4);
        ev.a = (dwParam1 >> 8) & 0xff;
        ev.b = (dwParam1 >> 16) & 0xff;
        switch ((int) (dwParam1 & 0x000000f0)) {
@@ -422,9 +596,19 @@ int rtsyn_play_one_data (int port, int32 dwParam1, double event_time){
                        printf("MIDI Time Code Qtr\n");
                if ((dwParam1 & 0x000000ff) == 0xf3)
                        //Song Select(Song #) (not need)
-               if ((dwParam1 & 0x000000ff) == 0xf6)
-                       //Tune request (not need)
-                       printf("Tune request\n");
+#endif
+               if ((dwParam1 & 0x000000ff) == 0xf6){
+                       //Tune request  but use to make TiMidity++  to calculate.
+                       if(rtsyn_sample_time_mode == 1){
+                               ev.type = ME_NONE;
+                               rtsyn_play_event_sample(&ev, event_time);
+                               aq_fill_nonblocking();
+                               //aq_soft_flush();
+                       }else{
+                               //printf("Tune request\n");
+                       }
+               }
+#if 0
                if ((dwParam1 & 0x000000ff) == 0xf8)
                        //Timing Clock (not need)
                        printf("Timing Clock\n");
@@ -444,8 +628,12 @@ int rtsyn_play_one_data (int port, int32 dwParam1, double event_time){
                        active_sensing_time = get_current_calender_time();
                }
                if ((dwParam1 & 0x000000ff) == 0xff) {
-                       //System Reset
-                       printf("System Reset\n");
+                       //System Reset  use for TiMidity++  timer  reset
+                       if(rtsyn_sample_time_mode == 1){
+                               rtsyn_tmr_reset();
+                       }else{
+                               //printf("System Reset\n");
+                       }
                }
                break;
        default:
@@ -453,32 +641,45 @@ int rtsyn_play_one_data (int port, int32 dwParam1, double event_time){
                break;
        }
        if (ev.type != ME_NONE) {
-               rtsyn_play_event_time(&ev, event_time);
+               if(rtsyn_sample_time_mode != 1){
+                               rtsyn_play_event_time(&ev, event_time);
+               }else{
+                               rtsyn_play_event_sample(&ev, event_time);
+               }
        }
        return 0;
 }
 
 
-void rtsyn_play_one_sysex (char *sysexbuffer, int exlen, double event_time ){
+void rtsyn_play_one_sysex (uint8 *sysexbuffer, int exlen, double event_time ){
        int i,j,chk,ne;
        MidiEvent ev;
        MidiEvent evm[260];
        
-       event_time = event_time + rtsyn_latency;
-
-       if(sysexbuffer[exlen-1] == '\xf7'){            // I don't konw why this need
-               for(i=0;i<EX_RESET_NO;i++){
-                       chk=0;
-                       for(j=0;(j<exlen)&&(j<11);j++){
-                               if(chk==0 && sysex_resets[i][j]!=sysexbuffer[j]){
-                                       chk=~0;
-                               }
-                       }
-                       if(chk==0){
-                                rtsyn_server_reset();
+       if(rtsyn_sample_time_mode != 1){
+               event_time += rtsyn_latency;
+       }
+
+       if( ((int8)sysexbuffer[0] != '\xf0') && ((int8)sysexbuffer[0] != '\xf7') ) return ;
+
+/* // this is bad check  someone send SysEx f0xxxxxxxxxxx without xf7 format.
+       if(   (((int8)sysexbuffer[0] != '\xf0') && ((int8)sysexbuffer[0] != '\xf7')) ||
+       (((int8)sysexbuffer[0] == '\xf0') && ((int8)sysexbuffer[exlen-1] != '\xf7'))  ) return ;
+*/
+
+/*
+       for(i=0;i<EX_RESET_NO;i++){
+               chk=0;
+               for(j=0;(j<exlen)&&(j<11);j++){
+                       if(chk==0 && sysex_resets[i][j]!=sysexbuffer[j]){
+                               chk=~0;
                        }
                }
-
+               if(chk==0){
+                        rtsyn_server_reset();
+               }
+       }
+*/
 /*
                printf("SyeEx length=%x bytes \n", exlen);
                for(i=0;i<exlen;i++){
@@ -486,19 +687,32 @@ void rtsyn_play_one_sysex (char *sysexbuffer, int exlen, double event_time ){
                }
                printf("\n");
 */
-               if(parse_sysex_event(sysexbuffer+1,exlen-1,&ev)){
-                       if(ev.type==ME_RESET && rtsyn_system_mode!=DEFAULT_SYSTEM_MODE){
-                               ev.a=rtsyn_system_mode;
-                               change_system_mode(rtsyn_system_mode);
+       if(parse_sysex_event(sysexbuffer+1,exlen-1,&ev)){
+               if(ev.type==ME_RESET)  rtsyn_server_reset();
+               if(ev.type==ME_RESET && rtsyn_system_mode!=DEFAULT_SYSTEM_MODE){
+                       ev.a=rtsyn_system_mode;
+                       change_system_mode(rtsyn_system_mode);
+                       if(rtsyn_sample_time_mode != 1){
                                rtsyn_play_event_time(&ev, event_time);
                        }else{
+                               rtsyn_play_event_sample(&ev, event_time);
+                       }
+               }else{
+                       if(rtsyn_sample_time_mode != 1){
                                rtsyn_play_event_time(&ev, event_time);
+                       }else{
+                               rtsyn_play_event_sample(&ev, event_time);
                        }
                }
-               if(ne=parse_sysex_event_multi(sysexbuffer+1,exlen-1, evm)){
-                       for (i = 0; i < ne; i++){
-                                       rtsyn_play_event_time(&evm[i], event_time);
+       }
+       if(ne=parse_sysex_event_multi(sysexbuffer+1,exlen-1, evm)){
+               for (i = 0; i < ne; i++){
+                       if(rtsyn_sample_time_mode != 1){
+                               rtsyn_play_event_time(&(evm[i]), event_time);
+                       }else{
+                               rtsyn_play_event_sample(&(evm[i]), event_time);
                        }
                }
        }
+       
 }