From 2633fbfc4b79f3fca88f200a264aefbd892ae207 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sat, 30 Nov 2013 20:37:37 -0800 Subject: Add a method to check if a file is a soundfont --- OpenAL32/Include/alMain.h | 2 + OpenAL32/Include/alMidi.h | 5 +++ OpenAL32/alMidi.c | 99 ++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 91 insertions(+), 15 deletions(-) (limited to 'OpenAL32') diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index 4888246a..304672f5 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -37,6 +37,7 @@ #define AL_PROGRAMCHANGE_SOFT 0x00C0 #define AL_CHANNELPRESSURE_SOFT 0x00D0 #define AL_PITCHBEND_SOFT 0x00E0 +typedef ALboolean (AL_APIENTRY*LPALISSOUNDFONTSOFT)(const char *filename); 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); @@ -46,6 +47,7 @@ typedef void (AL_APIENTRY*LPALMIDISTOPSOFT)(void); typedef ALint64SOFT (AL_APIENTRY*LPALGETINTEGER64SOFT)(ALenum pname); typedef void (AL_APIENTRY*LPALGETINTEGER64VSOFT)(ALenum pname, ALint64SOFT *values); #ifdef AL_ALEXT_PROTOTYPES +AL_API ALboolean AL_APIENTRY alIsSoundfontSOFT(const char *filename); 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); diff --git a/OpenAL32/Include/alMidi.h b/OpenAL32/Include/alMidi.h index 6aeffedc..51bdeb07 100644 --- a/OpenAL32/Include/alMidi.h +++ b/OpenAL32/Include/alMidi.h @@ -37,9 +37,12 @@ ALuint64 MidiSynth_getTime(const MidiSynth *self); struct MidiSynthVtable { void (*const Destruct)(MidiSynth *self); + ALboolean (*const isSoundfont)(MidiSynth *self, const char *filename); ALenum (*const loadSoundfont)(MidiSynth *self, const char *filename); + void (*const setState)(MidiSynth *self, ALenum state); void (*const reset)(MidiSynth *self); + void (*const update)(MidiSynth *self, ALCdevice *device); void (*const process)(MidiSynth *self, ALuint samples, ALfloat (*restrict DryBuffer)[BUFFERSIZE]); @@ -48,6 +51,7 @@ struct MidiSynthVtable { #define DEFINE_MIDISYNTH_VTABLE(T) \ DECLARE_THUNK(T, MidiSynth, void, Destruct) \ +DECLARE_THUNK1(T, MidiSynth, ALboolean, isSoundfont, const char*) \ DECLARE_THUNK1(T, MidiSynth, ALenum, loadSoundfont, const char*) \ DECLARE_THUNK1(T, MidiSynth, void, setState, ALenum) \ DECLARE_THUNK(T, MidiSynth, void, reset) \ @@ -58,6 +62,7 @@ DECLARE_THUNK(T, MidiSynth, void, Delete) \ static const struct MidiSynthVtable T##_MidiSynth_vtable = { \ T##_MidiSynth_Destruct, \ \ + T##_MidiSynth_isSoundfont, \ T##_MidiSynth_loadSoundfont, \ T##_MidiSynth_setState, \ T##_MidiSynth_reset, \ diff --git a/OpenAL32/alMidi.c b/OpenAL32/alMidi.c index 13a17c84..8a783e50 100644 --- a/OpenAL32/alMidi.c +++ b/OpenAL32/alMidi.c @@ -1,6 +1,7 @@ #include "config.h" +#include #include #include #include @@ -163,6 +164,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 ALboolean FSynth_isSoundfont(FSynth *self, const char *filename); static ALenum FSynth_loadSoundfont(FSynth *self, const char *filename); static void FSynth_setState(FSynth *self, ALenum state); static void FSynth_reset(FSynth *self); @@ -224,6 +226,22 @@ static ALboolean FSynth_init(FSynth *self, ALCdevice *device) return AL_TRUE; } + +static ALboolean FSynth_isSoundfont(FSynth* UNUSED(self), const char *filename) +{ + if(!filename || !filename[0]) + filename = GetConfigValue("midi", "soundfont", ""); + if(!filename[0]) + { + WARN("No default soundfont found\n"); + return AL_FALSE; + } + + if(!fluid_is_soundfont(filename)) + return AL_FALSE; + return AL_TRUE; +} + static ALenum FSynth_loadSoundfont(FSynth *self, const char *filename) { int fontid; @@ -250,6 +268,7 @@ static ALenum FSynth_loadSoundfont(FSynth *self, const char *filename) return AL_NO_ERROR; } + static void FSynth_setState(FSynth *self, ALenum state) { if(state == AL_PLAYING && self->FontID == FLUID_FAILED) @@ -419,6 +438,7 @@ typedef struct DSynth { static void DSynth_Construct(DSynth *self, ALCdevice *device); static DECLARE_FORWARD(DSynth, MidiSynth, void, Destruct) +static ALboolean DSynth_isSoundfont(DSynth *self, const char *filename); static ALenum DSynth_loadSoundfont(DSynth *self, const char *filename); static DECLARE_FORWARD1(DSynth, MidiSynth, void, setState, ALenum) static DECLARE_FORWARD(DSynth, MidiSynth, void, reset) @@ -435,8 +455,42 @@ static void DSynth_Construct(DSynth *self, ALCdevice *device) } -static ALenum DSynth_loadSoundfont(DSynth* UNUSED(self), const char* UNUSED(filename)) +static ALboolean DSynth_isSoundfont(DSynth* UNUSED(self), const char *filename) +{ + char buf[12]; + FILE *f; + + if(!filename || !filename[0]) + filename = GetConfigValue("midi", "soundfont", ""); + if(!filename[0]) + { + WARN("No default soundfont found\n"); + return AL_FALSE; + } + + f = fopen(filename, "rb"); + if(!f) return AL_FALSE; + + if(fread(buf, 1, sizeof(buf), f) != sizeof(buf)) + { + fclose(f); + return AL_FALSE; + } + + if(memcmp(buf, "RIFF", 4) != 0 || memcmp(buf+8, "sfbk", 4) != 0) + { + fclose(f); + return AL_FALSE; + } + + fclose(f); + return AL_TRUE; +} + +static ALenum DSynth_loadSoundfont(DSynth *self, const char *filename) { + if(!DSynth_isSoundfont(self, filename)) + return AL_INVALID_VALUE; return AL_NO_ERROR; } @@ -529,31 +583,46 @@ MidiSynth *SynthCreate(ALCdevice *device) } +AL_API ALboolean AL_APIENTRY alIsSoundfontSOFT(const char *filename) +{ + ALCdevice *device; + ALCcontext *context; + ALboolean ret; + + context = GetContextRef(); + if(!context) return AL_FALSE; + + device = context->Device; + ret = V(device->Synth,isSoundfont)(filename); + + ALCcontext_DecRef(context); + + return ret; +} + AL_API void AL_APIENTRY alMidiSoundfontSOFT(const char *filename) { + ALCdevice *device; ALCcontext *context; + MidiSynth *synth; ALenum err; context = GetContextRef(); if(!context) return; - if(!(filename && filename[0])) - alSetError(context, AL_INVALID_VALUE); + device = context->Device; + synth = device->Synth; + + WriteLock(&synth->Lock); + if(synth->State == AL_PLAYING || synth->State == AL_PAUSED) + alSetError(context, AL_INVALID_OPERATION); else { - ALCdevice *device = context->Device; - MidiSynth *synth = device->Synth; - WriteLock(&synth->Lock); - if(synth->State == AL_PLAYING || synth->State == AL_PAUSED) - alSetError(context, AL_INVALID_OPERATION); - else - { - err = V(synth,loadSoundfont)(filename); - if(err != AL_NO_ERROR) - alSetError(context, err); - } - WriteUnlock(&synth->Lock); + err = V(synth,loadSoundfont)(filename); + if(err != AL_NO_ERROR) + alSetError(context, err); } + WriteUnlock(&synth->Lock); ALCcontext_DecRef(context); } -- cgit v1.2.3