Merge pull request #315 from paulfd/trigger-on-cc

Don't require an explicit hikey/key=-1 to trigger on CC
This commit is contained in:
Paul Ferrand 2020-07-06 09:48:05 +02:00 committed by GitHub
commit eca794a93e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 57 additions and 10 deletions

View file

@ -186,14 +186,15 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode)
break; break;
// Region logic: key mapping // Region logic: key mapping
case hash("lokey"): case hash("lokey"):
triggerOnNote = true;
setRangeStartFromOpcode(opcode, keyRange, Default::keyRange); setRangeStartFromOpcode(opcode, keyRange, Default::keyRange);
break; break;
case hash("hikey"): case hash("hikey"):
triggerOnCC = (opcode.value == "-1"); triggerOnNote = (opcode.value != "-1");
setRangeEndFromOpcode(opcode, keyRange, Default::keyRange); setRangeEndFromOpcode(opcode, keyRange, Default::keyRange);
break; break;
case hash("key"): case hash("key"):
triggerOnCC = (opcode.value == "-1"); triggerOnNote = (opcode.value != "-1");
setRangeStartFromOpcode(opcode, keyRange, Default::keyRange); setRangeStartFromOpcode(opcode, keyRange, Default::keyRange);
setRangeEndFromOpcode(opcode, keyRange, Default::keyRange); setRangeEndFromOpcode(opcode, keyRange, Default::keyRange);
setValueFromOpcode(opcode, pitchKeycenter, Default::keyRange); setValueFromOpcode(opcode, pitchKeycenter, Default::keyRange);
@ -334,26 +335,34 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode)
case hash("start_locc&"): // also on_locc& case hash("start_locc&"): // also on_locc&
if (opcode.parameters.back() >= config::numCCs) if (opcode.parameters.back() >= config::numCCs)
return false; 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)); ccTriggers[opcode.parameters.back()].setStart(normalizeCC(*value));
}
break; break;
case hash("start_hicc&"): // also on_hicc& case hash("start_hicc&"): // also on_hicc&
if (opcode.parameters.back() >= config::numCCs) if (opcode.parameters.back() >= config::numCCs)
return false; 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)); ccTriggers[opcode.parameters.back()].setEnd(normalizeCC(*value));
}
break; break;
case hash("start_lohdcc&"): // also on_lohdcc& case hash("start_lohdcc&"): // also on_lohdcc&
if (opcode.parameters.back() >= config::numCCs) if (opcode.parameters.back() >= config::numCCs)
return false; 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); ccTriggers[opcode.parameters.back()].setStart(*value);
}
break; break;
case hash("start_hihdcc&"): // also on_hihdcc& case hash("start_hihdcc&"): // also on_hihdcc&
if (opcode.parameters.back() >= config::numCCs) if (opcode.parameters.back() >= config::numCCs)
return false; 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); ccTriggers[opcode.parameters.back()].setEnd(*value);
}
break; break;
// Performance parameters: amplifier // Performance parameters: amplifier
@ -987,7 +996,7 @@ bool sfz::Region::registerNoteOn(int noteNumber, float velocity, float randValue
if (!isSwitchedOn()) if (!isSwitchedOn())
return false; return false;
if (triggerOnCC) if (!triggerOnNote)
return false; return false;
if (previousNote && !(previousKeySwitched && noteNumber != *previousNote)) if (previousNote && !(previousKeySwitched && noteNumber != *previousNote))
@ -1019,7 +1028,7 @@ bool sfz::Region::registerNoteOff(int noteNumber, float velocity, float randValu
if (!isSwitchedOn()) if (!isSwitchedOn())
return false; return false;
if (triggerOnCC) if (!triggerOnNote)
return false; return false;
const bool velOk = velocityRange.containsWithEnd(velocity); const bool velOk = velocityRange.containsWithEnd(velocity);

View file

@ -381,6 +381,7 @@ private:
bool aftertouchSwitched { true }; bool aftertouchSwitched { true };
std::bitset<config::numCCs> ccSwitched; std::bitset<config::numCCs> ccSwitched;
bool triggerOnCC { false }; bool triggerOnCC { false };
bool triggerOnNote { true };
absl::string_view defaultPath { "" }; absl::string_view defaultPath { "" };
int sequenceCounter { 0 }; int sequenceCounter { 0 };

View file

@ -34,6 +34,9 @@ void sfz::Voice::startVoice(Region* region, int delay, int number, float value,
{ {
ASSERT(value >= 0.0f && value <= 1.0f); ASSERT(value >= 0.0f && value <= 1.0f);
if (triggerType == TriggerType::CC)
number = region->pitchKeycenter;
this->triggerType = triggerType; this->triggerType = triggerType;
triggerNumber = number; triggerNumber = number;
triggerValue = value; triggerValue = value;

View file

@ -114,8 +114,8 @@ TEST_CASE("Basic triggers", "Region triggers")
region.parseOpcode({ "on_locc47", "64" }); region.parseOpcode({ "on_locc47", "64" });
region.parseOpcode({ "on_hicc47", "68" }); region.parseOpcode({ "on_hicc47", "68" });
REQUIRE(!region.registerCC(47, 63_norm)); REQUIRE(!region.registerCC(47, 63_norm));
REQUIRE(!region.registerCC(47, 64_norm)); REQUIRE(region.registerCC(47, 64_norm));
REQUIRE(!region.registerCC(47, 65_norm)); REQUIRE(region.registerCC(47, 65_norm));
region.parseOpcode({ "hikey", "-1" }); region.parseOpcode({ "hikey", "-1" });
REQUIRE(region.registerCC(47, 64_norm)); REQUIRE(region.registerCC(47, 64_norm));
REQUIRE(region.registerCC(47, 65_norm)); REQUIRE(region.registerCC(47, 65_norm));
@ -125,6 +125,40 @@ TEST_CASE("Basic triggers", "Region triggers")
REQUIRE(!region.registerCC(47, 69_norm)); REQUIRE(!region.registerCC(47, 69_norm));
REQUIRE(!region.registerCC(40, 64_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") TEST_CASE("Legato triggers", "Region triggers")