diff options
-rw-r--r-- | al/listener.h | 1 | ||||
-rw-r--r-- | alc/alc.cpp | 2 | ||||
-rw-r--r-- | alc/alu.cpp | 134 | ||||
-rw-r--r-- | alc/alu.h | 1 | ||||
-rw-r--r-- | alc/effects/reverb.cpp | 9 |
5 files changed, 59 insertions, 88 deletions
diff --git a/al/listener.h b/al/listener.h index a71db9f8..692880cd 100644 --- a/al/listener.h +++ b/al/listener.h @@ -44,7 +44,6 @@ struct ALlistener { ALfloat DopplerFactor; ALfloat SpeedOfSound; /* in units per sec! */ - ALfloat ReverbSpeedOfSound; /* in meters per sec! */ ALboolean SourceDistanceModel; DistanceModel mDistanceModel; diff --git a/alc/alc.cpp b/alc/alc.cpp index f66654c2..ca7ce4fb 100644 --- a/alc/alc.cpp +++ b/alc/alc.cpp @@ -2448,8 +2448,6 @@ void ALCcontext::init() mListener.Params.MetersPerUnit = mMetersPerUnit; mListener.Params.DopplerFactor = mDopplerFactor; mListener.Params.SpeedOfSound = mSpeedOfSound * mDopplerVelocity; - mListener.Params.ReverbSpeedOfSound = mListener.Params.SpeedOfSound * - mListener.Params.MetersPerUnit; mListener.Params.SourceDistanceModel = mSourceDistanceModel; mListener.Params.mDistanceModel = mDistanceModel; diff --git a/alc/alu.cpp b/alc/alu.cpp index 412bfffa..4044c712 100644 --- a/alc/alu.cpp +++ b/alc/alu.cpp @@ -102,15 +102,6 @@ ALfloat InitZScale() return ret; } -ALboolean InitReverbSOS() -{ - ALboolean ret{AL_FALSE}; - const char *str{getenv("__ALSOFT_REVERB_IGNORES_SOUND_SPEED")}; - if(str && (strcasecmp(str, "true") == 0 || strtol(str, nullptr, 0) == 1)) - ret = AL_TRUE; - return ret; -} - } // namespace /* Cone scalar */ @@ -119,9 +110,6 @@ const ALfloat ConeScale{InitConeScale()}; /* Localized Z scalar for mono sources */ const ALfloat ZScale{InitZScale()}; -/* Force default speed of sound for distance-related reverb decay. */ -const ALboolean OverrideReverbSpeedOfSound{InitReverbSOS()}; - namespace { @@ -287,9 +275,6 @@ bool CalcContextParams(ALCcontext *Context) Listener.Params.DopplerFactor = props->DopplerFactor; Listener.Params.SpeedOfSound = props->SpeedOfSound * props->DopplerVelocity; - if(!OverrideReverbSpeedOfSound) - Listener.Params.ReverbSpeedOfSound = Listener.Params.SpeedOfSound * - Listener.Params.MetersPerUnit; Listener.Params.SourceDistanceModel = props->SourceDistanceModel; Listener.Params.mDistanceModel = props->mDistanceModel; @@ -334,76 +319,68 @@ bool CalcListenerParams(ALCcontext *Context) return true; } -bool CalcEffectSlotParams(ALeffectslot *slot, ALCcontext *context, bool force) +bool CalcEffectSlotParams(ALeffectslot *slot, ALCcontext *context) { ALeffectslotProps *props{slot->Update.exchange(nullptr, std::memory_order_acq_rel)}; - if(!props && !force) return false; + if(!props) return false; - EffectState *state; - if(!props) - state = slot->Params.mEffectState; + slot->Params.Gain = props->Gain; + slot->Params.AuxSendAuto = props->AuxSendAuto; + slot->Params.Target = props->Target; + slot->Params.EffectType = props->Type; + slot->Params.mEffectProps = props->Props; + if(IsReverbEffect(props->Type)) + { + slot->Params.RoomRolloff = props->Props.Reverb.RoomRolloffFactor; + slot->Params.DecayTime = props->Props.Reverb.DecayTime; + slot->Params.DecayLFRatio = props->Props.Reverb.DecayLFRatio; + slot->Params.DecayHFRatio = props->Props.Reverb.DecayHFRatio; + slot->Params.DecayHFLimit = props->Props.Reverb.DecayHFLimit; + slot->Params.AirAbsorptionGainHF = props->Props.Reverb.AirAbsorptionGainHF; + } else { - slot->Params.Gain = props->Gain; - slot->Params.AuxSendAuto = props->AuxSendAuto; - slot->Params.Target = props->Target; - slot->Params.EffectType = props->Type; - slot->Params.mEffectProps = props->Props; - if(IsReverbEffect(props->Type)) + slot->Params.RoomRolloff = 0.0f; + slot->Params.DecayTime = 0.0f; + slot->Params.DecayLFRatio = 0.0f; + slot->Params.DecayHFRatio = 0.0f; + slot->Params.DecayHFLimit = AL_FALSE; + slot->Params.AirAbsorptionGainHF = 1.0f; + } + + EffectState *state{props->State}; + props->State = nullptr; + EffectState *oldstate{slot->Params.mEffectState}; + slot->Params.mEffectState = state; + + /* Only release the old state if it won't get deleted, since we can't be + * deleting/freeing anything in the mixer. + */ + if(!oldstate->releaseIfNoDelete()) + { + /* Otherwise, if it would be deleted send it off with a release event. */ + RingBuffer *ring{context->mAsyncEvents.get()}; + auto evt_vec = ring->getWriteVector(); + if LIKELY(evt_vec.first.len > 0) { - slot->Params.RoomRolloff = props->Props.Reverb.RoomRolloffFactor; - slot->Params.DecayTime = props->Props.Reverb.DecayTime; - slot->Params.DecayLFRatio = props->Props.Reverb.DecayLFRatio; - slot->Params.DecayHFRatio = props->Props.Reverb.DecayHFRatio; - slot->Params.DecayHFLimit = props->Props.Reverb.DecayHFLimit; - slot->Params.AirAbsorptionGainHF = props->Props.Reverb.AirAbsorptionGainHF; + AsyncEvent *evt{new (evt_vec.first.buf) AsyncEvent{EventType_ReleaseEffectState}}; + evt->u.mEffectState = oldstate; + ring->writeAdvance(1); + context->mEventSem.post(); } else { - slot->Params.RoomRolloff = 0.0f; - slot->Params.DecayTime = 0.0f; - slot->Params.DecayLFRatio = 0.0f; - slot->Params.DecayHFRatio = 0.0f; - slot->Params.DecayHFLimit = AL_FALSE; - slot->Params.AirAbsorptionGainHF = 1.0f; - } - - state = props->State; - props->State = nullptr; - EffectState *oldstate{slot->Params.mEffectState}; - slot->Params.mEffectState = state; - - /* Only decrement the old state if it won't get deleted, since we can't - * be deleting/freeing anything in the mixer. - */ - if(!oldstate->releaseIfNoDelete()) - { - /* Otherwise, if it would be deleted, send it off with a release - * event. + /* If writing the event failed, the queue was probably full. Store + * the old state in the property object where it can eventually be + * cleaned up sometime later (not ideal, but better than blocking + * or leaking). */ - RingBuffer *ring{context->mAsyncEvents.get()}; - auto evt_vec = ring->getWriteVector(); - if LIKELY(evt_vec.first.len > 0) - { - AsyncEvent *evt{new (evt_vec.first.buf) AsyncEvent{EventType_ReleaseEffectState}}; - evt->u.mEffectState = oldstate; - ring->writeAdvance(1); - context->mEventSem.post(); - } - else - { - /* If writing the event failed, the queue was probably full. - * Store the old state in the property object where it can - * eventually be cleaned up sometime later (not ideal, but - * better than blocking or leaking). - */ - props->State = oldstate; - } + props->State = oldstate; } - - AtomicReplaceHead(context->mFreeEffectslotProps, props); } + AtomicReplaceHead(context->mFreeEffectslotProps, props); + EffectTarget output; if(ALeffectslot *target{slot->Params.Target}) output = EffectTarget{&target->Wet, nullptr}; @@ -1034,8 +1011,7 @@ void CalcAttnSourceParams(ALvoice *voice, const ALvoicePropsBase *props, const A /* Calculate the distances to where this effect's decay reaches * -60dB. */ - DecayDistance[i] = SendSlots[i]->Params.DecayTime * - Listener.Params.ReverbSpeedOfSound; + DecayDistance[i] = SendSlots[i]->Params.DecayTime * SPEEDOFSOUNDMETRESPERSEC; DecayLFDistance[i] = DecayDistance[i] * SendSlots[i]->Params.DecayLFRatio; DecayHFDistance[i] = DecayDistance[i] * SendSlots[i]->Params.DecayHFRatio; if(SendSlots[i]->Params.DecayHFLimit) @@ -1349,11 +1325,11 @@ void ProcessParamUpdates(ALCcontext *ctx, const ALeffectslotArray &slots, IncrementRef(ctx->mUpdateCount); if LIKELY(!ctx->mHoldUpdates.load(std::memory_order_acquire)) { - bool cforce{CalcContextParams(ctx)}; - bool force{CalcListenerParams(ctx) || cforce}; - force = std::accumulate(slots.begin(), slots.end(), force, - [ctx,cforce](bool force, ALeffectslot *slot) -> bool - { return CalcEffectSlotParams(slot, ctx, cforce) | force; } + bool force{CalcContextParams(ctx)}; + force |= CalcListenerParams(ctx); + force |= std::accumulate(slots.begin(), slots.end(), bool{false}, + [ctx](bool force, ALeffectslot *slot) -> bool + { return CalcEffectSlotParams(slot, ctx) | force; } ); std::for_each(voices.begin(), voices.end(), @@ -461,6 +461,5 @@ extern RowMixerFunc MixRowSamples; extern const ALfloat ConeScale; extern const ALfloat ZScale; -extern const ALboolean OverrideReverbSpeedOfSound; #endif diff --git a/alc/effects/reverb.cpp b/alc/effects/reverb.cpp index a8c4523e..eb8db3d1 100644 --- a/alc/effects/reverb.cpp +++ b/alc/effects/reverb.cpp @@ -675,14 +675,15 @@ inline ALvoid CalcMatrixCoeffs(const ALfloat diffusion, ALfloat *x, ALfloat *y) * filters. */ ALfloat CalcLimitedHfRatio(const ALfloat hfRatio, const ALfloat airAbsorptionGainHF, - const ALfloat decayTime, const ALfloat SpeedOfSound) + const ALfloat decayTime) { /* Find the attenuation due to air absorption in dB (converting delay * time to meters using the speed of sound). Then reversing the decay * equation, solve for HF ratio. The delay length is cancelled out of * the equation, so it can be calculated once for all lines. */ - ALfloat limitRatio{1.0f / (CalcDecayLength(airAbsorptionGainHF, decayTime) * SpeedOfSound)}; + ALfloat limitRatio{1.0f / + (CalcDecayLength(airAbsorptionGainHF, decayTime) * SPEEDOFSOUNDMETRESPERSEC)}; /* Using the limit calculated above, apply the upper bound to the HF ratio. */ @@ -906,7 +907,6 @@ void ReverbState::update3DPanning(const ALfloat *ReflectionsPan, const ALfloat * void ReverbState::update(const ALCcontext *Context, const ALeffectslot *Slot, const EffectProps *props, const EffectTarget target) { const ALCdevice *Device{Context->mDevice.get()}; - const ALlistener &Listener = Context->mListener; const auto frequency = static_cast<ALfloat>(Device->Frequency); /* Calculate the master filters */ @@ -944,8 +944,7 @@ void ReverbState::update(const ALCcontext *Context, const ALeffectslot *Slot, co ALfloat hfRatio{props->Reverb.DecayHFRatio}; if(props->Reverb.DecayHFLimit && props->Reverb.AirAbsorptionGainHF < 1.0f) hfRatio = CalcLimitedHfRatio(hfRatio, props->Reverb.AirAbsorptionGainHF, - props->Reverb.DecayTime, Listener.Params.ReverbSpeedOfSound - ); + props->Reverb.DecayTime); /* Calculate the LF/HF decay times. */ const ALfloat lfDecayTime{clampf(props->Reverb.DecayTime * props->Reverb.DecayLFRatio, |