diff options
author | Chris Robinson <[email protected]> | 2020-12-15 17:25:45 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2020-12-15 18:41:50 -0800 |
commit | daf9d464781280d01b50994f1b157448a46dc916 (patch) | |
tree | 4e26a50b748d62ddfec726cdcc27eee502f737f9 | |
parent | 03358a0d8092520788690b7f143a4af098472b3f (diff) |
Use a separate structure for the context/listener params
-rw-r--r-- | al/effect.h | 5 | ||||
-rw-r--r-- | al/listener.cpp | 8 | ||||
-rw-r--r-- | al/listener.h | 35 | ||||
-rw-r--r-- | al/state.cpp | 8 | ||||
-rw-r--r-- | alc/alc.cpp | 40 | ||||
-rw-r--r-- | alc/alcontext.h | 47 | ||||
-rw-r--r-- | alc/alu.cpp | 92 |
7 files changed, 109 insertions, 126 deletions
diff --git a/al/effect.h b/al/effect.h index c30a749a..d543828a 100644 --- a/al/effect.h +++ b/al/effect.h @@ -4,8 +4,8 @@ #include "AL/al.h" #include "AL/efx.h" -#include "effects/base.h" #include "al/effects/effects.h" +#include "alc/effects/base.h" enum { @@ -53,9 +53,6 @@ struct ALeffect { DISABLE_ALLOC() }; -inline bool IsReverbEffect(const ALenum type) noexcept -{ return type == AL_EFFECT_REVERB || type == AL_EFFECT_EAXREVERB; } - EffectStateFactory *getFactoryByType(ALenum type); void InitEffect(ALeffect *effect); diff --git a/al/listener.cpp b/al/listener.cpp index 1f045d08..cef96fb0 100644 --- a/al/listener.cpp +++ b/al/listener.cpp @@ -419,12 +419,12 @@ END_API_FUNC void UpdateListenerProps(ALCcontext *context) { /* Get an unused proprty container, or allocate a new one as needed. */ - ALlistenerProps *props{context->mFreeListenerProps.load(std::memory_order_acquire)}; + ListenerProps *props{context->mFreeListenerProps.load(std::memory_order_acquire)}; if(!props) - props = new ALlistenerProps{}; + props = new ListenerProps{}; else { - ALlistenerProps *next; + ListenerProps *next; do { next = props->next.load(std::memory_order_relaxed); } while(context->mFreeListenerProps.compare_exchange_weak(props, next, @@ -441,7 +441,7 @@ void UpdateListenerProps(ALCcontext *context) props->MetersPerUnit = listener.mMetersPerUnit; /* Set the new container for updating internal parameters. */ - props = listener.Params.Update.exchange(props, std::memory_order_acq_rel); + props = context->mParams.ListenerUpdate.exchange(props, std::memory_order_acq_rel); if(props) { /* If there was an unused update container, put it back in the diff --git a/al/listener.h b/al/listener.h index e30f45c3..5f3ce3ec 100644 --- a/al/listener.h +++ b/al/listener.h @@ -9,23 +9,7 @@ #include "AL/efx.h" #include "almalloc.h" -#include "vecmat.h" -enum class DistanceModel; - - -struct ALlistenerProps { - std::array<float,3> Position; - std::array<float,3> Velocity; - std::array<float,3> OrientAt; - std::array<float,3> OrientUp; - float Gain; - float MetersPerUnit; - - std::atomic<ALlistenerProps*> next; - - DEF_NEWDEL(ALlistenerProps) -}; struct ALlistener { std::array<float,3> Position{{0.0f, 0.0f, 0.0f}}; @@ -37,25 +21,6 @@ struct ALlistener { std::atomic_flag PropsClean; - struct { - /* Pointer to the most recent property values that are awaiting an - * update. - */ - std::atomic<ALlistenerProps*> Update{nullptr}; - - alu::Matrix Matrix; - alu::Vector Velocity; - - float Gain; - float MetersPerUnit; - - float DopplerFactor; - float SpeedOfSound; /* in units per sec! */ - - bool SourceDistanceModel; - DistanceModel mDistanceModel; - } Params; - ALlistener() { PropsClean.test_and_set(std::memory_order_relaxed); } DISABLE_ALLOC() diff --git a/al/state.cpp b/al/state.cpp index ee05d3b9..f70d3689 100644 --- a/al/state.cpp +++ b/al/state.cpp @@ -834,12 +834,12 @@ END_API_FUNC void UpdateContextProps(ALCcontext *context) { /* Get an unused proprty container, or allocate a new one as needed. */ - ALcontextProps *props{context->mFreeContextProps.load(std::memory_order_acquire)}; + ContextProps *props{context->mFreeContextProps.load(std::memory_order_acquire)}; if(!props) - props = new ALcontextProps{}; + props = new ContextProps{}; else { - ALcontextProps *next; + ContextProps *next; do { next = props->next.load(std::memory_order_relaxed); } while(context->mFreeContextProps.compare_exchange_weak(props, next, @@ -855,7 +855,7 @@ void UpdateContextProps(ALCcontext *context) props->mDistanceModel = context->mDistanceModel; /* Set the new container for updating internal parameters. */ - props = context->mUpdate.exchange(props, std::memory_order_acq_rel); + props = context->mParams.ContextUpdate.exchange(props, std::memory_order_acq_rel); if(props) { /* If there was an unused update container, put it back in the diff --git a/alc/alc.cpp b/alc/alc.cpp index 6ff76d46..c712c311 100644 --- a/alc/alc.cpp +++ b/alc/alc.cpp @@ -2340,7 +2340,7 @@ ALCcontext::~ALCcontext() TRACE("Freeing context %p\n", voidp{this}); size_t count{0}; - ALcontextProps *cprops{mUpdate.exchange(nullptr, std::memory_order_relaxed)}; + ContextProps *cprops{mParams.ContextUpdate.exchange(nullptr, std::memory_order_relaxed)}; if(cprops) { ++count; @@ -2349,9 +2349,8 @@ ALCcontext::~ALCcontext() cprops = mFreeContextProps.exchange(nullptr, std::memory_order_acquire); while(cprops) { - ALcontextProps *next{cprops->next.load(std::memory_order_relaxed)}; - delete cprops; - cprops = next; + std::unique_ptr<ContextProps> old{cprops}; + cprops = old->next.load(std::memory_order_relaxed); ++count; } TRACE("Freed %zu context property object%s\n", count, (count==1)?"":"s"); @@ -2368,9 +2367,8 @@ ALCcontext::~ALCcontext() EffectSlotProps *eprops{mFreeEffectslotProps.exchange(nullptr, std::memory_order_acquire)}; while(eprops) { - EffectSlotProps *next{eprops->next.load(std::memory_order_relaxed)}; - delete eprops; - eprops = next; + std::unique_ptr<EffectSlotProps> old{eprops}; + eprops = old->next.load(std::memory_order_relaxed); ++count; } TRACE("Freed %zu AuxiliaryEffectSlot property object%s\n", count, (count==1)?"":"s"); @@ -2394,9 +2392,8 @@ ALCcontext::~ALCcontext() VoicePropsItem *vprops{mFreeVoiceProps.exchange(nullptr, std::memory_order_acquire)}; while(vprops) { - VoicePropsItem *next{vprops->next.load(std::memory_order_relaxed)}; - delete vprops; - vprops = next; + std::unique_ptr<VoicePropsItem> old{vprops}; + vprops = old->next.load(std::memory_order_relaxed); ++count; } TRACE("Freed %zu voice property object%s\n", count, (count==1)?"":"s"); @@ -2404,7 +2401,7 @@ ALCcontext::~ALCcontext() delete mVoices.exchange(nullptr, std::memory_order_relaxed); count = 0; - ALlistenerProps *lprops{mListener.Params.Update.exchange(nullptr, std::memory_order_relaxed)}; + ListenerProps *lprops{mParams.ListenerUpdate.exchange(nullptr, std::memory_order_relaxed)}; if(lprops) { ++count; @@ -2413,9 +2410,8 @@ ALCcontext::~ALCcontext() lprops = mFreeListenerProps.exchange(nullptr, std::memory_order_acquire); while(lprops) { - ALlistenerProps *next{lprops->next.load(std::memory_order_relaxed)}; - delete lprops; - lprops = next; + std::unique_ptr<ListenerProps> old{lprops}; + lprops = old->next.load(std::memory_order_relaxed); ++count; } TRACE("Freed %zu listener property object%s\n", count, (count==1)?"":"s"); @@ -2476,14 +2472,14 @@ void ALCcontext::init() mExtensionList = alExtList; - mListener.Params.Matrix = alu::Matrix::Identity(); - mListener.Params.Velocity = alu::Vector{}; - mListener.Params.Gain = mListener.Gain; - mListener.Params.MetersPerUnit = mListener.mMetersPerUnit; - mListener.Params.DopplerFactor = mDopplerFactor; - mListener.Params.SpeedOfSound = mSpeedOfSound * mDopplerVelocity; - mListener.Params.SourceDistanceModel = mSourceDistanceModel; - mListener.Params.mDistanceModel = mDistanceModel; + mParams.Matrix = alu::Matrix::Identity(); + mParams.Velocity = alu::Vector{}; + mParams.Gain = mListener.Gain; + mParams.MetersPerUnit = mListener.mMetersPerUnit; + mParams.DopplerFactor = mDopplerFactor; + mParams.SpeedOfSound = mSpeedOfSound * mDopplerVelocity; + mParams.SourceDistanceModel = mSourceDistanceModel; + mParams.mDistanceModel = mDistanceModel; mAsyncEvents = RingBuffer::Create(511, sizeof(AsyncEvent), false); diff --git a/alc/alcontext.h b/alc/alcontext.h index 3699b244..37cd010d 100644 --- a/alc/alcontext.h +++ b/alc/alcontext.h @@ -1,6 +1,7 @@ #ifndef ALCONTEXT_H #define ALCONTEXT_H +#include <array> #include <atomic> #include <cstddef> #include <cstdint> @@ -20,6 +21,7 @@ #include "inprogext.h" #include "intrusive_ptr.h" #include "threads.h" +#include "vecmat.h" #include "vector.h" #include "voice.h" @@ -54,16 +56,47 @@ struct WetBuffer { using WetBufferPtr = std::unique_ptr<WetBuffer>; -struct ALcontextProps { +struct ContextProps { float DopplerFactor; float DopplerVelocity; float SpeedOfSound; bool SourceDistanceModel; DistanceModel mDistanceModel; - std::atomic<ALcontextProps*> next; + std::atomic<ContextProps*> next; - DEF_NEWDEL(ALcontextProps) + DEF_NEWDEL(ContextProps) +}; + +struct ListenerProps { + std::array<float,3> Position; + std::array<float,3> Velocity; + std::array<float,3> OrientAt; + std::array<float,3> OrientUp; + float Gain; + float MetersPerUnit; + + std::atomic<ListenerProps*> next; + + DEF_NEWDEL(ListenerProps) +}; + +struct ContextParams { + /* Pointer to the most recent property values that are awaiting an update. */ + std::atomic<ContextProps*> ContextUpdate{nullptr}; + std::atomic<ListenerProps*> ListenerUpdate{nullptr}; + + alu::Matrix Matrix{alu::Matrix::Identity()}; + alu::Vector Velocity{}; + + float Gain{1.0f}; + float MetersPerUnit{1.0f}; + + float DopplerFactor{1.0f}; + float SpeedOfSound{343.3f}; /* in units per sec! */ + + bool SourceDistanceModel{false}; + DistanceModel mDistanceModel{}; }; @@ -141,13 +174,11 @@ struct ALCcontext : public al::intrusive_ref<ALCcontext> { float mGainBoost{1.0f}; - std::atomic<ALcontextProps*> mUpdate{nullptr}; - /* Linked lists of unused property containers, free to use for future * updates. */ - std::atomic<ALcontextProps*> mFreeContextProps{nullptr}; - std::atomic<ALlistenerProps*> mFreeListenerProps{nullptr}; + std::atomic<ContextProps*> mFreeContextProps{nullptr}; + std::atomic<ListenerProps*> mFreeListenerProps{nullptr}; std::atomic<VoicePropsItem*> mFreeVoiceProps{nullptr}; std::atomic<EffectSlotProps*> mFreeEffectslotProps{nullptr}; @@ -212,6 +243,8 @@ struct ALCcontext : public al::intrusive_ref<ALCcontext> { ALlistener mListener{}; + ContextParams mParams; + ALCcontext(al::intrusive_ptr<ALCdevice> device); ALCcontext(const ALCcontext&) = delete; diff --git a/alc/alu.cpp b/alc/alu.cpp index eefeca4d..da1a2f66 100644 --- a/alc/alu.cpp +++ b/alc/alu.cpp @@ -44,11 +44,7 @@ #include "AL/alc.h" #include "AL/efx.h" -#include "al/auxeffectslot.h" -#include "al/buffer.h" -#include "al/effect.h" #include "al/event.h" -#include "al/listener.h" #include "alcmain.h" #include "alcontext.h" #include "almalloc.h" @@ -69,6 +65,7 @@ #include "core/uhjfilter.h" #include "cpu_caps.h" #include "effects/base.h" +#include "effectslot.h" #include "fpu_ctrl.h" #include "front_stablizer.h" #include "hrtf.h" @@ -367,27 +364,25 @@ auto GetAmbi2DLayout(AmbiLayout layouttype) noexcept -> const std::array<uint8_t } -bool CalcContextParams(ALCcontext *Context) +bool CalcContextParams(ALCcontext *ctx) { - ALcontextProps *props{Context->mUpdate.exchange(nullptr, std::memory_order_acq_rel)}; + ContextProps *props{ctx->mParams.ContextUpdate.exchange(nullptr, std::memory_order_acq_rel)}; if(!props) return false; - ALlistener &Listener = Context->mListener; - Listener.Params.DopplerFactor = props->DopplerFactor; - Listener.Params.SpeedOfSound = props->SpeedOfSound * props->DopplerVelocity; + ctx->mParams.DopplerFactor = props->DopplerFactor; + ctx->mParams.SpeedOfSound = props->SpeedOfSound * props->DopplerVelocity; - Listener.Params.SourceDistanceModel = props->SourceDistanceModel; - Listener.Params.mDistanceModel = props->mDistanceModel; + ctx->mParams.SourceDistanceModel = props->SourceDistanceModel; + ctx->mParams.mDistanceModel = props->mDistanceModel; - AtomicReplaceHead(Context->mFreeContextProps, props); + AtomicReplaceHead(ctx->mFreeContextProps, props); return true; } -bool CalcListenerParams(ALCcontext *Context) +bool CalcListenerParams(ALCcontext *ctx) { - ALlistener &Listener = Context->mListener; - - ALlistenerProps *props{Listener.Params.Update.exchange(nullptr, std::memory_order_acq_rel)}; + ListenerProps *props{ctx->mParams.ListenerUpdate.exchange(nullptr, + std::memory_order_acq_rel)}; if(!props) return false; /* AT then UP */ @@ -405,21 +400,20 @@ bool CalcListenerParams(ALCcontext *Context) U[2], V[2], -N[2], 0.0, 0.0, 0.0, 0.0, 1.0}; const alu::VectorR<double> pos{props->Position[0],props->Position[1],props->Position[2],1.0}; + const alu::VectorR<double> vel{props->Velocity[0],props->Velocity[1],props->Velocity[2],0.0}; const alu::Vector P{alu::cast_to<float>(rot * pos)}; - Listener.Params.Matrix = alu::Matrix{ + ctx->mParams.Matrix = alu::Matrix{ U[0], V[0], -N[0], 0.0f, U[1], V[1], -N[1], 0.0f, U[2], V[2], -N[2], 0.0f, -P[0], -P[1], -P[2], 1.0f}; + ctx->mParams.Velocity = alu::cast_to<float>(rot * vel); - const alu::Vector vel{props->Velocity[0], props->Velocity[1], props->Velocity[2], 0.0f}; - Listener.Params.Velocity = Listener.Params.Matrix * vel; - - Listener.Params.Gain = props->Gain * Context->mGainBoost; - Listener.Params.MetersPerUnit = props->MetersPerUnit; + ctx->mParams.Gain = props->Gain * ctx->mGainBoost; + ctx->mParams.MetersPerUnit = props->MetersPerUnit; - AtomicReplaceHead(Context->mFreeListenerProps, props); + AtomicReplaceHead(ctx->mFreeListenerProps, props); return true; } @@ -438,7 +432,7 @@ bool CalcEffectSlotParams(EffectSlot *slot, EffectSlot **sorted_slots, ALCcontex slot->Target = props->Target; slot->EffectType = props->Type; slot->mEffectProps = props->Props; - if(IsReverbEffect(props->Type)) + if(props->Type == AL_EFFECT_REVERB || props->Type == AL_EFFECT_EAXREVERB) { slot->RoomRolloff = props->Props.Reverb.RoomRolloffFactor; slot->DecayTime = props->Props.Reverb.DecayTime; @@ -683,7 +677,7 @@ struct GainTriplet { float Base, HF, LF; }; void CalcPanningAndFilters(Voice *voice, const float xpos, const float ypos, const float zpos, const float Distance, const float Spread, const GainTriplet &DryGain, const al::span<const GainTriplet,MAX_SENDS> WetGain, EffectSlot *(&SendSlots)[MAX_SENDS], - const VoiceProps *props, const ALlistener &Listener, const ALCdevice *Device) + const VoiceProps *props, const ContextParams &Context, const ALCdevice *Device) { static const ChanMap MonoMap[1]{ { FrontCenter, 0.0f, 0.0f } @@ -882,8 +876,8 @@ void CalcPanningAndFilters(Voice *voice, const float xpos, const float ypos, con V.normalize(); if(!props->HeadRelative) { - N = Listener.Params.Matrix * N; - V = Listener.Params.Matrix * V; + N = Context.Matrix * N; + V = Context.Matrix * V; } /* Build and normalize right-vector */ alu::Vector U{N.cross_product(V)}; @@ -1201,9 +1195,9 @@ void CalcPanningAndFilters(Voice *voice, const float xpos, const float ypos, con } } -void CalcNonAttnSourceParams(Voice *voice, const VoiceProps *props, const ALCcontext *ALContext) +void CalcNonAttnSourceParams(Voice *voice, const VoiceProps *props, const ALCcontext *context) { - const ALCdevice *Device{ALContext->mDevice.get()}; + const ALCdevice *Device{context->mDevice.get()}; EffectSlot *SendSlots[MAX_SENDS]; voice->mDirect.Buffer = Device->Dry.Buffer; @@ -1229,30 +1223,28 @@ void CalcNonAttnSourceParams(Voice *voice, const VoiceProps *props, const ALCcon voice->mResampler = PrepareResampler(props->mResampler, voice->mStep, &voice->mResampleState); /* Calculate gains */ - const ALlistener &Listener = ALContext->mListener; GainTriplet DryGain; DryGain.Base = minf(clampf(props->Gain, props->MinGain, props->MaxGain) * props->Direct.Gain * - Listener.Params.Gain, GainMixMax); + context->mParams.Gain, GainMixMax); DryGain.HF = props->Direct.GainHF; DryGain.LF = props->Direct.GainLF; GainTriplet WetGain[MAX_SENDS]; for(ALuint i{0};i < Device->NumAuxSends;i++) { WetGain[i].Base = minf(clampf(props->Gain, props->MinGain, props->MaxGain) * - props->Send[i].Gain * Listener.Params.Gain, GainMixMax); + props->Send[i].Gain * context->mParams.Gain, GainMixMax); WetGain[i].HF = props->Send[i].GainHF; WetGain[i].LF = props->Send[i].GainLF; } CalcPanningAndFilters(voice, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, DryGain, WetGain, SendSlots, props, - Listener, Device); + context->mParams, Device); } -void CalcAttnSourceParams(Voice *voice, const VoiceProps *props, const ALCcontext *ALContext) +void CalcAttnSourceParams(Voice *voice, const VoiceProps *props, const ALCcontext *context) { - const ALCdevice *Device{ALContext->mDevice.get()}; + const ALCdevice *Device{context->mDevice.get()}; const ALuint NumSends{Device->NumAuxSends}; - const ALlistener &Listener = ALContext->mListener; /* Set mixing buffers and get send parameters. */ voice->mDirect.Buffer = Device->Dry.Buffer; @@ -1318,14 +1310,14 @@ void CalcAttnSourceParams(Voice *voice, const VoiceProps *props, const ALCcontex if(!props->HeadRelative) { /* Transform source vectors */ - Position = Listener.Params.Matrix * Position; - Velocity = Listener.Params.Matrix * Velocity; - Direction = Listener.Params.Matrix * Direction; + Position = context->mParams.Matrix * Position; + Velocity = context->mParams.Matrix * Velocity; + Direction = context->mParams.Matrix * Direction; } else { /* Offset the source velocity to be relative of the listener velocity */ - Velocity += Listener.Params.Velocity; + Velocity += context->mParams.Velocity; } const bool directional{Direction.normalize() > 0.0f}; @@ -1341,8 +1333,8 @@ void CalcAttnSourceParams(Voice *voice, const VoiceProps *props, const ALCcontex /* Calculate distance attenuation */ float ClampedDist{Distance}; - switch(Listener.Params.SourceDistanceModel ? - props->mDistanceModel : Listener.Params.mDistanceModel) + switch(context->mParams.SourceDistanceModel ? props->mDistanceModel + : context->mParams.mDistanceModel) { case DistanceModel::InverseClamped: ClampedDist = clampf(ClampedDist, props->RefDistance, props->MaxDistance); @@ -1441,13 +1433,13 @@ void CalcAttnSourceParams(Voice *voice, const VoiceProps *props, const ALCcontex /* Apply gain and frequency filters */ DryGain.Base = minf(clampf(DryGain.Base, props->MinGain, props->MaxGain) * props->Direct.Gain * - Listener.Params.Gain, GainMixMax); + context->mParams.Gain, GainMixMax); DryGain.HF *= props->Direct.GainHF; DryGain.LF *= props->Direct.GainLF; for(ALuint i{0};i < NumSends;i++) { WetGain[i].Base = minf(clampf(WetGain[i].Base, props->MinGain, props->MaxGain) * - props->Send[i].Gain * Listener.Params.Gain, GainMixMax); + props->Send[i].Gain * context->mParams.Gain, GainMixMax); WetGain[i].HF *= props->Send[i].GainHF; WetGain[i].LF *= props->Send[i].GainLF; } @@ -1456,7 +1448,7 @@ void CalcAttnSourceParams(Voice *voice, const VoiceProps *props, const ALCcontex if(ClampedDist > props->RefDistance && props->RolloffFactor > 0.0f) { const float meters_base{(ClampedDist-props->RefDistance) * props->RolloffFactor * - Listener.Params.MetersPerUnit}; + context->mParams.MetersPerUnit}; if(props->AirAbsorptionFactor > 0.0f) { const float hfattn{std::pow(AirAbsorbGainHF, meters_base*props->AirAbsorptionFactor)}; @@ -1497,14 +1489,14 @@ void CalcAttnSourceParams(Voice *voice, const VoiceProps *props, const ALCcontex float Pitch{props->Pitch}; /* Calculate velocity-based doppler effect */ - float DopplerFactor{props->DopplerFactor * Listener.Params.DopplerFactor}; + float DopplerFactor{props->DopplerFactor * context->mParams.DopplerFactor}; if(DopplerFactor > 0.0f) { - const alu::Vector &lvelocity = Listener.Params.Velocity; + const alu::Vector &lvelocity = context->mParams.Velocity; float vss{Velocity.dot_product(ToSource) * -DopplerFactor}; float vls{lvelocity.dot_product(ToSource) * -DopplerFactor}; - const float SpeedOfSound{Listener.Params.SpeedOfSound}; + const float SpeedOfSound{context->mParams.SpeedOfSound}; if(!(vls < SpeedOfSound)) { /* Listener moving away from the source at the speed of sound. @@ -1545,8 +1537,8 @@ void CalcAttnSourceParams(Voice *voice, const VoiceProps *props, const ALCcontex spread = std::asin(props->Radius/Distance) * 2.0f; CalcPanningAndFilters(voice, ToSource[0], ToSource[1], ToSource[2]*ZScale, - Distance*Listener.Params.MetersPerUnit, spread, DryGain, WetGain, SendSlots, props, - Listener, Device); + Distance*context->mParams.MetersPerUnit, spread, DryGain, WetGain, SendSlots, props, + context->mParams, Device); } void CalcSourceParams(Voice *voice, ALCcontext *context, bool force) |