Normalize CCs internally in Synth and region
This commit is contained in:
parent
0e1e65135e
commit
601126db0d
6 changed files with 82 additions and 44 deletions
|
|
@ -68,14 +68,13 @@ namespace Default
|
||||||
|
|
||||||
// Region logic: key mapping
|
// Region logic: key mapping
|
||||||
constexpr Range<uint8_t> keyRange { 0, 127 };
|
constexpr Range<uint8_t> keyRange { 0, 127 };
|
||||||
constexpr Range<float> velocityRange { 0.0f, 1.0f };
|
constexpr auto velocityRange = normalizedRange;
|
||||||
|
|
||||||
// Region logic: MIDI conditions
|
// Region logic: MIDI conditions
|
||||||
constexpr Range<uint8_t> channelRange { 1, 16 };
|
constexpr Range<uint8_t> channelRange { 1, 16 };
|
||||||
constexpr Range<uint8_t> midiChannelRange { 0, 15 };
|
constexpr Range<uint8_t> midiChannelRange { 0, 15 };
|
||||||
constexpr Range<uint16_t> ccNumberRange { 0, config::numCCs };
|
constexpr Range<uint16_t> ccNumberRange { 0, config::numCCs };
|
||||||
constexpr Range<uint8_t> ccValueRange { 0, 127 };
|
constexpr auto ccValueRange = normalizedRange;
|
||||||
constexpr uint8_t cc { 0 };
|
|
||||||
constexpr Range<int> bendRange { -8192, 8192 };
|
constexpr Range<int> bendRange { -8192, 8192 };
|
||||||
constexpr int bend { 0 };
|
constexpr int bend { 0 };
|
||||||
constexpr SfzVelocityOverride velocityOverride { SfzVelocityOverride::current };
|
constexpr SfzVelocityOverride velocityOverride { SfzVelocityOverride::current };
|
||||||
|
|
@ -92,7 +91,7 @@ namespace Default
|
||||||
|
|
||||||
// Region logic: Triggers
|
// Region logic: Triggers
|
||||||
constexpr SfzTrigger trigger { SfzTrigger::attack };
|
constexpr SfzTrigger trigger { SfzTrigger::attack };
|
||||||
constexpr Range<uint8_t> ccTriggerValueRange{ 0, 127 };
|
constexpr Range<float> ccTriggerValueRange = normalizedRange;
|
||||||
|
|
||||||
// Performance parameters: amplifier
|
// Performance parameters: amplifier
|
||||||
constexpr float globalVolume { -7.35f };
|
constexpr float globalVolume { -7.35f };
|
||||||
|
|
@ -123,8 +122,8 @@ namespace Default
|
||||||
constexpr Range<uint8_t> crossfadeKeyOutRange { 127, 127 };
|
constexpr Range<uint8_t> crossfadeKeyOutRange { 127, 127 };
|
||||||
constexpr Range<float> crossfadeVelInRange { 0.0f, 0.0f };
|
constexpr Range<float> crossfadeVelInRange { 0.0f, 0.0f };
|
||||||
constexpr Range<float> crossfadeVelOutRange { 1.0f, 1.0f };
|
constexpr Range<float> crossfadeVelOutRange { 1.0f, 1.0f };
|
||||||
constexpr Range<uint8_t> crossfadeCCInRange { 0, 0 };
|
constexpr Range<float> crossfadeCCInRange { 0.0f, 0.0f };
|
||||||
constexpr Range<uint8_t> crossfadeCCOutRange { 127, 127 };
|
constexpr Range<float> crossfadeCCOutRange { 1.0f, 1.0f };
|
||||||
constexpr SfzCrossfadeCurve crossfadeKeyCurve { SfzCrossfadeCurve::power };
|
constexpr SfzCrossfadeCurve crossfadeKeyCurve { SfzCrossfadeCurve::power };
|
||||||
constexpr SfzCrossfadeCurve crossfadeVelCurve { SfzCrossfadeCurve::power };
|
constexpr SfzCrossfadeCurve crossfadeVelCurve { SfzCrossfadeCurve::power };
|
||||||
constexpr SfzCrossfadeCurve crossfadeCCCurve { SfzCrossfadeCurve::power };
|
constexpr SfzCrossfadeCurve crossfadeCCCurve { SfzCrossfadeCurve::power };
|
||||||
|
|
|
||||||
|
|
@ -155,10 +155,16 @@ bool sfz::Region::parseOpcode(const Opcode& opcode)
|
||||||
setRangeEndFromOpcode(opcode, bendRange, Default::bendRange);
|
setRangeEndFromOpcode(opcode, bendRange, Default::bendRange);
|
||||||
break;
|
break;
|
||||||
case hash("locc&"):
|
case hash("locc&"):
|
||||||
setRangeStartFromOpcode(opcode, ccConditions[opcode.parameters.back()], Default::ccValueRange);
|
if (opcode.parameters.back() > config::numCCs)
|
||||||
|
return false;
|
||||||
|
if (auto value = readOpcode(opcode.value, Default::midi7Range))
|
||||||
|
ccConditions[opcode.parameters.back()].setStart(normalizeCC(*value));
|
||||||
break;
|
break;
|
||||||
case hash("hicc&"):
|
case hash("hicc&"):
|
||||||
setRangeEndFromOpcode(opcode, ccConditions[opcode.parameters.back()], Default::ccValueRange);
|
if (opcode.parameters.back() > config::numCCs)
|
||||||
|
return false;
|
||||||
|
if (auto value = readOpcode(opcode.value, Default::midi7Range))
|
||||||
|
ccConditions[opcode.parameters.back()].setEnd(normalizeCC(*value));
|
||||||
break;
|
break;
|
||||||
case hash("sw_lokey"):
|
case hash("sw_lokey"):
|
||||||
setRangeStartFromOpcode(opcode, keyswitchRange, Default::keyRange);
|
setRangeStartFromOpcode(opcode, keyswitchRange, Default::keyRange);
|
||||||
|
|
@ -250,11 +256,17 @@ bool sfz::Region::parseOpcode(const Opcode& opcode)
|
||||||
break;
|
break;
|
||||||
case hash("on_locc&"): // fallthrough
|
case hash("on_locc&"): // fallthrough
|
||||||
case hash("start_locc&"):
|
case hash("start_locc&"):
|
||||||
setRangeStartFromOpcode(opcode, ccTriggers[opcode.parameters.back()], Default::ccTriggerValueRange);
|
if (opcode.parameters.back() > config::numCCs)
|
||||||
|
return false;
|
||||||
|
if (auto value = readOpcode(opcode.value, Default::midi7Range))
|
||||||
|
ccTriggers[opcode.parameters.back()].setStart(normalizeCC(*value));
|
||||||
break;
|
break;
|
||||||
case hash("on_hicc&"): // fallthrough
|
case hash("on_hicc&"): // fallthrough
|
||||||
case hash("start_hicc&"):
|
case hash("start_hicc&"):
|
||||||
setRangeEndFromOpcode(opcode, ccTriggers[opcode.parameters.back()], Default::ccTriggerValueRange);
|
if (opcode.parameters.back() > config::numCCs)
|
||||||
|
return false;
|
||||||
|
if (auto value = readOpcode(opcode.value, Default::midi7Range))
|
||||||
|
ccTriggers[opcode.parameters.back()].setEnd(normalizeCC(*value));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Performance parameters: amplifier
|
// Performance parameters: amplifier
|
||||||
|
|
@ -366,16 +378,28 @@ bool sfz::Region::parseOpcode(const Opcode& opcode)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case hash("xfin_locc&"):
|
case hash("xfin_locc&"):
|
||||||
setRangeStartFromOpcode(opcode, crossfadeCCInRange[opcode.parameters.back()], Default::ccValueRange);
|
if (opcode.parameters.back() > config::numCCs)
|
||||||
|
return false;
|
||||||
|
if (auto value = readOpcode(opcode.value, Default::midi7Range))
|
||||||
|
crossfadeCCInRange[opcode.parameters.back()].setStart(normalizeCC(*value));
|
||||||
break;
|
break;
|
||||||
case hash("xfin_hicc&"):
|
case hash("xfin_hicc&"):
|
||||||
setRangeEndFromOpcode(opcode, crossfadeCCInRange[opcode.parameters.back()], Default::ccValueRange);
|
if (opcode.parameters.back() > config::numCCs)
|
||||||
|
return false;
|
||||||
|
if (auto value = readOpcode(opcode.value, Default::midi7Range))
|
||||||
|
crossfadeCCInRange[opcode.parameters.back()].setEnd(normalizeCC(*value));
|
||||||
break;
|
break;
|
||||||
case hash("xfout_locc&"):
|
case hash("xfout_locc&"):
|
||||||
setRangeStartFromOpcode(opcode, crossfadeCCOutRange[opcode.parameters.back()], Default::ccValueRange);
|
if (opcode.parameters.back() > config::numCCs)
|
||||||
|
return false;
|
||||||
|
if (auto value = readOpcode(opcode.value, Default::midi7Range))
|
||||||
|
crossfadeCCOutRange[opcode.parameters.back()].setStart(normalizeCC(*value));
|
||||||
break;
|
break;
|
||||||
case hash("xfout_hicc&"):
|
case hash("xfout_hicc&"):
|
||||||
setRangeEndFromOpcode(opcode, crossfadeCCOutRange[opcode.parameters.back()], Default::ccValueRange);
|
if (opcode.parameters.back() > config::numCCs)
|
||||||
|
return false;
|
||||||
|
if (auto value = readOpcode(opcode.value, Default::midi7Range))
|
||||||
|
crossfadeCCOutRange[opcode.parameters.back()].setEnd(normalizeCC(*value));
|
||||||
break;
|
break;
|
||||||
case hash("xf_cccurve"):
|
case hash("xf_cccurve"):
|
||||||
switch (hash(opcode.value)) {
|
switch (hash(opcode.value)) {
|
||||||
|
|
@ -872,6 +896,11 @@ bool sfz::Region::registerNoteOffNormalized(int noteNumber, float velocity, floa
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sfz::Region::registerCC(int ccNumber, uint8_t ccValue) noexcept
|
bool sfz::Region::registerCC(int ccNumber, uint8_t ccValue) noexcept
|
||||||
|
{
|
||||||
|
return registerCCNormalized(ccNumber, normalizeCC(ccValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool sfz::Region::registerCCNormalized(int ccNumber, float ccValue) noexcept
|
||||||
{
|
{
|
||||||
if (ccConditions.getWithDefault(ccNumber).containsWithEnd(ccValue))
|
if (ccConditions.getWithDefault(ccNumber).containsWithEnd(ccValue))
|
||||||
ccSwitched.set(ccNumber, true);
|
ccSwitched.set(ccNumber, true);
|
||||||
|
|
@ -1063,13 +1092,13 @@ float sfz::Region::getCrossfadeGain() const noexcept
|
||||||
|
|
||||||
// Crossfades due to CC states
|
// Crossfades due to CC states
|
||||||
for (const auto& valuePair : crossfadeCCInRange) {
|
for (const auto& valuePair : crossfadeCCInRange) {
|
||||||
const auto ccValue = midiState.getCCValue(valuePair.cc);
|
const auto ccValue = midiState.getCCValueNormalized(valuePair.cc);
|
||||||
const auto crossfadeRange = valuePair.value;
|
const auto crossfadeRange = valuePair.value;
|
||||||
gain *= crossfadeIn(crossfadeRange, ccValue, crossfadeCCCurve);
|
gain *= crossfadeIn(crossfadeRange, ccValue, crossfadeCCCurve);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& valuePair : crossfadeCCOutRange) {
|
for (const auto& valuePair : crossfadeCCOutRange) {
|
||||||
const auto ccValue = midiState.getCCValue(valuePair.cc);
|
const auto ccValue = midiState.getCCValueNormalized(valuePair.cc);
|
||||||
const auto crossfadeRange = valuePair.value;
|
const auto crossfadeRange = valuePair.value;
|
||||||
gain *= crossfadeOut(crossfadeRange, ccValue, crossfadeCCCurve);
|
gain *= crossfadeOut(crossfadeRange, ccValue, crossfadeCCCurve);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -132,6 +132,16 @@ struct Region {
|
||||||
* @return false
|
* @return false
|
||||||
*/
|
*/
|
||||||
bool registerCC(int ccNumber, uint8_t ccValue) noexcept;
|
bool registerCC(int ccNumber, uint8_t ccValue) noexcept;
|
||||||
|
/**
|
||||||
|
* @brief Register a new CC event. The region may be switched on or off using CCs so
|
||||||
|
* this function checks if it indeeds need to activate or not.
|
||||||
|
*
|
||||||
|
* @param ccNumber
|
||||||
|
* @param ccValue
|
||||||
|
* @return true if the region should trigger on this event
|
||||||
|
* @return false
|
||||||
|
*/
|
||||||
|
bool registerCCNormalized(int ccNumber, float ccValue) noexcept;
|
||||||
/**
|
/**
|
||||||
* @brief Register a new pitch wheel event.
|
* @brief Register a new pitch wheel event.
|
||||||
*
|
*
|
||||||
|
|
@ -295,7 +305,7 @@ struct Region {
|
||||||
|
|
||||||
// Region logic: MIDI conditions
|
// Region logic: MIDI conditions
|
||||||
Range<int> bendRange { Default::bendRange }; // hibend and lobend
|
Range<int> bendRange { Default::bendRange }; // hibend and lobend
|
||||||
CCMap<Range<uint8_t>> ccConditions { Default::ccValueRange };
|
CCMap<Range<float>> ccConditions { Default::ccValueRange };
|
||||||
Range<uint8_t> keyswitchRange { Default::keyRange }; // sw_hikey and sw_lokey
|
Range<uint8_t> keyswitchRange { Default::keyRange }; // sw_hikey and sw_lokey
|
||||||
absl::optional<uint8_t> keyswitch {}; // sw_last
|
absl::optional<uint8_t> keyswitch {}; // sw_last
|
||||||
absl::optional<uint8_t> keyswitchUp {}; // sw_up
|
absl::optional<uint8_t> keyswitchUp {}; // sw_up
|
||||||
|
|
@ -314,7 +324,7 @@ struct Region {
|
||||||
|
|
||||||
// Region logic: triggers
|
// Region logic: triggers
|
||||||
SfzTrigger trigger { Default::trigger }; // trigger
|
SfzTrigger trigger { Default::trigger }; // trigger
|
||||||
CCMap<Range<uint8_t>> ccTriggers { Default::ccTriggerValueRange }; // on_loccN on_hiccN
|
CCMap<Range<float>> ccTriggers { Default::ccTriggerValueRange }; // on_loccN on_hiccN
|
||||||
|
|
||||||
// Performance parameters: amplifier
|
// Performance parameters: amplifier
|
||||||
float volume { Default::volume }; // volume
|
float volume { Default::volume }; // volume
|
||||||
|
|
@ -339,8 +349,8 @@ struct Region {
|
||||||
SfzCrossfadeCurve crossfadeKeyCurve { Default::crossfadeKeyCurve };
|
SfzCrossfadeCurve crossfadeKeyCurve { Default::crossfadeKeyCurve };
|
||||||
SfzCrossfadeCurve crossfadeVelCurve { Default::crossfadeVelCurve };
|
SfzCrossfadeCurve crossfadeVelCurve { Default::crossfadeVelCurve };
|
||||||
SfzCrossfadeCurve crossfadeCCCurve { Default::crossfadeCCCurve };
|
SfzCrossfadeCurve crossfadeCCCurve { Default::crossfadeCCCurve };
|
||||||
CCMap<Range<uint8_t>> crossfadeCCInRange { Default::crossfadeCCInRange }; // xfin_loccN xfin_hiccN
|
CCMap<Range<float>> crossfadeCCInRange { Default::crossfadeCCInRange }; // xfin_loccN xfin_hiccN
|
||||||
CCMap<Range<uint8_t>> crossfadeCCOutRange { Default::crossfadeCCOutRange }; // xfout_loccN xfout_hiccN
|
CCMap<Range<float>> crossfadeCCOutRange { Default::crossfadeCCOutRange }; // xfout_loccN xfout_hiccN
|
||||||
float rtDecay { Default::rtDecay }; // rt_decay
|
float rtDecay { Default::rtDecay }; // rt_decay
|
||||||
|
|
||||||
// Filters and EQs
|
// Filters and EQs
|
||||||
|
|
|
||||||
|
|
@ -181,7 +181,7 @@ void sfz::Synth::handleControlOpcodes(const std::vector<Opcode>& members)
|
||||||
case hash("Set_cc&"): // fallthrough
|
case hash("Set_cc&"): // fallthrough
|
||||||
case hash("set_cc&"):
|
case hash("set_cc&"):
|
||||||
if (Default::ccNumberRange.containsWithEnd(member.parameters.back())) {
|
if (Default::ccNumberRange.containsWithEnd(member.parameters.back())) {
|
||||||
const auto ccValue = readOpcode(member.value, Default::ccValueRange).value_or(0);
|
const auto ccValue = readOpcode(member.value, Default::midi7Range).value_or(0);
|
||||||
resources.midiState.ccEvent(0, member.parameters.back(), ccValue);
|
resources.midiState.ccEvent(0, member.parameters.back(), ccValue);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -236,7 +236,7 @@ TEST_CASE("[Files] Pizz basic")
|
||||||
REQUIRE(synth.getRegionView(i)->keyRange == sfz::Range<uint8_t>(12, 22));
|
REQUIRE(synth.getRegionView(i)->keyRange == sfz::Range<uint8_t>(12, 22));
|
||||||
REQUIRE(synth.getRegionView(i)->velocityRange == sfz::Range<float>(97_norm, 127_norm));
|
REQUIRE(synth.getRegionView(i)->velocityRange == sfz::Range<float>(97_norm, 127_norm));
|
||||||
REQUIRE(synth.getRegionView(i)->pitchKeycenter == 21);
|
REQUIRE(synth.getRegionView(i)->pitchKeycenter == 21);
|
||||||
REQUIRE(synth.getRegionView(i)->ccConditions.getWithDefault(107) == sfz::Range<uint8_t>(0, 13));
|
REQUIRE(synth.getRegionView(i)->ccConditions.getWithDefault(107) == sfz::Range<float>(0_norm, 13_norm));
|
||||||
}
|
}
|
||||||
REQUIRE(synth.getRegionView(0)->randRange == sfz::Range<float>(0, 0.25));
|
REQUIRE(synth.getRegionView(0)->randRange == sfz::Range<float>(0, 0.25));
|
||||||
REQUIRE(synth.getRegionView(1)->randRange == sfz::Range<float>(0.25, 0.5));
|
REQUIRE(synth.getRegionView(1)->randRange == sfz::Range<float>(0.25, 0.5));
|
||||||
|
|
|
||||||
|
|
@ -240,16 +240,16 @@ TEST_CASE("[Region] Parsing opcodes")
|
||||||
|
|
||||||
SECTION("locc, hicc")
|
SECTION("locc, hicc")
|
||||||
{
|
{
|
||||||
REQUIRE(region.ccConditions.getWithDefault(0) == sfz::Range<uint8_t>(0, 127));
|
REQUIRE(region.ccConditions.getWithDefault(0) == sfz::Range<float>(0_norm, 127_norm));
|
||||||
REQUIRE(region.ccConditions[127] == sfz::Range<uint8_t>(0, 127));
|
REQUIRE(region.ccConditions[127] == sfz::Range<float>(0_norm, 127_norm));
|
||||||
region.parseOpcode({ "locc6", "4" });
|
region.parseOpcode({ "locc6", "4" });
|
||||||
REQUIRE(region.ccConditions[6] == sfz::Range<uint8_t>(4, 127));
|
REQUIRE(region.ccConditions[6] == sfz::Range<float>(4_norm, 127_norm));
|
||||||
region.parseOpcode({ "locc12", "-128" });
|
region.parseOpcode({ "locc12", "-128" });
|
||||||
REQUIRE(region.ccConditions[12] == sfz::Range<uint8_t>(0, 127));
|
REQUIRE(region.ccConditions[12] == sfz::Range<float>(0_norm, 127_norm));
|
||||||
region.parseOpcode({ "hicc65", "39" });
|
region.parseOpcode({ "hicc65", "39" });
|
||||||
REQUIRE(region.ccConditions[65] == sfz::Range<uint8_t>(0, 39));
|
REQUIRE(region.ccConditions[65] == sfz::Range<float>(0_norm, 39_norm));
|
||||||
region.parseOpcode({ "hicc127", "135" });
|
region.parseOpcode({ "hicc127", "135" });
|
||||||
REQUIRE(region.ccConditions[127] == sfz::Range<uint8_t>(0, 127));
|
REQUIRE(region.ccConditions[127] == sfz::Range<float>(0_norm, 127_norm));
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("sw_lokey, sw_hikey")
|
SECTION("sw_lokey, sw_hikey")
|
||||||
|
|
@ -427,10 +427,10 @@ TEST_CASE("[Region] Parsing opcodes")
|
||||||
}
|
}
|
||||||
region.parseOpcode({ "on_locc45", "15" });
|
region.parseOpcode({ "on_locc45", "15" });
|
||||||
REQUIRE(region.ccTriggers.contains(45));
|
REQUIRE(region.ccTriggers.contains(45));
|
||||||
REQUIRE(region.ccTriggers[45] == sfz::Range<uint8_t>(15, 127));
|
REQUIRE(region.ccTriggers[45] == sfz::Range<float>(15_norm, 127_norm));
|
||||||
region.parseOpcode({ "on_hicc4", "47" });
|
region.parseOpcode({ "on_hicc4", "47" });
|
||||||
REQUIRE(region.ccTriggers.contains(45));
|
REQUIRE(region.ccTriggers.contains(45));
|
||||||
REQUIRE(region.ccTriggers[4] == sfz::Range<uint8_t>(0, 47));
|
REQUIRE(region.ccTriggers[4] == sfz::Range<float>(0_norm, 47_norm));
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("volume")
|
SECTION("volume")
|
||||||
|
|
@ -650,38 +650,38 @@ TEST_CASE("[Region] Parsing opcodes")
|
||||||
{
|
{
|
||||||
REQUIRE(!region.crossfadeCCInRange.contains(4));
|
REQUIRE(!region.crossfadeCCInRange.contains(4));
|
||||||
region.parseOpcode({ "xfin_locc4", "4" });
|
region.parseOpcode({ "xfin_locc4", "4" });
|
||||||
REQUIRE(region.crossfadeCCInRange[4] == sfz::Range<uint8_t>(4, 4));
|
REQUIRE(region.crossfadeCCInRange[4] == sfz::Range<float>(4_norm, 4_norm));
|
||||||
region.parseOpcode({ "xfin_locc4", "128" });
|
region.parseOpcode({ "xfin_locc4", "128" });
|
||||||
REQUIRE(region.crossfadeCCInRange[4] == sfz::Range<uint8_t>(127, 127));
|
REQUIRE(region.crossfadeCCInRange[4] == sfz::Range<float>(127_norm, 127_norm));
|
||||||
region.parseOpcode({ "xfin_locc4", "59" });
|
region.parseOpcode({ "xfin_locc4", "59" });
|
||||||
REQUIRE(region.crossfadeCCInRange[4] == sfz::Range<uint8_t>(59, 127));
|
REQUIRE(region.crossfadeCCInRange[4] == sfz::Range<float>(59_norm, 127_norm));
|
||||||
region.parseOpcode({ "xfin_hicc4", "59" });
|
region.parseOpcode({ "xfin_hicc4", "59" });
|
||||||
REQUIRE(region.crossfadeCCInRange[4] == sfz::Range<uint8_t>(59, 59));
|
REQUIRE(region.crossfadeCCInRange[4] == sfz::Range<float>(59_norm, 59_norm));
|
||||||
region.parseOpcode({ "xfin_hicc4", "128" });
|
region.parseOpcode({ "xfin_hicc4", "128" });
|
||||||
REQUIRE(region.crossfadeCCInRange[4] == sfz::Range<uint8_t>(59, 127));
|
REQUIRE(region.crossfadeCCInRange[4] == sfz::Range<float>(59_norm, 127_norm));
|
||||||
region.parseOpcode({ "xfin_hicc4", "0" });
|
region.parseOpcode({ "xfin_hicc4", "0" });
|
||||||
REQUIRE(region.crossfadeCCInRange[4] == sfz::Range<uint8_t>(0, 0));
|
REQUIRE(region.crossfadeCCInRange[4] == sfz::Range<float>(0_norm, 0_norm));
|
||||||
region.parseOpcode({ "xfin_hicc4", "-1" });
|
region.parseOpcode({ "xfin_hicc4", "-1" });
|
||||||
REQUIRE(region.crossfadeCCInRange[4] == sfz::Range<uint8_t>(0, 0));
|
REQUIRE(region.crossfadeCCInRange[4] == sfz::Range<float>(0_norm, 0_norm));
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("xfout_locc, xfout_hicc")
|
SECTION("xfout_locc, xfout_hicc")
|
||||||
{
|
{
|
||||||
REQUIRE(!region.crossfadeCCOutRange.contains(4));
|
REQUIRE(!region.crossfadeCCOutRange.contains(4));
|
||||||
region.parseOpcode({ "xfout_locc4", "4" });
|
region.parseOpcode({ "xfout_locc4", "4" });
|
||||||
REQUIRE(region.crossfadeCCOutRange[4] == sfz::Range<uint8_t>(4, 127));
|
REQUIRE(region.crossfadeCCOutRange[4] == sfz::Range<float>(4_norm, 127_norm));
|
||||||
region.parseOpcode({ "xfout_locc4", "128" });
|
region.parseOpcode({ "xfout_locc4", "128" });
|
||||||
REQUIRE(region.crossfadeCCOutRange[4] == sfz::Range<uint8_t>(127, 127));
|
REQUIRE(region.crossfadeCCOutRange[4] == sfz::Range<float>(127_norm, 127_norm));
|
||||||
region.parseOpcode({ "xfout_locc4", "59" });
|
region.parseOpcode({ "xfout_locc4", "59" });
|
||||||
REQUIRE(region.crossfadeCCOutRange[4] == sfz::Range<uint8_t>(59, 127));
|
REQUIRE(region.crossfadeCCOutRange[4] == sfz::Range<float>(59_norm, 127_norm));
|
||||||
region.parseOpcode({ "xfout_hicc4", "59" });
|
region.parseOpcode({ "xfout_hicc4", "59" });
|
||||||
REQUIRE(region.crossfadeCCOutRange[4] == sfz::Range<uint8_t>(59, 59));
|
REQUIRE(region.crossfadeCCOutRange[4] == sfz::Range<float>(59_norm, 59_norm));
|
||||||
region.parseOpcode({ "xfout_hicc4", "128" });
|
region.parseOpcode({ "xfout_hicc4", "128" });
|
||||||
REQUIRE(region.crossfadeCCOutRange[4] == sfz::Range<uint8_t>(59, 127));
|
REQUIRE(region.crossfadeCCOutRange[4] == sfz::Range<float>(59_norm, 127_norm));
|
||||||
region.parseOpcode({ "xfout_hicc4", "0" });
|
region.parseOpcode({ "xfout_hicc4", "0" });
|
||||||
REQUIRE(region.crossfadeCCOutRange[4] == sfz::Range<uint8_t>(0, 0));
|
REQUIRE(region.crossfadeCCOutRange[4] == sfz::Range<float>(0_norm, 0_norm));
|
||||||
region.parseOpcode({ "xfout_hicc4", "-1" });
|
region.parseOpcode({ "xfout_hicc4", "-1" });
|
||||||
REQUIRE(region.crossfadeCCOutRange[4] == sfz::Range<uint8_t>(0, 0));
|
REQUIRE(region.crossfadeCCOutRange[4] == sfz::Range<float>(0_norm, 0_norm));
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("xf_keycurve")
|
SECTION("xf_keycurve")
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue