Merge pull request #233 from jpcima/set-hdcc
Support the opcode set_hdccN
This commit is contained in:
commit
9c93120b83
12 changed files with 1582 additions and 1081 deletions
|
|
@ -42,6 +42,12 @@ enum OpcodeCategory {
|
||||||
enum OpcodeScope {
|
enum OpcodeScope {
|
||||||
//! unknown scope or other
|
//! unknown scope or other
|
||||||
kOpcodeScopeGeneric,
|
kOpcodeScopeGeneric,
|
||||||
|
//! global scope
|
||||||
|
kOpcodeScopeGlobal,
|
||||||
|
//! control scope
|
||||||
|
kOpcodeScopeControl,
|
||||||
|
//! group scope
|
||||||
|
kOpcodeScopeGroup,
|
||||||
//! region scope
|
//! region scope
|
||||||
kOpcodeScopeRegion,
|
kOpcodeScopeRegion,
|
||||||
//! effect scope
|
//! effect scope
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -8,6 +8,7 @@
|
||||||
#include "Opcode.h"
|
#include "Opcode.h"
|
||||||
#include "absl/strings/string_view.h"
|
#include "absl/strings/string_view.h"
|
||||||
#include "absl/strings/str_cat.h"
|
#include "absl/strings/str_cat.h"
|
||||||
|
#include "absl/strings/ascii.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace sfz {
|
namespace sfz {
|
||||||
|
|
@ -16,6 +17,9 @@ static std::string cleanUpOpcodeName(absl::string_view rawOpcode, OpcodeScope sc
|
||||||
{
|
{
|
||||||
std::string opcode { rawOpcode };
|
std::string opcode { rawOpcode };
|
||||||
|
|
||||||
|
// always convert it to lower case
|
||||||
|
absl::AsciiStrToLower(&opcode);
|
||||||
|
|
||||||
/*!re2c
|
/*!re2c
|
||||||
re2c:flags:posix-captures = 1;
|
re2c:flags:posix-captures = 1;
|
||||||
re2c:define:YYCTYPE = char;
|
re2c:define:YYCTYPE = char;
|
||||||
|
|
@ -45,24 +49,28 @@ static std::string cleanUpOpcodeName(absl::string_view rawOpcode, OpcodeScope sc
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
if (scope == kOpcodeScopeRegion) {
|
||||||
|
|
||||||
YYCURSOR = opcode.c_str();
|
YYCURSOR = opcode.c_str();
|
||||||
|
|
||||||
/*!re2c
|
/*!re2c
|
||||||
|
|
||||||
(any) "_cc" (number) END {
|
(any) "_cc" (number) END {
|
||||||
opcode = absl::StrCat(group(1), "_oncc", group(2));
|
opcode = absl::StrCat(group(1), "_oncc", group(2));
|
||||||
goto end_generic;
|
goto end_region_oncc;
|
||||||
}
|
}
|
||||||
|
|
||||||
* {
|
* {
|
||||||
goto end_generic;
|
goto end_region_oncc;
|
||||||
}
|
}
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
end_generic:
|
end_region_oncc:
|
||||||
/* end */;
|
/* end */;
|
||||||
|
|
||||||
|
} // scope == kOpcodeScopeRegion
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
if (scope == kOpcodeScopeRegion) {
|
if (scope == kOpcodeScopeRegion) {
|
||||||
|
|
@ -132,6 +140,10 @@ end_generic:
|
||||||
opcode = absl::StrCat("start_", group(1), "cc", group(2));
|
opcode = absl::StrCat("start_", group(1), "cc", group(2));
|
||||||
goto end_region;
|
goto end_region;
|
||||||
}
|
}
|
||||||
|
"on_" ("hi"|"lo") "hdcc" (number) END {
|
||||||
|
opcode = absl::StrCat("start_", group(1), "hdcc", group(2));
|
||||||
|
goto end_region;
|
||||||
|
}
|
||||||
|
|
||||||
"fil_" (any) END {
|
"fil_" (any) END {
|
||||||
opcode = absl::StrCat("fil1_", group(1));
|
opcode = absl::StrCat("fil1_", group(1));
|
||||||
|
|
@ -146,6 +158,11 @@ end_generic:
|
||||||
goto end_region;
|
goto end_region;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
("hi"|"lo") "realcc" (number) END {
|
||||||
|
opcode = absl::StrCat(group(1), "hdcc", group(2));
|
||||||
|
goto end_region;
|
||||||
|
}
|
||||||
|
|
||||||
* {
|
* {
|
||||||
goto end_region;
|
goto end_region;
|
||||||
}
|
}
|
||||||
|
|
@ -159,6 +176,31 @@ end_region:
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
if (scope == kOpcodeScopeControl) {
|
||||||
|
|
||||||
|
YYCURSOR = opcode.c_str();
|
||||||
|
|
||||||
|
/*!re2c
|
||||||
|
|
||||||
|
"set_realcc" (number) END {
|
||||||
|
opcode = absl::StrCat("set_hdcc", group(1));
|
||||||
|
goto end_control;
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
goto end_control;
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
end_control:
|
||||||
|
/* end */;
|
||||||
|
|
||||||
|
} // scope == kOpcodeScopeControl
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
#undef YYMAXNMATCH
|
#undef YYMAXNMATCH
|
||||||
|
|
||||||
return opcode;
|
return opcode;
|
||||||
|
|
|
||||||
|
|
@ -102,6 +102,20 @@ public:
|
||||||
_start = value;
|
_start = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Convert the range to a different value type
|
||||||
|
*
|
||||||
|
* @return Range<Other>
|
||||||
|
*/
|
||||||
|
template <class Other>
|
||||||
|
Range<Other> to() const noexcept
|
||||||
|
{
|
||||||
|
return Range<Other> {
|
||||||
|
static_cast<Other>(_start),
|
||||||
|
static_cast<Other>(_end),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Type _start { static_cast<Type>(0.0) };
|
Type _start { static_cast<Type>(0.0) };
|
||||||
Type _end { static_cast<Type>(0.0) };
|
Type _end { static_cast<Type>(0.0) };
|
||||||
|
|
|
||||||
|
|
@ -206,6 +206,18 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode)
|
||||||
if (auto value = readOpcode(opcode.value, Default::midi7Range))
|
if (auto value = readOpcode(opcode.value, Default::midi7Range))
|
||||||
ccConditions[opcode.parameters.back()].setEnd(normalizeCC(*value));
|
ccConditions[opcode.parameters.back()].setEnd(normalizeCC(*value));
|
||||||
break;
|
break;
|
||||||
|
case hash("lohdcc&"): // also lorealcc&
|
||||||
|
if (opcode.parameters.back() >= config::numCCs)
|
||||||
|
return false;
|
||||||
|
if (auto value = readOpcode(opcode.value, Default::normalizedRange))
|
||||||
|
ccConditions[opcode.parameters.back()].setStart(*value);
|
||||||
|
break;
|
||||||
|
case hash("hihdcc&"): // also hirealcc&
|
||||||
|
if (opcode.parameters.back() >= config::numCCs)
|
||||||
|
return false;
|
||||||
|
if (auto value = readOpcode(opcode.value, Default::normalizedRange))
|
||||||
|
ccConditions[opcode.parameters.back()].setEnd(*value);
|
||||||
|
break;
|
||||||
case hash("sw_lokey"):
|
case hash("sw_lokey"):
|
||||||
setRangeStartFromOpcode(opcode, keyswitchRange, Default::keyRange);
|
setRangeStartFromOpcode(opcode, keyswitchRange, Default::keyRange);
|
||||||
break;
|
break;
|
||||||
|
|
@ -309,6 +321,18 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode)
|
||||||
if (auto value = readOpcode(opcode.value, Default::midi7Range))
|
if (auto value = readOpcode(opcode.value, Default::midi7Range))
|
||||||
ccTriggers[opcode.parameters.back()].setEnd(normalizeCC(*value));
|
ccTriggers[opcode.parameters.back()].setEnd(normalizeCC(*value));
|
||||||
break;
|
break;
|
||||||
|
case hash("start_lohdcc&"): // also on_lohdcc&
|
||||||
|
if (opcode.parameters.back() >= config::numCCs)
|
||||||
|
return false;
|
||||||
|
if (auto value = readOpcode(opcode.value, Default::midi7Range.to<float>()))
|
||||||
|
ccTriggers[opcode.parameters.back()].setStart(normalizeCC(*value));
|
||||||
|
break;
|
||||||
|
case hash("start_hihdcc&"): // also on_hihdcc&
|
||||||
|
if (opcode.parameters.back() >= config::numCCs)
|
||||||
|
return false;
|
||||||
|
if (auto value = readOpcode(opcode.value, Default::midi7Range.to<float>()))
|
||||||
|
ccTriggers[opcode.parameters.back()].setEnd(normalizeCC(*value));
|
||||||
|
break;
|
||||||
|
|
||||||
// Performance parameters: amplifier
|
// Performance parameters: amplifier
|
||||||
case hash("volume"): // also gain
|
case hash("volume"): // also gain
|
||||||
|
|
|
||||||
|
|
@ -194,6 +194,16 @@ namespace literals {
|
||||||
|
|
||||||
return normalize7Bits(value);
|
return normalize7Bits(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline float operator""_norm(long double value)
|
||||||
|
{
|
||||||
|
if (value < 0)
|
||||||
|
value = 0;
|
||||||
|
if (value > 127)
|
||||||
|
value = 127;
|
||||||
|
|
||||||
|
return normalize7Bits(value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -158,7 +158,9 @@ void sfz::Synth::clear()
|
||||||
|
|
||||||
void sfz::Synth::handleGlobalOpcodes(const std::vector<Opcode>& members)
|
void sfz::Synth::handleGlobalOpcodes(const std::vector<Opcode>& members)
|
||||||
{
|
{
|
||||||
for (auto& member : members) {
|
for (auto& rawMember : members) {
|
||||||
|
const Opcode member = rawMember.cleanUp(kOpcodeScopeGlobal);
|
||||||
|
|
||||||
switch (member.lettersOnlyHash) {
|
switch (member.lettersOnlyHash) {
|
||||||
case hash("sw_default"):
|
case hash("sw_default"):
|
||||||
setValueFromOpcode(member, defaultSwitch, Default::keyRange);
|
setValueFromOpcode(member, defaultSwitch, Default::keyRange);
|
||||||
|
|
@ -176,7 +178,9 @@ void sfz::Synth::handleGroupOpcodes(const std::vector<Opcode>& members, const st
|
||||||
absl::optional<unsigned> groupIdx;
|
absl::optional<unsigned> groupIdx;
|
||||||
unsigned maxPolyphony { config::maxVoices };
|
unsigned maxPolyphony { config::maxVoices };
|
||||||
|
|
||||||
const auto parseOpcode = [&](const Opcode& member) {
|
const auto parseOpcode = [&](const Opcode& rawMember) {
|
||||||
|
const Opcode member = rawMember.cleanUp(kOpcodeScopeGroup);
|
||||||
|
|
||||||
switch (member.lettersOnlyHash) {
|
switch (member.lettersOnlyHash) {
|
||||||
case hash("group"):
|
case hash("group"):
|
||||||
setValueFromOpcode(member, groupIdx, Default::groupRange);
|
setValueFromOpcode(member, groupIdx, Default::groupRange);
|
||||||
|
|
@ -199,9 +203,10 @@ void sfz::Synth::handleGroupOpcodes(const std::vector<Opcode>& members, const st
|
||||||
|
|
||||||
void sfz::Synth::handleControlOpcodes(const std::vector<Opcode>& members)
|
void sfz::Synth::handleControlOpcodes(const std::vector<Opcode>& members)
|
||||||
{
|
{
|
||||||
for (auto& member : members) {
|
for (auto& rawMember : members) {
|
||||||
|
const Opcode member = rawMember.cleanUp(kOpcodeScopeControl);
|
||||||
|
|
||||||
switch (member.lettersOnlyHash) {
|
switch (member.lettersOnlyHash) {
|
||||||
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::midi7Range);
|
const auto ccValue = readOpcode(member.value, Default::midi7Range);
|
||||||
|
|
@ -209,7 +214,13 @@ void sfz::Synth::handleControlOpcodes(const std::vector<Opcode>& members)
|
||||||
resources.midiState.ccEvent(0, member.parameters.back(), normalizeCC(*ccValue));
|
resources.midiState.ccEvent(0, member.parameters.back(), normalizeCC(*ccValue));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case hash("Label_cc&"): // fallthrough
|
case hash("set_hdcc&"):
|
||||||
|
if (Default::ccNumberRange.containsWithEnd(member.parameters.back())) {
|
||||||
|
const auto ccValue = readOpcode(member.value, Default::normalizedRange);
|
||||||
|
if (ccValue)
|
||||||
|
resources.midiState.ccEvent(0, member.parameters.back(), *ccValue);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case hash("label_cc&"):
|
case hash("label_cc&"):
|
||||||
if (Default::ccNumberRange.containsWithEnd(member.parameters.back()))
|
if (Default::ccNumberRange.containsWithEnd(member.parameters.back()))
|
||||||
ccLabels.emplace_back(member.parameters.back(), std::string(member.value));
|
ccLabels.emplace_back(member.parameters.back(), std::string(member.value));
|
||||||
|
|
@ -218,8 +229,6 @@ void sfz::Synth::handleControlOpcodes(const std::vector<Opcode>& members)
|
||||||
if (Default::keyRange.containsWithEnd(member.parameters.back()))
|
if (Default::keyRange.containsWithEnd(member.parameters.back()))
|
||||||
keyLabels.emplace_back(member.parameters.back(), std::string(member.value));
|
keyLabels.emplace_back(member.parameters.back(), std::string(member.value));
|
||||||
break;
|
break;
|
||||||
case hash("Default_path"):
|
|
||||||
// fallthrough
|
|
||||||
case hash("default_path"):
|
case hash("default_path"):
|
||||||
defaultPath = absl::StrReplaceAll(trim(member.value), { { "\\", "/" } });
|
defaultPath = absl::StrReplaceAll(trim(member.value), { { "\\", "/" } });
|
||||||
DBG("Changing default sample path to " << defaultPath);
|
DBG("Changing default sample path to " << defaultPath);
|
||||||
|
|
|
||||||
|
|
@ -408,6 +408,24 @@ TEST_CASE("[Files] Set CC applies properly")
|
||||||
REQUIRE(midiState.getCCValue(61) == 122_norm);
|
REQUIRE(midiState.getCCValue(61) == 122_norm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("[Files] Set HDCC applies properly")
|
||||||
|
{
|
||||||
|
sfz::Synth synth;
|
||||||
|
const auto& midiState = synth.getResources().midiState;
|
||||||
|
synth.loadSfzFile(fs::current_path() / "tests/TestFiles/set_hdcc.sfz");
|
||||||
|
REQUIRE(midiState.getCCValue(142) == Approx(0.5678));
|
||||||
|
REQUIRE(midiState.getCCValue(61) == Approx(0.1234));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("[Files] Set RealCC applies properly")
|
||||||
|
{
|
||||||
|
sfz::Synth synth;
|
||||||
|
const auto& midiState = synth.getResources().midiState;
|
||||||
|
synth.loadSfzFile(fs::current_path() / "tests/TestFiles/set_realcc.sfz");
|
||||||
|
REQUIRE(midiState.getCCValue(142) == Approx(0.5678));
|
||||||
|
REQUIRE(midiState.getCCValue(61) == Approx(0.1234));
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("[Files] Note and octave offsets")
|
TEST_CASE("[Files] Note and octave offsets")
|
||||||
{
|
{
|
||||||
sfz::Synth synth;
|
sfz::Synth synth;
|
||||||
|
|
|
||||||
|
|
@ -161,8 +161,12 @@ TEST_CASE("[Opcode] Derived names")
|
||||||
|
|
||||||
TEST_CASE("[Opcode] Normalization")
|
TEST_CASE("[Opcode] Normalization")
|
||||||
{
|
{
|
||||||
REQUIRE(sfz::Opcode("foo_cc7", "").cleanUp(sfz::kOpcodeScopeGeneric).opcode == "foo_oncc7");
|
// *_ccN
|
||||||
|
|
||||||
REQUIRE(sfz::Opcode("foo_cc7", "").cleanUp(sfz::kOpcodeScopeRegion).opcode == "foo_oncc7");
|
REQUIRE(sfz::Opcode("foo_cc7", "").cleanUp(sfz::kOpcodeScopeRegion).opcode == "foo_oncc7");
|
||||||
|
REQUIRE(sfz::Opcode("foo_cc7", "").cleanUp(sfz::kOpcodeScopeControl).opcode == "foo_cc7");
|
||||||
|
|
||||||
|
// <region>
|
||||||
|
|
||||||
static const std::pair<absl::string_view, absl::string_view> regionSpecific[] = {
|
static const std::pair<absl::string_view, absl::string_view> regionSpecific[] = {
|
||||||
// LFO SFZv1
|
// LFO SFZv1
|
||||||
|
|
@ -202,6 +206,10 @@ TEST_CASE("[Opcode] Normalization")
|
||||||
{"gain_foobar", "volume_foobar"},
|
{"gain_foobar", "volume_foobar"},
|
||||||
{"tune", "pitch"},
|
{"tune", "pitch"},
|
||||||
{"tune_foobar", "pitch_foobar"},
|
{"tune_foobar", "pitch_foobar"},
|
||||||
|
{"lorealcc24", "lohdcc24"},
|
||||||
|
{"hirealcc25", "hihdcc25"},
|
||||||
|
{"on_lohdcc26", "start_lohdcc26"},
|
||||||
|
{"on_hihdcc27", "start_hihdcc27"},
|
||||||
// SFZv2 aliases
|
// SFZv2 aliases
|
||||||
{"on_hicc22", "start_hicc22"},
|
{"on_hicc22", "start_hicc22"},
|
||||||
{"on_locc23", "start_locc23"},
|
{"on_locc23", "start_locc23"},
|
||||||
|
|
@ -219,4 +227,22 @@ TEST_CASE("[Opcode] Normalization")
|
||||||
REQUIRE(sfz::Opcode(input, "").cleanUp(sfz::kOpcodeScopeRegion).opcode == expected);
|
REQUIRE(sfz::Opcode(input, "").cleanUp(sfz::kOpcodeScopeRegion).opcode == expected);
|
||||||
REQUIRE(sfz::Opcode(input, "").cleanUp(sfz::kOpcodeScopeGeneric).opcode == input);
|
REQUIRE(sfz::Opcode(input, "").cleanUp(sfz::kOpcodeScopeGeneric).opcode == input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// <control>
|
||||||
|
|
||||||
|
static const std::pair<absl::string_view, absl::string_view> controlSpecific[] = {
|
||||||
|
// ARIA aliases
|
||||||
|
{"set_realcc1", "set_hdcc1"},
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto pair : controlSpecific) {
|
||||||
|
absl::string_view input = pair.first;
|
||||||
|
absl::string_view expected = pair.second;
|
||||||
|
REQUIRE(sfz::Opcode(input, "").cleanUp(sfz::kOpcodeScopeControl).opcode == expected);
|
||||||
|
REQUIRE(sfz::Opcode(input, "").cleanUp(sfz::kOpcodeScopeGeneric).opcode == input);
|
||||||
|
}
|
||||||
|
|
||||||
|
// case
|
||||||
|
|
||||||
|
REQUIRE(sfz::Opcode("SaMpLe", "").cleanUp(sfz::kOpcodeScopeRegion).opcode == "sample");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -278,6 +278,34 @@ TEST_CASE("[Region] Parsing opcodes")
|
||||||
REQUIRE(region.ccConditions[127] == sfz::Range<float>(0_norm, 127_norm));
|
REQUIRE(region.ccConditions[127] == sfz::Range<float>(0_norm, 127_norm));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("lohdcc, hihdcc")
|
||||||
|
{
|
||||||
|
region.parseOpcode({ "lohdcc7", "0.12" });
|
||||||
|
REQUIRE(region.ccConditions[7].getStart() == Approx(0.12f));
|
||||||
|
REQUIRE(region.ccConditions[7].getEnd() == 1.0f);
|
||||||
|
region.parseOpcode({ "lohdcc13", "-1.0" });
|
||||||
|
REQUIRE(region.ccConditions[13] == sfz::Range<float>(0.0f, 1.0f));
|
||||||
|
region.parseOpcode({ "hihdcc64", "0.45" });
|
||||||
|
REQUIRE(region.ccConditions[64].getStart() == 0.0f);
|
||||||
|
REQUIRE(region.ccConditions[64].getEnd() == Approx(0.45f));
|
||||||
|
region.parseOpcode({ "hihdcc126", "1.2" });
|
||||||
|
REQUIRE(region.ccConditions[126] == sfz::Range<float>(0.0f, 1.0f));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("lorealcc, hirealcc")
|
||||||
|
{
|
||||||
|
region.parseOpcode({ "lorealcc8", "0.12" });
|
||||||
|
REQUIRE(region.ccConditions[8].getStart() == Approx(0.12f));
|
||||||
|
REQUIRE(region.ccConditions[8].getEnd() == 1.0f);
|
||||||
|
region.parseOpcode({ "lorealcc14", "-1.0" });
|
||||||
|
REQUIRE(region.ccConditions[14] == sfz::Range<float>(0.0f, 1.0f));
|
||||||
|
region.parseOpcode({ "hirealcc63", "0.45" });
|
||||||
|
REQUIRE(region.ccConditions[63].getStart() == 0.0f);
|
||||||
|
REQUIRE(region.ccConditions[63].getEnd() == Approx(0.45f));
|
||||||
|
region.parseOpcode({ "hirealcc125", "1.2" });
|
||||||
|
REQUIRE(region.ccConditions[125] == sfz::Range<float>(0.0f, 1.0f));
|
||||||
|
}
|
||||||
|
|
||||||
SECTION("sw_lokey, sw_hikey")
|
SECTION("sw_lokey, sw_hikey")
|
||||||
{
|
{
|
||||||
REQUIRE(region.keyswitchRange == sfz::Range<uint8_t>(0, 127));
|
REQUIRE(region.keyswitchRange == sfz::Range<uint8_t>(0, 127));
|
||||||
|
|
@ -468,6 +496,21 @@ TEST_CASE("[Region] Parsing opcodes")
|
||||||
REQUIRE(region.ccTriggers[4] == sfz::Range<float>(0_norm, 47_norm));
|
REQUIRE(region.ccTriggers[4] == sfz::Range<float>(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", "15.9" });
|
||||||
|
REQUIRE(region.ccTriggers.contains(46));
|
||||||
|
REQUIRE(region.ccTriggers[46].getStart() == Approx(15.9_norm));
|
||||||
|
REQUIRE(region.ccTriggers[46].getEnd() == 1.0f);
|
||||||
|
region.parseOpcode({ "on_hihdcc5", "47.3" });
|
||||||
|
REQUIRE(region.ccTriggers.contains(5));
|
||||||
|
REQUIRE(region.ccTriggers[5].getStart() == 0.0f);
|
||||||
|
REQUIRE(region.ccTriggers[5].getEnd() == Approx(47.3_norm));
|
||||||
|
}
|
||||||
|
|
||||||
SECTION("volume")
|
SECTION("volume")
|
||||||
{
|
{
|
||||||
REQUIRE(region.volume == 0.0f);
|
REQUIRE(region.volume == 0.0f);
|
||||||
|
|
|
||||||
3
tests/TestFiles/set_hdcc.sfz
Normal file
3
tests/TestFiles/set_hdcc.sfz
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
<control> set_hdcc61=0.1234
|
||||||
|
<control> set_hdcc142=0.5678
|
||||||
|
<region> sample=snare.wav
|
||||||
3
tests/TestFiles/set_realcc.sfz
Normal file
3
tests/TestFiles/set_realcc.sfz
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
<control> set_realcc61=0.1234
|
||||||
|
<control> set_realcc142=0.5678
|
||||||
|
<region> sample=snare.wav
|
||||||
Loading…
Add table
Reference in a new issue