aboutsummaryrefslogtreecommitdiffstats
path: root/alc
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2021-01-08 18:54:46 -0800
committerChris Robinson <[email protected]>2021-01-08 18:54:46 -0800
commit89906453ea947da4f67dd42bfd007e6fc3931d56 (patch)
tree328d8facc4632161192912e142d9ede20369637a /alc
parent537fd6d0a15fda5f4b6ed3f767aa9bf6f15caa21 (diff)
Quickly fade out samples of a stopping voice
Rather than linearly fading out the mix over the mixing update, logarithmically fade out the post-resampled samples by approx -60dB per millisecond.
Diffstat (limited to 'alc')
-rw-r--r--alc/voice.cpp20
1 files changed, 20 insertions, 0 deletions
diff --git a/alc/voice.cpp b/alc/voice.cpp
index 336d8a92..54357f06 100644
--- a/alc/voice.cpp
+++ b/alc/voice.cpp
@@ -497,6 +497,15 @@ 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));
+ }
+
uint buffers_done{0u};
uint OutPos{0u};
do {
@@ -572,6 +581,7 @@ void Voice::mix(const State vstate, ALCcontext *Context, const uint SamplesToDo)
}
}
+ const float fadeVal{fadeGain};
ASSUME(DstBufferSize > 0);
for(auto &chandata : mChans)
{
@@ -621,6 +631,16 @@ 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;
{