summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Alc/ALc.c1
-rw-r--r--OpenAL32/Include/alMain.h2
-rw-r--r--OpenAL32/Include/alMidi.h3
-rw-r--r--OpenAL32/alMidi.c74
4 files changed, 73 insertions, 7 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index dfc39ffb..91c365dc 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -280,6 +280,7 @@ static const ALCfunction alcFunctions[] = {
DECL(alGetSource3i64SOFT),
DECL(alGetSourcei64vSOFT),
+ DECL(alMidiSoundfontSOFT),
DECL(alMidiEventSOFT),
DECL(alMidiPlaySOFT),
DECL(alMidiPauseSOFT),
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;