Add a method to set and get soundfonts
The main purpose of this is to select soundfonts for playback, eventually, instead of the existing method that takes a filename.
This commit is contained in:
parent
2b772a5607
commit
f85d733f9d
@ -304,6 +304,7 @@ static const ALCfunction alcFunctions[] = {
|
||||
DECL(alFontsoundivSOFT),
|
||||
DECL(alGetFontsoundivSOFT),
|
||||
DECL(alMidiSoundfontSOFT),
|
||||
DECL(alMidiSoundfontsSOFT),
|
||||
DECL(alMidiEventSOFT),
|
||||
DECL(alMidiSysExSOFT),
|
||||
DECL(alMidiPlaySOFT),
|
||||
|
@ -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);
|
||||
|
@ -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, \
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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))
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user