aboutsummaryrefslogtreecommitdiffstats
path: root/OpenAL32/alMidi.c
diff options
context:
space:
mode:
Diffstat (limited to 'OpenAL32/alMidi.c')
-rw-r--r--OpenAL32/alMidi.c57
1 files changed, 57 insertions, 0 deletions
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;