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;
|
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
|
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())
|
if (freeVoice != voices.end())
|
||||||
return freeVoice->get();
|
return freeVoice->get();
|
||||||
|
|
||||||
// Find voices that can be stolen
|
// Find voices that can be stolen
|
||||||
absl::c_sort(voiceViewArray, [](Voice* lhs, Voice* rhs) {
|
absl::c_sort(voiceViewArray, [](Voice* lhs, Voice* rhs) {
|
||||||
return lhs->getAverageEnvelope() < rhs->getAverageEnvelope();
|
return lhs->getAge() < rhs->getAge();
|
||||||
});
|
});
|
||||||
|
|
||||||
voiceViewArray.front()->reset();
|
const auto sumEnvelope = absl::c_accumulate(voiceViewArray, 0.0f, [] (float sum, const Voice* v) {
|
||||||
return voiceViewArray.front();
|
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
|
int sfz::Synth::getNumActiveVoices() const noexcept
|
||||||
|
|
|
||||||
|
|
@ -495,6 +495,8 @@ private:
|
||||||
void noteOnDispatch(int delay, int noteNumber, float velocity) noexcept;
|
void noteOnDispatch(int delay, int noteNumber, float velocity) noexcept;
|
||||||
void noteOffDispatch(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
|
// Opcode memory; these are used to build regions, as a new region
|
||||||
// will integrate opcodes from the group, master and global block
|
// will integrate opcodes from the group, master and global block
|
||||||
std::vector<Opcode> globalOpcodes;
|
std::vector<Opcode> globalOpcodes;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue