Add a method to specifying MIDI SysEx messages

This commit is contained in:
Chris Robinson
2013-11-29 05:37:45 -08:00
parent ea1d7d56d3
commit be446366fb
3 changed files with 60 additions and 0 deletions
+1
View File
@@ -282,6 +282,7 @@ static const ALCfunction alcFunctions[] = {
DECL(alMidiSoundfontSOFT),
DECL(alMidiEventSOFT),
DECL(alMidiSysExSOFT),
DECL(alMidiPlaySOFT),
DECL(alMidiPauseSOFT),
DECL(alMidiStopSOFT),
+2
View File
@@ -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);
+57
View File
@@ -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;