Skip to content

Commit

Permalink
Rework fading of stopped sounds
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
kcat committed Jan 27, 2021
1 parent 3b89246 commit f0f7bc0
Showing 1 changed file with 13 additions and 22 deletions.
35 changes: 13 additions & 22 deletions alc/voice.cpp
Expand Up @@ -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};
Expand Down Expand Up @@ -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);
Expand All @@ -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()});
Expand Down Expand Up @@ -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;
{
Expand Down

0 comments on commit f0f7bc0

Please sign in to comment.