Handle note_polyphony and note_selfmask
This commit is contained in:
parent
5ef9d6e996
commit
26a9ab2c70
2 changed files with 34 additions and 7 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue