diff --git a/README.md b/README.md index b4eb02cb..fe250123 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,8 @@ Requirements: CHANGELOG 0.4.3 +* Fixed Visual Studio optimized builds. (Bug #192, function pointer + issue.) * Fixed a thinko in one of the buffer size checks added in v0.4.2. * Fix possible out of bounds reads in sysex commands. (Bug #190). diff --git a/include/internal_midi.h b/include/internal_midi.h index 3316bcd0..db1110a2 100644 --- a/include/internal_midi.h +++ b/include/internal_midi.h @@ -74,7 +74,56 @@ struct _note { struct _mdi; +enum _event_type { + ev_null = -1, + ev_midi_divisions, + ev_note_off, + ev_note_on, + ev_aftertouch, + ev_control_bank_select, + ev_control_data_entry_course, + ev_control_channel_volume, + ev_control_channel_balance, + ev_control_channel_pan, + ev_control_channel_expression, + ev_control_data_entry_fine, + ev_control_channel_hold, + ev_control_data_increment, + ev_control_data_decrement, + ev_control_non_registered_param_fine, + ev_control_non_registered_param_course, + ev_control_registered_param_fine, + ev_control_registered_param_course, + ev_control_channel_sound_off, + ev_control_channel_controllers_off, + ev_control_channel_notes_off, + ev_control_dummy, + ev_patch, + ev_channel_pressure, + ev_pitch, + ev_sysex_roland_drum_track, + ev_sysex_gm_reset, + ev_sysex_roland_reset, + ev_sysex_yamaha_reset, + ev_meta_endoftrack, + ev_meta_tempo, + ev_meta_timesignature, + ev_meta_keysignature, + ev_meta_sequenceno, + ev_meta_channelprefix, + ev_meta_portprefix, + ev_meta_smpteoffset, + ev_meta_text, + ev_meta_copyright, + ev_meta_trackname, + ev_meta_instrumentname, + ev_meta_lyric, + ev_meta_marker, + ev_meta_cuepoint +}; + struct _event { + enum _event_type evtype; void (*do_event)(struct _mdi *mdi, struct _event_data *data); struct _event_data event_data; uint32_t samples_to_next; diff --git a/src/f_midi.c b/src/f_midi.c index e7b696e6..305c82bb 100644 --- a/src/f_midi.c +++ b/src/f_midi.c @@ -492,14 +492,16 @@ _WM_Event2Midi(struct _mdi *mdi, uint8_t **out, uint32_t *outsize) { do { /* TODO Is there a better way? */ - if (event->do_event == _WM_do_midi_divisions) { + switch (event->evtype) { + case ev_midi_divisions: // DEBUG // fprintf(stderr,"Division: %u\r\n",event->event_data.data); divisions = event->event_data.data.value; (*out)[12] = (divisions >> 8) & 0xff; (*out)[13] = divisions & 0xff; samples_per_tick = _WM_GetSamplesPerTick(divisions, tempo); - } else if (event->do_event == _WM_do_note_off) { + break; + case ev_note_off: // DEBUG // fprintf(stderr,"Note Off: %u %.4x\r\n",event->event_data.channel, event->event_data.data); if (running_event != (0x80 | event->event_data.channel)) { @@ -508,7 +510,8 @@ _WM_Event2Midi(struct _mdi *mdi, uint8_t **out, uint32_t *outsize) { } (*out)[out_ofs++] = (event->event_data.data.value >> 8) & 0xff; (*out)[out_ofs++] = event->event_data.data.value & 0xff; - } else if (event->do_event == _WM_do_note_on) { + break; + case ev_note_on: // DEBUG // fprintf(stderr,"Note On: %u %.4x\r\n",event->event_data.channel, event->event_data.data); if (running_event != (0x90 | event->event_data.channel)) { @@ -517,7 +520,8 @@ _WM_Event2Midi(struct _mdi *mdi, uint8_t **out, uint32_t *outsize) { } (*out)[out_ofs++] = (event->event_data.data.value >> 8) & 0xff; (*out)[out_ofs++] = event->event_data.data.value & 0xff; - } else if (event->do_event == _WM_do_aftertouch) { + break; + case ev_aftertouch: // DEBUG // fprintf(stderr,"Aftertouch: %u %.4x\r\n",event->event_data.channel, event->event_data.data); if (running_event != (0xa0 | event->event_data.channel)) { @@ -526,7 +530,8 @@ _WM_Event2Midi(struct _mdi *mdi, uint8_t **out, uint32_t *outsize) { } (*out)[out_ofs++] = (event->event_data.data.value >> 8) & 0xff; (*out)[out_ofs++] = event->event_data.data.value & 0xff; - } else if (event->do_event == _WM_do_control_bank_select) { + break; + case ev_control_bank_select: // DEBUG // fprintf(stderr,"Control Bank Select: %u %.4x\r\n",event->event_data.channel, event->event_data.data); if (running_event != (0xb0 | event->event_data.channel)) { @@ -535,7 +540,8 @@ _WM_Event2Midi(struct _mdi *mdi, uint8_t **out, uint32_t *outsize) { } (*out)[out_ofs++] = 0; (*out)[out_ofs++] = event->event_data.data.value & 0xff; - } else if (event->do_event == _WM_do_control_data_entry_course) { + break; + case ev_control_data_entry_course: // DEBUG // fprintf(stderr,"Control Data Entry Course: %u %.4x\r\n",event->event_data.channel, event->event_data.data); if (running_event != (0xb0 | event->event_data.channel)) { @@ -544,7 +550,8 @@ _WM_Event2Midi(struct _mdi *mdi, uint8_t **out, uint32_t *outsize) { } (*out)[out_ofs++] = 6; (*out)[out_ofs++] = event->event_data.data.value & 0xff; - } else if (event->do_event == _WM_do_control_channel_volume) { + break; + case ev_control_channel_volume: // DEBUG // fprintf(stderr,"Control Channel Volume: %u %.4x\r\n",event->event_data.channel, event->event_data.data); if (running_event != (0xb0 | event->event_data.channel)) { @@ -553,7 +560,8 @@ _WM_Event2Midi(struct _mdi *mdi, uint8_t **out, uint32_t *outsize) { } (*out)[out_ofs++] = 7; (*out)[out_ofs++] = event->event_data.data.value & 0xff; - } else if (event->do_event == _WM_do_control_channel_balance) { + break; + case ev_control_channel_balance: // DEBUG // fprintf(stderr,"Control Channel Balance: %u %.4x\r\n",event->event_data.channel, event->event_data.data); if (running_event != (0xb0 | event->event_data.channel)) { @@ -562,7 +570,8 @@ _WM_Event2Midi(struct _mdi *mdi, uint8_t **out, uint32_t *outsize) { } (*out)[out_ofs++] = 8; (*out)[out_ofs++] = event->event_data.data.value & 0xff; - } else if (event->do_event == _WM_do_control_channel_pan) { + break; + case ev_control_channel_pan: // DEBUG // fprintf(stderr,"Control Channel Pan: %u %.4x\r\n",event->event_data.channel, event->event_data.data); if (running_event != (0xb0 | event->event_data.channel)) { @@ -571,7 +580,8 @@ _WM_Event2Midi(struct _mdi *mdi, uint8_t **out, uint32_t *outsize) { } (*out)[out_ofs++] = 10; (*out)[out_ofs++] = event->event_data.data.value & 0xff; - } else if (event->do_event == _WM_do_control_channel_expression) { + break; + case ev_control_channel_expression: // DEBUG // fprintf(stderr,"Control Channel Expression: %u %.4x\r\n",event->event_data.channel, event->event_data.data); if (running_event != (0xb0 | event->event_data.channel)) { @@ -580,7 +590,8 @@ _WM_Event2Midi(struct _mdi *mdi, uint8_t **out, uint32_t *outsize) { } (*out)[out_ofs++] = 11; (*out)[out_ofs++] = event->event_data.data.value & 0xff; - } else if (event->do_event == _WM_do_control_data_entry_fine) { + break; + case ev_control_data_entry_fine: // DEBUG // fprintf(stderr,"Control Data Entry Fine: %u %.4x\r\n",event->event_data.channel, event->event_data.data); if (running_event != (0xb0 | event->event_data.channel)) { @@ -589,7 +600,8 @@ _WM_Event2Midi(struct _mdi *mdi, uint8_t **out, uint32_t *outsize) { } (*out)[out_ofs++] = 38; (*out)[out_ofs++] = event->event_data.data.value & 0xff; - } else if (event->do_event == _WM_do_control_channel_hold) { + break; + case ev_control_channel_hold: // DEBUG // fprintf(stderr,"Control Channel Hold: %u %.4x\r\n",event->event_data.channel, event->event_data.data); if (running_event != (0xb0 | event->event_data.channel)) { @@ -598,7 +610,8 @@ _WM_Event2Midi(struct _mdi *mdi, uint8_t **out, uint32_t *outsize) { } (*out)[out_ofs++] = 64; (*out)[out_ofs++] = event->event_data.data.value & 0xff; - } else if (event->do_event == _WM_do_control_data_increment) { + break; + case ev_control_data_increment: // DEBUG // fprintf(stderr,"Control Data Increment: %u %.4x\r\n",event->event_data.channel, event->event_data.data); if (running_event != (0xb0 | event->event_data.channel)) { @@ -607,7 +620,8 @@ _WM_Event2Midi(struct _mdi *mdi, uint8_t **out, uint32_t *outsize) { } (*out)[out_ofs++] = 96; (*out)[out_ofs++] = event->event_data.data.value & 0xff; - } else if (event->do_event == _WM_do_control_data_decrement) { + break; + case ev_control_data_decrement: // DEBUG //fprintf(stderr,"Control Data Decrement: %u %.4x\r\n",event->event_data.channel, event->event_data.data); if (running_event != (0xb0 | event->event_data.channel)) { @@ -616,7 +630,8 @@ _WM_Event2Midi(struct _mdi *mdi, uint8_t **out, uint32_t *outsize) { } (*out)[out_ofs++] = 97; (*out)[out_ofs++] = event->event_data.data.value & 0xff; - } else if (event->do_event == _WM_do_control_non_registered_param_fine) { + break; + case ev_control_non_registered_param_fine: // DEBUG // fprintf(stderr,"Control Non Registered Param: %u %.4x\r\n",event->event_data.channel, event->event_data.data); if (running_event != (0xb0 | event->event_data.channel)) { @@ -625,7 +640,8 @@ _WM_Event2Midi(struct _mdi *mdi, uint8_t **out, uint32_t *outsize) { } (*out)[out_ofs++] = 98; (*out)[out_ofs++] = event->event_data.data.value & 0x7f; - } else if (event->do_event == _WM_do_control_non_registered_param_course) { + break; + case ev_control_non_registered_param_course: // DEBUG // fprintf(stderr,"Control Non Registered Param: %u %.4x\r\n",event->event_data.channel, event->event_data.data); if (running_event != (0xb0 | event->event_data.channel)) { @@ -634,7 +650,8 @@ _WM_Event2Midi(struct _mdi *mdi, uint8_t **out, uint32_t *outsize) { } (*out)[out_ofs++] = 99; (*out)[out_ofs++] = (event->event_data.data.value >> 7) & 0x7f; - } else if (event->do_event == _WM_do_control_registered_param_fine) { + break; + case ev_control_registered_param_fine: // DEBUG // fprintf(stderr,"Control Registered Param Fine: %u %.4x\r\n",event->event_data.channel, event->event_data.data); if (running_event != (0xb0 | event->event_data.channel)) { @@ -643,7 +660,8 @@ _WM_Event2Midi(struct _mdi *mdi, uint8_t **out, uint32_t *outsize) { } (*out)[out_ofs++] = 100; (*out)[out_ofs++] = event->event_data.data.value & 0x7f; - } else if (event->do_event == _WM_do_control_registered_param_course) { + break; + case ev_control_registered_param_course: // DEBUG // fprintf(stderr,"Control Registered Param Course: %u %.4x\r\n",event->event_data.channel, event->event_data.data); if (running_event != (0xb0 | event->event_data.channel)) { @@ -652,7 +670,8 @@ _WM_Event2Midi(struct _mdi *mdi, uint8_t **out, uint32_t *outsize) { } (*out)[out_ofs++] = 101; (*out)[out_ofs++] = (event->event_data.data.value >> 7) & 0x7f; - } else if (event->do_event == _WM_do_control_channel_sound_off) { + break; + case ev_control_channel_sound_off: // DEBUG // fprintf(stderr,"Control Channel Sound Off: %u %.4x\r\n",event->event_data.channel, event->event_data.data); if (running_event != (0xb0 | event->event_data.channel)) { @@ -661,7 +680,8 @@ _WM_Event2Midi(struct _mdi *mdi, uint8_t **out, uint32_t *outsize) { } (*out)[out_ofs++] = 120; (*out)[out_ofs++] = event->event_data.data.value & 0xff; - } else if (event->do_event == _WM_do_control_channel_controllers_off) { + break; + case ev_control_channel_controllers_off: // DEBUG // fprintf(stderr,"Control Channel Controllers Off: %u %.4x\r\n",event->event_data.channel, event->event_data.data); if (running_event != (0xb0 | event->event_data.channel)) { @@ -670,7 +690,8 @@ _WM_Event2Midi(struct _mdi *mdi, uint8_t **out, uint32_t *outsize) { } (*out)[out_ofs++] = 121; (*out)[out_ofs++] = event->event_data.data.value & 0xff; - } else if (event->do_event == _WM_do_control_channel_notes_off) { + break; + case ev_control_channel_notes_off: // DEBUG // fprintf(stderr,"Control Channel Notes Off: %u %.4x\r\n",event->event_data.channel, event->event_data.data); if (running_event != (0xb0 | event->event_data.channel)) { @@ -679,7 +700,8 @@ _WM_Event2Midi(struct _mdi *mdi, uint8_t **out, uint32_t *outsize) { } (*out)[out_ofs++] = 123; (*out)[out_ofs++] = event->event_data.data.value & 0xff; - } else if (event->do_event == _WM_do_control_dummy) { + break; + case ev_control_dummy: // DEBUG // fprintf(stderr,"Control Dummy Event: %u %.4x\r\n",event->event_data.channel, event->event_data.data); if (running_event != (0xb0 | event->event_data.channel)) { @@ -688,7 +710,8 @@ _WM_Event2Midi(struct _mdi *mdi, uint8_t **out, uint32_t *outsize) { } (*out)[out_ofs++] = (event->event_data.data.value >> 8) & 0xff; (*out)[out_ofs++] = event->event_data.data.value & 0xff; - } else if (event->do_event == _WM_do_patch) { + break; + case ev_patch: // DEBUG // fprintf(stderr,"Patch: %u %.4x\r\n",event->event_data.channel, event->event_data.data); if (running_event != (0xc0 | event->event_data.channel)) { @@ -696,7 +719,8 @@ _WM_Event2Midi(struct _mdi *mdi, uint8_t **out, uint32_t *outsize) { running_event = (*out)[out_ofs - 1]; } (*out)[out_ofs++] = event->event_data.data.value & 0xff; - } else if (event->do_event == _WM_do_channel_pressure) { + break; + case ev_channel_pressure: // DEBUG // fprintf(stderr,"Channel Pressure: %u %.4x\r\n",event->event_data.channel, event->event_data.data); if (running_event != (0xd0 | event->event_data.channel)) { @@ -704,7 +728,8 @@ _WM_Event2Midi(struct _mdi *mdi, uint8_t **out, uint32_t *outsize) { running_event = (*out)[out_ofs - 1]; } (*out)[out_ofs++] = event->event_data.data.value & 0xff; - } else if (event->do_event == _WM_do_pitch) { + break; + case ev_pitch: // DEBUG // fprintf(stderr,"Pitch: %u %.4x\r\n",event->event_data.channel, event->event_data.data); if (running_event != (0xe0 | event->event_data.channel)) { @@ -713,7 +738,8 @@ _WM_Event2Midi(struct _mdi *mdi, uint8_t **out, uint32_t *outsize) { } (*out)[out_ofs++] = event->event_data.data.value & 0x7f; (*out)[out_ofs++] = (event->event_data.data.value >> 7) & 0x7f; - } else if (event->do_event == _WM_do_sysex_roland_drum_track) { + break; + case ev_sysex_roland_drum_track: { // DEBUG // fprintf(stderr,"Sysex Roland Drum Track: %u %.4x\r\n",event->event_data.channel, event->event_data.data); uint8_t foo[] = {0xf0, 0x09, 0x41, 0x10, 0x42, 0x12, 0x40, 0x00, 0x15, 0x00, 0xf7}; @@ -728,28 +754,32 @@ _WM_Event2Midi(struct _mdi *mdi, uint8_t **out, uint32_t *outsize) { memcpy(&((*out)[out_ofs]),foo,11); out_ofs += 11; running_event = 0; - } else if (event->do_event == _WM_do_sysex_gm_reset) { + } break; + case ev_sysex_gm_reset: { // DEBUG // fprintf(stderr,"Sysex GM Reset\r\n"); uint8_t foo[] = {0xf0, 0x05, 0x7e, 0x7f, 0x09, 0x01, 0xf7}; memcpy(&((*out)[out_ofs]),foo,7); out_ofs += 7; running_event = 0; - } else if (event->do_event == _WM_do_sysex_roland_reset) { + } break; + case ev_sysex_roland_reset: { // DEBUG // fprintf(stderr,"Sysex Roland Reset\r\n"); uint8_t foo[] = {0xf0, 0x0a, 0x41, 0x10, 0x42, 0x12, 0x40, 0x00, 0x7f, 0x00, 0x41, 0xf7}; memcpy(&((*out)[out_ofs]),foo,12); out_ofs += 12; running_event = 0; - } else if (event->do_event == _WM_do_sysex_yamaha_reset) { + } break; + case ev_sysex_yamaha_reset: { // DEBUG // fprintf(stderr,"Sysex Yamaha Reset\r\n"); uint8_t foo[] = {0xf0, 0x08, 0x43, 0x10, 0x4c, 0x00, 0x00, 0x7e, 0x00, 0xf7}; memcpy(&((*out)[out_ofs]),foo,10); out_ofs += 10; running_event = 0; - } else if (event->do_event == _WM_do_meta_endoftrack) { + } break; + case ev_meta_endoftrack: // DEBUG // fprintf(stderr,"End Of Track\r\n"); if ((!(_WM_MixerOptions & WM_MO_SAVEASTYPE0)) && (mdi->is_type2)) { @@ -763,7 +793,7 @@ _WM_Event2Midi(struct _mdi *mdi, uint8_t **out, uint32_t *outsize) { (*out)[track_start - 2] = (track_size >> 8) & 0xff; (*out)[track_start - 1] = track_size & 0xff; - if (event[1].do_event != NULL) { + if (event[1].evtype != ev_null) { (*out)[out_ofs++] = 'M'; (*out)[out_ofs++] = 'T'; (*out)[out_ofs++] = 'r'; @@ -779,7 +809,7 @@ _WM_Event2Midi(struct _mdi *mdi, uint8_t **out, uint32_t *outsize) { } } goto NEXT_EVENT; - } else if (event->do_event == _WM_do_meta_tempo) { + case ev_meta_tempo: // DEBUG // fprintf(stderr,"Tempo: %u\r\n",event->event_data.data); tempo = event->event_data.data.value & 0xffffff; @@ -795,7 +825,8 @@ _WM_Event2Midi(struct _mdi *mdi, uint8_t **out, uint32_t *outsize) { (*out)[out_ofs++] = (tempo & 0xff0000) >> 16; (*out)[out_ofs++] = (tempo & 0xff00) >> 8; (*out)[out_ofs++] = (tempo & 0xff); - } else if (event->do_event == _WM_do_meta_timesignature) { + break; + case ev_meta_timesignature: // DEBUG // fprintf(stderr,"Time Signature: %x\r\n",event->event_data.data); (*out)[out_ofs++] = 0xff; @@ -805,7 +836,8 @@ _WM_Event2Midi(struct _mdi *mdi, uint8_t **out, uint32_t *outsize) { (*out)[out_ofs++] = (event->event_data.data.value & 0xff0000) >> 16; (*out)[out_ofs++] = (event->event_data.data.value & 0xff00) >> 8; (*out)[out_ofs++] = (event->event_data.data.value & 0xff); - } else if (event->do_event == _WM_do_meta_keysignature) { + break; + case ev_meta_keysignature: // DEBUG // fprintf(stderr,"Key Signature: %x\r\n",event->event_data.data); (*out)[out_ofs++] = 0xff; @@ -813,7 +845,8 @@ _WM_Event2Midi(struct _mdi *mdi, uint8_t **out, uint32_t *outsize) { (*out)[out_ofs++] = 0x02; (*out)[out_ofs++] = (event->event_data.data.value & 0xff00) >> 8; (*out)[out_ofs++] = (event->event_data.data.value & 0xff); - } else if (event->do_event == _WM_do_meta_sequenceno) { + break; + case ev_meta_sequenceno: // DEBUG // fprintf(stderr,"Sequence Number: %x\r\n",event->event_data.data); (*out)[out_ofs++] = 0xff; @@ -821,21 +854,24 @@ _WM_Event2Midi(struct _mdi *mdi, uint8_t **out, uint32_t *outsize) { (*out)[out_ofs++] = 0x02; (*out)[out_ofs++] = (event->event_data.data.value & 0xff00) >> 8; (*out)[out_ofs++] = (event->event_data.data.value & 0xff); - } else if (event->do_event == _WM_do_meta_channelprefix) { + break; + case ev_meta_channelprefix: // DEBUG // fprintf(stderr,"Channel Prefix: %x\r\n",event->event_data.data); (*out)[out_ofs++] = 0xff; (*out)[out_ofs++] = 0x20; (*out)[out_ofs++] = 0x01; (*out)[out_ofs++] = (event->event_data.data.value & 0xff); - } else if (event->do_event == _WM_do_meta_portprefix) { + break; + case ev_meta_portprefix: // DEBUG // fprintf(stderr,"Port Prefix: %x\r\n",event->event_data.data); (*out)[out_ofs++] = 0xff; (*out)[out_ofs++] = 0x21; (*out)[out_ofs++] = 0x01; (*out)[out_ofs++] = (event->event_data.data.value & 0xff); - } else if (event->do_event == _WM_do_meta_smpteoffset) { + break; + case ev_meta_smpteoffset: // DEBUG // fprintf(stderr,"SMPTE Offset: %x\r\n",event->event_data.data); (*out)[out_ofs++] = 0xff; @@ -849,44 +885,45 @@ _WM_Event2Midi(struct _mdi *mdi, uint8_t **out, uint32_t *outsize) { (*out)[out_ofs++] = (event->event_data.data.value & 0xff0000) >> 16; (*out)[out_ofs++] = (event->event_data.data.value & 0xff00) >> 8; (*out)[out_ofs++] = (event->event_data.data.value & 0xff); + break; - } else if (event->do_event == _WM_do_meta_text) { + case ev_meta_text: (*out)[out_ofs++] = 0xff; (*out)[out_ofs++] = 0x01; goto _WRITE_TEXT; - } else if (event->do_event == _WM_do_meta_copyright) { + case ev_meta_copyright: (*out)[out_ofs++] = 0xff; (*out)[out_ofs++] = 0x02; goto _WRITE_TEXT; - } else if (event->do_event == _WM_do_meta_trackname) { + case ev_meta_trackname: (*out)[out_ofs++] = 0xff; (*out)[out_ofs++] = 0x03; goto _WRITE_TEXT; - } else if (event->do_event == _WM_do_meta_instrumentname) { + case ev_meta_instrumentname: (*out)[out_ofs++] = 0xff; (*out)[out_ofs++] = 0x04; goto _WRITE_TEXT; - } else if (event->do_event == _WM_do_meta_lyric) { + case ev_meta_lyric: (*out)[out_ofs++] = 0xff; (*out)[out_ofs++] = 0x05; goto _WRITE_TEXT; - } else if (event->do_event == _WM_do_meta_marker) { + case ev_meta_marker: (*out)[out_ofs++] = 0xff; (*out)[out_ofs++] = 0x06; goto _WRITE_TEXT; - } else if (event->do_event == _WM_do_meta_cuepoint) { + case ev_meta_cuepoint: (*out)[out_ofs++] = 0xff; (*out)[out_ofs++] = 0x07; @@ -904,8 +941,9 @@ _WM_Event2Midi(struct _mdi *mdi, uint8_t **out, uint32_t *outsize) { memcpy(&(*out)[out_ofs], event->event_data.data.string, value); out_ofs += value; + break; - } else { + default: // DEBUG // fprintf(stderr,"Unknown Event %.2x %.4x\n",event->event_data.channel, event->event_data.data.value); event++; @@ -929,7 +967,7 @@ _WM_Event2Midi(struct _mdi *mdi, uint8_t **out, uint32_t *outsize) { (*out)[out_ofs++] = (value & 0x7f); NEXT_EVENT: event++; - } while (event->do_event != NULL); + } while (event->evtype != ev_null); if ((_WM_MixerOptions & WM_MO_SAVEASTYPE0) || (!mdi->is_type2)) { /* Write end of track marker */ diff --git a/src/internal_midi.c b/src/internal_midi.c index 1b78ca0b..b456f5b7 100644 --- a/src/internal_midi.c +++ b/src/internal_midi.c @@ -1416,6 +1416,7 @@ void _WM_ResetToStart(struct _mdi *mdi) { /* Ensure last event is NULL */ _WM_CheckEventMemoryPool(mdi); + mdi->events[mdi->event_count].evtype = ev_null; mdi->events[mdi->event_count].do_event = NULL; mdi->events[mdi->event_count].event_data.channel = 0; mdi->events[mdi->event_count].event_data.data.value = 0; @@ -1424,7 +1425,7 @@ void _WM_ResetToStart(struct _mdi *mdi) { if (_WM_MixerOptions & WM_MO_STRIPSILENCE) { event = mdi->events; /* Scan for first note on removing any samples as we go */ - if (event->do_event != *_WM_do_note_on) { + if (event->evtype != ev_note_on) { do { if (event->samples_to_next != 0) { mdi->extra_info.approx_total_samples -= event->samples_to_next; @@ -1432,18 +1433,18 @@ void _WM_ResetToStart(struct _mdi *mdi) { } event++; if (event == NULL) break; - } while (event->do_event != *_WM_do_note_on); + } while (event->evtype != ev_note_on); } /* Reverse scan for last note off removing any samples as we go */ event = &mdi->events[mdi->event_count - 1]; - if (event->do_event != *_WM_do_note_off) { + if (event->evtype != ev_note_off) { do { mdi->extra_info.approx_total_samples -= event->samples_to_next; event->samples_to_next = 0; if (event == mdi->events) break; /* just to be safe */ event--; - } while (event->do_event != *_WM_do_note_off); + } while (event->evtype != ev_note_off); } mdi->extra_info.approx_total_samples -= event->samples_to_next; event->samples_to_next = 0; @@ -1453,6 +1454,7 @@ void _WM_ResetToStart(struct _mdi *mdi) { int _WM_midi_setup_divisions(struct _mdi *mdi, uint32_t divisions) { MIDI_EVENT_DEBUG(__FUNCTION__,0,0); _WM_CheckEventMemoryPool(mdi); + mdi->events[mdi->event_count].evtype = ev_midi_divisions; mdi->events[mdi->event_count].do_event = _WM_do_midi_divisions; mdi->events[mdi->event_count].event_data.channel = 0; mdi->events[mdi->event_count].event_data.data.value = divisions; @@ -1466,6 +1468,7 @@ int _WM_midi_setup_noteoff(struct _mdi *mdi, uint8_t channel, MIDI_EVENT_DEBUG(__FUNCTION__,channel, note); _WM_CheckEventMemoryPool(mdi); note &= 0x7f; /* silently bound note to 0..127 (github bug #180) */ + mdi->events[mdi->event_count].evtype = ev_note_off; mdi->events[mdi->event_count].do_event = _WM_do_note_off; mdi->events[mdi->event_count].event_data.channel = channel; mdi->events[mdi->event_count].event_data.data.value = (note << 8) | velocity; @@ -1479,6 +1482,7 @@ static int midi_setup_noteon(struct _mdi *mdi, uint8_t channel, MIDI_EVENT_DEBUG(__FUNCTION__,channel, note); _WM_CheckEventMemoryPool(mdi); note &= 0x7f; /* silently bound note to 0..127 (github bug #180) */ + mdi->events[mdi->event_count].evtype = ev_note_on; mdi->events[mdi->event_count].do_event = _WM_do_note_on; mdi->events[mdi->event_count].event_data.channel = channel; mdi->events[mdi->event_count].event_data.data.value = (note << 8) | velocity; @@ -1495,6 +1499,7 @@ static int midi_setup_aftertouch(struct _mdi *mdi, uint8_t channel, MIDI_EVENT_DEBUG(__FUNCTION__,channel, note); _WM_CheckEventMemoryPool(mdi); note &= 0x7f; /* silently bound note to 0..127 (github bug #180) */ + mdi->events[mdi->event_count].evtype = ev_aftertouch; mdi->events[mdi->event_count].do_event = _WM_do_aftertouch; mdi->events[mdi->event_count].event_data.channel = channel; mdi->events[mdi->event_count].event_data.data.value = (note << 8) | pressure; @@ -1505,7 +1510,9 @@ static int midi_setup_aftertouch(struct _mdi *mdi, uint8_t channel, static int midi_setup_control(struct _mdi *mdi, uint8_t channel, uint8_t controller, uint8_t setting) { - void (*tmp_event)(struct _mdi *mdi, struct _event_data *data) = NULL; + void (*tmp_event)(struct _mdi *mdi, struct _event_data *data); + enum _event_type ev; + MIDI_EVENT_DEBUG(__FUNCTION__,channel, controller); switch (controller) { @@ -1517,67 +1524,86 @@ static int midi_setup_control(struct _mdi *mdi, uint8_t channel, ********************************************************************** */ case 0: + ev = ev_control_bank_select; tmp_event = _WM_do_control_bank_select; mdi->channel[channel].bank = setting; break; case 6: + ev = ev_control_data_entry_course; tmp_event = _WM_do_control_data_entry_course; break; case 7: + ev = ev_control_channel_volume; tmp_event = _WM_do_control_channel_volume; mdi->channel[channel].volume = setting; break; case 8: + ev = ev_control_channel_balance; tmp_event = _WM_do_control_channel_balance; break; case 10: + ev = ev_control_channel_pan; tmp_event = _WM_do_control_channel_pan; break; case 11: + ev = ev_control_channel_expression; tmp_event = _WM_do_control_channel_expression; break; case 38: + ev = ev_control_data_entry_fine; tmp_event = _WM_do_control_data_entry_fine; break; case 64: + ev = ev_control_channel_hold; tmp_event = _WM_do_control_channel_hold; break; case 96: + ev = ev_control_data_increment; tmp_event = _WM_do_control_data_increment; break; case 97: + ev = ev_control_data_decrement; tmp_event = _WM_do_control_data_decrement; break; case 98: + ev = ev_control_non_registered_param_fine; tmp_event = _WM_do_control_non_registered_param_fine; break; case 99: + ev = ev_control_non_registered_param_course; tmp_event = _WM_do_control_non_registered_param_course; break; case 100: + ev = ev_control_registered_param_fine; tmp_event = _WM_do_control_registered_param_fine; break; case 101: + ev = ev_control_registered_param_course; tmp_event = _WM_do_control_registered_param_course; break; case 120: + ev = ev_control_channel_sound_off; tmp_event = _WM_do_control_channel_sound_off; break; case 121: + ev = ev_control_channel_controllers_off; tmp_event = _WM_do_control_channel_controllers_off; break; case 123: + ev = ev_control_channel_notes_off; tmp_event = _WM_do_control_channel_notes_off; break; default: + ev = ev_control_dummy; tmp_event = _WM_do_control_dummy; break; } _WM_CheckEventMemoryPool(mdi); + mdi->events[mdi->event_count].evtype = ev; mdi->events[mdi->event_count].do_event = tmp_event; mdi->events[mdi->event_count].event_data.channel = channel; - if (tmp_event != *_WM_do_control_dummy) { + if (ev != ev_control_dummy) { mdi->events[mdi->event_count].event_data.data.value = setting; } else { mdi->events[mdi->event_count].event_data.data.value = (controller << 8) | setting; @@ -1590,6 +1616,7 @@ static int midi_setup_control(struct _mdi *mdi, uint8_t channel, static int midi_setup_patch(struct _mdi *mdi, uint8_t channel, uint8_t patch) { MIDI_EVENT_DEBUG(__FUNCTION__,channel, patch); _WM_CheckEventMemoryPool(mdi); + mdi->events[mdi->event_count].evtype = ev_patch; mdi->events[mdi->event_count].do_event = _WM_do_patch; mdi->events[mdi->event_count].event_data.channel = channel; mdi->events[mdi->event_count].event_data.data.value = patch; @@ -1610,6 +1637,7 @@ static int midi_setup_channel_pressure(struct _mdi *mdi, uint8_t channel, uint8_t pressure) { MIDI_EVENT_DEBUG(__FUNCTION__,channel, pressure); _WM_CheckEventMemoryPool(mdi); + mdi->events[mdi->event_count].evtype = ev_channel_pressure; mdi->events[mdi->event_count].do_event = _WM_do_channel_pressure; mdi->events[mdi->event_count].event_data.channel = channel; mdi->events[mdi->event_count].event_data.data.value = pressure; @@ -1621,6 +1649,7 @@ static int midi_setup_channel_pressure(struct _mdi *mdi, uint8_t channel, static int midi_setup_pitch(struct _mdi *mdi, uint8_t channel, uint16_t pitch) { MIDI_EVENT_DEBUG(__FUNCTION__,channel, pitch); _WM_CheckEventMemoryPool(mdi); + mdi->events[mdi->event_count].evtype = ev_pitch; mdi->events[mdi->event_count].do_event = _WM_do_pitch; mdi->events[mdi->event_count].event_data.channel = channel; mdi->events[mdi->event_count].event_data.data.value = pitch; @@ -1633,6 +1662,7 @@ static int midi_setup_sysex_roland_drum_track(struct _mdi *mdi, uint8_t channel, uint16_t setting) { MIDI_EVENT_DEBUG(__FUNCTION__,channel, setting); _WM_CheckEventMemoryPool(mdi); + mdi->events[mdi->event_count].evtype = ev_sysex_roland_drum_track; mdi->events[mdi->event_count].do_event = _WM_do_sysex_roland_drum_track; mdi->events[mdi->event_count].event_data.channel = channel; mdi->events[mdi->event_count].event_data.data.value = setting; @@ -1651,6 +1681,7 @@ static int midi_setup_sysex_gm_reset(struct _mdi *mdi) { MIDI_EVENT_DEBUG(__FUNCTION__,0,0); _WM_CheckEventMemoryPool(mdi); + mdi->events[mdi->event_count].evtype = ev_sysex_roland_reset; mdi->events[mdi->event_count].do_event = _WM_do_sysex_roland_reset; mdi->events[mdi->event_count].event_data.channel = 0; mdi->events[mdi->event_count].event_data.data.value = 0; @@ -1662,6 +1693,7 @@ static int midi_setup_sysex_gm_reset(struct _mdi *mdi) { static int midi_setup_sysex_roland_reset(struct _mdi *mdi) { MIDI_EVENT_DEBUG(__FUNCTION__,0,0); _WM_CheckEventMemoryPool(mdi); + mdi->events[mdi->event_count].evtype = ev_sysex_roland_reset; mdi->events[mdi->event_count].do_event = _WM_do_sysex_roland_reset; mdi->events[mdi->event_count].event_data.channel = 0; mdi->events[mdi->event_count].event_data.data.value = 0; @@ -1673,6 +1705,7 @@ static int midi_setup_sysex_roland_reset(struct _mdi *mdi) { static int midi_setup_sysex_yamaha_reset(struct _mdi *mdi) { MIDI_EVENT_DEBUG(__FUNCTION__,0,0); _WM_CheckEventMemoryPool(mdi); + mdi->events[mdi->event_count].evtype = ev_sysex_roland_reset; mdi->events[mdi->event_count].do_event = _WM_do_sysex_roland_reset; mdi->events[mdi->event_count].event_data.channel = 0; mdi->events[mdi->event_count].event_data.data.value = 0; @@ -1684,6 +1717,7 @@ static int midi_setup_sysex_yamaha_reset(struct _mdi *mdi) { int _WM_midi_setup_endoftrack(struct _mdi *mdi) { MIDI_EVENT_DEBUG(__FUNCTION__,0,0); _WM_CheckEventMemoryPool(mdi); + mdi->events[mdi->event_count].evtype = ev_meta_endoftrack; mdi->events[mdi->event_count].do_event = _WM_do_meta_endoftrack; mdi->events[mdi->event_count].event_data.channel = 0; mdi->events[mdi->event_count].event_data.data.value = 0; @@ -1695,6 +1729,7 @@ int _WM_midi_setup_endoftrack(struct _mdi *mdi) { int _WM_midi_setup_tempo(struct _mdi *mdi, uint32_t setting) { MIDI_EVENT_DEBUG(__FUNCTION__,0,setting); _WM_CheckEventMemoryPool(mdi); + mdi->events[mdi->event_count].evtype = ev_meta_tempo; mdi->events[mdi->event_count].do_event = _WM_do_meta_tempo; mdi->events[mdi->event_count].event_data.channel = 0; mdi->events[mdi->event_count].event_data.data.value = setting; @@ -1706,6 +1741,7 @@ int _WM_midi_setup_tempo(struct _mdi *mdi, uint32_t setting) { static int midi_setup_timesignature(struct _mdi *mdi, uint32_t setting) { MIDI_EVENT_DEBUG(__FUNCTION__,0, setting); _WM_CheckEventMemoryPool(mdi); + mdi->events[mdi->event_count].evtype = ev_meta_timesignature; mdi->events[mdi->event_count].do_event = _WM_do_meta_timesignature; mdi->events[mdi->event_count].event_data.channel = 0; mdi->events[mdi->event_count].event_data.data.value = setting; @@ -1717,6 +1753,7 @@ static int midi_setup_timesignature(struct _mdi *mdi, uint32_t setting) { static int midi_setup_keysignature(struct _mdi *mdi, uint32_t setting) { MIDI_EVENT_DEBUG(__FUNCTION__,0, setting); _WM_CheckEventMemoryPool(mdi); + mdi->events[mdi->event_count].evtype = ev_meta_keysignature; mdi->events[mdi->event_count].do_event = _WM_do_meta_keysignature; mdi->events[mdi->event_count].event_data.channel = 0; mdi->events[mdi->event_count].event_data.data.value = setting; @@ -1728,6 +1765,7 @@ static int midi_setup_keysignature(struct _mdi *mdi, uint32_t setting) { static int midi_setup_sequenceno(struct _mdi *mdi, uint32_t setting) { MIDI_EVENT_DEBUG(__FUNCTION__,0, setting); _WM_CheckEventMemoryPool(mdi); + mdi->events[mdi->event_count].evtype = ev_meta_sequenceno; mdi->events[mdi->event_count].do_event = _WM_do_meta_sequenceno; mdi->events[mdi->event_count].event_data.channel = 0; mdi->events[mdi->event_count].event_data.data.value = setting; @@ -1739,6 +1777,7 @@ static int midi_setup_sequenceno(struct _mdi *mdi, uint32_t setting) { static int midi_setup_channelprefix(struct _mdi *mdi, uint32_t setting) { MIDI_EVENT_DEBUG(__FUNCTION__,0, setting); _WM_CheckEventMemoryPool(mdi); + mdi->events[mdi->event_count].evtype = ev_meta_channelprefix; mdi->events[mdi->event_count].do_event = _WM_do_meta_channelprefix; mdi->events[mdi->event_count].event_data.channel = 0; mdi->events[mdi->event_count].event_data.data.value = setting; @@ -1750,6 +1789,7 @@ static int midi_setup_channelprefix(struct _mdi *mdi, uint32_t setting) { static int midi_setup_portprefix(struct _mdi *mdi, uint32_t setting) { MIDI_EVENT_DEBUG(__FUNCTION__,0, setting); _WM_CheckEventMemoryPool(mdi); + mdi->events[mdi->event_count].evtype = ev_meta_portprefix; mdi->events[mdi->event_count].do_event = _WM_do_meta_portprefix; mdi->events[mdi->event_count].event_data.channel = 0; mdi->events[mdi->event_count].event_data.data.value = setting; @@ -1761,6 +1801,7 @@ static int midi_setup_portprefix(struct _mdi *mdi, uint32_t setting) { static int midi_setup_smpteoffset(struct _mdi *mdi, uint32_t setting) { MIDI_EVENT_DEBUG(__FUNCTION__,0, setting); _WM_CheckEventMemoryPool(mdi); + mdi->events[mdi->event_count].evtype = ev_meta_smpteoffset; mdi->events[mdi->event_count].do_event = _WM_do_meta_smpteoffset; mdi->events[mdi->event_count].event_data.channel = 0; mdi->events[mdi->event_count].event_data.data.value = setting; @@ -1788,6 +1829,7 @@ static int midi_setup_text(struct _mdi *mdi, char * text) { MIDI_EVENT_SDEBUG(__FUNCTION__,0, text); strip_text(text); _WM_CheckEventMemoryPool(mdi); + mdi->events[mdi->event_count].evtype = ev_meta_text; mdi->events[mdi->event_count].do_event = _WM_do_meta_text; mdi->events[mdi->event_count].event_data.channel = 0; mdi->events[mdi->event_count].event_data.data.string = text; @@ -1800,6 +1842,7 @@ static int midi_setup_copyright(struct _mdi *mdi, char * text) { MIDI_EVENT_SDEBUG(__FUNCTION__,0, text); strip_text(text); _WM_CheckEventMemoryPool(mdi); + mdi->events[mdi->event_count].evtype = ev_meta_copyright; mdi->events[mdi->event_count].do_event = _WM_do_meta_copyright; mdi->events[mdi->event_count].event_data.channel = 0; mdi->events[mdi->event_count].event_data.data.string = text; @@ -1812,6 +1855,7 @@ static int midi_setup_trackname(struct _mdi *mdi, char * text) { MIDI_EVENT_SDEBUG(__FUNCTION__,0, text); strip_text(text); _WM_CheckEventMemoryPool(mdi); + mdi->events[mdi->event_count].evtype = ev_meta_trackname; mdi->events[mdi->event_count].do_event = _WM_do_meta_trackname; mdi->events[mdi->event_count].event_data.channel = 0; mdi->events[mdi->event_count].event_data.data.string = text; @@ -1824,6 +1868,7 @@ static int midi_setup_instrumentname(struct _mdi *mdi, char * text) { MIDI_EVENT_SDEBUG(__FUNCTION__,0, text); strip_text(text); _WM_CheckEventMemoryPool(mdi); + mdi->events[mdi->event_count].evtype = ev_meta_instrumentname; mdi->events[mdi->event_count].do_event = _WM_do_meta_instrumentname; mdi->events[mdi->event_count].event_data.channel = 0; mdi->events[mdi->event_count].event_data.data.string = text; @@ -1836,6 +1881,7 @@ static int midi_setup_lyric(struct _mdi *mdi, char * text) { MIDI_EVENT_SDEBUG(__FUNCTION__,0, text); strip_text(text); _WM_CheckEventMemoryPool(mdi); + mdi->events[mdi->event_count].evtype = ev_meta_lyric; mdi->events[mdi->event_count].do_event = _WM_do_meta_lyric; mdi->events[mdi->event_count].event_data.channel = 0; mdi->events[mdi->event_count].event_data.data.string = text; @@ -1848,6 +1894,7 @@ static int midi_setup_marker(struct _mdi *mdi, char * text) { MIDI_EVENT_SDEBUG(__FUNCTION__,0, text); strip_text(text); _WM_CheckEventMemoryPool(mdi); + mdi->events[mdi->event_count].evtype = ev_meta_marker; mdi->events[mdi->event_count].do_event = _WM_do_meta_marker; mdi->events[mdi->event_count].event_data.channel = 0; mdi->events[mdi->event_count].event_data.data.string = text; @@ -1860,6 +1907,7 @@ static int midi_setup_cuepoint(struct _mdi *mdi, char * text) { MIDI_EVENT_SDEBUG(__FUNCTION__,0, text); strip_text(text); _WM_CheckEventMemoryPool(mdi); + mdi->events[mdi->event_count].evtype = ev_meta_cuepoint; mdi->events[mdi->event_count].do_event = _WM_do_meta_cuepoint; mdi->events[mdi->event_count].event_data.channel = 0; mdi->events[mdi->event_count].event_data.data.string = text; @@ -1930,20 +1978,18 @@ void _WM_freeMDI(struct _mdi *mdi) { if (mdi->event_count != 0) { for (i = 0; i < mdi->event_count; i++) { /* Free up the string event storage */ - if (mdi->events[i].do_event == _WM_do_meta_text) { - free(mdi->events[i].event_data.data.string); - } else if (mdi->events[i].do_event == _WM_do_meta_copyright) { - free(mdi->events[i].event_data.data.string); - } else if (mdi->events[i].do_event == _WM_do_meta_trackname) { - free(mdi->events[i].event_data.data.string); - } else if (mdi->events[i].do_event == _WM_do_meta_instrumentname) { - free(mdi->events[i].event_data.data.string); - } else if (mdi->events[i].do_event == _WM_do_meta_lyric) { - free(mdi->events[i].event_data.data.string); - } else if (mdi->events[i].do_event == _WM_do_meta_marker) { - free(mdi->events[i].event_data.data.string); - } else if (mdi->events[i].do_event == _WM_do_meta_cuepoint) { + switch (mdi->events[i].evtype) { + case ev_meta_text: + case ev_meta_copyright: + case ev_meta_trackname: + case ev_meta_instrumentname: + case ev_meta_lyric: + case ev_meta_marker: + case ev_meta_cuepoint: free(mdi->events[i].event_data.data.string); + break; + default: + break; } } } diff --git a/src/wildmidi_lib.c b/src/wildmidi_lib.c index 19ea0231..15540cdd 100644 --- a/src/wildmidi_lib.c +++ b/src/wildmidi_lib.c @@ -856,7 +856,7 @@ static int WM_GetOutput_Linear(midi * handle, int8_t *buffer, uint32_t size) { if (__builtin_expect((!mdi->samples_to_mix), 0)) { while ((!mdi->samples_to_mix) && (event->do_event)) { event->do_event(mdi, &event->event_data); - if ((mdi->extra_info.mixer_options & WM_MO_LOOP) && (event[0].do_event == _WM_do_meta_endoftrack)) { + if ((mdi->extra_info.mixer_options & WM_MO_LOOP) && (event[0].evtype == ev_meta_endoftrack)) { _WM_ResetToStart(mdi); event = mdi->current_event; } else { @@ -1174,7 +1174,7 @@ static int WM_GetOutput_Gauss(midi * handle, int8_t *buffer, uint32_t size) { if (__builtin_expect((!mdi->samples_to_mix), 0)) { while ((!mdi->samples_to_mix) && (event->do_event)) { event->do_event(mdi, &event->event_data); - if ((mdi->extra_info.mixer_options & WM_MO_LOOP) && (event[0].do_event == _WM_do_meta_endoftrack)) { + if ((mdi->extra_info.mixer_options & WM_MO_LOOP) && (event[0].evtype == ev_meta_endoftrack)) { _WM_ResetToStart(mdi); event = mdi->current_event; } else { @@ -1859,7 +1859,7 @@ WM_SYMBOL int WildMidi_SongSeek (midi * handle, int8_t nextsong) { */ uint8_t eof_cnt = 1; while (event != mdi->events) { - if (event[-1].do_event == _WM_do_meta_endoftrack) { + if (event[-1].evtype == ev_meta_endoftrack) { if (eof_cnt == 0) { break; } @@ -1873,10 +1873,10 @@ WM_SYMBOL int WildMidi_SongSeek (midi * handle, int8_t nextsong) { } else if (nextsong == 1) { /* goto start of next song */ - while (event->do_event != NULL) { - if (event->do_event == _WM_do_meta_endoftrack) { + while (event->evtype != ev_null) { + if (event->evtype == ev_meta_endoftrack) { event++; - if (event->do_event == NULL) { + if (event->evtype == ev_null) { event--; goto START_THIS_SONG; } else { @@ -1893,7 +1893,7 @@ WM_SYMBOL int WildMidi_SongSeek (midi * handle, int8_t nextsong) { /* goto start of this song */ /* first find the offset */ while (event != mdi->events) { - if (event[-1].do_event == _WM_do_meta_endoftrack) { + if (event[-1].evtype == ev_meta_endoftrack) { break; } event--;