a306407b67
This properly accounts for the room rolloff factor for normal air absorption (which makes it none by default, like distance attenuation), and uses the reverb's decay time, decay hf ratio, decay hf limit, and room air absorption properties to calculate an initial hf decay with the WetGainAuto flag. This mirrors the behavior of the initial distance decay.
191 lines
6.4 KiB
C
191 lines
6.4 KiB
C
#ifndef _AL_AUXEFFECTSLOT_H_
|
|
#define _AL_AUXEFFECTSLOT_H_
|
|
|
|
#include "alMain.h"
|
|
#include "alEffect.h"
|
|
|
|
#include "atomic.h"
|
|
#include "align.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
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, const ALCdevice *device, 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);
|
|
};
|
|
|
|
#define DEFINE_ALEFFECTSTATE_VTABLE(T) \
|
|
DECLARE_THUNK(T, ALeffectState, void, Destruct) \
|
|
DECLARE_THUNK1(T, ALeffectState, ALboolean, deviceUpdate, ALCdevice*) \
|
|
DECLARE_THUNK3(T, ALeffectState, void, update, const ALCdevice*, 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)); } \
|
|
\
|
|
static const struct ALeffectStateVtable T##_ALeffectState_vtable = { \
|
|
T##_ALeffectState_Destruct, \
|
|
\
|
|
T##_ALeffectState_deviceUpdate, \
|
|
T##_ALeffectState_update, \
|
|
T##_ALeffectState_process, \
|
|
\
|
|
T##_ALeffectState_Delete, \
|
|
}
|
|
|
|
|
|
struct ALeffectStateFactoryVtable;
|
|
|
|
typedef struct ALeffectStateFactory {
|
|
const struct ALeffectStateFactoryVtable *vtbl;
|
|
} ALeffectStateFactory;
|
|
|
|
struct ALeffectStateFactoryVtable {
|
|
ALeffectState *(*const create)(ALeffectStateFactory *factory);
|
|
};
|
|
|
|
#define DEFINE_ALEFFECTSTATEFACTORY_VTABLE(T) \
|
|
DECLARE_THUNK(T, ALeffectStateFactory, ALeffectState*, create) \
|
|
\
|
|
static const struct ALeffectStateFactoryVtable T##_ALeffectStateFactory_vtable = { \
|
|
T##_ALeffectStateFactory_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 {
|
|
ALfloat Gain;
|
|
ALboolean AuxSendAuto;
|
|
|
|
struct {
|
|
ALenum Type;
|
|
ALeffectProps Props;
|
|
|
|
ALeffectState *State;
|
|
} Effect;
|
|
|
|
ATOMIC_FLAG PropsClean;
|
|
|
|
RefCount ref;
|
|
|
|
ATOMIC(struct ALeffectslotProps*) Update;
|
|
ATOMIC(struct ALeffectslotProps*) FreeList;
|
|
|
|
struct {
|
|
ALfloat Gain;
|
|
ALboolean AuxSendAuto;
|
|
|
|
ALenum EffectType;
|
|
ALeffectState *EffectState;
|
|
|
|
ALfloat RoomRolloff; /* Added to the source's room rolloff, not multiplied. */
|
|
ALfloat DecayTime;
|
|
ALfloat DecayHFRatio;
|
|
ALfloat AirAbsorptionGainHF;
|
|
ALboolean DecayHFLimit;
|
|
} Params;
|
|
|
|
/* Self ID */
|
|
ALuint 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
|
|
* * Channel 2 is OpenAL Y
|
|
* * Channel 3 is OpenAL -Z
|
|
* 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 pan (ComputeFirstOrderGains) for
|
|
* first-order device output (FOAOut).
|
|
*/
|
|
alignas(16) ALfloat WetBuffer[MAX_EFFECT_CHANNELS][BUFFERSIZE];
|
|
} ALeffectslot;
|
|
|
|
inline void LockEffectSlotsRead(ALCcontext *context)
|
|
{ LockUIntMapRead(&context->EffectSlotMap); }
|
|
inline void UnlockEffectSlotsRead(ALCcontext *context)
|
|
{ UnlockUIntMapRead(&context->EffectSlotMap); }
|
|
inline void LockEffectSlotsWrite(ALCcontext *context)
|
|
{ LockUIntMapWrite(&context->EffectSlotMap); }
|
|
inline void UnlockEffectSlotsWrite(ALCcontext *context)
|
|
{ UnlockUIntMapWrite(&context->EffectSlotMap); }
|
|
|
|
inline struct ALeffectslot *LookupEffectSlot(ALCcontext *context, ALuint id)
|
|
{ return (struct ALeffectslot*)LookupUIntMapKeyNoLock(&context->EffectSlotMap, id); }
|
|
inline struct ALeffectslot *RemoveEffectSlot(ALCcontext *context, ALuint id)
|
|
{ return (struct ALeffectslot*)RemoveUIntMapKeyNoLock(&context->EffectSlotMap, id); }
|
|
|
|
ALenum InitEffectSlot(ALeffectslot *slot);
|
|
void DeinitEffectSlot(ALeffectslot *slot);
|
|
void UpdateEffectSlotProps(ALeffectslot *slot);
|
|
void UpdateAllEffectSlotProps(ALCcontext *context);
|
|
ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context);
|
|
|
|
|
|
ALeffectStateFactory *ALnullStateFactory_getFactory(void);
|
|
ALeffectStateFactory *ALreverbStateFactory_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);
|
|
|
|
ALeffectStateFactory *ALdedicatedStateFactory_getFactory(void);
|
|
|
|
|
|
ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *effect);
|
|
|
|
void InitEffectFactoryMap(void);
|
|
void DeinitEffectFactoryMap(void);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|