diff options
author | Chris Robinson <[email protected]> | 2021-01-27 14:17:46 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2021-01-27 14:55:20 -0800 |
commit | f0f7bc036f3480423ba5a1ddded787cf7df7a353 (patch) | |
tree | 89c143794cef8406ebff2809c199587f245c210e /alc/voice.cpp | |
parent | 3b89246733420f2ca0ac495c710b856f58ee580e (diff) |
Rework fading of stopped sounds
Voices that stop and have no more accessible samples now fade out over 64
samples max. The extra loaded samples are also prevented from moving away from
0 amplitude. Paused voices that still have samples will still fade out over the
whole mix.
Diffstat (limited to 'alc/voice.cpp')
-rw-r--r-- | alc/voice.cpp | 35 |
1 files changed, 13 insertions, 22 deletions
diff --git a/alc/voice.cpp b/alc/voice.cpp index 3b795b04..310e3f3c 100644 --- a/alc/voice.cpp +++ b/alc/voice.cpp @@ -486,15 +486,8 @@ void Voice::mix(const State vstate, ALCcontext *Context, const uint SamplesToDo) } } } - - float fadeCoeff{1.0f}, fadeGain{1.0f}; - if UNLIKELY(vstate == Stopping) - { - /* Calculate the multiplier for fading the resampled signal by -60dB - * over 1ms. - */ - fadeCoeff = std::pow(0.001f, 1000.0f/static_cast<float>(Device->Frequency)); - } + else if UNLIKELY(!BufferListItem) + Counter = std::min(Counter, 64u); uint buffers_done{0u}; uint OutPos{0u}; @@ -569,7 +562,6 @@ void Voice::mix(const State vstate, ALCcontext *Context, const uint SamplesToDo) } } - const float fadeVal{fadeGain}; const size_t num_chans{mChans.size()}; size_t chan_idx{0}; ASSUME(DstBufferSize > 0); @@ -584,8 +576,17 @@ void Voice::mix(const State vstate, ALCcontext *Context, const uint SamplesToDo) SrcData.begin()); if UNLIKELY(!BufferListItem) - srciter = std::copy(chandata.mPrevSamples.begin()+(MaxResamplerPadding>>1), - chandata.mPrevSamples.end(), srciter); + { + /* When loading from a voice that ended prematurely, only take + * the samples that get closest to 0 amplitude. This helps + * certain sounds fade out better. + */ + auto abs_lt = [](const float lhs, const float rhs) noexcept -> bool + { return std::abs(lhs) < std::abs(rhs); }; + auto input = chandata.mPrevSamples.begin() + (MaxResamplerPadding>>1); + auto in_end = std::min_element(input, chandata.mPrevSamples.end(), abs_lt); + srciter = std::copy(input, in_end, srciter); + } else if((mFlags&VoiceIsStatic)) srciter = LoadBufferStatic(BufferListItem, BufferLoopItem, num_chans, SampleType, SampleSize, chan_idx, DataPosInt, {srciter, SrcData.end()}); @@ -618,16 +619,6 @@ void Voice::mix(const State vstate, ALCcontext *Context, const uint SamplesToDo) chandata.mAmbiSplitter.processHfScale({ResampledData, DstBufferSize}, chandata.mAmbiScale); - if UNLIKELY(vstate == Stopping) - { - fadeGain = fadeVal; - for(float &sample : al::span<float>{ResampledData, DstBufferSize}) - { - fadeGain *= fadeCoeff; - sample *= fadeGain; - } - } - /* Now filter and mix to the appropriate outputs. */ float (&FilterBuf)[BufferLineSize] = Device->FilteredData; { |