diff options
-rw-r--r-- | Alc/ALc.c | 1 | ||||
-rw-r--r-- | Alc/midi/base.c | 43 | ||||
-rw-r--r-- | Alc/midi/base.h | 7 | ||||
-rw-r--r-- | Alc/midi/dummy.c | 1 | ||||
-rw-r--r-- | Alc/midi/fluidsynth.c | 1 | ||||
-rw-r--r-- | OpenAL32/Include/alMain.h | 16 | ||||
-rw-r--r-- | OpenAL32/alMidi.c | 32 | ||||
-rw-r--r-- | OpenAL32/alState.c | 52 |
8 files changed, 145 insertions, 8 deletions
@@ -304,6 +304,7 @@ static const ALCfunction alcFunctions[] = { DECL(alFontsoundivSOFT), DECL(alGetFontsoundivSOFT), DECL(alMidiSoundfontSOFT), + DECL(alMidiSoundfontsSOFT), DECL(alMidiEventSOFT), DECL(alMidiSysExSOFT), DECL(alMidiPlaySOFT), diff --git a/Alc/midi/base.c b/Alc/midi/base.c index 6449d7fc..8b498680 100644 --- a/Alc/midi/base.c +++ b/Alc/midi/base.c @@ -124,6 +124,9 @@ void MidiSynth_Construct(MidiSynth *self, ALCdevice *device) RWLockInit(&self->Lock); + self->Soundfonts = NULL; + self->NumSoundfonts = 0; + self->Gain = 1.0f; self->State = AL_INITIAL; @@ -137,6 +140,14 @@ void MidiSynth_Construct(MidiSynth *self, ALCdevice *device) void MidiSynth_Destruct(MidiSynth *self) { + ALsizei i; + + for(i = 0;i < self->NumSoundfonts;i++) + DecrementRef(&self->Soundfonts[i]->ref); + free(self->Soundfonts); + self->Soundfonts = NULL; + self->NumSoundfonts = 0; + ResetEvtQueue(&self->EventQueue); } @@ -152,6 +163,38 @@ const char *MidiSynth_getFontName(const MidiSynth* UNUSED(self), const char *fil return filename; } +ALenum MidiSynth_selectSoundfonts(MidiSynth *self, ALCdevice *device, ALsizei count, const ALuint *ids) +{ + ALsoundfont **sfonts; + ALsizei i; + + if(self->State != AL_INITIAL && self->State != AL_STOPPED) + return AL_INVALID_OPERATION; + + sfonts = calloc(1, count * sizeof(sfonts[0])); + if(!sfonts) return AL_OUT_OF_MEMORY; + + for(i = 0;i < count;i++) + { + if(!(sfonts[i]=LookupSfont(device, ids[i]))) + { + free(sfonts); + return AL_INVALID_VALUE; + } + } + + for(i = 0;i < count;i++) + IncrementRef(&sfonts[i]->ref); + sfonts = ExchangePtr((XchgPtr*)&self->Soundfonts, sfonts); + count = ExchangeInt(&self->NumSoundfonts, count); + + for(i = 0;i < count;i++) + DecrementRef(&sfonts[i]->ref); + free(sfonts); + + return AL_NO_ERROR; +} + extern inline void MidiSynth_setGain(MidiSynth *self, ALfloat gain); extern inline ALfloat MidiSynth_getGain(const MidiSynth *self); extern inline void MidiSynth_setState(MidiSynth *self, ALenum state); diff --git a/Alc/midi/base.h b/Alc/midi/base.h index 4f10b89b..d038eebc 100644 --- a/Alc/midi/base.h +++ b/Alc/midi/base.h @@ -27,6 +27,9 @@ typedef struct MidiSynth { */ RWLock Lock; + struct ALsoundfont **Soundfonts; + ALsizei NumSoundfonts; + volatile ALfloat Gain; volatile ALenum State; @@ -36,6 +39,7 @@ typedef struct MidiSynth { void MidiSynth_Construct(MidiSynth *self, ALCdevice *device); void MidiSynth_Destruct(MidiSynth *self); const char *MidiSynth_getFontName(const MidiSynth *self, const char *filename); +ALenum MidiSynth_selectSoundfonts(MidiSynth *self, ALCdevice *device, ALsizei count, const ALuint *ids); inline void MidiSynth_setGain(MidiSynth *self, ALfloat gain) { self->Gain = gain; } inline ALfloat MidiSynth_getGain(const MidiSynth *self) { return self->Gain; } inline void MidiSynth_setState(MidiSynth *self, ALenum state) { ExchangeInt(&self->State, state); } @@ -60,6 +64,7 @@ struct MidiSynthVtable { ALboolean (*const isSoundfont)(MidiSynth *self, const char *filename); ALenum (*const loadSoundfont)(MidiSynth *self, const char *filename); + ALenum (*const selectSoundfonts)(MidiSynth *self, ALCdevice *device, ALsizei count, const ALuint *ids); void (*const setGain)(MidiSynth *self, ALfloat gain); void (*const setState)(MidiSynth *self, ALenum state); @@ -77,6 +82,7 @@ struct MidiSynthVtable { DECLARE_THUNK(T, MidiSynth, void, Destruct) \ DECLARE_THUNK1(T, MidiSynth, ALboolean, isSoundfont, const char*) \ DECLARE_THUNK1(T, MidiSynth, ALenum, loadSoundfont, const char*) \ +DECLARE_THUNK3(T, MidiSynth, ALenum, selectSoundfonts, ALCdevice*, ALsizei, const ALuint*) \ DECLARE_THUNK1(T, MidiSynth, void, setGain, ALfloat) \ DECLARE_THUNK1(T, MidiSynth, void, setState, ALenum) \ DECLARE_THUNK(T, MidiSynth, void, stop) \ @@ -90,6 +96,7 @@ static const struct MidiSynthVtable T##_MidiSynth_vtable = { \ \ T##_MidiSynth_isSoundfont, \ T##_MidiSynth_loadSoundfont, \ + T##_MidiSynth_selectSoundfonts, \ T##_MidiSynth_setGain, \ T##_MidiSynth_setState, \ T##_MidiSynth_stop, \ diff --git a/Alc/midi/dummy.c b/Alc/midi/dummy.c index 4e53270e..3b72b63f 100644 --- a/Alc/midi/dummy.c +++ b/Alc/midi/dummy.c @@ -22,6 +22,7 @@ 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_FORWARD3(DSynth, MidiSynth, ALenum, selectSoundfonts, ALCdevice*, ALsizei, const ALuint*) static DECLARE_FORWARD1(DSynth, MidiSynth, void, setGain, ALfloat) static DECLARE_FORWARD1(DSynth, MidiSynth, void, setState, ALenum) static DECLARE_FORWARD(DSynth, MidiSynth, void, stop) diff --git a/Alc/midi/fluidsynth.c b/Alc/midi/fluidsynth.c index 7461cc4e..55526238 100644 --- a/Alc/midi/fluidsynth.c +++ b/Alc/midi/fluidsynth.c @@ -42,6 +42,7 @@ 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 DECLARE_FORWARD3(FSynth, MidiSynth, ALenum, selectSoundfonts, ALCdevice*, ALsizei, const ALuint*) static void FSynth_setGain(FSynth *self, ALfloat gain); static void FSynth_setState(FSynth *self, ALenum state); static void FSynth_stop(FSynth *self); diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index a471fb92..184a1fcd 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -33,10 +33,12 @@ #define AL_MIDI_GAIN_SOFT 0x9998 #define AL_MIDI_PRESET_SOFT 0x9997 #define AL_MIDI_BANK_SOFT 0x9996 -#define AL_PRESETS_SIZE_SOFT 0x9995 -#define AL_PRESETS_SOFT 0x9994 -#define AL_FONTSOUNDS_SIZE_SOFT 0x9993 -#define AL_FONTSOUNDS_SOFT 0x9992 +#define AL_SOUNDFONTS_SIZE_SOFT 0x9995 +#define AL_SOUNDFONTS_SOFT 0x9994 +#define AL_PRESETS_SIZE_SOFT 0x9993 +#define AL_PRESETS_SOFT 0x9992 +#define AL_FONTSOUNDS_SIZE_SOFT 0x9991 +#define AL_FONTSOUNDS_SOFT 0x9990 #define AL_SAMPLE_START_SOFT 0x2000 #define AL_SAMPLE_END_SOFT 0x2001 #define AL_SAMPLE_LOOP_START_SOFT 0x2002 @@ -79,6 +81,7 @@ typedef void (AL_APIENTRY*LPALFONTSOUND2ISOFT)(ALuint id, ALenum param, ALint va typedef void (AL_APIENTRY*LPALFONTSOUNDIVSOFT)(ALuint id, ALenum param, const ALint *values); typedef void (AL_APIENTRY*LPALGETFONTSOUNDIVSOFT)(ALuint id, ALenum param, ALint *values); typedef void (AL_APIENTRY*LPALMIDISOUNDFONTSOFT)(const char *filename); +typedef void (AL_APIENTRY*LPALMIDISOUNDFONTSSOFT)(ALsizei count, const ALuint *ids); 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); @@ -115,6 +118,7 @@ AL_API void AL_APIENTRY alFontsoundivSOFT(ALuint id, ALenum param, const ALint * AL_API void AL_APIENTRY alGetFontsoundivSOFT(ALuint id, ALenum param, ALint *values); AL_API void AL_APIENTRY alMidiSoundfontSOFT(const char *filename); +AL_API void AL_APIENTRY alMidiSoundfontsSOFT(ALsizei count, const ALuint *ids); 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); @@ -215,6 +219,10 @@ rettype T1##_##func(T1 *obj, argtype1 a) \ rettype T1##_##func(T1 *obj, argtype1 a, argtype2 b) \ { return T2##_##func(STATIC_CAST(T2, obj), a, b); } +#define DECLARE_FORWARD3(T1, T2, rettype, func, argtype1, argtype2, argtype3) \ +rettype T1##_##func(T1 *obj, argtype1 a, argtype2 b, argtype3 c) \ +{ return T2##_##func(STATIC_CAST(T2, obj), a, b, c); } + #define GET_VTABLE1(T1) (&(T1##_vtable)) #define GET_VTABLE2(T1, T2) (&(T1##_##T2##_vtable)) diff --git a/OpenAL32/alMidi.c b/OpenAL32/alMidi.c index 19cfb179..29e9e974 100644 --- a/OpenAL32/alMidi.c +++ b/OpenAL32/alMidi.c @@ -52,6 +52,38 @@ AL_API void AL_APIENTRY alMidiSoundfontSOFT(const char *filename) ALCcontext_DecRef(context); } +AL_API void AL_APIENTRY alMidiSoundfontsSOFT(ALsizei count, const ALuint *ids) +{ + ALCdevice *device; + ALCcontext *context; + MidiSynth *synth; + ALenum err; + + context = GetContextRef(); + if(!context) return; + + if(count < 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + device = context->Device; + synth = device->Synth; + + WriteLock(&synth->Lock); + if(synth->State == AL_PLAYING || synth->State == AL_PAUSED) + alSetError(context, AL_INVALID_OPERATION); + else + { + err = V(synth,selectSoundfonts)(device, count, ids); + if(err != AL_NO_ERROR) + alSetError(context, err); + } + WriteUnlock(&synth->Lock); + +done: + ALCcontext_DecRef(context); +} + + AL_API void AL_APIENTRY alMidiEventSOFT(ALuint64SOFT time, ALenum event, ALsizei channel, ALsizei param1, ALsizei param2) { ALCdevice *device; diff --git a/OpenAL32/alState.c b/OpenAL32/alState.c index 8d96018b..6a528519 100644 --- a/OpenAL32/alState.c +++ b/OpenAL32/alState.c @@ -28,6 +28,7 @@ #include "alError.h" #include "alSource.h" #include "alAuxEffectSlot.h" +#include "alMidi.h" #include "midi/base.h" @@ -249,6 +250,8 @@ done: AL_API ALint AL_APIENTRY alGetInteger(ALenum pname) { ALCcontext *context; + ALCdevice *device; + MidiSynth *synth; ALint value = 0; context = GetContextRef(); @@ -276,6 +279,12 @@ AL_API ALint AL_APIENTRY alGetInteger(ALenum pname) value = (ALint)context->DeferUpdates; break; + case AL_SOUNDFONTS_SIZE_SOFT: + device = context->Device; + synth = device->Synth; + value = synth->NumSoundfonts; + break; + default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } @@ -290,6 +299,7 @@ AL_API ALint64SOFT AL_APIENTRY alGetInteger64SOFT(ALenum pname) { ALCcontext *context; ALCdevice *device; + MidiSynth *synth; ALint64SOFT value = 0; context = GetContextRef(); @@ -324,6 +334,12 @@ AL_API ALint64SOFT AL_APIENTRY alGetInteger64SOFT(ALenum pname) ALCdevice_Unlock(device); break; + case AL_SOUNDFONTS_SIZE_SOFT: + device = context->Device; + synth = device->Synth; + value = (ALint64SOFT)synth->NumSoundfonts; + break; + default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } @@ -438,6 +454,9 @@ done: AL_API ALvoid AL_APIENTRY alGetIntegerv(ALenum pname, ALint *values) { ALCcontext *context; + ALCdevice *device; + MidiSynth *synth; + ALsizei i; if(values) { @@ -448,6 +467,7 @@ AL_API ALvoid AL_APIENTRY alGetIntegerv(ALenum pname, ALint *values) case AL_DISTANCE_MODEL: case AL_SPEED_OF_SOUND: case AL_DEFERRED_UPDATES_SOFT: + case AL_SOUNDFONTS_SIZE_SOFT: values[0] = alGetInteger(pname); return; } @@ -456,10 +476,20 @@ AL_API ALvoid AL_APIENTRY alGetIntegerv(ALenum pname, ALint *values) context = GetContextRef(); if(!context) return; - if(!(values)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); switch(pname) { + case AL_SOUNDFONTS_SOFT: + device = context->Device; + synth = device->Synth; + if(synth->NumSoundfonts > 0) + { + if(!(values)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + for(i = 0;i < synth->NumSoundfonts;i++) + values[i] = synth->Soundfonts[i]->id; + } + break; + default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } @@ -471,6 +501,9 @@ done: AL_API void AL_APIENTRY alGetInteger64vSOFT(ALenum pname, ALint64SOFT *values) { ALCcontext *context; + ALCdevice *device; + MidiSynth *synth; + ALsizei i; if(values) { @@ -482,6 +515,7 @@ AL_API void AL_APIENTRY alGetInteger64vSOFT(ALenum pname, ALint64SOFT *values) case AL_SPEED_OF_SOUND: case AL_DEFERRED_UPDATES_SOFT: case AL_MIDI_CLOCK_SOFT: + case AL_SOUNDFONTS_SIZE_SOFT: values[0] = alGetInteger64SOFT(pname); return; } @@ -490,10 +524,20 @@ AL_API void AL_APIENTRY alGetInteger64vSOFT(ALenum pname, ALint64SOFT *values) context = GetContextRef(); if(!context) return; - if(!(values)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); switch(pname) { + case AL_SOUNDFONTS_SOFT: + device = context->Device; + synth = device->Synth; + if(synth->NumSoundfonts > 0) + { + if(!(values)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + for(i = 0;i < synth->NumSoundfonts;i++) + values[i] = (ALint64SOFT)synth->Soundfonts[i]->id; + } + break; + default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } |