Handle note_polyphony and note_selfmask

This commit is contained in:
Paul Ferrand 2020-03-29 01:12:52 +01:00
parent 5ef9d6e996
commit 26a9ab2c70
2 changed files with 34 additions and 7 deletions

View file

@ -687,6 +687,8 @@ void sfz::Synth::noteOnDispatch(int delay, int noteNumber, float velocity) noexc
for (auto& region : noteActivationLists[noteNumber]) {
if (region->registerNoteOn(noteNumber, velocity, randValue)) {
unsigned activeNotesInGroup { 0 };
unsigned activeNotes { 0 };
Voice* selfMaskCandidate { nullptr };
for (auto& voice : voices) {
const auto voiceRegion = voice->getRegion();
@ -696,6 +698,24 @@ void sfz::Synth::noteOnDispatch(int delay, int noteNumber, float velocity) noexc
if (voiceRegion->group == region->group)
activeNotesInGroup += 1;
if (region->notePolyphony) {
if (voice->getTriggerNumber() == noteNumber && voice->getTriggerType() == Voice::TriggerType::NoteOn) {
activeNotes += 1;
switch (region->selfMask) {
case SfzSelfMask::mask:
if (voice->getTriggerValue() < velocity) {
if (!selfMaskCandidate || selfMaskCandidate->getTriggerValue() > voice->getTriggerValue())
selfMaskCandidate = voice.get();
}
break;
case SfzSelfMask::dontMask:
if (!selfMaskCandidate || selfMaskCandidate->getSourcePosition() < voice->getSourcePosition())
selfMaskCandidate = voice.get();
break;
}
}
}
if (voice->checkOffGroup(delay, region->group))
noteOffDispatch(delay, voice->getTriggerNumber(), voice->getTriggerValue());
}
@ -703,6 +723,13 @@ void sfz::Synth::noteOnDispatch(int delay, int noteNumber, float velocity) noexc
if (activeNotesInGroup >= groupMaxPolyphony[region->group])
continue;
if (region->notePolyphony && activeNotes >= *region->notePolyphony) {
if (selfMaskCandidate != nullptr)
selfMaskCandidate->release(delay);
else // We're the lowest velocity guy here
continue;
}
auto voice = findFreeVoice();
if (voice == nullptr)
continue;

View file

@ -210,6 +210,13 @@ public:
* @param numFilters
*/
void setMaxEQsPerVoice(size_t numEQs);
/**
* @brief Release the voice after a given delay
*
* @param delay
* @param fastRelease whether to do a normal release or cut the voice abruptly
*/
void release(int delay, bool fastRelease = false) noexcept;
Duration getLastDataDuration() const noexcept { return dataDuration; }
Duration getLastAmplitudeDuration() const noexcept { return amplitudeDuration; }
@ -243,13 +250,6 @@ private:
* @param buffer
*/
void processStereo(AudioSpan<float> buffer) noexcept;
/**
* @brief Release the voice after a given delay
*
* @param delay
* @param fastRelease whether to do a normal release or cut the voice abruptly
*/
void release(int delay, bool fastRelease = false) noexcept;
Region* region { nullptr };
enum class State {