diff options
-rw-r--r-- | Alc/ALc.c | 4 | ||||
-rw-r--r-- | Alc/alcChorus.c | 40 | ||||
-rw-r--r-- | Alc/alcDedicated.c | 40 | ||||
-rw-r--r-- | Alc/alcDistortion.c | 45 | ||||
-rw-r--r-- | Alc/alcEcho.c | 40 | ||||
-rw-r--r-- | Alc/alcEqualizer.c | 41 | ||||
-rw-r--r-- | Alc/alcFlanger.c | 40 | ||||
-rw-r--r-- | Alc/alcModulator.c | 40 | ||||
-rw-r--r-- | Alc/alcReverb.c | 177 | ||||
-rw-r--r-- | OpenAL32/Include/alAuxEffectSlot.h | 65 | ||||
-rw-r--r-- | OpenAL32/Include/alMain.h | 5 | ||||
-rw-r--r-- | OpenAL32/alAuxEffectSlot.c | 119 |
12 files changed, 513 insertions, 143 deletions
@@ -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)); |