/*
TiMidity++ -- MIDI to WAVE converter and player
- Copyright (C) 1999-2002 Masanao Izumo <mo@goice.co.jp>
+ Copyright (C) 1999-2004 Masanao Izumo <iz@onicos.co.jp>
Copyright (C) 1995 Tuukka Toivonen <tt@cgs.fi>
This program is free software; you can redistribute it and/or modify
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
rtsyn_common.c
- Copyright (c) 2003 Keishi Suenaga <s_keishi@mutt.freemail.ne.jp>
+ Copyright (c) 2003-2005 Keishi Suenaga <s_keishi@mutt.freemail.ne.jp>
I referenced following sources.
alsaseq_c.c - ALSA sequencer server interface
#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;
+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 int32 event_time_offset;
-static double starttime;
-double rtsyn_reachtime;
-static int time_advance;
+static int rtsyn_played = 0;
+static double rtsyn_start_time;
+static double last_event_time;
+static double last_calc_time;
static int set_time_first=2;
//acitive sensing
static double active_sensing_time=0;
//timer interrupt
-#ifdef USE_WINSYN_TIMER_I
-rtsyn_mutex_t timerMUTEX;
-
-#ifdef __W32__
-MMRESULT timerID;
-#else
-pthread_t timer_thread;
-int thread_on_f=0;
-#endif
-
-#endif
+/*
#define EX_RESET_NO 7
static char sysex_resets[EX_RESET_NO][11]={
'\xf0','\x7e','\x7f','\x09','\x00','\xf7','\x00','\x00','\x00','\x00','\x00',
'\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]={
};
*/
-static void seq_set_time(MidiEvent *ev);
-
+void rtsyn_seq_set_time(MidiEvent *ev, double event_time);
void rtsyn_gm_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;
ev.a=GM_SYSTEM_MODE;
rtsyn_play_event(&ev);
change_system_mode(rtsyn_system_mode);
+ reset_midi(1);
}
ev.a=GS_SYSTEM_MODE;
rtsyn_play_event(&ev);
change_system_mode(rtsyn_system_mode);
+ reset_midi(1);
}
ev.a=XG_SYSTEM_MODE;
rtsyn_play_event(&ev);
change_system_mode(rtsyn_system_mode);
+ reset_midi(1);
}
-void rtsyn_normal_modeset(){
+void rtsyn_gm2_modeset(){
MidiEvent ev;
rtsyn_server_reset();
- rtsyn_system_mode=DEFAULT_SYSTEM_MODE;
+ rtsyn_system_mode=GM2_SYSTEM_MODE;
ev.type=ME_RESET;
- ev.a=GS_SYSTEM_MODE;
+ ev.a=GM2_SYSTEM_MODE;
rtsyn_play_event(&ev);
change_system_mode(rtsyn_system_mode);
+ reset_midi(1);
}
+void rtsyn_sd_modeset(){
+ MidiEvent ev;
-#ifdef USE_WINSYN_TIMER_I
-#ifdef __W32__
-VOID CALLBACK timercalc(UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD dummy1, DWORD dummy2){
+ 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;
- double time_div, currenttime;
-
- rtsyn_mutex_lock(timerMUTEX);
- currenttime=get_current_calender_time();
- time_div=currenttime-starttime;
- if( time_div > 1.0/TICKTIME_HZ*2.0){
- time_div= 1.0/TICKTIME_HZ-3/(play_mode->rate);
- }
- ev.time= ((double)current_sample
- + (play_mode->rate)*time_div+0.5);
- starttime=currenttime;
- ev.type = ME_NONE;
- play_event(&ev);
-// compute_data(tmdy_struct,(tmdy_struct->output->play_mode->rate)*time_div);
- aq_fill_nonblocking();
- rtsyn_reachtime=currenttime + (double)(1.0f/TICKTIME_HZ);
- rtsyn_mutex_unlock(timerMUTEX);
- return;
+
+ 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);
}
-#else
-void *timercalc(void *arg){
- MidiEvent ev;
- unsigned int slt;
- double reachtime,delay;
- delay=(double)(1.0/TICKTIME_HZ);
- while(thread_on_f==1){
- rtsyn_mutex_lock(timerMUTEX);
- reachtime=get_current_calender_time()+delay;
- ev.type = ME_NONE;
- seq_set_time(&ev);
- play_event(&ev);
- aq_fill_nonblocking();
- rtsyn_mutex_unlock(timerMUTEX);
- do{
- sleep(0);
- }while(get_current_calender_time()<reachtime);
- }
- return NULL;
+
+
+
+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);
}
-#endif
-#endif
+
+
+void rtsyn_normal_modeset(){
+ MidiEvent ev;
+
+ rtsyn_server_reset();
+ rtsyn_system_mode=DEFAULT_SYSTEM_MODE;
+ ev.type=ME_RESET;
+ 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 * 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;
/* set constants */
opt_realtime_playing = 1; /* Enable loading patch while playing */
allocate_cache_size = 0; /* Don't use pre-calclated samples */
auto_reduce_polyphony = 0;
- current_keysig = current_temper_keysig = opt_init_keysig;
- note_key_offset = 0;
- time_advance=play_mode->rate/TICKTIME_HZ*2;
- if (!(play_mode->encoding & PE_MONO))
- time_advance >>= 1;
- if (play_mode->encoding & PE_16BIT)
- time_advance >>= 1;
-
- if (opt_force_keysig != 8) {
- i = current_keysig + ((current_keysig < 8) ? 7 : -6);
- j = opt_force_keysig + ((current_keysig < 8) ? 7 : 10);
- while (i != j && i != j + 12) {
- if (++note_key_offset > 6)
- note_key_offset -= 12;
- i += (i > 10) ? -5 : 7;
- }
- }
+ opt_sf_close_each_file = 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 != 19)
+ 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;
-#ifdef USE_WINSYN_TIMER_I
-
- rtsyn_mutex_init(timerMUTEX);
-#ifdef __W32__
- timeBeginPeriod(1);
- {
- DWORD data;
- UINT delay;
- delay=(1000/TICKTIME_HZ);
-
-
- timerID = timeSetEvent( delay, 0, timercalc, data,
- TIME_PERIODIC | TIME_CALLBACK_FUNCTION );
- if( !timerID ){
- ctl->cmsg( CMSG_ERROR, VERB_NORMAL,"Fail to setup Timer Interrupt (winsyn) \n");
- }
- }
-#else
- thread_on_f=1;
- if(0!=pthread_create(&timer_thread,NULL,timercalc,NULL)){
- ctl->cmsg( CMSG_ERROR, VERB_NORMAL,"Fail to setup Timer Interrupt (winsyn) \n");
- }
-#endif
+ 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);
-#endif
- rtsyn_server_reset();
+ reset_midi(0);
}
void rtsyn_close(void){
-#ifdef USE_WINSYN_TIMER_I
-#ifdef __W32__
- timeKillEvent( timerID );
- timeEndPeriod(1);
-#else
- thread_on_f=0;
- pthread_join(timer_thread, NULL);
-#endif
- rtsyn_mutex_destroy(timerMUTEX);
-#endif
+ 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(MidiEvent *ev)
-{
- int gch;
- int32 cet;
-#ifdef USE_WINSYN_TIMER_I
- rtsyn_mutex_lock(timerMUTEX);
-#endif
-
- gch = GLOBAL_CHANNEL_EVENT_TYPE(ev->type);
- if(gch || !IS_SET_CHANNELMASK(quietchannels, ev->channel) ){
-// if ( !seq_quit ) {
- ev->time=0;
- play_event(ev);
-// }
- }
-#ifdef USE_WINSYN_TIMER_I
- rtsyn_mutex_unlock(timerMUTEX);
-#endif
-
+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_reset(void){
- rtsyn_stop_playing();
-#ifdef USE_WINSYN_TIMER_I
- rtsyn_mutex_lock(timerMUTEX);
-#endif
+void rtsyn_play_event_time(MidiEvent *ev, double event_time){
+ int gch;
+ double current_event_time, buf_time;
+ MidiEvent nev;
+
+ 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();
+ }
+ }
+ 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 ;
+ }
+ }
+// }
+// }
+ rtsyn_played = 1;
- free_instruments(0); //also in rtsyn_server_reset
- free_global_mblock();
-#ifdef USE_WINSYN_TIMER_I
- rtsyn_mutex_unlock(timerMUTEX);
-#endif
- rtsyn_server_reset();
-// printf("system reseted\n");
+}
+void rtsyn_play_event(MidiEvent *ev){
+ rtsyn_play_event_time(ev, get_current_calender_time());
}
-void rtsyn_server_reset(void){
-#ifdef USE_WINSYN_TIMER_I
- rtsyn_mutex_lock(timerMUTEX);
-#endif
- 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.
+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->acntl(PM_REQ_FLUSH, NULL);
+
readmidi_read_init();
playmidi_stream_init();
- starttime=get_current_calender_time();
+ 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;
- event_time_offset = 0;
-#ifdef USE_WINSYN_TIMER_I
- rtsyn_mutex_unlock(timerMUTEX);
-#endif
+}
+
+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(&ev);
-#ifdef USE_WINSYN_TIMER_I
- rtsyn_mutex_lock(timerMUTEX);
-#endif
- aq_flush(1);
-#ifdef USE_WINSYN_TIMER_I
- rtsyn_mutex_unlock(timerMUTEX);
-#endif
+ 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();
}
-extern int32 current_sample;
-extern FLOAT_T midi_time_ratio;
-extern int volatile stream_max_compute;
-static void seq_set_time(MidiEvent *ev)
+void rtsyn_seq_set_time(MidiEvent *ev, double event_time)
{
double currenttime, time_div;
- currenttime=get_current_calender_time();
- time_div=currenttime-starttime;
- ev->time=((double) current_sample
- + (play_mode->rate)*time_div+0.5);
- starttime=currenttime;
-
- rtsyn_reachtime=currenttime + (double)(1.0f/TICKTIME_HZ);
+ time_div = event_time - rtsyn_start_time;
+ ev->time = rtsyn_start_sample
+ +(int32) ((double)(play_mode->rate) * time_div+0.5);
}
-#if 0
-static void seq_set_time(MidiEvent *ev)
-{
- double past_time,btime;
- static int shift=0;
-
- if(set_time_first==2){
- starttime=get_current_calender_time()-(double)current_sample/(double)play_mode->rate;
- }
- past_time = (int32)((get_current_calender_time() - starttime)*play_mode->rate);
-// printf("%f,%f\n",(double)past_time,( (double)current_sample-(double)past_time ) );
- if (set_time_first==1){
- shift=(double)past_time-(double)current_sample;
-/// printf("%d\n",shift);
- }
- if (set_time_first>0) set_time_first--;
- event_time_offset=play_mode->rate/TICKTIME_HZ;
- ev->time = past_time;
- if(set_time_first==0 && (past_time-current_sample>stream_max_compute*play_mode->rate/1000)){
- starttime=get_current_calender_time()-(double)(current_sample+shift)/(double)play_mode->rate;
- ev->time=current_sample+shift;
- }
- ev->time += (int32)event_time_offset;
-
-
- rtsyn_reachtime=get_current_calender_time()+ (double)(1.0f/TICKTIME_HZ);
-
-#if 0
- btime = (double)((ev->time-current_sample/midi_time_ratio)/play_mode->rate);
- btime *= 1.01; /* to be sure */
- aq_set_soft_queue(btime, 0.0);
-#endif
-}
-#endif
void rtsyn_play_calculate(){
MidiEvent ev;
-
-#ifndef USE_WINSYN_TIMER_I
- ev.type = ME_NONE;
- seq_set_time(&ev);
- play_event(&ev);
- aq_fill_nonblocking();
-#endif
+ double currenet_event_time, current_time;
+
+ current_time = get_current_calender_time();
+ currenet_event_time = current_time + rtsyn_latency;
+ if( (rtsyn_played == 0) && (currenet_event_time > last_calc_time + 1.0/(double)TICKTIME_HZ) /* event buffer is empty */
+ || (current_time + 1.0/(double)TICKTIME_HZ*2.0 > last_event_time) /* near miss */
+ ){
+ ev.type = ME_NONE;
+ rtsyn_play_event_time(&ev, currenet_event_time);
+ last_calc_time=currenet_event_time;
+ }
+ rtsyn_played = 0;
+
+
if(active_sensing_flag==~0 && (get_current_calender_time() > active_sensing_time+0.5)){
//normaly acitive sensing expiering time is 330ms(>300ms) but this loop is heavy
play_mode->close_output();
play_mode->open_output();
ctl->cmsg( CMSG_ERROR, VERB_NORMAL,"Active Sensing Expired\n");
+ rtsyn_server_reset();
active_sensing_flag=0;
}
}
-int rtsyn_play_one_data (int port, int32 dwParam1){
+int rtsyn_play_one_data (int port, int32 dwParam1, double event_time){
MidiEvent ev;
-
+
+ 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)) {
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");
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:
break;
}
if (ev.type != ME_NONE) {
- rtsyn_play_event(&ev);
+ 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 ){
+void rtsyn_play_one_sysex (uint8 *sysexbuffer, int exlen, double event_time ){
int i,j,chk,ne;
MidiEvent ev;
MidiEvent evm[260];
+
+ if(rtsyn_sample_time_mode != 1){
+ 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( ((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++){
}
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);
- rtsyn_play_event(&ev);
+ 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(&ev);
+ 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(&evm[i]);
+ }
+ 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);
}
}
}
+
}