aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2013-11-29 05:37:45 -0800
committerChris Robinson <[email protected]>2013-11-29 05:37:45 -0800
commitbe446366fbc61b558d033bfc41f8e093c687e062 (patch)
treea943b08598b07bcf298f98db7d042c091d1941b4
parentea1d7d56d3e343fa1b0246096eca88d1e804a556 (diff)
Add a method to specifying MIDI SysEx messages
-rw-r--r--Alc/ALc.c1
-rw-r--r--OpenAL32/Include/alMain.h2
-rw-r--r--OpenAL32/alMidi.c57
3 files changed, 60 insertions, 0 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index 38da53c7..eb1e83b2 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -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;