diff options
author | Chris Robinson <[email protected]> | 2013-11-28 03:38:17 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2013-11-28 03:38:17 -0800 |
commit | bb0207d784ee2d5ebbdb6d7c26a4a626e62dbbed (patch) | |
tree | 54f03776b22009a630f78d041a9d1fe5d1cf2e35 /OpenAL32 | |
parent | a3c76c32740248a54827696b87841c6381ee8550 (diff) |
Add a method to load a soundfont
Diffstat (limited to 'OpenAL32')
-rw-r--r-- | OpenAL32/Include/alMain.h | 2 | ||||
-rw-r--r-- | OpenAL32/Include/alMidi.h | 3 | ||||
-rw-r--r-- | OpenAL32/alMidi.c | 74 |
3 files changed, 72 insertions, 7 deletions
diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index de98b85c..4715dc99 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -37,12 +37,14 @@ #define AL_PROGRAMCHANGE_SOFT 0x00C0 #define AL_CHANNELPRESSURE_SOFT 0x00D0 #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*LPALMIDIPLAYSOFT)(void); typedef void (AL_APIENTRY*LPALMIDIPAUSESOFT)(void); typedef ALint64SOFT (AL_APIENTRY*LPALGETINTEGER64SOFT)(ALenum pname); typedef void (AL_APIENTRY*LPALGETINTEGER64VSOFT)(ALenum pname, ALint64SOFT *values); #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 alMidiPlaySOFT(void); AL_API void AL_APIENTRY alMidiPauseSOFT(void); diff --git a/OpenAL32/Include/alMidi.h b/OpenAL32/Include/alMidi.h index 963adf3f..f2b29df0 100644 --- a/OpenAL32/Include/alMidi.h +++ b/OpenAL32/Include/alMidi.h @@ -32,6 +32,7 @@ ALuint64 MidiSynth_getTime(const MidiSynth *self); struct MidiSynthVtable { void (*const Destruct)(MidiSynth *self); + ALenum (*const loadSoundfont)(MidiSynth *self, const char *filename); void (*const setState)(MidiSynth *self, ALenum state); void (*const update)(MidiSynth *self, ALCdevice *device); void (*const process)(MidiSynth *self, ALuint samples, ALfloat (*restrict DryBuffer)[BUFFERSIZE]); @@ -41,6 +42,7 @@ struct MidiSynthVtable { #define DEFINE_MIDISYNTH_VTABLE(T) \ DECLARE_THUNK(T, MidiSynth, void, Destruct) \ +DECLARE_THUNK1(T, MidiSynth, ALenum, loadSoundfont, const char*) \ DECLARE_THUNK1(T, MidiSynth, void, setState, ALenum) \ DECLARE_THUNK1(T, MidiSynth, void, update, ALCdevice*) \ DECLARE_THUNK2(T, MidiSynth, void, process, ALuint, ALfloatBUFFERSIZE*restrict) \ @@ -49,6 +51,7 @@ DECLARE_THUNK(T, MidiSynth, void, Delete) \ static const struct MidiSynthVtable T##_MidiSynth_vtable = { \ T##_MidiSynth_Destruct, \ \ + T##_MidiSynth_loadSoundfont, \ T##_MidiSynth_setState, \ T##_MidiSynth_update, \ T##_MidiSynth_process, \ diff --git a/OpenAL32/alMidi.c b/OpenAL32/alMidi.c index 16f7fbf4..0cbe11b2 100644 --- a/OpenAL32/alMidi.c +++ b/OpenAL32/alMidi.c @@ -120,6 +120,7 @@ typedef struct FSynth { static void FSynth_Construct(FSynth *self, ALCdevice *device); static void FSynth_Destruct(FSynth *self); static ALboolean FSynth_init(FSynth *self, ALCdevice *device); +static ALenum FSynth_loadSoundfont(FSynth *self, const char *filename); static void FSynth_setState(FSynth *self, ALenum state); static void FSynth_update(FSynth *self, ALCdevice *device); static void FSynth_process(FSynth *self, ALuint SamplesToDo, ALfloat (*restrict DryBuffer)[BUFFERSIZE]); @@ -181,6 +182,35 @@ static ALboolean FSynth_init(FSynth *self, ALCdevice *device) return AL_TRUE; } +static ALenum FSynth_loadSoundfont(FSynth *self, const char *filename) +{ + ALenum state; + int fontid; + + WriteLock(&self->Lock); + state = STATIC_CAST(MidiSynth, self)->State; + if(state == AL_PLAYING || state == AL_PAUSED) + { + WriteUnlock(&self->Lock); + return AL_INVALID_OPERATION; + } + + fontid = fluid_synth_sfload(self->Synth, filename, 1); + if(fontid == FLUID_FAILED) + { + WriteUnlock(&self->Lock); + ERR("Failed to load soundfont '%s'\n", filename); + return AL_INVALID_VALUE; + } + + if(self->FontID != FLUID_FAILED) + fluid_synth_sfunload(self->Synth, self->FontID, 1); + self->FontID = fontid; + WriteUnlock(&self->Lock); + + return AL_NO_ERROR; +} + static void FSynth_setState(FSynth *self, ALenum state) { WriteLock(&self->Lock); @@ -188,14 +218,15 @@ static void FSynth_setState(FSynth *self, ALenum state) { if(self->FontID == FLUID_FAILED) { - int fontid = FLUID_FAILED; - const char *fname = getenv("FLUID_SOUNDFONT"); - if(fname && fname[0]) - fontid = fluid_synth_sfload(self->Synth, fname, 1); - if(fontid != FLUID_FAILED) - self->FontID = fontid; + const char *filename = getenv("FLUID_SOUNDFONT"); + if(!filename || !filename[0]) + ERR("No default soundfont found!\n"); else - ERR("Failed to load soundfont '%s'\n", fname?fname:"(nil)"); + { + self->FontID = fluid_synth_sfload(self->Synth, filename, 1); + if(self->FontID == FLUID_FAILED) + ERR("Failed to load soundfont '%s'\n", filename); + } } } MidiSynth_setState(STATIC_CAST(MidiSynth, self), state); @@ -322,6 +353,7 @@ typedef struct DSynth { static void DSynth_Construct(DSynth *self, ALCdevice *device); static DECLARE_FORWARD(DSynth, MidiSynth, void, Destruct) +static ALenum DSynth_loadSoundfont(DSynth *self, const char *filename); static DECLARE_FORWARD1(DSynth, MidiSynth, void, setState, ALenum) static DECLARE_FORWARD1(DSynth, MidiSynth, void, update, ALCdevice*) static void DSynth_process(DSynth *self, ALuint SamplesToDo, ALfloat (*restrict DryBuffer)[BUFFERSIZE]); @@ -336,6 +368,12 @@ static void DSynth_Construct(DSynth *self, ALCdevice *device) } +static ALenum DSynth_loadSoundfont(DSynth* UNUSED(self), const char* UNUSED(filename)) +{ + return AL_NO_ERROR; +} + + static void DSynth_processQueue(DSynth *self, ALuint64 time) { EvtQueue *queue = &STATIC_CAST(MidiSynth, self)->EventQueue; @@ -428,6 +466,28 @@ MidiSynth *SynthCreate(ALCdevice *device) } +AL_API void AL_APIENTRY alMidiSoundfontSOFT(const char *filename) +{ + ALCdevice *device; + ALCcontext *context; + ALenum err; + + context = GetContextRef(); + if(!context) return; + + device = context->Device; + if(!(filename && filename[0])) + alSetError(context, AL_INVALID_VALUE); + else + { + err = V(device->Synth,loadSoundfont)(filename); + if(err != AL_NO_ERROR) + alSetError(context, err); + } + + ALCcontext_DecRef(context); +} + AL_API void AL_APIENTRY alMidiEventSOFT(ALuint64SOFT time, ALenum event, ALsizei channel, ALsizei param1, ALsizei param2) { ALCdevice *device; |