diff --git a/src/sfizz/Config.h b/src/sfizz/Config.h index a26d36df..b8f9d4ff 100644 --- a/src/sfizz/Config.h +++ b/src/sfizz/Config.h @@ -59,6 +59,16 @@ namespace config { constexpr int maxCurves { 256 }; constexpr int chunkSize { 1024 }; constexpr int filtersInPool { maxVoices * 2 }; + /** + * @brief The threshold for age stealing. + * In percentage of the voice's max age. + */ + constexpr float stealingAgeCoeff { 0.5f }; + /** + * @brief The threshold for envelope stealing. + * In percentage of the sum of all envelopes. + */ + constexpr float stealingEnvelopeCoeff { 0.5f }; constexpr int filtersPerVoice { 2 }; constexpr int eqsPerVoice { 3 }; constexpr int oscillatorsPerVoice { 9 }; diff --git a/src/sfizz/Synth.cpp b/src/sfizz/Synth.cpp index 7380053c..bb939560 100644 --- a/src/sfizz/Synth.cpp +++ b/src/sfizz/Synth.cpp @@ -481,14 +481,15 @@ sfz::Voice* sfz::Synth::findFreeVoice() noexcept if (freeVoice != voices.end()) return freeVoice->get(); - // Find voices that can be stolen + // Start of the voice stealing algorithm absl::c_sort(voiceViewArray, voiceOrdering); const auto sumEnvelope = absl::c_accumulate(voiceViewArray, 0.0f, [](float sum, const Voice* v) { return sum + v->getAverageEnvelope(); }); - const auto envThreshold = sumEnvelope / static_cast(voiceViewArray.size()) * 0.5f; - const auto ageThreshold = voiceViewArray.front()->getAge() * 0.5f; + const auto envThreshold = sumEnvelope + / static_cast(voiceViewArray.size()) * config::stealingEnvelopeCoeff; + const auto ageThreshold = voiceViewArray.front()->getAge() * config::stealingAgeCoeff; auto tempSpan = resources.bufferPool.getStereoBuffer(samplesPerBlock); const auto killVoice = [&] (Voice* v) { @@ -506,7 +507,7 @@ sfz::Voice* sfz::Synth::findFreeVoice() noexcept if (ref->getAge() < ageThreshold) { unsigned killIdx = 1; while (killIdx < voiceViewArray.size() - && sisterVoices(returnedVoice, voiceViewArray[killIdx])) { + && sisterVoices(returnedVoice, voiceViewArray[killIdx])) { killVoice(voiceViewArray[killIdx]); killIdx++; } @@ -517,7 +518,8 @@ sfz::Voice* sfz::Synth::findFreeVoice() noexcept } float maxEnvelope = ref->getAverageEnvelope(); - while (idx < voiceViewArray.size() && sisterVoices(ref, voiceViewArray[idx])) { + while (idx < voiceViewArray.size() + && sisterVoices(ref, voiceViewArray[idx])) { maxEnvelope = max(maxEnvelope, voiceViewArray[idx]->getAverageEnvelope()); idx++; }