diff --git a/src/sfizz/OpcodeCleanup.re b/src/sfizz/OpcodeCleanup.re index 8f48ab6c..795fe053 100644 --- a/src/sfizz/OpcodeCleanup.re +++ b/src/sfizz/OpcodeCleanup.re @@ -132,6 +132,10 @@ end_generic: opcode = absl::StrCat("start_", group(1), "cc", group(2)); goto end_region; } + "on_" ("hi"|"lo") "hdcc" (number) END { + opcode = absl::StrCat("start_", group(1), "hdcc", group(2)); + goto end_region; + } "fil_" (any) END { opcode = absl::StrCat("fil1_", group(1)); diff --git a/src/sfizz/Region.cpp b/src/sfizz/Region.cpp index 5c14c38b..b6613c69 100644 --- a/src/sfizz/Region.cpp +++ b/src/sfizz/Region.cpp @@ -321,6 +321,18 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) if (auto value = readOpcode(opcode.value, Default::midi7Range)) 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)) + 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)) + ccTriggers[opcode.parameters.back()].setEnd(*value); + break; // Performance parameters: amplifier case hash("volume"): // also gain diff --git a/tests/OpcodeT.cpp b/tests/OpcodeT.cpp index 733a185c..ed3fb40e 100644 --- a/tests/OpcodeT.cpp +++ b/tests/OpcodeT.cpp @@ -202,6 +202,10 @@ TEST_CASE("[Opcode] Normalization") {"gain_foobar", "volume_foobar"}, {"tune", "pitch"}, {"tune_foobar", "pitch_foobar"}, + {"lorealcc24", "lohdcc24"}, + {"hirealcc25", "hihdcc25"}, + {"on_lohdcc26", "start_lohdcc26"}, + {"on_hihdcc27", "start_hihdcc27"}, // SFZv2 aliases {"on_hicc22", "start_hicc22"}, {"on_locc23", "start_locc23"}, diff --git a/tests/RegionT.cpp b/tests/RegionT.cpp index 19d2ab71..4884274b 100644 --- a/tests/RegionT.cpp +++ b/tests/RegionT.cpp @@ -496,6 +496,21 @@ TEST_CASE("[Region] Parsing opcodes") REQUIRE(region.ccTriggers[4] == sfz::Range(0_norm, 47_norm)); } + SECTION("on_lohdcc, on_hihdcc") + { + for (int ccIdx = 1; ccIdx < 128; ++ccIdx) { + REQUIRE(!region.ccTriggers.contains(ccIdx)); + } + region.parseOpcode({ "on_lohdcc46", "0.15" }); + REQUIRE(region.ccTriggers.contains(46)); + REQUIRE(region.ccTriggers[46].getStart() == Approx(0.15f)); + REQUIRE(region.ccTriggers[46].getEnd() == 1.0f); + region.parseOpcode({ "on_hihdcc5", "0.47" }); + REQUIRE(region.ccTriggers.contains(5)); + REQUIRE(region.ccTriggers[5].getStart() == 0.0f); + REQUIRE(region.ccTriggers[5].getEnd() == Approx(0.47f)); + } + SECTION("volume") { REQUIRE(region.volume == 0.0f);