From 0a328068b280849f80f34a134009c3aef78e2732 Mon Sep 17 00:00:00 2001 From: Paul Ferrand Date: Sun, 5 Jul 2020 23:33:43 +0200 Subject: [PATCH 1/3] Don't require an explicit hikey/key=-1 to trigger on CC --- src/sfizz/Region.cpp | 17 +++++++++++++---- tests/RegionTriggersT.cpp | 4 ++-- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/sfizz/Region.cpp b/src/sfizz/Region.cpp index bbfd5e8e..bef70718 100644 --- a/src/sfizz/Region.cpp +++ b/src/sfizz/Region.cpp @@ -186,6 +186,7 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) break; // Region logic: key mapping case hash("lokey"): + triggerOnCC = false; setRangeStartFromOpcode(opcode, keyRange, Default::keyRange); break; case hash("hikey"): @@ -334,26 +335,34 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) case hash("start_locc&"): // also on_locc& if (opcode.parameters.back() >= config::numCCs) return false; - if (auto value = readOpcode(opcode.value, Default::midi7Range)) + if (auto value = readOpcode(opcode.value, Default::midi7Range)) { + triggerOnCC = true; ccTriggers[opcode.parameters.back()].setStart(normalizeCC(*value)); + } break; case hash("start_hicc&"): // also on_hicc& if (opcode.parameters.back() >= config::numCCs) return false; - if (auto value = readOpcode(opcode.value, Default::midi7Range)) + if (auto value = readOpcode(opcode.value, Default::midi7Range)) { + triggerOnCC = true; ccTriggers[opcode.parameters.back()].setEnd(normalizeCC(*value)); + } break; case hash("start_lohdcc&"): // also on_lohdcc& if (opcode.parameters.back() >= config::numCCs) return false; - if (auto value = readOpcode(opcode.value, Default::normalizedRange)) + if (auto value = readOpcode(opcode.value, Default::normalizedRange)) { + triggerOnCC = true; ccTriggers[opcode.parameters.back()].setStart(*value); + } break; case hash("start_hihdcc&"): // also on_hihdcc& if (opcode.parameters.back() >= config::numCCs) return false; - if (auto value = readOpcode(opcode.value, Default::normalizedRange)) + if (auto value = readOpcode(opcode.value, Default::normalizedRange)) { + triggerOnCC = true; ccTriggers[opcode.parameters.back()].setEnd(*value); + } break; // Performance parameters: amplifier diff --git a/tests/RegionTriggersT.cpp b/tests/RegionTriggersT.cpp index 4ee56cde..4c567a52 100644 --- a/tests/RegionTriggersT.cpp +++ b/tests/RegionTriggersT.cpp @@ -114,8 +114,8 @@ TEST_CASE("Basic triggers", "Region triggers") region.parseOpcode({ "on_locc47", "64" }); region.parseOpcode({ "on_hicc47", "68" }); REQUIRE(!region.registerCC(47, 63_norm)); - REQUIRE(!region.registerCC(47, 64_norm)); - REQUIRE(!region.registerCC(47, 65_norm)); + REQUIRE(region.registerCC(47, 64_norm)); + REQUIRE(region.registerCC(47, 65_norm)); region.parseOpcode({ "hikey", "-1" }); REQUIRE(region.registerCC(47, 64_norm)); REQUIRE(region.registerCC(47, 65_norm)); From b46b30f35d984b0414cdd1fd9bcf46241679480d Mon Sep 17 00:00:00 2001 From: Paul Ferrand Date: Mon, 6 Jul 2020 00:00:30 +0200 Subject: [PATCH 2/3] Use the pitch keycenter for cc triggers --- src/sfizz/Voice.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/sfizz/Voice.cpp b/src/sfizz/Voice.cpp index 4f23fd5d..144b680d 100644 --- a/src/sfizz/Voice.cpp +++ b/src/sfizz/Voice.cpp @@ -34,6 +34,9 @@ void sfz::Voice::startVoice(Region* region, int delay, int number, float value, { ASSERT(value >= 0.0f && value <= 1.0f); + if (triggerType == TriggerType::CC) + number = region->pitchKeycenter; + this->triggerType = triggerType; triggerNumber = number; triggerValue = value; From cda4ae2db38ab926302626261648d60c74d6cec1 Mon Sep 17 00:00:00 2001 From: Paul Ferrand Date: Mon, 6 Jul 2020 09:03:06 +0200 Subject: [PATCH 3/3] Triggering on note or CC is not exclusive --- src/sfizz/Region.cpp | 10 +++++----- src/sfizz/Region.h | 1 + tests/RegionTriggersT.cpp | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/src/sfizz/Region.cpp b/src/sfizz/Region.cpp index bef70718..205ed9f4 100644 --- a/src/sfizz/Region.cpp +++ b/src/sfizz/Region.cpp @@ -186,15 +186,15 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) break; // Region logic: key mapping case hash("lokey"): - triggerOnCC = false; + triggerOnNote = true; setRangeStartFromOpcode(opcode, keyRange, Default::keyRange); break; case hash("hikey"): - triggerOnCC = (opcode.value == "-1"); + triggerOnNote = (opcode.value != "-1"); setRangeEndFromOpcode(opcode, keyRange, Default::keyRange); break; case hash("key"): - triggerOnCC = (opcode.value == "-1"); + triggerOnNote = (opcode.value != "-1"); setRangeStartFromOpcode(opcode, keyRange, Default::keyRange); setRangeEndFromOpcode(opcode, keyRange, Default::keyRange); setValueFromOpcode(opcode, pitchKeycenter, Default::keyRange); @@ -996,7 +996,7 @@ bool sfz::Region::registerNoteOn(int noteNumber, float velocity, float randValue if (!isSwitchedOn()) return false; - if (triggerOnCC) + if (!triggerOnNote) return false; if (previousNote && !(previousKeySwitched && noteNumber != *previousNote)) @@ -1028,7 +1028,7 @@ bool sfz::Region::registerNoteOff(int noteNumber, float velocity, float randValu if (!isSwitchedOn()) return false; - if (triggerOnCC) + if (!triggerOnNote) return false; const bool velOk = velocityRange.containsWithEnd(velocity); diff --git a/src/sfizz/Region.h b/src/sfizz/Region.h index e96ebe0f..ea8ebcdb 100644 --- a/src/sfizz/Region.h +++ b/src/sfizz/Region.h @@ -381,6 +381,7 @@ private: bool aftertouchSwitched { true }; std::bitset ccSwitched; bool triggerOnCC { false }; + bool triggerOnNote { true }; absl::string_view defaultPath { "" }; int sequenceCounter { 0 }; diff --git a/tests/RegionTriggersT.cpp b/tests/RegionTriggersT.cpp index 4c567a52..0226f263 100644 --- a/tests/RegionTriggersT.cpp +++ b/tests/RegionTriggersT.cpp @@ -125,6 +125,40 @@ TEST_CASE("Basic triggers", "Region triggers") REQUIRE(!region.registerCC(47, 69_norm)); REQUIRE(!region.registerCC(40, 64_norm)); } + + SECTION("on_loccN does not disable key triggering") + { + region.parseOpcode({ "sample", "*sine" }); + region.parseOpcode({ "on_locc1", "127" }); + region.parseOpcode({ "on_hicc1", "127" }); + REQUIRE(!region.registerCC(1, 126_norm)); + REQUIRE(!region.registerCC(2, 127_norm)); + REQUIRE(region.registerCC(1, 127_norm)); + REQUIRE(region.registerNoteOn(64, 127_norm, 0.5f)); + } + + SECTION("on_loccN does not disable key triggering, but adding key=-1 does") + { + region.parseOpcode({ "sample", "*sine" }); + region.parseOpcode({ "on_locc1", "127" }); + region.parseOpcode({ "on_hicc1", "127" }); + region.parseOpcode({ "key", "-1" }); + REQUIRE(!region.registerCC(1, 126_norm)); + REQUIRE(region.registerCC(1, 127_norm)); + REQUIRE(!region.registerNoteOn(64, 127_norm, 0.5f)); + } + + SECTION("on_loccN does not disable key triggering, but adding hikey=-1 does") + { + region.parseOpcode({ "sample", "*sine" }); + region.parseOpcode({ "on_locc1", "127" }); + region.parseOpcode({ "on_hicc1", "127" }); + region.parseOpcode({ "hikey", "-1" }); + REQUIRE(!region.registerCC(1, 126_norm)); + REQUIRE(!region.registerCC(2, 127_norm)); + REQUIRE(region.registerCC(1, 127_norm)); + REQUIRE(!region.registerNoteOn(64, 127_norm, 0.5f)); + } } TEST_CASE("Legato triggers", "Region triggers")