Use age and average envelope for stealing

This commit is contained in:
Paul Ferrand 2020-05-07 12:54:30 +02:00
parent b78a7945ab
commit 36e4c69fc2
2 changed files with 45 additions and 4 deletions

View file

@ -473,19 +473,58 @@ bool sfz::Synth::loadSfzFile(const fs::path& file)
return true;
}
unsigned sfz::Synth::killSisterVoices(const Voice* voiceToKill) noexcept
{
const auto age = voiceToKill->getAge();
const auto type = voiceToKill->getTriggerType();
const auto number = voiceToKill->getTriggerNumber();
const auto value = voiceToKill->getTriggerValue();
unsigned killedVoices = 0;
for (auto & voice : voiceViewArray) {
if (voice->getAge() == age
&& voice->getTriggerType() == type
&& voice->getTriggerNumber() == number
&& voice->getTriggerValue() == value) {
killedVoices++;
voice->reset();
}
}
return killedVoices;
}
sfz::Voice* sfz::Synth::findFreeVoice() noexcept
{
auto freeVoice = absl::c_find_if(voices, [](const std::unique_ptr<Voice>& voice) { return voice->isFree(); });
auto freeVoice = absl::c_find_if(voices, [](const std::unique_ptr<Voice>& voice) {
return voice->isFree();
});
if (freeVoice != voices.end())
return freeVoice->get();
// Find voices that can be stolen
absl::c_sort(voiceViewArray, [](Voice* lhs, Voice* rhs) {
return lhs->getAverageEnvelope() < rhs->getAverageEnvelope();
return lhs->getAge() < rhs->getAge();
});
voiceViewArray.front()->reset();
return voiceViewArray.front();
const auto sumEnvelope = absl::c_accumulate(voiceViewArray, 0.0f, [] (float sum, const Voice* v) {
return sum + v->getAverageEnvelope();
});
const auto threshold = sumEnvelope / static_cast<float>(voiceViewArray.size()) / 2;
Voice* returnedVoice = voiceViewArray.front();
for (auto & voice : voiceViewArray) {
if (voice->getAverageEnvelope() < threshold) {
returnedVoice = voice;
break;
}
}
const auto killedVoices = killSisterVoices(returnedVoice);
UNUSED(killedVoices); // only in debug
assert(killedVoices > 0);
assert(returnedVoice->isFree());
std::cout << "Killed " << killedVoices << " voices";
return returnedVoice;
}
int sfz::Synth::getNumActiveVoices() const noexcept

View file

@ -495,6 +495,8 @@ private:
void noteOnDispatch(int delay, int noteNumber, float velocity) noexcept;
void noteOffDispatch(int delay, int noteNumber, float velocity) noexcept;
unsigned killSisterVoices(const Voice* voiceToKill) noexcept;
// Opcode memory; these are used to build regions, as a new region
// will integrate opcodes from the group, master and global block
std::vector<Opcode> globalOpcodes;