Use age and average envelope for stealing
This commit is contained in:
parent
b78a7945ab
commit
36e4c69fc2
2 changed files with 45 additions and 4 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue