aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Alc/ALc.c4
-rw-r--r--Alc/alcChorus.c40
-rw-r--r--Alc/alcDedicated.c40
-rw-r--r--Alc/alcDistortion.c45
-rw-r--r--Alc/alcEcho.c40
-rw-r--r--Alc/alcEqualizer.c41
-rw-r--r--Alc/alcFlanger.c40
-rw-r--r--Alc/alcModulator.c40
-rw-r--r--Alc/alcReverb.c177
-rw-r--r--OpenAL32/Include/alAuxEffectSlot.h65
-rw-r--r--OpenAL32/Include/alMain.h5
-rw-r--r--OpenAL32/alAuxEffectSlot.c119
12 files changed, 513 insertions, 143 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index 24c2fbe5..aaddfea8 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -1038,6 +1038,8 @@ static void alc_initconfig(void)
} while(next++);
}
+ InitEffectFactoryMap();
+
InitEffect(&DefaultEffect);
str = getenv("ALSOFT_DEFAULT_REVERB");
if((str && str[0]) || ConfigValueStr(NULL, "default-reverb", &str))
@@ -1071,6 +1073,8 @@ static void alc_cleanup(void)
} while((dev=dev->next) != NULL);
ERR("%u device%s not closed\n", num, (num>1)?"s":"");
}
+
+ DeinitEffectFactoryMap();
}
static void alc_deinit_safe(void)
diff --git a/Alc/alcChorus.c b/Alc/alcChorus.c
index ff1c9492..018caac5 100644
--- a/Alc/alcChorus.c
+++ b/Alc/alcChorus.c
@@ -30,6 +30,13 @@
#include "alu.h"
+typedef struct ALchorusStateFactory {
+ DERIVE_FROM_TYPE(ALeffectStateFactory);
+} ALchorusStateFactory;
+
+static ALchorusStateFactory ChorusFactory;
+
+
typedef struct ALchorusState {
DERIVE_FROM_TYPE(ALeffectState);
@@ -57,8 +64,6 @@ static ALvoid ALchorusState_Destroy(ALchorusState *state)
free(state->SampleBufferRight);
state->SampleBufferRight = NULL;
-
- free(state);
}
static ALboolean ALchorusState_DeviceUpdate(ALchorusState *state, ALCdevice *Device)
@@ -238,9 +243,15 @@ static ALvoid ALchorusState_Process(ALchorusState *state, ALuint SamplesToDo, co
ProcessSinusoid(state, SamplesToDo, SamplesIn, SamplesOut);
}
+static ALeffectStateFactory *ALchorusState_getCreator(void)
+{
+ return STATIC_CAST(ALeffectStateFactory, &ChorusFactory);
+}
+
DEFINE_ALEFFECTSTATE_VTABLE(ALchorusState);
-ALeffectState *ChorusCreate(void)
+
+static ALeffectState *ALchorusStateFactory_create(void)
{
ALchorusState *state;
@@ -256,6 +267,29 @@ ALeffectState *ChorusCreate(void)
return STATIC_CAST(ALeffectState, state);
}
+static ALvoid ALchorusStateFactory_destroy(ALeffectState *effect)
+{
+ ALchorusState *state = STATIC_UPCAST(ALchorusState, ALeffectState, effect);
+ ALchorusState_Destroy(state);
+ free(state);
+}
+
+DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALchorusStateFactory);
+
+
+static void init_chorus_factory(void)
+{
+ SET_VTABLE2(ALchorusStateFactory, ALeffectStateFactory, &ChorusFactory);
+}
+
+ALeffectStateFactory *ALchorusStateFactory_getFactory(void)
+{
+ static pthread_once_t once = PTHREAD_ONCE_INIT;
+ pthread_once(&once, init_chorus_factory);
+ return STATIC_CAST(ALeffectStateFactory, &ChorusFactory);
+}
+
+
void chorus_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val)
{
switch(param)
diff --git a/Alc/alcDedicated.c b/Alc/alcDedicated.c
index 7d32c153..fbe2a5f1 100644
--- a/Alc/alcDedicated.c
+++ b/Alc/alcDedicated.c
@@ -29,6 +29,13 @@
#include "alu.h"
+typedef struct ALdedicatedStateFactory {
+ DERIVE_FROM_TYPE(ALeffectStateFactory);
+} ALdedicatedStateFactory;
+
+static ALdedicatedStateFactory DedicatedFactory;
+
+
typedef struct ALdedicatedState {
DERIVE_FROM_TYPE(ALeffectState);
@@ -38,7 +45,7 @@ typedef struct ALdedicatedState {
static ALvoid ALdedicatedState_Destroy(ALdedicatedState *state)
{
- free(state);
+ (void)state;
}
static ALboolean ALdedicatedState_DeviceUpdate(ALdedicatedState *state, ALCdevice *Device)
@@ -78,9 +85,15 @@ static ALvoid ALdedicatedState_Process(ALdedicatedState *state, ALuint SamplesTo
}
}
+static ALeffectStateFactory *ALdedicatedState_getCreator(void)
+{
+ return STATIC_CAST(ALeffectStateFactory, &DedicatedFactory);
+}
+
DEFINE_ALEFFECTSTATE_VTABLE(ALdedicatedState);
-ALeffectState *DedicatedCreate(void)
+
+ALeffectState *ALdedicatedStateFactory_create(void)
{
ALdedicatedState *state;
ALsizei s;
@@ -95,6 +108,29 @@ ALeffectState *DedicatedCreate(void)
return STATIC_CAST(ALeffectState, state);
}
+static ALvoid ALdedicatedStateFactory_destroy(ALeffectState *effect)
+{
+ ALdedicatedState *state = STATIC_UPCAST(ALdedicatedState, ALeffectState, effect);
+ ALdedicatedState_Destroy(state);
+ free(state);
+}
+
+DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALdedicatedStateFactory);
+
+
+static void init_dedicated_factory(void)
+{
+ SET_VTABLE2(ALdedicatedStateFactory, ALeffectStateFactory, &DedicatedFactory);
+}
+
+ALeffectStateFactory *ALdedicatedStateFactory_getFactory(void)
+{
+ static pthread_once_t once = PTHREAD_ONCE_INIT;
+ pthread_once(&once, init_dedicated_factory);
+ return STATIC_CAST(ALeffectStateFactory, &DedicatedFactory);
+}
+
+
void ded_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val)
{ (void)effect;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); }
void ded_SetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals)
diff --git a/Alc/alcDistortion.c b/Alc/alcDistortion.c
index 8c0f5e97..ec48ad03 100644
--- a/Alc/alcDistortion.c
+++ b/Alc/alcDistortion.c
@@ -29,6 +29,14 @@
#include "alError.h"
#include "alu.h"
+
+typedef struct ALdistortionStateFactory {
+ DERIVE_FROM_TYPE(ALeffectStateFactory);
+} ALdistortionStateFactory;
+
+static ALdistortionStateFactory DistortionFactory;
+
+
/* Filters implementation is based on the "Cookbook formulae for audio *
* EQ biquad filter coefficients" by Robert Bristow-Johnson *
* http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt */
@@ -61,14 +69,14 @@ typedef struct ALdistortionState {
static ALvoid ALdistortionState_Destroy(ALdistortionState *state)
{
- free(state);
+ (void)state;
}
-static ALboolean ALdistortionState_DeviceUpdate(ALdistortionState *state, ALCdevice *Device)
+static ALboolean ALdistortionState_DeviceUpdate(ALdistortionState *state, ALCdevice *device)
{
return AL_TRUE;
(void)state;
- (void)Device;
+ (void)device;
}
static ALvoid ALdistortionState_Update(ALdistortionState *state, ALCdevice *Device, const ALeffectslot *Slot)
@@ -226,9 +234,15 @@ static ALvoid ALdistortionState_Process(ALdistortionState *state, ALuint Samples
}
}
+static ALeffectStateFactory *ALdistortionState_getCreator(void)
+{
+ return STATIC_CAST(ALeffectStateFactory, &DistortionFactory);
+}
+
DEFINE_ALEFFECTSTATE_VTABLE(ALdistortionState);
-ALeffectState *DistortionCreate(void)
+
+static ALeffectState *ALdistortionStateFactory_create(void)
{
ALdistortionState *state;
@@ -249,6 +263,29 @@ ALeffectState *DistortionCreate(void)
return STATIC_CAST(ALeffectState, state);
}
+static ALvoid ALdistortionStateFactory_destroy(ALeffectState *effect)
+{
+ ALdistortionState *state = STATIC_UPCAST(ALdistortionState, ALeffectState, effect);
+ ALdistortionState_Destroy(state);
+ free(state);
+}
+
+DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALdistortionStateFactory);
+
+
+static void init_distortion_factory(void)
+{
+ SET_VTABLE2(ALdistortionStateFactory, ALeffectStateFactory, &DistortionFactory);
+}
+
+ALeffectStateFactory *ALdistortionStateFactory_getFactory(void)
+{
+ static pthread_once_t once = PTHREAD_ONCE_INIT;
+ pthread_once(&once, init_distortion_factory);
+ return STATIC_CAST(ALeffectStateFactory, &DistortionFactory);
+}
+
+
void distortion_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val)
{
effect=effect;
diff --git a/Alc/alcEcho.c b/Alc/alcEcho.c
index 1aab9870..e38e1457 100644
--- a/Alc/alcEcho.c
+++ b/Alc/alcEcho.c
@@ -30,6 +30,13 @@
#include "alu.h"
+typedef struct ALechoStateFactory {
+ DERIVE_FROM_TYPE(ALeffectStateFactory);
+} ALechoStateFactory;
+
+static ALechoStateFactory EchoFactory;
+
+
typedef struct ALechoState {
DERIVE_FROM_TYPE(ALeffectState);
@@ -54,8 +61,6 @@ static ALvoid ALechoState_Destroy(ALechoState *state)
{
free(state->SampleBuffer);
state->SampleBuffer = NULL;
-
- free(state);
}
static ALboolean ALechoState_DeviceUpdate(ALechoState *state, ALCdevice *Device)
@@ -170,9 +175,15 @@ static ALvoid ALechoState_Process(ALechoState *state, ALuint SamplesToDo, const
state->Offset = offset;
}
+static ALeffectStateFactory *ALechoState_getCreator(void)
+{
+ return STATIC_CAST(ALeffectStateFactory, &EchoFactory);
+}
+
DEFINE_ALEFFECTSTATE_VTABLE(ALechoState);
-ALeffectState *EchoCreate(void)
+
+ALeffectState *ALechoStateFactory_create(void)
{
ALechoState *state;
@@ -194,6 +205,29 @@ ALeffectState *EchoCreate(void)
return STATIC_CAST(ALeffectState, state);
}
+static ALvoid ALechoStateFactory_destroy(ALeffectState *effect)
+{
+ ALechoState *state = STATIC_UPCAST(ALechoState, ALeffectState, effect);
+ ALechoState_Destroy(state);
+ free(state);
+}
+
+DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALechoStateFactory);
+
+
+static void init_echo_factory(void)
+{
+ SET_VTABLE2(ALechoStateFactory, ALeffectStateFactory, &EchoFactory);
+}
+
+ALeffectStateFactory *ALechoStateFactory_getFactory(void)
+{
+ static pthread_once_t once = PTHREAD_ONCE_INIT;
+ pthread_once(&once, init_echo_factory);
+ return STATIC_CAST(ALeffectStateFactory, &EchoFactory);
+}
+
+
void echo_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val)
{ (void)effect;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); }
void echo_SetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals)
diff --git a/Alc/alcEqualizer.c b/Alc/alcEqualizer.c
index 318593ee..5a1d8841 100644
--- a/Alc/alcEqualizer.c
+++ b/Alc/alcEqualizer.c
@@ -29,6 +29,14 @@
#include "alError.h"
#include "alu.h"
+
+typedef struct ALequalizerStateFactory {
+ DERIVE_FROM_TYPE(ALeffectStateFactory);
+} ALequalizerStateFactory;
+
+static ALequalizerStateFactory EqualizerFactory;
+
+
/* The document "Effects Extension Guide.pdf" says that low and high *
* frequencies are cutoff frequencies. This is not fully correct, they *
* are corner frequencies for low and high shelf filters. If they were *
@@ -96,7 +104,7 @@ typedef struct ALequalizerState {
static ALvoid ALequalizerState_Destroy(ALequalizerState *state)
{
- free(state);
+ (void)state;
}
static ALboolean ALequalizerState_DeviceUpdate(ALequalizerState *state, ALCdevice *device)
@@ -262,9 +270,15 @@ static ALvoid ALequalizerState_Process(ALequalizerState *state, ALuint SamplesTo
}
}
+static ALeffectStateFactory *ALequalizerState_getCreator(void)
+{
+ return STATIC_CAST(ALeffectStateFactory, &EqualizerFactory);
+}
+
DEFINE_ALEFFECTSTATE_VTABLE(ALequalizerState);
-ALeffectState *EqualizerCreate(void)
+
+ALeffectState *ALequalizerStateFactory_create(void)
{
ALequalizerState *state;
int it;
@@ -291,6 +305,29 @@ ALeffectState *EqualizerCreate(void)
return STATIC_CAST(ALeffectState, state);
}
+static ALvoid ALequalizerStateFactory_destroy(ALeffectState *effect)
+{
+ ALequalizerState *state = STATIC_UPCAST(ALequalizerState, ALeffectState, effect);
+ ALequalizerState_Destroy(state);
+ free(state);
+}
+
+DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALequalizerStateFactory);
+
+
+static void init_equalizer_factory(void)
+{
+ SET_VTABLE2(ALequalizerStateFactory, ALeffectStateFactory, &EqualizerFactory);
+}
+
+ALeffectStateFactory *ALequalizerStateFactory_getFactory(void)
+{
+ static pthread_once_t once = PTHREAD_ONCE_INIT;
+ pthread_once(&once, init_equalizer_factory);
+ return STATIC_CAST(ALeffectStateFactory, &EqualizerFactory);
+}
+
+
void equalizer_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val)
{
effect=effect;
diff --git a/Alc/alcFlanger.c b/Alc/alcFlanger.c
index 574fa9d7..953828f6 100644
--- a/Alc/alcFlanger.c
+++ b/Alc/alcFlanger.c
@@ -30,6 +30,13 @@
#include "alu.h"
+typedef struct ALflangerStateFactory {
+ DERIVE_FROM_TYPE(ALeffectStateFactory);
+} ALflangerStateFactory;
+
+static ALflangerStateFactory FlangerFactory;
+
+
typedef struct ALflangerState {
DERIVE_FROM_TYPE(ALeffectState);
@@ -57,8 +64,6 @@ static ALvoid ALflangerState_Destroy(ALflangerState *state)
free(state->SampleBufferRight);
state->SampleBufferRight = NULL;
-
- free(state);
}
static ALboolean ALflangerState_DeviceUpdate(ALflangerState *state, ALCdevice *Device)
@@ -238,9 +243,15 @@ static ALvoid ALflangerState_Process(ALflangerState *state, ALuint SamplesToDo,
ProcessSinusoid(state, SamplesToDo, SamplesIn, SamplesOut);
}
+static ALeffectStateFactory *ALflangerState_getCreator(void)
+{
+ return STATIC_CAST(ALeffectStateFactory, &FlangerFactory);
+}
+
DEFINE_ALEFFECTSTATE_VTABLE(ALflangerState);
-ALeffectState *FlangerCreate(void)
+
+ALeffectState *ALflangerStateFactory_create(void)
{
ALflangerState *state;
@@ -256,6 +267,29 @@ ALeffectState *FlangerCreate(void)
return STATIC_CAST(ALeffectState, state);
}
+static ALvoid ALflangerStateFactory_destroy(ALeffectState *effect)
+{
+ ALflangerState *state = STATIC_UPCAST(ALflangerState, ALeffectState, effect);
+ ALflangerState_Destroy(state);
+ free(state);
+}
+
+DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALflangerStateFactory);
+
+
+static void init_flanger_factory(void)
+{
+ SET_VTABLE2(ALflangerStateFactory, ALeffectStateFactory, &FlangerFactory);
+}
+
+ALeffectStateFactory *ALflangerStateFactory_getFactory(void)
+{
+ static pthread_once_t once = PTHREAD_ONCE_INIT;
+ pthread_once(&once, init_flanger_factory);
+ return STATIC_CAST(ALeffectStateFactory, &FlangerFactory);
+}
+
+
void flanger_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val)
{
switch(param)
diff --git a/Alc/alcModulator.c b/Alc/alcModulator.c
index bb90d646..25b5bcc4 100644
--- a/Alc/alcModulator.c
+++ b/Alc/alcModulator.c
@@ -30,6 +30,13 @@
#include "alu.h"
+typedef struct ALmodulatorStateFactory {
+ DERIVE_FROM_TYPE(ALeffectStateFactory);
+} ALmodulatorStateFactory;
+
+static ALmodulatorStateFactory ModulatorFactory;
+
+
typedef struct ALmodulatorState {
DERIVE_FROM_TYPE(ALeffectState);
@@ -130,7 +137,7 @@ DECL_TEMPLATE(Square)
static ALvoid ALmodulatorState_Destroy(ALmodulatorState *state)
{
- free(state);
+ (void)state;
}
static ALboolean ALmodulatorState_DeviceUpdate(ALmodulatorState *state, ALCdevice *Device)
@@ -190,9 +197,15 @@ static ALvoid ALmodulatorState_Process(ALmodulatorState *state, ALuint SamplesTo
}
}
+static ALeffectStateFactory *ALmodulatorState_getCreator(void)
+{
+ return STATIC_CAST(ALeffectStateFactory, &ModulatorFactory);
+}
+
DEFINE_ALEFFECTSTATE_VTABLE(ALmodulatorState);
-ALeffectState *ModulatorCreate(void)
+
+static ALeffectState *ALmodulatorStateFactory_create(void)
{
ALmodulatorState *state;
@@ -209,6 +222,29 @@ ALeffectState *ModulatorCreate(void)
return STATIC_CAST(ALeffectState, state);
}
+static ALvoid ALmodulatorStateFactory_destroy(ALeffectState *effect)
+{
+ ALmodulatorState *state = STATIC_UPCAST(ALmodulatorState, ALeffectState, effect);
+ ALmodulatorState_Destroy(state);
+ free(state);
+}
+
+DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALmodulatorStateFactory);
+
+
+static void init_modulator_factory(void)
+{
+ SET_VTABLE2(ALmodulatorStateFactory, ALeffectStateFactory, &ModulatorFactory);
+}
+
+ALeffectStateFactory *ALmodulatorStateFactory_getFactory(void)
+{
+ static pthread_once_t once = PTHREAD_ONCE_INIT;
+ pthread_once(&once, init_modulator_factory);
+ return STATIC_CAST(ALeffectStateFactory, &ModulatorFactory);
+}
+
+
void mod_SetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val)
{
switch(param)
diff --git a/Alc/alcReverb.c b/Alc/alcReverb.c
index 01f4ab83..b3de2fad 100644
--- a/Alc/alcReverb.c
+++ b/Alc/alcReverb.c
@@ -31,6 +31,14 @@
#include "alFilter.h"
#include "alError.h"
+
+typedef struct ALreverbStateFactory {
+ DERIVE_FROM_TYPE(ALeffectStateFactory);
+} ALreverbStateFactory;
+
+static ALreverbStateFactory ReverbFactory;
+
+
typedef struct DelayLine
{
// The delay lines use sample lengths that are powers of 2 to allow the
@@ -1174,106 +1182,131 @@ static ALvoid ALreverbState_Destroy(ALreverbState *State)
{
free(State->SampleBuffer);
State->SampleBuffer = NULL;
+}
- free(State);
+static ALeffectStateFactory *ALreverbState_getCreator(void)
+{
+ return STATIC_CAST(ALeffectStateFactory, &ReverbFactory);
}
DEFINE_ALEFFECTSTATE_VTABLE(ALreverbState);
-// This creates the reverb state. It should be called only when the reverb
-// effect is loaded into a slot that doesn't already have a reverb effect.
-ALeffectState *ReverbCreate(void)
+
+static ALeffectState *ALreverbStateFactory_create(void)
{
- ALreverbState *State;
+ ALreverbState *state;
ALuint index;
- State = malloc(sizeof(ALreverbState));
- if(!State) return NULL;
- SET_VTABLE2(ALreverbState, ALeffectState, State);
+ state = malloc(sizeof(ALreverbState));
+ if(!state) return NULL;
+ SET_VTABLE2(ALreverbState, ALeffectState, state);
- State->TotalSamples = 0;
- State->SampleBuffer = NULL;
+ state->TotalSamples = 0;
+ state->SampleBuffer = NULL;
- State->LpFilter.coeff = 0.0f;
- State->LpFilter.history[0] = 0.0f;
- State->LpFilter.history[1] = 0.0f;
+ state->LpFilter.coeff = 0.0f;
+ state->LpFilter.history[0] = 0.0f;
+ state->LpFilter.history[1] = 0.0f;
- State->Mod.Delay.Mask = 0;
- State->Mod.Delay.Line = NULL;
- State->Mod.Index = 0;
- State->Mod.Range = 1;
- State->Mod.Depth = 0.0f;
- State->Mod.Coeff = 0.0f;
- State->Mod.Filter = 0.0f;
+ state->Mod.Delay.Mask = 0;
+ state->Mod.Delay.Line = NULL;
+ state->Mod.Index = 0;
+ state->Mod.Range = 1;
+ state->Mod.Depth = 0.0f;
+ state->Mod.Coeff = 0.0f;
+ state->Mod.Filter = 0.0f;
- State->Delay.Mask = 0;
- State->Delay.Line = NULL;
- State->DelayTap[0] = 0;
- State->DelayTap[1] = 0;
+ state->Delay.Mask = 0;
+ state->Delay.Line = NULL;
+ state->DelayTap[0] = 0;
+ state->DelayTap[1] = 0;
- State->Early.Gain = 0.0f;
+ state->Early.Gain = 0.0f;
for(index = 0;index < 4;index++)
{
- State->Early.Coeff[index] = 0.0f;
- State->Early.Delay[index].Mask = 0;
- State->Early.Delay[index].Line = NULL;
- State->Early.Offset[index] = 0;
+ state->Early.Coeff[index] = 0.0f;
+ state->Early.Delay[index].Mask = 0;
+ state->Early.Delay[index].Line = NULL;
+ state->Early.Offset[index] = 0;
}
- State->Decorrelator.Mask = 0;
- State->Decorrelator.Line = NULL;
- State->DecoTap[0] = 0;
- State->DecoTap[1] = 0;
- State->DecoTap[2] = 0;
+ state->Decorrelator.Mask = 0;
+ state->Decorrelator.Line = NULL;
+ state->DecoTap[0] = 0;
+ state->DecoTap[1] = 0;
+ state->DecoTap[2] = 0;
- State->Late.Gain = 0.0f;
- State->Late.DensityGain = 0.0f;
- State->Late.ApFeedCoeff = 0.0f;
- State->Late.MixCoeff = 0.0f;
+ state->Late.Gain = 0.0f;
+ state->Late.DensityGain = 0.0f;
+ state->Late.ApFeedCoeff = 0.0f;
+ state->Late.MixCoeff = 0.0f;
for(index = 0;index < 4;index++)
{
- State->Late.ApCoeff[index] = 0.0f;
- State->Late.ApDelay[index].Mask = 0;
- State->Late.ApDelay[index].Line = NULL;
- State->Late.ApOffset[index] = 0;
-
- State->Late.Coeff[index] = 0.0f;
- State->Late.Delay[index].Mask = 0;
- State->Late.Delay[index].Line = NULL;
- State->Late.Offset[index] = 0;
-
- State->Late.LpCoeff[index] = 0.0f;
- State->Late.LpSample[index] = 0.0f;
+ state->Late.ApCoeff[index] = 0.0f;
+ state->Late.ApDelay[index].Mask = 0;
+ state->Late.ApDelay[index].Line = NULL;
+ state->Late.ApOffset[index] = 0;
+
+ state->Late.Coeff[index] = 0.0f;
+ state->Late.Delay[index].Mask = 0;
+ state->Late.Delay[index].Line = NULL;
+ state->Late.Offset[index] = 0;
+
+ state->Late.LpCoeff[index] = 0.0f;
+ state->Late.LpSample[index] = 0.0f;
}
for(index = 0;index < MaxChannels;index++)
{
- State->Early.PanGain[index] = 0.0f;
- State->Late.PanGain[index] = 0.0f;
+ state->Early.PanGain[index] = 0.0f;
+ state->Late.PanGain[index] = 0.0f;
}
- State->Echo.DensityGain = 0.0f;
- State->Echo.Delay.Mask = 0;
- State->Echo.Delay.Line = NULL;
- State->Echo.ApDelay.Mask = 0;
- State->Echo.ApDelay.Line = NULL;
- State->Echo.Coeff = 0.0f;
- State->Echo.ApFeedCoeff = 0.0f;
- State->Echo.ApCoeff = 0.0f;
- State->Echo.Offset = 0;
- State->Echo.ApOffset = 0;
- State->Echo.LpCoeff = 0.0f;
- State->Echo.LpSample = 0.0f;
- State->Echo.MixCoeff[0] = 0.0f;
- State->Echo.MixCoeff[1] = 0.0f;
-
- State->Offset = 0;
-
- State->Gain = State->Late.PanGain;
-
- return STATIC_CAST(ALeffectState, State);
+ state->Echo.DensityGain = 0.0f;
+ state->Echo.Delay.Mask = 0;
+ state->Echo.Delay.Line = NULL;
+ state->Echo.ApDelay.Mask = 0;
+ state->Echo.ApDelay.Line = NULL;
+ state->Echo.Coeff = 0.0f;
+ state->Echo.ApFeedCoeff = 0.0f;
+ state->Echo.ApCoeff = 0.0f;
+ state->Echo.Offset = 0;
+ state->Echo.ApOffset = 0;
+ state->Echo.LpCoeff = 0.0f;
+ state->Echo.LpSample = 0.0f;
+ state->Echo.MixCoeff[0] = 0.0f;
+ state->Echo.MixCoeff[1] = 0.0f;
+
+ state->Offset = 0;
+
+ state->Gain = state->Late.PanGain;
+
+ return STATIC_CAST(ALeffectState, state);
+}
+
+static ALvoid ALreverbStateFactory_destroy(ALeffectState *effect)
+{
+ ALreverbState *state = STATIC_UPCAST(ALreverbState, ALeffectState, effect);
+ ALreverbState_Destroy(state);
+ free(state);
+}
+
+DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALreverbStateFactory);
+
+
+static void init_reverb_factory(void)
+{
+ SET_VTABLE2(ALreverbStateFactory, ALeffectStateFactory, &ReverbFactory);
}
+ALeffectStateFactory *ALreverbStateFactory_getFactory(void)
+{
+ static pthread_once_t once = PTHREAD_ONCE_INIT;
+ pthread_once(&once, init_reverb_factory);
+ return STATIC_CAST(ALeffectStateFactory, &ReverbFactory);
+}
+
+
void eaxreverb_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val)
{
switch(param)
diff --git a/OpenAL32/Include/alAuxEffectSlot.h b/OpenAL32/Include/alAuxEffectSlot.h
index 547e7040..6d5ad8bb 100644
--- a/OpenAL32/Include/alAuxEffectSlot.h
+++ b/OpenAL32/Include/alAuxEffectSlot.h
@@ -8,6 +8,8 @@
extern "C" {
#endif
+typedef struct ALeffectStateFactory ALeffectStateFactory;
+
typedef struct ALeffectState ALeffectState;
typedef struct ALeffectslot ALeffectslot;
@@ -16,12 +18,19 @@ struct ALeffectStateVtable {
ALboolean (*const DeviceUpdate)(ALeffectState *state, ALCdevice *device);
ALvoid (*const Update)(ALeffectState *state, ALCdevice *device, const ALeffectslot *slot);
ALvoid (*const Process)(ALeffectState *state, ALuint samplesToDo, const ALfloat *RESTRICT samplesIn, ALfloat (*RESTRICT samplesOut)[BUFFERSIZE]);
+ ALeffectStateFactory *(*const getCreator)(void);
};
struct ALeffectState {
const struct ALeffectStateVtable *vtbl;
};
+#define ALeffectState_Destroy(a) ((a)->vtbl->Destroy((a)))
+#define ALeffectState_DeviceUpdate(a,b) ((a)->vtbl->DeviceUpdate((a),(b)))
+#define ALeffectState_Update(a,b,c) ((a)->vtbl->Update((a),(b),(c)))
+#define ALeffectState_Process(a,b,c,d) ((a)->vtbl->Process((a),(b),(c),(d)))
+#define ALeffectState_getCreator(a) ((a)->vtbl->getCreator())
+
#define DEFINE_ALEFFECTSTATE_VTABLE(T) \
static ALvoid T##_ALeffectState_Destroy(ALeffectState *state) \
{ T##_Destroy(STATIC_UPCAST(T, ALeffectState, state)); } \
@@ -31,16 +40,40 @@ static ALvoid T##_ALeffectState_Update(ALeffectState *state, ALCdevice *device,
{ T##_Update(STATIC_UPCAST(T, ALeffectState, state), device, slot); } \
static ALvoid T##_ALeffectState_Process(ALeffectState *state, ALuint samplesToDo, const ALfloat *RESTRICT samplesIn, ALfloat (*RESTRICT samplesOut)[BUFFERSIZE]) \
{ T##_Process(STATIC_UPCAST(T, ALeffectState, state), samplesToDo, samplesIn, samplesOut); } \
+static ALeffectStateFactory* T##_ALeffectState_getCreator(void) \
+{ return T##_getCreator(); } \
\
static const struct ALeffectStateVtable T##_ALeffectState_vtable = { \
T##_ALeffectState_Destroy, \
T##_ALeffectState_DeviceUpdate, \
T##_ALeffectState_Update, \
- T##_ALeffectState_Process \
+ T##_ALeffectState_Process, \
+ T##_ALeffectState_getCreator, \
}
-#define SET_VTABLE1(T1, obj) ((obj)->vtbl = &(T1##_vtable))
-#define SET_VTABLE2(T1, T2, obj) SET_VTABLE1(T1##_##T2, STATIC_CAST(T2, (obj)))
+
+struct ALeffectStateFactoryVtable {
+ ALeffectState *(*const create)(void);
+ ALvoid (*const destroy)(ALeffectState *state);
+};
+
+struct ALeffectStateFactory {
+ const struct ALeffectStateFactoryVtable *vtbl;
+};
+
+#define ALeffectStateFactory_create(p) ((p)->vtbl->create())
+#define ALeffectStateFactory_destroy(p,a) ((p)->vtbl->destroy((a)))
+
+#define DEFINE_ALEFFECTSTATEFACTORY_VTABLE(T) \
+static ALeffectState* T##_ALeffectStateFactory_create(void) \
+{ return T##_create(); } \
+static ALvoid T##_ALeffectStateFactory_destroy(ALeffectState *state) \
+{ T##_destroy(state); } \
+ \
+static const struct ALeffectStateFactoryVtable T##_ALeffectStateFactory_vtable = { \
+ T##_ALeffectStateFactory_create, \
+ T##_ALeffectStateFactory_destroy \
+}
struct ALeffectslot
@@ -68,23 +101,23 @@ struct ALeffectslot
ALenum InitEffectSlot(ALeffectslot *slot);
ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context);
-ALeffectState *NoneCreate(void);
-ALeffectState *ReverbCreate(void);
-ALeffectState *EchoCreate(void);
-ALeffectState *ModulatorCreate(void);
-ALeffectState *DedicatedCreate(void);
-ALeffectState *ChorusCreate(void);
-ALeffectState *FlangerCreate(void);
-ALeffectState *EqualizerCreate(void);
-ALeffectState *DistortionCreate(void);
-#define ALeffectState_Destroy(a) ((a)->vtbl->Destroy((a)))
-#define ALeffectState_DeviceUpdate(a,b) ((a)->vtbl->DeviceUpdate((a),(b)))
-#define ALeffectState_Update(a,b,c) ((a)->vtbl->Update((a),(b),(c)))
-#define ALeffectState_Process(a,b,c,d) ((a)->vtbl->Process((a),(b),(c),(d)))
+ALeffectStateFactory *ALreverbStateFactory_getFactory(void);
+ALeffectStateFactory *ALchorusStateFactory_getFactory(void);
+ALeffectStateFactory *ALdistortionStateFactory_getFactory(void);
+ALeffectStateFactory *ALechoStateFactory_getFactory(void);
+ALeffectStateFactory *ALequalizerStateFactory_getFactory(void);
+ALeffectStateFactory *ALflangerStateFactory_getFactory(void);
+ALeffectStateFactory *ALmodulatorStateFactory_getFactory(void);
+
+ALeffectStateFactory *ALdedicatedStateFactory_getFactory(void);
+
ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *effect);
+void InitEffectFactoryMap(void);
+void DeinitEffectFactoryMap(void);
+
#ifdef __cplusplus
}
#endif
diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h
index 4cdaf783..fc078175 100644
--- a/OpenAL32/Include/alMain.h
+++ b/OpenAL32/Include/alMain.h
@@ -62,10 +62,15 @@ static const union {
#define COUNTOF(x) (sizeof((x))/sizeof((x)[0]))
+
#define DERIVE_FROM_TYPE(t) t t##_parent
#define STATIC_CAST(to, obj) (&(obj)->to##_parent)
#define STATIC_UPCAST(to, from, obj) ((to*)((char*)(obj) - offsetof(to, from##_parent)))
+#define SET_VTABLE1(T1, obj) ((obj)->vtbl = &(T1##_vtable))
+#define SET_VTABLE2(T1, T2, obj) SET_VTABLE1(T1##_##T2, STATIC_CAST(T2, (obj)))
+
+
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c
index 3c31ecb8..0daeaeb1 100644
--- a/OpenAL32/alAuxEffectSlot.c
+++ b/OpenAL32/alAuxEffectSlot.c
@@ -35,7 +35,12 @@
static ALenum AddEffectSlotArray(ALCcontext *Context, ALsizei count, const ALuint *slots);
static ALvoid RemoveEffectSlotArray(ALCcontext *Context, ALeffectslot *slot);
-static ALeffectState *CreateStateByType(ALenum type);
+
+static UIntMap EffectStateFactoryMap;
+static __inline ALeffectStateFactory *getFactoryByType(ALenum type)
+{
+ return LookupUIntMapKey(&EffectStateFactoryMap, type);
+}
AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots)
@@ -69,7 +74,8 @@ AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslo
if(err != AL_NO_ERROR)
{
FreeThunkEntry(slot->id);
- ALeffectState_Destroy(slot->EffectState);
+ ALeffectStateFactory_destroy(ALeffectState_getCreator(slot->EffectState),
+ slot->EffectState);
al_free(slot);
alDeleteAuxiliaryEffectSlots(cur, effectslots);
@@ -118,7 +124,8 @@ AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, const ALuint *
FreeThunkEntry(slot->id);
RemoveEffectSlotArray(Context, slot);
- ALeffectState_Destroy(slot->EffectState);
+ ALeffectStateFactory_destroy(ALeffectState_getCreator(slot->EffectState),
+ slot->EffectState);
memset(slot, 0, sizeof(*slot));
al_free(slot);
@@ -393,12 +400,21 @@ AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotfv(ALuint effectslot, ALenum p
}
+typedef struct ALnoneStateFactory {
+ DERIVE_FROM_TYPE(ALeffectStateFactory);
+} ALnoneStateFactory;
+
+static ALnoneStateFactory NoneFactory;
+
+
typedef struct ALnoneState {
DERIVE_FROM_TYPE(ALeffectState);
} ALnoneState;
static ALvoid ALnoneState_Destroy(ALnoneState *state)
-{ free(state); }
+{
+ (void)state;
+}
static ALboolean ALnoneState_DeviceUpdate(ALnoneState *state, ALCdevice *device)
{
return AL_TRUE;
@@ -418,10 +434,15 @@ static ALvoid ALnoneState_Process(ALnoneState *state, ALuint samplesToDo, const
(void)samplesIn;
(void)samplesOut;
}
+static ALeffectStateFactory *ALnoneState_getCreator(void)
+{
+ return STATIC_CAST(ALeffectStateFactory, &NoneFactory);
+}
DEFINE_ALEFFECTSTATE_VTABLE(ALnoneState);
-ALeffectState *NoneCreate(void)
+
+ALeffectState *ALnoneStateFactory_create(void)
{
ALnoneState *state;
@@ -432,6 +453,29 @@ ALeffectState *NoneCreate(void)
return STATIC_CAST(ALeffectState, state);
}
+static ALvoid ALnoneStateFactory_destroy(ALeffectState *effect)
+{
+ ALnoneState *state = STATIC_UPCAST(ALnoneState, ALeffectState, effect);
+ ALnoneState_Destroy(state);
+ free(state);
+}
+
+DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALnoneStateFactory);
+
+
+static void init_none_factory(void)
+{
+ SET_VTABLE2(ALnoneStateFactory, ALeffectStateFactory, &NoneFactory);
+}
+
+ALeffectStateFactory *ALnoneStateFactory_getFactory(void)
+{
+ static pthread_once_t once = PTHREAD_ONCE_INIT;
+ pthread_once(&once, init_none_factory);
+ return STATIC_CAST(ALeffectStateFactory, &NoneFactory);
+}
+
+
void null_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val)
{ (void)effect;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); }
void null_SetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals)
@@ -504,46 +548,46 @@ static ALenum AddEffectSlotArray(ALCcontext *Context, ALsizei count, const ALuin
}
-static ALeffectState *CreateStateByType(ALenum type)
+void InitEffectFactoryMap(void)
{
- switch(type)
- {
- case AL_EFFECT_NULL:
- return NoneCreate();
- case AL_EFFECT_EAXREVERB:
- case AL_EFFECT_REVERB:
- return ReverbCreate();
- case AL_EFFECT_CHORUS:
- return ChorusCreate();
- case AL_EFFECT_DISTORTION:
- return DistortionCreate();
- case AL_EFFECT_ECHO:
- return EchoCreate();
- case AL_EFFECT_EQUALIZER:
- return EqualizerCreate();
- case AL_EFFECT_FLANGER:
- return FlangerCreate();
- case AL_EFFECT_RING_MODULATOR:
- return ModulatorCreate();
- case AL_EFFECT_DEDICATED_DIALOGUE:
- case AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT:
- return DedicatedCreate();
- }
+ InitUIntMap(&EffectStateFactoryMap, ~0);
+
+ InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_NULL, ALnoneStateFactory_getFactory());
+ InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_EAXREVERB, ALreverbStateFactory_getFactory());
+ InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_REVERB, ALreverbStateFactory_getFactory());
+ InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_CHORUS, ALchorusStateFactory_getFactory());
+ InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_DISTORTION, ALdistortionStateFactory_getFactory());
+ InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_ECHO, ALechoStateFactory_getFactory());
+ InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_EQUALIZER, ALequalizerStateFactory_getFactory());
+ InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_FLANGER, ALflangerStateFactory_getFactory());
+ InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_RING_MODULATOR, ALmodulatorStateFactory_getFactory());
+ InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_DEDICATED_DIALOGUE, ALdedicatedStateFactory_getFactory());
+ InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT, ALdedicatedStateFactory_getFactory());
+}
- ERR("Unexpected effect type: 0x%04x\n", type);
- return NULL;
+void DeinitEffectFactoryMap(void)
+{
+ ResetUIntMap(&EffectStateFactoryMap);
}
+
ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *effect)
{
ALenum newtype = (effect ? effect->type : AL_EFFECT_NULL);
+ ALeffectStateFactory *factory;
if(newtype != EffectSlot->effect.type)
{
ALeffectState *State;
FPUCtl oldMode;
- State = CreateStateByType(newtype);
+ factory = getFactoryByType(newtype);
+ if(!factory)
+ {
+ ERR("Failed to find factory for effect type 0x%04x\n", newtype);
+ return AL_INVALID_ENUM;
+ }
+ State = ALeffectStateFactory_create(factory);
if(!State)
return AL_OUT_OF_MEMORY;
@@ -554,7 +598,7 @@ ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *e
{
ALCdevice_Unlock(Device);
RestoreFPUMode(&oldMode);
- ALeffectState_Destroy(State);
+ ALeffectStateFactory_destroy(ALeffectState_getCreator(State), State);
return AL_OUT_OF_MEMORY;
}
@@ -573,7 +617,7 @@ ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *e
RestoreFPUMode(&oldMode);
- ALeffectState_Destroy(State);
+ ALeffectStateFactory_destroy(ALeffectState_getCreator(State), State);
State = NULL;
}
else
@@ -593,9 +637,11 @@ ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *e
ALenum InitEffectSlot(ALeffectslot *slot)
{
+ ALeffectStateFactory *factory;
ALint i, c;
- if(!(slot->EffectState=NoneCreate()))
+ factory = getFactoryByType(AL_EFFECT_NULL);
+ if(!(slot->EffectState=ALeffectStateFactory_create(factory)))
return AL_OUT_OF_MEMORY;
slot->Gain = 1.0;
@@ -621,7 +667,8 @@ ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context)
ALeffectslot *temp = Context->EffectSlotMap.array[pos].value;
Context->EffectSlotMap.array[pos].value = NULL;
- ALeffectState_Destroy(temp->EffectState);
+ ALeffectStateFactory_destroy(ALeffectState_getCreator(temp->EffectState),
+ temp->EffectState);
FreeThunkEntry(temp->id);
memset(temp, 0, sizeof(ALeffectslot));