From 6f106803490ab00495c5e58d0386bff4b1de402c Mon Sep 17 00:00:00 2001 From: Paul Ferrand Date: Fri, 3 Jan 2020 17:57:57 +0100 Subject: [PATCH] Slightly better handling of the loop indicesMay still need work --- src/sfizz/Voice.cpp | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/sfizz/Voice.cpp b/src/sfizz/Voice.cpp index eb97c57e..24af701f 100644 --- a/src/sfizz/Voice.cpp +++ b/src/sfizz/Voice.cpp @@ -398,26 +398,31 @@ void sfz::Voice::fillWithData(AudioSpan buffer) noexcept sfzInterpolationCast(jumps, indices, leftCoeffs, rightCoeffs); add(sourcePosition, indices); - //FIXME : all this casting is driving me crazy - const auto sampleEnd = min( - static_cast(region->trueSampleEnd(currentPromise->oversamplingFactor)), - static_cast(source.getNumFrames()) - ) - 2; + absl::optional releaseAt {}; if (region->shouldLoop() && region->loopEnd(currentPromise->oversamplingFactor) <= source.getNumFrames()) { - const auto offset = sampleEnd - static_cast(region->loopStart(currentPromise->oversamplingFactor)); + const auto loopEnd = static_cast(region->loopEnd(currentPromise->oversamplingFactor)) - 1; + const auto offset = loopEnd - static_cast(region->loopStart(currentPromise->oversamplingFactor)); for (auto* index = indices.begin(); index < indices.end(); ++index) { - if (*index > sampleEnd) { + if (*index >= loopEnd) { const auto remainingElements = static_cast(std::distance(index, indices.end())); subtract(offset, { index, remainingElements }); } } } else { + const auto sampleEnd = min( + static_cast(region->trueSampleEnd(currentPromise->oversamplingFactor)), + static_cast(source.getNumFrames()) + ) - 2; for (auto* index = indices.begin(); index < indices.end(); ++index) { - if (*index > sampleEnd) { + if (*index >= sampleEnd) { + releaseAt = static_cast(std::distance(indices.begin(), index)); const auto remainingElements = static_cast(std::distance(index, indices.end())); - if (*index >= static_cast(source.getNumFrames()) && source.getNumFrames() != region->trueSampleEnd(currentPromise->oversamplingFactor)) { - DBG("[sfizz] Underflow: source available samples " << source.getNumFrames() << "/" << region->trueSampleEnd(currentPromise->oversamplingFactor) << " for sample " << region->sample); + if (source.getNumFrames() != region->trueSampleEnd(currentPromise->oversamplingFactor)) { + DBG("[sfizz] Underflow: source available samples " + << source.getNumFrames() << "/" + << region->trueSampleEnd(currentPromise->oversamplingFactor) + << " for sample " << region->sample); } fill(indices.last(remainingElements), sampleEnd); fill(leftCoeffs.last(remainingElements), 0.0f); @@ -450,10 +455,10 @@ void sfz::Voice::fillWithData(AudioSpan buffer) noexcept sourcePosition = indices.back(); floatPositionOffset = rightCoeffs.back(); - if (state != State::release && !region->shouldLoop() && sourcePosition == sampleEnd) { - auto last = std::distance(indices.begin(), absl::c_find(indices, sampleEnd)); - release(last); - buffer.subspan(last).fill(0.0f); + if (state != State::release && releaseAt) { + release(*releaseAt); + // TODO: not needed probably + buffer.subspan(*releaseAt).fill(0.0f); } }