Use factories to create and destroy effect states

This commit is contained in:
Chris Robinson 2013-05-21 12:47:18 -07:00
parent af1936be5d
commit a5d94f5d09
12 changed files with 508 additions and 138 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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;

View File

@ -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)

View File

@ -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;

View File

@ -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)

View File

@ -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)

View File

@ -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.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.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.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->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->Offset = 0;
State->Gain = State->Late.PanGain;
state->Gain = state->Late.PanGain;
return STATIC_CAST(ALeffectState, State);
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)

View File

@ -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

View File

@ -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

View File

@ -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);
ERR("Unexpected effect type: 0x%04x\n", type);
return NULL;
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());
}
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));