diff options
author | Chris Robinson <[email protected]> | 2013-11-29 23:57:32 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2013-11-29 23:57:32 -0800 |
commit | e0babed29bbb52df0f853de44fb9670bde3607a4 (patch) | |
tree | 2f5f2a518a86305667b324c2fe90b630464c3ef9 /OpenAL32/alMidi.c | |
parent | be446366fbc61b558d033bfc41f8e093c687e062 (diff) |
Add a workaround for allowing GM2 bank selection with a GM2 On SysEx
Diffstat (limited to 'OpenAL32/alMidi.c')
-rw-r--r-- | OpenAL32/alMidi.c | 35 |
1 files changed, 34 insertions, 1 deletions
diff --git a/OpenAL32/alMidi.c b/OpenAL32/alMidi.c index 5332b2f5..13a17c84 100644 --- a/OpenAL32/alMidi.c +++ b/OpenAL32/alMidi.c @@ -156,6 +156,8 @@ typedef struct FSynth { fluid_settings_t *Settings; fluid_synth_t *Synth; int FontID; + + ALboolean ForceGM2BankSelect; } FSynth; static void FSynth_Construct(FSynth *self, ALCdevice *device); @@ -178,6 +180,7 @@ static void FSynth_Construct(FSynth *self, ALCdevice *device) self->Settings = NULL; self->Synth = NULL; self->FontID = FLUID_FAILED; + self->ForceGM2BankSelect = AL_FALSE; } static void FSynth_Destruct(FSynth *self) @@ -286,7 +289,20 @@ static void FSynth_processQueue(FSynth *self, ALuint64 time) const MidiEvent *evt = &queue->events[queue->pos]; if(evt->event == SYSEX_EVENT) - fluid_synth_sysex(self->Synth, evt->param.sysex.data, evt->param.sysex.size, NULL, NULL, NULL, 0); + { + static const ALbyte gm2_on[] = { 0x7E, 0x7F, 0x09, 0x03 }; + static const ALbyte gm2_off[] = { 0x7E, 0x7F, 0x09, 0x02 }; + int handled = 0; + + fluid_synth_sysex(self->Synth, evt->param.sysex.data, evt->param.sysex.size, NULL, NULL, &handled, 0); + if(!handled && evt->param.sysex.size >= (ALsizei)sizeof(gm2_on)) + { + if(memcmp(evt->param.sysex.data, gm2_on, sizeof(gm2_on)) == 0) + self->ForceGM2BankSelect = AL_TRUE; + else if(memcmp(evt->param.sysex.data, gm2_off, sizeof(gm2_off)) == 0) + self->ForceGM2BankSelect = AL_FALSE; + } + } else switch((evt->event&0xF0)) { case AL_NOTEOFF_SOFT: @@ -299,6 +315,23 @@ static void FSynth_processQueue(FSynth *self, ALuint64 time) break; case AL_CONTROLLERCHANGE_SOFT: + if(self->ForceGM2BankSelect) + { + int chan = (evt->event&0x0F); + if(evt->param.val[0] == 0) + { + if(evt->param.val[1] == 120 && (chan == 9 || chan == 10)) + fluid_synth_set_channel_type(self->Synth, chan, CHANNEL_TYPE_DRUM); + else if(evt->param.val[1] == 121) + fluid_synth_set_channel_type(self->Synth, chan, CHANNEL_TYPE_MELODIC); + break; + } + if(evt->param.val[0] == 32) + { + fluid_synth_bank_select(self->Synth, chan, evt->param.val[1]); + break; + } + } fluid_synth_cc(self->Synth, (evt->event&0x0F), evt->param.val[0], evt->param.val[1]); break; case AL_PROGRAMCHANGE_SOFT: |