aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Alc/ALc.c1
-rw-r--r--OpenAL32/Include/alMain.h3
-rw-r--r--OpenAL32/Include/alMidi.h6
-rw-r--r--OpenAL32/alMidi.c41
-rw-r--r--OpenAL32/alState.c12
5 files changed, 63 insertions, 0 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index 0a3c8321..e89b459f 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -287,6 +287,7 @@ static const ALCfunction alcFunctions[] = {
DECL(alMidiPlaySOFT),
DECL(alMidiPauseSOFT),
DECL(alMidiStopSOFT),
+ DECL(alMidiGainSOFT),
DECL(alGetInteger64SOFT),
DECL(alGetInteger64vSOFT),
diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h
index 304672f5..e19ab487 100644
--- a/OpenAL32/Include/alMain.h
+++ b/OpenAL32/Include/alMain.h
@@ -30,6 +30,7 @@
#ifndef ALC_SOFT_midi_interface
#define ALC_SOFT_midi_interface 1
#define AL_MIDI_CLOCK_SOFT 0x9999
+#define AL_MIDI_GAIN_SOFT 0x9998
#define AL_NOTEOFF_SOFT 0x0080
#define AL_NOTEON_SOFT 0x0090
#define AL_AFTERTOUCH_SOFT 0x00A0
@@ -44,6 +45,7 @@ typedef void (AL_APIENTRY*LPALMIDISYSEXSOFT)(ALuint64SOFT time, const ALbyte *da
typedef void (AL_APIENTRY*LPALMIDIPLAYSOFT)(void);
typedef void (AL_APIENTRY*LPALMIDIPAUSESOFT)(void);
typedef void (AL_APIENTRY*LPALMIDISTOPSOFT)(void);
+typedef void (AL_APIENTRY*LPALMIDIGAINSOFT)(ALfloat value);
typedef ALint64SOFT (AL_APIENTRY*LPALGETINTEGER64SOFT)(ALenum pname);
typedef void (AL_APIENTRY*LPALGETINTEGER64VSOFT)(ALenum pname, ALint64SOFT *values);
#ifdef AL_ALEXT_PROTOTYPES
@@ -54,6 +56,7 @@ AL_API void AL_APIENTRY alMidiSysExSOFT(ALuint64SOFT time, const ALbyte *data, A
AL_API void AL_APIENTRY alMidiPlaySOFT(void);
AL_API void AL_APIENTRY alMidiPauseSOFT(void);
AL_API void AL_APIENTRY alMidiStopSOFT(void);
+AL_API void AL_APIENTRY alMidiGainSOFT(ALfloat value);
AL_API ALint64SOFT AL_APIENTRY alGetInteger64SOFT(ALenum pname);
AL_API void AL_APIENTRY alGetInteger64vSOFT(ALenum pname, ALint64SOFT *values);
#endif
diff --git a/OpenAL32/Include/alMidi.h b/OpenAL32/Include/alMidi.h
index 51bdeb07..847af04e 100644
--- a/OpenAL32/Include/alMidi.h
+++ b/OpenAL32/Include/alMidi.h
@@ -26,11 +26,13 @@ typedef struct MidiSynth {
*/
RWLock Lock;
+ volatile ALfloat Gain;
volatile ALenum State;
const struct MidiSynthVtable *vtbl;
} MidiSynth;
+ALfloat MidiSynth_getGain(const MidiSynth *self);
ALuint64 MidiSynth_getTime(const MidiSynth *self);
@@ -40,7 +42,9 @@ struct MidiSynthVtable {
ALboolean (*const isSoundfont)(MidiSynth *self, const char *filename);
ALenum (*const loadSoundfont)(MidiSynth *self, const char *filename);
+ void (*const setGain)(MidiSynth *self, ALfloat gain);
void (*const setState)(MidiSynth *self, ALenum state);
+
void (*const reset)(MidiSynth *self);
void (*const update)(MidiSynth *self, ALCdevice *device);
@@ -53,6 +57,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_THUNK1(T, MidiSynth, void, setGain, ALfloat) \
DECLARE_THUNK1(T, MidiSynth, void, setState, ALenum) \
DECLARE_THUNK(T, MidiSynth, void, reset) \
DECLARE_THUNK1(T, MidiSynth, void, update, ALCdevice*) \
@@ -64,6 +69,7 @@ static const struct MidiSynthVtable T##_MidiSynth_vtable = { \
\
T##_MidiSynth_isSoundfont, \
T##_MidiSynth_loadSoundfont, \
+ T##_MidiSynth_setGain, \
T##_MidiSynth_setState, \
T##_MidiSynth_reset, \
T##_MidiSynth_update, \
diff --git a/OpenAL32/alMidi.c b/OpenAL32/alMidi.c
index 8a783e50..7e3b5f54 100644
--- a/OpenAL32/alMidi.c
+++ b/OpenAL32/alMidi.c
@@ -37,6 +37,7 @@ static void MidiSynth_Construct(MidiSynth *self, ALCdevice *device)
RWLockInit(&self->Lock);
+ self->Gain = 1.0f;
self->State = AL_INITIAL;
self->LastEvtTime = 0;
@@ -52,6 +53,16 @@ static void MidiSynth_Destruct(MidiSynth *self)
ResetEvtQueue(&self->EventQueue);
}
+static inline void MidiSynth_setGain(MidiSynth *self, ALfloat gain)
+{
+ self->Gain = gain;
+}
+
+ALfloat MidiSynth_getGain(const MidiSynth *self)
+{
+ return self->Gain;
+}
+
static inline void MidiSynth_setState(MidiSynth *self, ALenum state)
{
ExchangeInt(&self->State, state);
@@ -166,6 +177,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 void FSynth_setGain(FSynth *self, ALfloat gain);
static void FSynth_setState(FSynth *self, ALenum state);
static void FSynth_reset(FSynth *self);
static void FSynth_update(FSynth *self, ALCdevice *device);
@@ -269,6 +281,15 @@ static ALenum FSynth_loadSoundfont(FSynth *self, const char *filename)
}
+static void FSynth_setGain(FSynth *self, ALfloat gain)
+{
+ /* Add an additional 0.2 (-14dB) to the gain, to help keep the mix from clipping. */
+ fluid_settings_setnum(self->Settings, "synth.gain", 0.2 * gain);
+ fluid_synth_set_gain(self->Synth, 0.2f * gain);
+ MidiSynth_setGain(STATIC_CAST(MidiSynth, self), gain);
+}
+
+
static void FSynth_setState(FSynth *self, ALenum state)
{
if(state == AL_PLAYING && self->FontID == FLUID_FAILED)
@@ -440,6 +461,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_FORWARD1(DSynth, MidiSynth, void, setGain, ALfloat)
static DECLARE_FORWARD1(DSynth, MidiSynth, void, setState, ALenum)
static DECLARE_FORWARD(DSynth, MidiSynth, void, reset)
static DECLARE_FORWARD1(DSynth, MidiSynth, void, update, ALCdevice*)
@@ -744,6 +766,25 @@ AL_API void AL_APIENTRY alMidiStopSOFT(void)
}
+AL_API void AL_APIENTRY alMidiGainSOFT(ALfloat value)
+{
+ ALCdevice *device;
+ ALCcontext *context;
+
+ context = GetContextRef();
+ if(!context) return;
+
+ if(!(value >= 0.0f && isfinite(value)))
+ SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
+
+ device = context->Device;
+ V(device->Synth,setGain)(value);
+
+done:
+ ALCcontext_DecRef(context);
+}
+
+
void InitEvtQueue(EvtQueue *queue)
{
queue->events = NULL;
diff --git a/OpenAL32/alState.c b/OpenAL32/alState.c
index 5f88ff5e..8ddfd024 100644
--- a/OpenAL32/alState.c
+++ b/OpenAL32/alState.c
@@ -157,6 +157,7 @@ done:
AL_API ALdouble AL_APIENTRY alGetDouble(ALenum pname)
{
+ ALCdevice *device;
ALCcontext *context;
ALdouble value = 0.0;
@@ -185,6 +186,10 @@ AL_API ALdouble AL_APIENTRY alGetDouble(ALenum pname)
value = (ALdouble)context->DeferUpdates;
break;
+ case AL_MIDI_GAIN_SOFT:
+ device = context->Device;
+ value = (ALdouble)MidiSynth_getGain(device->Synth);
+
default:
SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
}
@@ -197,6 +202,7 @@ done:
AL_API ALfloat AL_APIENTRY alGetFloat(ALenum pname)
{
+ ALCdevice *device;
ALCcontext *context;
ALfloat value = 0.0f;
@@ -225,6 +231,10 @@ AL_API ALfloat AL_APIENTRY alGetFloat(ALenum pname)
value = (ALfloat)context->DeferUpdates;
break;
+ case AL_MIDI_GAIN_SOFT:
+ device = context->Device;
+ value = MidiSynth_getGain(device->Synth);
+
default:
SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
}
@@ -369,6 +379,7 @@ AL_API ALvoid AL_APIENTRY alGetDoublev(ALenum pname, ALdouble *values)
case AL_DISTANCE_MODEL:
case AL_SPEED_OF_SOUND:
case AL_DEFERRED_UPDATES_SOFT:
+ case AL_MIDI_GAIN_SOFT:
values[0] = alGetDouble(pname);
return;
}
@@ -402,6 +413,7 @@ AL_API ALvoid AL_APIENTRY alGetFloatv(ALenum pname, ALfloat *values)
case AL_DISTANCE_MODEL:
case AL_SPEED_OF_SOUND:
case AL_DEFERRED_UPDATES_SOFT:
+ case AL_MIDI_GAIN_SOFT:
values[0] = alGetFloat(pname);
return;
}