aboutsummaryrefslogtreecommitdiffstats
path: root/OpenAL32
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2013-05-21 12:47:18 -0700
committerChris Robinson <[email protected]>2013-05-21 12:47:18 -0700
commita5d94f5d09be24bf34cbf8433a288cfd9ca396fb (patch)
tree456165199302b1b30bc68aadd4913f5d4ecf1572 /OpenAL32
parentaf1936be5dd4724367bfb7a90965f8769aa4f705 (diff)
Use factories to create and destroy effect states
Diffstat (limited to 'OpenAL32')
-rw-r--r--OpenAL32/Include/alAuxEffectSlot.h65
-rw-r--r--OpenAL32/Include/alMain.h5
-rw-r--r--OpenAL32/alAuxEffectSlot.c119
3 files changed, 137 insertions, 52 deletions
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));