diff --git a/src/sfizz/Synth.cpp b/src/sfizz/Synth.cpp index c1983016..c244620b 100644 --- a/src/sfizz/Synth.cpp +++ b/src/sfizz/Synth.cpp @@ -930,7 +930,7 @@ void sfz::Synth::noteOnDispatch(int delay, int noteNumber, float velocity) noexc notePolyphonyCounter += 1; switch (region->selfMask) { case SfzSelfMask::mask: - if (voice->getTriggerValue() < velocity) { + if (voice->getTriggerValue() <= velocity) { if (!selfMaskCandidate || selfMaskCandidate->getTriggerValue() > voice->getTriggerValue()) selfMaskCandidate = voice.get(); } diff --git a/tests/PolyphonyT.cpp b/tests/PolyphonyT.cpp index aeac0ebe..15173915 100644 --- a/tests/PolyphonyT.cpp +++ b/tests/PolyphonyT.cpp @@ -224,3 +224,21 @@ TEST_CASE("[Polyphony] Not self-masking") REQUIRE(synth.getVoiceView(2)->getTriggerValue() == 64_norm); REQUIRE(!synth.getVoiceView(2)->releasedOrFree()); } + +TEST_CASE("[Polyphony] Self-masking with the exact same velocity") +{ + sfz::Synth synth; + synth.loadSfzString(fs::current_path(), R"( + sample=*sine key=64 note_polyphony=2 + )"); + synth.noteOn(0, 64, 64); + synth.noteOn(0, 64, 63); + synth.noteOn(0, 64, 63); + REQUIRE(synth.getNumActiveVoices(true) == 3); // One of these is releasing + REQUIRE(synth.getVoiceView(0)->getTriggerValue() == 64_norm); + REQUIRE(!synth.getVoiceView(0)->releasedOrFree()); + REQUIRE(synth.getVoiceView(1)->getTriggerValue() == 63_norm); + REQUIRE(synth.getVoiceView(1)->releasedOrFree()); // The first one is the masking candidate since they have the same velocity + REQUIRE(synth.getVoiceView(2)->getTriggerValue() == 63_norm); + REQUIRE(!synth.getVoiceView(2)->releasedOrFree()); +}