From 639aff5ba1a3c2a23fb03a0979001b3d014afb85 Mon Sep 17 00:00:00 2001 From: Paul Ferrand Date: Wed, 6 May 2020 15:41:18 +0200 Subject: [PATCH] Release the envelope and let the voice clean up itself (#215) In the previous version, for very short sample, the voice could start and end in the same block and falsely reset itself before finishing its rendering pass --- src/sfizz/Voice.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/sfizz/Voice.cpp b/src/sfizz/Voice.cpp index acf037db8..9caea5a4b 100644 --- a/src/sfizz/Voice.cpp +++ b/src/sfizz/Voice.cpp @@ -119,7 +119,7 @@ void sfz::Voice::release(int delay, bool fastRelease) noexcept if (state != State::playing) return; - if (egEnvelope.getRemainingDelay() > std::max(0, delay - initialDelay)) { + if (egEnvelope.getRemainingDelay() > delay) { reset(); } else { egEnvelope.startRelease(delay, fastRelease); @@ -475,19 +475,21 @@ void sfz::Voice::fillWithData(AudioSpan buffer) noexcept static_cast(region->trueSampleEnd(currentPromise->oversamplingFactor)), static_cast(source.getNumFrames()) ) - 2; - for (auto* index = indices->begin(); index < indices->end(); ++index) { - if (*index >= sampleEnd) { - release(static_cast(std::distance(indices->begin(), index))); - const auto remainingElements = static_cast(std::distance(index, indices->end())); + for (unsigned i = 0; i < indices->size(); ++i) { + if ((*indices)[i] >= sampleEnd) { +#ifndef NDEBUG + // Check for underflow if (source.getNumFrames() - 1 < region->trueSampleEnd(currentPromise->oversamplingFactor)) { DBG("[sfizz] Underflow: source available samples " << source.getNumFrames() << "/" << region->trueSampleEnd(currentPromise->oversamplingFactor) << " for sample " << region->sampleId); } - fill(indices->last(remainingElements), sampleEnd); - fill(leftCoeffs->last(remainingElements), 0.0f); - fill(rightCoeffs->last(remainingElements), 1.0f); +#endif + egEnvelope.startRelease(i, true); + fill(indices->subspan(i), sampleEnd); + fill(leftCoeffs->subspan(i), 0.0f); + fill(rightCoeffs->subspan(i), 1.0f); break; } }