Use sister voices in the voice stealing algorithm
This commit is contained in:
parent
f4660b1a02
commit
9215b1705a
1 changed files with 17 additions and 28 deletions
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue