Engine polyphony is checked in findFreeVoice()

This commit is contained in:
Paul Ferrand 2020-08-25 19:31:47 +02:00
parent ca7d74e841
commit 5139c648f0
2 changed files with 16 additions and 18 deletions

View file

@ -659,7 +659,18 @@ sfz::Voice* sfz::Synth::findFreeVoice() noexcept
if (freeVoice != voices.end())
return freeVoice->get();
return {};
// Engine polyphony reached
Voice* stolenVoice = stealer.steal(absl::MakeSpan(voiceViewArray));
if (stolenVoice == nullptr)
return {};
auto tempSpan = resources.bufferPool.getStereoBuffer(samplesPerBlock);
SisterVoiceRing::applyToRing(stolenVoice, [&] (Voice* v) {
renderVoiceToOutputs(*v, *tempSpan);
v->reset();
});
return stolenVoice;
}
int sfz::Synth::getNumActiveVoices(bool recompute) const noexcept
@ -997,27 +1008,11 @@ void sfz::Synth::noteOnDispatch(int delay, int noteNumber, float velocity) noexc
}
Voice* selectedVoice = findFreeVoice();
// Engine polyphony reached, we're stealing something
if (selectedVoice == nullptr) {
selectedVoice = stealer.steal(absl::MakeSpan(voiceViewArray));
}
// For some reason we did not find a voice to use.
// This is a degraded case but we'll just drop the note on.
if (selectedVoice == nullptr)
continue;
// Kill voice if necessary, pre-rendering it into the output buffers
if (!selectedVoice->isFree()) {
auto tempSpan = resources.bufferPool.getStereoBuffer(samplesPerBlock);
SisterVoiceRing::applyToRing(selectedVoice, [&] (Voice* v) {
renderVoiceToOutputs(*v, *tempSpan);
v->reset();
});
}
// Voice should be free now
ASSERT(selectedVoice->isFree());
selectedVoice->startVoice(region, delay, noteNumber, velocity, Voice::TriggerType::NoteOn);
ring.addVoiceToRing(selectedVoice);

View file

@ -765,18 +765,21 @@ private:
using RegionSetPtr = std::unique_ptr<RegionSet>;
std::vector<RegionPtr> regions;
std::vector<VoicePtr> voices;
// These are more general "groups" than sfz and encapsulates the full hierarchy
RegionSet* currentSet;
OpcodeScope lastHeader { OpcodeScope::kOpcodeScopeGlobal };
std::vector<RegionSetPtr> sets;
// These are the `group=` groups where you can off voices
std::vector<PolyphonyGroup> polyphonyGroups;
// Views to speed up iteration over the regions and voices when events
// occur in the audio callback
VoiceViewVector regionPolyphonyArray;
VoiceViewVector voiceViewArray;
VoiceStealing stealer;
VoiceViewVector voiceViewArray;
std::array<RegionViewVector, 128> noteActivationLists;
std::array<RegionViewVector, config::numCCs> ccActivationLists;