diff options
author | Chris Robinson <[email protected]> | 2019-08-05 11:37:05 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2019-08-05 11:37:05 -0700 |
commit | 3154a915b1f811416f3c29c6af0c0f13fc3acd3e (patch) | |
tree | ca8f86ca621f06037a360513f30748dac87fe3a0 | |
parent | 3bc9490fd2861bdb28951bae5af37500e93de7ad (diff) |
Remove the ReverbSpeedOfSound hack
No other effect depends on context or listener properties, so reverb being the
only exception for speed of sound and meters per unit was putting extra work on
the effect engine for no real reason. Especially since the reverb decay time
should be the time actual time to decay irrespective of other settings.
-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, |