diff options
author | Chris Robinson <[email protected]> | 2013-05-21 12:47:18 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2013-05-21 12:47:18 -0700 |
commit | a5d94f5d09be24bf34cbf8433a288cfd9ca396fb (patch) | |
tree | 456165199302b1b30bc68aadd4913f5d4ecf1572 /OpenAL32 | |
parent | af1936be5dd4724367bfb7a90965f8769aa4f705 (diff) |
Use factories to create and destroy effect states
Diffstat (limited to 'OpenAL32')
-rw-r--r-- | OpenAL32/Include/alAuxEffectSlot.h | 65 | ||||
-rw-r--r-- | OpenAL32/Include/alMain.h | 5 | ||||
-rw-r--r-- | OpenAL32/alAuxEffectSlot.c | 119 |
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)); |