Use sister voices in the voice stealing algorithm

This commit is contained in:
Paul Ferrand 2020-06-14 17:44:13 +02:00
parent f4660b1a02
commit 9215b1705a

View file

@ -551,49 +551,38 @@ sfz::Voice* sfz::Synth::findFreeVoice() noexcept
/ static_cast<float>(voiceViewArray.size()) * config::stealingEnvelopeCoeff; / static_cast<float>(voiceViewArray.size()) * config::stealingEnvelopeCoeff;
const auto ageThreshold = voiceViewArray.front()->getAge() * config::stealingAgeCoeff; const auto ageThreshold = voiceViewArray.front()->getAge() * config::stealingAgeCoeff;
auto tempSpan = resources.bufferPool.getStereoBuffer(samplesPerBlock);
const auto killVoice = [&] (Voice* v) {
renderVoiceToOutputs(*v, *tempSpan);
v->reset();
};
Voice* returnedVoice = voiceViewArray.front(); Voice* returnedVoice = voiceViewArray.front();
unsigned idx = 0; unsigned idx = 0;
while (idx < voiceViewArray.size()) { while (idx < voiceViewArray.size()) {
const auto refIdx = idx;
const auto ref = voiceViewArray[idx]; const auto ref = voiceViewArray[idx];
idx++;
if (ref->getAge() < ageThreshold) { if (ref->getAge() < ageThreshold) {
unsigned killIdx = 1; // Went too far, we'll kill the oldest note.
while (killIdx < voiceViewArray.size()
&& sisterVoices(returnedVoice, voiceViewArray[killIdx])) {
killVoice(voiceViewArray[killIdx]);
killIdx++;
}
// std::cout << "Went too far, picking the oldest voice and killing "
// << killIdx << " voices" << '\n';
killVoice(returnedVoice);
break; break;
} }
float maxEnvelope = ref->getAverageEnvelope(); float maxEnvelope { 0.0f };
while (idx < voiceViewArray.size() SisterVoiceRing::applyToRing(ref, [&](Voice* v) {
&& sisterVoices(ref, voiceViewArray[idx])) { maxEnvelope = max(maxEnvelope, v->getAverageEnvelope());
maxEnvelope = max(maxEnvelope, voiceViewArray[idx]->getAverageEnvelope()); });
idx++;
}
if (maxEnvelope < envThreshold) { if (maxEnvelope < envThreshold) {
returnedVoice = ref; returnedVoice = ref;
// std::cout << "Killing " << idx - refIdx << " voices" << '\n';
for (unsigned j = refIdx; j < idx; j++) {
killVoice(voiceViewArray[j]);
}
break; break;
} }
// Jump over the sister voices in the set
do { idx++; }
while (idx < voiceViewArray.size() && sisterVoices(ref, voiceViewArray[idx]));
} }
assert(returnedVoice->isFree());
auto tempSpan = resources.bufferPool.getStereoBuffer(samplesPerBlock);
SisterVoiceRing::applyToRing(returnedVoice, [&] (Voice* v) {
renderVoiceToOutputs(*v, *tempSpan);
v->reset();
});
ASSERT(returnedVoice->isFree());
return returnedVoice; return returnedVoice;
} }