aboutsummaryrefslogtreecommitdiffstats
path: root/OpenAL32/alAuxEffectSlot.c
diff options
context:
space:
mode:
Diffstat (limited to 'OpenAL32/alAuxEffectSlot.c')
-rw-r--r--OpenAL32/alAuxEffectSlot.c119
1 files changed, 83 insertions, 36 deletions
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));