aboutsummaryrefslogtreecommitdiffstats
path: root/OpenAL32
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2013-11-30 20:37:37 -0800
committerChris Robinson <[email protected]>2013-11-30 20:37:37 -0800
commit2633fbfc4b79f3fca88f200a264aefbd892ae207 (patch)
tree698db58cc716abe45f1663201428badd38224952 /OpenAL32
parente0babed29bbb52df0f853de44fb9670bde3607a4 (diff)
Add a method to check if a file is a soundfont
Diffstat (limited to 'OpenAL32')
-rw-r--r--OpenAL32/Include/alMain.h2
-rw-r--r--OpenAL32/Include/alMidi.h5
-rw-r--r--OpenAL32/alMidi.c99
3 files changed, 91 insertions, 15 deletions
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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
@@ -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);
}