aboutsummaryrefslogtreecommitdiffstats
path: root/alc/voice.cpp
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2021-01-27 14:17:46 -0800
committerChris Robinson <[email protected]>2021-01-27 14:55:20 -0800
commitf0f7bc036f3480423ba5a1ddded787cf7df7a353 (patch)
tree89c143794cef8406ebff2809c199587f245c210e /alc/voice.cpp
parent3b89246733420f2ca0ac495c710b856f58ee580e (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.cpp35
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;
{