diff --git a/src/sfizz/Voice.cpp b/src/sfizz/Voice.cpp index 78e96d64..8a2ba35b 100644 --- a/src/sfizz/Voice.cpp +++ b/src/sfizz/Voice.cpp @@ -1655,7 +1655,8 @@ bool Voice::checkOffGroup(const Region* other, int delay, int noteNumber) noexce if (impl.released()) return false; - if (impl.triggerEvent_.type == TriggerEventType::NoteOn + if ((impl.triggerEvent_.type == TriggerEventType::NoteOn + || impl.triggerEvent_.type == TriggerEventType::CC) && region->offBy && *region->offBy == other->group && (region->group != other->group || noteNumber != impl.triggerEvent_.number)) { off(delay); diff --git a/tests/SynthT.cpp b/tests/SynthT.cpp index 383775ac..facec42e 100644 --- a/tests/SynthT.cpp +++ b/tests/SynthT.cpp @@ -1693,6 +1693,23 @@ TEST_CASE("[Synth] Off by a CC event") REQUIRE( playingSamples(synth) == std::vector { "*sine" }); } +TEST_CASE("[Synth] CC triggered off by a CC event") +{ + sfz::Synth synth; + sfz::AudioBuffer buffer { 2, static_cast(synth.getSamplesPerBlock()) }; + + synth.loadSfzString(fs::current_path(), R"( + group=1 off_by=2 sample=*saw hikey=-1 on_locc64=126 on_hicc64=127 + group=2 sample=*triangle hikey=-1 on_locc64=0 on_hicc64=1 + )"); + synth.cc(0, 64, 127); + synth.renderBlock(buffer); + REQUIRE( playingSamples(synth) == std::vector { "*saw" }); + synth.cc(0, 64, 0); + synth.renderBlock(buffer); + REQUIRE( playingSamples(synth) == std::vector { "*triangle" }); +} + TEST_CASE("[Synth] Off by a note-off event") { sfz::Synth synth;