diff options
author | Chris Robinson <[email protected]> | 2013-11-29 04:56:33 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2013-11-29 04:56:33 -0800 |
commit | ea1d7d56d3e343fa1b0246096eca88d1e804a556 (patch) | |
tree | 36d1f8031380469e3746c79c32bb94ad013ea85a | |
parent | 82d4e69da1d5b443d943a55a3c97d4e7cbd811ba (diff) |
Add infrastructure for handling SysEx MIDI events
-rw-r--r-- | Alc/evtqueue.h | 8 | ||||
-rw-r--r-- | OpenAL32/alMidi.c | 58 |
2 files changed, 44 insertions, 22 deletions
diff --git a/Alc/evtqueue.h b/Alc/evtqueue.h index ab41c427..95702d79 100644 --- a/Alc/evtqueue.h +++ b/Alc/evtqueue.h @@ -8,7 +8,13 @@ typedef struct MidiEvent { ALuint64 time; ALuint event; - ALuint param[2]; + union { + ALuint val[2]; + struct { + ALvoid *data; + ALsizei size; + } sysex; + } param; } MidiEvent; typedef struct EvtQueue { diff --git a/OpenAL32/alMidi.c b/OpenAL32/alMidi.c index c3e7a804..073b78df 100644 --- a/OpenAL32/alMidi.c +++ b/OpenAL32/alMidi.c @@ -16,6 +16,9 @@ /* Microsecond resolution */ #define TICKS_PER_SECOND (1000000) +#define SYSEX_EVENT (0xF0) + + static void MidiSynth_Construct(MidiSynth *self, ALCdevice *device); static void MidiSynth_Destruct(MidiSynth *self); static inline void MidiSynth_setState(MidiSynth *self, ALenum state); @@ -92,9 +95,14 @@ static void MidiSynth_setSampleRate(MidiSynth *self, ALdouble srate) static ALenum MidiSynth_insertEvent(MidiSynth *self, ALuint64 time, ALuint event, ALsizei param1, ALsizei param2) { - MidiEvent entry = { time, event, { param1, param2 } }; + MidiEvent entry; ALenum err; + entry.time = time; + entry.event = event; + entry.param.val[0] = param1; + entry.param.val[1] = param2; + err = InsertEvtQueue(&self->EventQueue, &entry); if(err != AL_NO_ERROR) return err; @@ -249,42 +257,38 @@ static void FSynth_processQueue(FSynth *self, ALuint64 time) { const MidiEvent *evt = &queue->events[queue->pos]; - switch((evt->event&0xF0)) + if(evt->event == SYSEX_EVENT) + fluid_synth_sysex(self->Synth, evt->param.sysex.data, evt->param.sysex.size, NULL, NULL, NULL, 0); + else switch((evt->event&0xF0)) { case AL_NOTEOFF_SOFT: - fluid_synth_noteoff(self->Synth, (evt->event&0x0F), evt->param[0]); + fluid_synth_noteoff(self->Synth, (evt->event&0x0F), evt->param.val[0]); break; case AL_NOTEON_SOFT: - fluid_synth_noteon(self->Synth, (evt->event&0x0F), evt->param[0], evt->param[1]); + fluid_synth_noteon(self->Synth, (evt->event&0x0F), evt->param.val[0], evt->param.val[1]); break; case AL_AFTERTOUCH_SOFT: break; case AL_CONTROLLERCHANGE_SOFT: - fluid_synth_cc(self->Synth, (evt->event&0x0F), evt->param[0], evt->param[1]); + fluid_synth_cc(self->Synth, (evt->event&0x0F), evt->param.val[0], evt->param.val[1]); break; case AL_PROGRAMCHANGE_SOFT: - fluid_synth_program_change(self->Synth, (evt->event&0x0F), evt->param[0]); + fluid_synth_program_change(self->Synth, (evt->event&0x0F), evt->param.val[0]); break; case AL_CHANNELPRESSURE_SOFT: - fluid_synth_channel_pressure(self->Synth, (evt->event&0x0F), evt->param[0]); + fluid_synth_channel_pressure(self->Synth, (evt->event&0x0F), evt->param.val[0]); break; case AL_PITCHBEND_SOFT: - fluid_synth_pitch_bend(self->Synth, (evt->event&0x0F), (evt->param[0]&0x7F) | - ((evt->param[1]&0x7F)<<7)); + fluid_synth_pitch_bend(self->Synth, (evt->event&0x0F), (evt->param.val[0]&0x7F) | + ((evt->param.val[1]&0x7F)<<7)); break; } queue->pos++; } - - if(queue->pos == queue->size) - { - queue->pos = 0; - queue->size = 0; - } } static void FSynth_process(FSynth *self, ALuint SamplesToDo, ALfloat (*restrict DryBuffer)[BUFFERSIZE]) @@ -382,12 +386,6 @@ static void DSynth_processQueue(DSynth *self, ALuint64 time) while(queue->pos < queue->size && queue->events[queue->pos].time <= time) queue->pos++; - - if(queue->pos == queue->size) - { - queue->pos = 0; - queue->size = 0; - } } static void DSynth_process(DSynth *self, ALuint SamplesToDo, ALfloatBUFFERSIZE*restrict UNUSED(DryBuffer)) @@ -597,6 +595,16 @@ void InitEvtQueue(EvtQueue *queue) void ResetEvtQueue(EvtQueue *queue) { + ALsizei i; + for(i = 0;i < queue->size;i++) + { + if(queue->events[i].event == SYSEX_EVENT) + { + free(queue->events[i].param.sysex.data); + queue->events[i].param.sysex.data = NULL; + } + } + free(queue->events); queue->events = NULL; queue->maxsize = 0; @@ -614,6 +622,14 @@ ALenum InsertEvtQueue(EvtQueue *queue, const MidiEvent *evt) { /* Queue has some stale entries, remove them to make space for more * events. */ + for(pos = 0;pos < queue->pos;pos++) + { + if(queue->events[pos].event == SYSEX_EVENT) + { + free(queue->events[pos].param.sysex.data); + queue->events[pos].param.sysex.data = NULL; + } + } memmove(&queue->events[0], &queue->events[queue->pos], (queue->size-queue->pos)*sizeof(queue->events[0])); queue->size -= queue->pos; |