diff options
-rw-r--r-- | Alc/ALc.c | 1 | ||||
-rw-r--r-- | OpenAL32/Include/alMain.h | 2 | ||||
-rw-r--r-- | OpenAL32/alMidi.c | 57 |
3 files changed, 60 insertions, 0 deletions
@@ -282,6 +282,7 @@ static const ALCfunction alcFunctions[] = { DECL(alMidiSoundfontSOFT), DECL(alMidiEventSOFT), + DECL(alMidiSysExSOFT), DECL(alMidiPlaySOFT), DECL(alMidiPauseSOFT), DECL(alMidiStopSOFT), diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index 6a2f8a9a..4888246a 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -39,6 +39,7 @@ #define AL_PITCHBEND_SOFT 0x00E0 typedef void (AL_APIENTRY*LPALMIDISOUNDFONTSOFT)(const char *filename); typedef void (AL_APIENTRY*LPALMIDIEVENTSOFT)(ALuint64SOFT time, ALenum event, ALsizei channel, ALsizei param1, ALsizei param2); +typedef void (AL_APIENTRY*LPALMIDISYSEXSOFT)(ALuint64SOFT time, const ALbyte *data, ALsizei size); typedef void (AL_APIENTRY*LPALMIDIPLAYSOFT)(void); typedef void (AL_APIENTRY*LPALMIDIPAUSESOFT)(void); typedef void (AL_APIENTRY*LPALMIDISTOPSOFT)(void); @@ -47,6 +48,7 @@ typedef void (AL_APIENTRY*LPALGETINTEGER64VSOFT)(ALenum pname, ALint64SOFT *valu #ifdef AL_ALEXT_PROTOTYPES AL_API void AL_APIENTRY alMidiSoundfontSOFT(const char *filename); AL_API void AL_APIENTRY alMidiEventSOFT(ALuint64SOFT time, ALenum event, ALsizei channel, ALsizei param1, ALsizei param2); +AL_API void AL_APIENTRY alMidiSysExSOFT(ALuint64SOFT time, const ALbyte *data, ALsizei size); AL_API void AL_APIENTRY alMidiPlaySOFT(void); AL_API void AL_APIENTRY alMidiPauseSOFT(void); AL_API void AL_APIENTRY alMidiStopSOFT(void); diff --git a/OpenAL32/alMidi.c b/OpenAL32/alMidi.c index 073b78df..5332b2f5 100644 --- a/OpenAL32/alMidi.c +++ b/OpenAL32/alMidi.c @@ -93,6 +93,7 @@ static void MidiSynth_setSampleRate(MidiSynth *self, ALdouble srate) self->SamplesPerTick = sampletickrate; } + static ALenum MidiSynth_insertEvent(MidiSynth *self, ALuint64 time, ALuint event, ALsizei param1, ALsizei param2) { MidiEvent entry; @@ -117,6 +118,33 @@ static ALenum MidiSynth_insertEvent(MidiSynth *self, ALuint64 time, ALuint event return AL_NO_ERROR; } +static ALenum MidiSynth_insertSysExEvent(MidiSynth *self, ALuint64 time, const ALbyte *data, ALsizei size) +{ + MidiEvent entry; + ALenum err; + + entry.time = time; + entry.event = SYSEX_EVENT; + entry.param.sysex.size = size; + entry.param.sysex.data = malloc(size); + if(!entry.param.sysex.data) + return AL_OUT_OF_MEMORY; + memcpy(entry.param.sysex.data, data, size); + + err = InsertEvtQueue(&self->EventQueue, &entry); + if(err != AL_NO_ERROR) return err; + + if(entry.time < self->NextEvtTime) + { + self->NextEvtTime = entry.time; + + self->SamplesToNext = (self->NextEvtTime - self->LastEvtTime) * self->SamplesPerTick; + self->SamplesToNext -= self->SamplesSinceLast; + } + + return AL_NO_ERROR; +} + #ifdef HAVE_FLUIDSYNTH @@ -529,6 +557,35 @@ done: ALCcontext_DecRef(context); } +AL_API void AL_APIENTRY alMidiSysExSOFT(ALuint64SOFT time, const ALbyte *data, ALsizei size) +{ + ALCdevice *device; + ALCcontext *context; + ALenum err; + ALsizei i; + + context = GetContextRef(); + if(!context) return; + + if(!data || size < 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + for(i = 0;i < size;i++) + { + if((data[i]&0x80)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + } + + device = context->Device; + ALCdevice_Lock(device); + err = MidiSynth_insertSysExEvent(device->Synth, time, data, size); + ALCdevice_Unlock(device); + if(err != AL_NO_ERROR) + alSetError(context, err); + +done: + ALCcontext_DecRef(context); +} + AL_API void AL_APIENTRY alMidiPlaySOFT(void) { ALCcontext *context; |