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]) {
|
for (auto& region : noteActivationLists[noteNumber]) {
|
||||||
if (region->registerNoteOn(noteNumber, velocity, randValue)) {
|
if (region->registerNoteOn(noteNumber, velocity, randValue)) {
|
||||||
unsigned activeNotesInGroup { 0 };
|
unsigned activeNotesInGroup { 0 };
|
||||||
|
unsigned activeNotes { 0 };
|
||||||
|
Voice* selfMaskCandidate { nullptr };
|
||||||
|
|
||||||
for (auto& voice : voices) {
|
for (auto& voice : voices) {
|
||||||
const auto voiceRegion = voice->getRegion();
|
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)
|
if (voiceRegion->group == region->group)
|
||||||
activeNotesInGroup += 1;
|
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))
|
if (voice->checkOffGroup(delay, region->group))
|
||||||
noteOffDispatch(delay, voice->getTriggerNumber(), voice->getTriggerValue());
|
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])
|
if (activeNotesInGroup >= groupMaxPolyphony[region->group])
|
||||||
continue;
|
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();
|
auto voice = findFreeVoice();
|
||||||
if (voice == nullptr)
|
if (voice == nullptr)
|
||||||
continue;
|
continue;
|
||||||
|
|
|
||||||
|
|
@ -210,6 +210,13 @@ public:
|
||||||
* @param numFilters
|
* @param numFilters
|
||||||
*/
|
*/
|
||||||
void setMaxEQsPerVoice(size_t numEQs);
|
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 getLastDataDuration() const noexcept { return dataDuration; }
|
||||||
Duration getLastAmplitudeDuration() const noexcept { return amplitudeDuration; }
|
Duration getLastAmplitudeDuration() const noexcept { return amplitudeDuration; }
|
||||||
|
|
@ -243,13 +250,6 @@ private:
|
||||||
* @param buffer
|
* @param buffer
|
||||||
*/
|
*/
|
||||||
void processStereo(AudioSpan<float> buffer) noexcept;
|
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 };
|
Region* region { nullptr };
|
||||||
|
|
||||||
enum class State {
|
enum class State {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue