diff options
Diffstat (limited to 'OpenAL32/Include/alAuxEffectSlot.h')
-rw-r--r-- | OpenAL32/Include/alAuxEffectSlot.h | 148 |
1 files changed, 108 insertions, 40 deletions
diff --git a/OpenAL32/Include/alAuxEffectSlot.h b/OpenAL32/Include/alAuxEffectSlot.h index 0f0d3ef8..03ee97d6 100644 --- a/OpenAL32/Include/alAuxEffectSlot.h +++ b/OpenAL32/Include/alAuxEffectSlot.h @@ -4,6 +4,7 @@ #include "alMain.h" #include "alEffect.h" +#include "atomic.h" #include "align.h" #ifdef __cplusplus @@ -14,24 +15,36 @@ struct ALeffectStateVtable; struct ALeffectslot; typedef struct ALeffectState { + RefCount Ref; const struct ALeffectStateVtable *vtbl; + + ALfloat (*OutBuffer)[BUFFERSIZE]; + ALsizei OutChannels; } ALeffectState; +void ALeffectState_Construct(ALeffectState *state); +void ALeffectState_Destruct(ALeffectState *state); + struct ALeffectStateVtable { void (*const Destruct)(ALeffectState *state); ALboolean (*const deviceUpdate)(ALeffectState *state, ALCdevice *device); - void (*const update)(ALeffectState *state, ALCdevice *device, const struct ALeffectslot *slot); - void (*const process)(ALeffectState *state, ALuint samplesToDo, const ALfloat *restrict samplesIn, ALfloat (*restrict samplesOut)[BUFFERSIZE], ALuint numChannels); + void (*const update)(ALeffectState *state, const ALCcontext *context, const struct ALeffectslot *slot, const union ALeffectProps *props); + void (*const process)(ALeffectState *state, ALsizei samplesToDo, const ALfloat (*restrict samplesIn)[BUFFERSIZE], ALfloat (*restrict samplesOut)[BUFFERSIZE], ALsizei numChannels); void (*const Delete)(void *ptr); }; +/* Small hack to use a pointer-to-array types as a normal argument type. + * Shouldn't be used directly. + */ +typedef ALfloat ALfloatBUFFERSIZE[BUFFERSIZE]; + #define DEFINE_ALEFFECTSTATE_VTABLE(T) \ DECLARE_THUNK(T, ALeffectState, void, Destruct) \ DECLARE_THUNK1(T, ALeffectState, ALboolean, deviceUpdate, ALCdevice*) \ -DECLARE_THUNK2(T, ALeffectState, void, update, ALCdevice*, const ALeffectslot*) \ -DECLARE_THUNK4(T, ALeffectState, void, process, ALuint, const ALfloat*restrict, ALfloatBUFFERSIZE*restrict, ALuint) \ +DECLARE_THUNK3(T, ALeffectState, void, update, const ALCcontext*, const ALeffectslot*, const ALeffectProps*) \ +DECLARE_THUNK4(T, ALeffectState, void, process, ALsizei, const ALfloatBUFFERSIZE*restrict, ALfloatBUFFERSIZE*restrict, ALsizei) \ static void T##_ALeffectState_Delete(void *ptr) \ { return T##_Delete(STATIC_UPCAST(T, ALeffectState, (ALeffectState*)ptr)); } \ \ @@ -46,69 +59,124 @@ static const struct ALeffectStateVtable T##_ALeffectState_vtable = { \ } -struct ALeffectStateFactoryVtable; +struct EffectStateFactoryVtable; -typedef struct ALeffectStateFactory { - const struct ALeffectStateFactoryVtable *vtbl; -} ALeffectStateFactory; +typedef struct EffectStateFactory { + const struct EffectStateFactoryVtable *vtab; +} EffectStateFactory; -struct ALeffectStateFactoryVtable { - ALeffectState *(*const create)(ALeffectStateFactory *factory); +struct EffectStateFactoryVtable { + ALeffectState *(*const create)(EffectStateFactory *factory); }; +#define EffectStateFactory_create(x) ((x)->vtab->create((x))) -#define DEFINE_ALEFFECTSTATEFACTORY_VTABLE(T) \ -DECLARE_THUNK(T, ALeffectStateFactory, ALeffectState*, create) \ +#define DEFINE_EFFECTSTATEFACTORY_VTABLE(T) \ +DECLARE_THUNK(T, EffectStateFactory, ALeffectState*, create) \ \ -static const struct ALeffectStateFactoryVtable T##_ALeffectStateFactory_vtable = { \ - T##_ALeffectStateFactory_create, \ +static const struct EffectStateFactoryVtable T##_EffectStateFactory_vtable = { \ + T##_EffectStateFactory_create, \ } +#define MAX_EFFECT_CHANNELS (4) + + +struct ALeffectslotArray { + ALsizei count; + struct ALeffectslot *slot[]; +}; + + +struct ALeffectslotProps { + ALfloat Gain; + ALboolean AuxSendAuto; + + ALenum Type; + ALeffectProps Props; + + ALeffectState *State; + + ATOMIC(struct ALeffectslotProps*) next; +}; + + typedef struct ALeffectslot { - ALenum EffectType; - ALeffectProps EffectProps; + ALfloat Gain; + ALboolean AuxSendAuto; - volatile ALfloat Gain; - volatile ALboolean AuxSendAuto; + struct { + ALenum Type; + ALeffectProps Props; - ATOMIC(ALenum) NeedsUpdate; - ALeffectState *EffectState; + ALeffectState *State; + } Effect; - alignas(16) ALfloat WetBuffer[1][BUFFERSIZE]; + ATOMIC_FLAG PropsClean; RefCount ref; + ATOMIC(struct ALeffectslotProps*) Update; + + struct { + ALfloat Gain; + ALboolean AuxSendAuto; + + ALenum EffectType; + ALeffectProps EffectProps; + ALeffectState *EffectState; + + ALfloat RoomRolloff; /* Added to the source's room rolloff, not multiplied. */ + ALfloat DecayTime; + ALfloat DecayLFRatio; + ALfloat DecayHFRatio; + ALboolean DecayHFLimit; + ALfloat AirAbsorptionGainHF; + } Params; + /* Self ID */ ALuint id; -} ALeffectslot; -inline struct ALeffectslot *LookupEffectSlot(ALCcontext *context, ALuint id) -{ return (struct ALeffectslot*)LookupUIntMapKey(&context->EffectSlotMap, id); } -inline struct ALeffectslot *RemoveEffectSlot(ALCcontext *context, ALuint id) -{ return (struct ALeffectslot*)RemoveUIntMapKey(&context->EffectSlotMap, id); } + ALsizei NumChannels; + BFChannelConfig ChanMap[MAX_EFFECT_CHANNELS]; + /* Wet buffer configuration is ACN channel order with N3D scaling: + * * Channel 0 is the unattenuated mono signal. + * * Channel 1 is OpenAL -X * sqrt(3) + * * Channel 2 is OpenAL Y * sqrt(3) + * * Channel 3 is OpenAL -Z * sqrt(3) + * Consequently, effects that only want to work with mono input can use + * channel 0 by itself. Effects that want multichannel can process the + * ambisonics signal and make a B-Format source pan for first-order device + * output (FOAOut). + */ + alignas(16) ALfloat WetBuffer[MAX_EFFECT_CHANNELS][BUFFERSIZE]; +} ALeffectslot; ALenum InitEffectSlot(ALeffectslot *slot); +void DeinitEffectSlot(ALeffectslot *slot); +void UpdateEffectSlotProps(ALeffectslot *slot, ALCcontext *context); +void UpdateAllEffectSlotProps(ALCcontext *context); ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context); -ALeffectStateFactory *ALnullStateFactory_getFactory(void); -ALeffectStateFactory *ALreverbStateFactory_getFactory(void); -ALeffectStateFactory *ALautowahStateFactory_getFactory(void); -ALeffectStateFactory *ALchorusStateFactory_getFactory(void); -ALeffectStateFactory *ALcompressorStateFactory_getFactory(void); -ALeffectStateFactory *ALdistortionStateFactory_getFactory(void); -ALeffectStateFactory *ALechoStateFactory_getFactory(void); -ALeffectStateFactory *ALequalizerStateFactory_getFactory(void); -ALeffectStateFactory *ALflangerStateFactory_getFactory(void); -ALeffectStateFactory *ALmodulatorStateFactory_getFactory(void); +EffectStateFactory *NullStateFactory_getFactory(void); +EffectStateFactory *ReverbStateFactory_getFactory(void); +EffectStateFactory *AutowahStateFactory_getFactory(void); +EffectStateFactory *ChorusStateFactory_getFactory(void); +EffectStateFactory *CompressorStateFactory_getFactory(void); +EffectStateFactory *DistortionStateFactory_getFactory(void); +EffectStateFactory *EchoStateFactory_getFactory(void); +EffectStateFactory *EqualizerStateFactory_getFactory(void); +EffectStateFactory *FlangerStateFactory_getFactory(void); +EffectStateFactory *FshifterStateFactory_getFactory(void); +EffectStateFactory *ModulatorStateFactory_getFactory(void); +EffectStateFactory *PshifterStateFactory_getFactory(void); -ALeffectStateFactory *ALdedicatedStateFactory_getFactory(void); +EffectStateFactory *DedicatedStateFactory_getFactory(void); -ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *effect); +ALenum InitializeEffect(ALCcontext *Context, ALeffectslot *EffectSlot, ALeffect *effect); -void InitEffectFactoryMap(void); -void DeinitEffectFactoryMap(void); +void ALeffectState_DecRef(ALeffectState *state); #ifdef __cplusplus } |