Range was not in the namespace sfz

This commit is contained in:
paulfd 2019-09-28 14:17:34 +02:00
parent f52d1d5fc5
commit a3d53b46cc
5 changed files with 190 additions and 185 deletions

View file

@ -26,6 +26,10 @@
#include <initializer_list> #include <initializer_list>
#include <type_traits> #include <type_traits>
namespace sfz
{
template <class Type> template <class Type>
class Range { class Range {
static_assert(std::is_arithmetic<Type>::value, "The Type should be arithmetic"); static_assert(std::is_arithmetic<Type>::value, "The Type should be arithmetic");
@ -91,21 +95,22 @@ 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) };
}; };
}
template <class Type> template <class Type>
bool operator==(const Range<Type>& lhs, const Range<Type>& rhs) bool operator==(const sfz::Range<Type>& lhs, const sfz::Range<Type>& rhs)
{ {
return (lhs.getStart() == rhs.getStart()) && (lhs.getEnd() == rhs.getEnd()); return (lhs.getStart() == rhs.getStart()) && (lhs.getEnd() == rhs.getEnd());
} }
template <class Type> template <class Type>
bool operator==(const Range<Type>& lhs, const std::pair<Type, Type>& rhs) bool operator==(const sfz::Range<Type>& lhs, const std::pair<Type, Type>& rhs)
{ {
return (lhs.getStart() == rhs.first) && (lhs.getEnd() == rhs.second); return (lhs.getStart() == rhs.first) && (lhs.getEnd() == rhs.second);
} }
template <class Type> template <class Type>
bool operator==(const std::pair<Type, Type>& lhs, const Range<Type>& rhs) bool operator==(const std::pair<Type, Type>& lhs, const sfz::Range<Type>& rhs)
{ {
return rhs == lhs; return rhs == lhs;
} }

View file

@ -676,7 +676,7 @@ bool sfz::Region::isStereo() const noexcept
} }
template<class T, class U> template<class T, class U>
float crossfadeIn(const Range<T>& crossfadeRange, U value, SfzCrossfadeCurve curve) float crossfadeIn(const sfz::Range<T>& crossfadeRange, U value, SfzCrossfadeCurve curve)
{ {
if (value < crossfadeRange.getStart()) if (value < crossfadeRange.getStart())
return 0.0f; return 0.0f;
@ -692,7 +692,7 @@ float crossfadeIn(const Range<T>& crossfadeRange, U value, SfzCrossfadeCurve cur
} }
template<class T, class U> template<class T, class U>
float crossfadeOut(const Range<T>& crossfadeRange, U value, SfzCrossfadeCurve curve) float crossfadeOut(const sfz::Range<T>& crossfadeRange, U value, SfzCrossfadeCurve curve)
{ {
if (value > crossfadeRange.getEnd()) if (value > crossfadeRange.getEnd())
return 0.0f; return 0.0f;

View file

@ -50,7 +50,7 @@ TEST_CASE("[Files] Basic opcodes (regions_opcodes.sfz)")
sfz::Synth synth; sfz::Synth synth;
synth.loadSfzFile(fs::current_path() / "tests/TestFiles/Regions/regions_opcodes.sfz"); synth.loadSfzFile(fs::current_path() / "tests/TestFiles/Regions/regions_opcodes.sfz");
REQUIRE(synth.getNumRegions() == 1); REQUIRE(synth.getNumRegions() == 1);
REQUIRE(synth.getRegionView(0)->channelRange == Range<uint8_t>(2, 14)); REQUIRE(synth.getRegionView(0)->channelRange == sfz::Range<uint8_t>(2, 14));
} }
TEST_CASE("[Files] Underscore opcodes (underscore_opcodes.sfz)") TEST_CASE("[Files] Underscore opcodes (underscore_opcodes.sfz)")
@ -128,9 +128,9 @@ TEST_CASE("[Files] Define test")
sfz::Synth synth; sfz::Synth synth;
synth.loadSfzFile(fs::current_path() / "tests/TestFiles/defines.sfz"); synth.loadSfzFile(fs::current_path() / "tests/TestFiles/defines.sfz");
REQUIRE(synth.getNumRegions() == 3); REQUIRE(synth.getNumRegions() == 3);
REQUIRE(synth.getRegionView(0)->keyRange == Range<uint8_t>(36, 36)); REQUIRE(synth.getRegionView(0)->keyRange == sfz::Range<uint8_t>(36, 36));
REQUIRE(synth.getRegionView(1)->keyRange == Range<uint8_t>(38, 38)); REQUIRE(synth.getRegionView(1)->keyRange == sfz::Range<uint8_t>(38, 38));
REQUIRE(synth.getRegionView(2)->keyRange == Range<uint8_t>(42, 42)); REQUIRE(synth.getRegionView(2)->keyRange == sfz::Range<uint8_t>(42, 42));
} }
TEST_CASE("[Files] Group from AVL") TEST_CASE("[Files] Group from AVL")
@ -140,13 +140,13 @@ TEST_CASE("[Files] Group from AVL")
REQUIRE(synth.getNumRegions() == 5); REQUIRE(synth.getNumRegions() == 5);
for (int i = 0; i < synth.getNumRegions(); ++i) { for (int i = 0; i < synth.getNumRegions(); ++i) {
REQUIRE(synth.getRegionView(i)->volume == 6.0f); REQUIRE(synth.getRegionView(i)->volume == 6.0f);
REQUIRE(synth.getRegionView(i)->keyRange == Range<uint8_t>(36, 36)); REQUIRE(synth.getRegionView(i)->keyRange == sfz::Range<uint8_t>(36, 36));
} }
REQUIRE(synth.getRegionView(0)->velocityRange == Range<uint8_t>(1, 26)); REQUIRE(synth.getRegionView(0)->velocityRange == sfz::Range<uint8_t>(1, 26));
REQUIRE(synth.getRegionView(1)->velocityRange == Range<uint8_t>(27, 52)); REQUIRE(synth.getRegionView(1)->velocityRange == sfz::Range<uint8_t>(27, 52));
REQUIRE(synth.getRegionView(2)->velocityRange == Range<uint8_t>(53, 77)); REQUIRE(synth.getRegionView(2)->velocityRange == sfz::Range<uint8_t>(53, 77));
REQUIRE(synth.getRegionView(3)->velocityRange == Range<uint8_t>(78, 102)); REQUIRE(synth.getRegionView(3)->velocityRange == sfz::Range<uint8_t>(78, 102));
REQUIRE(synth.getRegionView(4)->velocityRange == Range<uint8_t>(103, 127)); REQUIRE(synth.getRegionView(4)->velocityRange == sfz::Range<uint8_t>(103, 127));
} }
TEST_CASE("[Files] Full hierarchy") TEST_CASE("[Files] Full hierarchy")
@ -159,35 +159,35 @@ TEST_CASE("[Files] Full hierarchy")
} }
REQUIRE(synth.getRegionView(0)->pan == 30.0f); REQUIRE(synth.getRegionView(0)->pan == 30.0f);
REQUIRE(synth.getRegionView(0)->delay == 67); REQUIRE(synth.getRegionView(0)->delay == 67);
REQUIRE(synth.getRegionView(0)->keyRange == Range<uint8_t>(60, 60)); REQUIRE(synth.getRegionView(0)->keyRange == sfz::Range<uint8_t>(60, 60));
REQUIRE(synth.getRegionView(1)->pan == 30.0f); REQUIRE(synth.getRegionView(1)->pan == 30.0f);
REQUIRE(synth.getRegionView(1)->delay == 67); REQUIRE(synth.getRegionView(1)->delay == 67);
REQUIRE(synth.getRegionView(1)->keyRange == Range<uint8_t>(61, 61)); REQUIRE(synth.getRegionView(1)->keyRange == sfz::Range<uint8_t>(61, 61));
REQUIRE(synth.getRegionView(2)->pan == 30.0f); REQUIRE(synth.getRegionView(2)->pan == 30.0f);
REQUIRE(synth.getRegionView(2)->delay == 56); REQUIRE(synth.getRegionView(2)->delay == 56);
REQUIRE(synth.getRegionView(2)->keyRange == Range<uint8_t>(50, 50)); REQUIRE(synth.getRegionView(2)->keyRange == sfz::Range<uint8_t>(50, 50));
REQUIRE(synth.getRegionView(3)->pan == 30.0f); REQUIRE(synth.getRegionView(3)->pan == 30.0f);
REQUIRE(synth.getRegionView(3)->delay == 56); REQUIRE(synth.getRegionView(3)->delay == 56);
REQUIRE(synth.getRegionView(3)->keyRange == Range<uint8_t>(51, 51)); REQUIRE(synth.getRegionView(3)->keyRange == sfz::Range<uint8_t>(51, 51));
REQUIRE(synth.getRegionView(4)->pan == -10.0f); REQUIRE(synth.getRegionView(4)->pan == -10.0f);
REQUIRE(synth.getRegionView(4)->delay == 47); REQUIRE(synth.getRegionView(4)->delay == 47);
REQUIRE(synth.getRegionView(4)->keyRange == Range<uint8_t>(40, 40)); REQUIRE(synth.getRegionView(4)->keyRange == sfz::Range<uint8_t>(40, 40));
REQUIRE(synth.getRegionView(5)->pan == -10.0f); REQUIRE(synth.getRegionView(5)->pan == -10.0f);
REQUIRE(synth.getRegionView(5)->delay == 47); REQUIRE(synth.getRegionView(5)->delay == 47);
REQUIRE(synth.getRegionView(5)->keyRange == Range<uint8_t>(41, 41)); REQUIRE(synth.getRegionView(5)->keyRange == sfz::Range<uint8_t>(41, 41));
REQUIRE(synth.getRegionView(6)->pan == -10.0f); REQUIRE(synth.getRegionView(6)->pan == -10.0f);
REQUIRE(synth.getRegionView(6)->delay == 36); REQUIRE(synth.getRegionView(6)->delay == 36);
REQUIRE(synth.getRegionView(6)->keyRange == Range<uint8_t>(30, 30)); REQUIRE(synth.getRegionView(6)->keyRange == sfz::Range<uint8_t>(30, 30));
REQUIRE(synth.getRegionView(7)->pan == -10.0f); REQUIRE(synth.getRegionView(7)->pan == -10.0f);
REQUIRE(synth.getRegionView(7)->delay == 36); REQUIRE(synth.getRegionView(7)->delay == 36);
REQUIRE(synth.getRegionView(7)->keyRange == Range<uint8_t>(31, 31)); REQUIRE(synth.getRegionView(7)->keyRange == sfz::Range<uint8_t>(31, 31));
} }
TEST_CASE("[Files] Reloading files") TEST_CASE("[Files] Reloading files")
@ -236,15 +236,15 @@ TEST_CASE("[Files] Pizz basic")
synth.loadSfzFile(fs::current_path() / "tests/TestFiles/SpecificBugs/MeatBassPizz/Programs/pizz.sfz"); synth.loadSfzFile(fs::current_path() / "tests/TestFiles/SpecificBugs/MeatBassPizz/Programs/pizz.sfz");
REQUIRE(synth.getNumRegions() == 4); REQUIRE(synth.getNumRegions() == 4);
for (int i = 0; i < synth.getNumRegions(); ++i) { for (int i = 0; i < synth.getNumRegions(); ++i) {
REQUIRE(synth.getRegionView(i)->keyRange == Range<uint8_t>(12, 22)); REQUIRE(synth.getRegionView(i)->keyRange == sfz::Range<uint8_t>(12, 22));
REQUIRE(synth.getRegionView(i)->velocityRange == Range<uint8_t>(97, 127)); REQUIRE(synth.getRegionView(i)->velocityRange == sfz::Range<uint8_t>(97, 127));
REQUIRE(synth.getRegionView(i)->pitchKeycenter == 21); REQUIRE(synth.getRegionView(i)->pitchKeycenter == 21);
REQUIRE(synth.getRegionView(i)->ccConditions.getWithDefault(107) == Range<uint8_t>(0, 13)); REQUIRE(synth.getRegionView(i)->ccConditions.getWithDefault(107) == sfz::Range<uint8_t>(0, 13));
} }
REQUIRE(synth.getRegionView(0)->randRange == Range<float>(0, 0.25)); REQUIRE(synth.getRegionView(0)->randRange == sfz::Range<float>(0, 0.25));
REQUIRE(synth.getRegionView(1)->randRange == Range<float>(0.25, 0.5)); REQUIRE(synth.getRegionView(1)->randRange == sfz::Range<float>(0.25, 0.5));
REQUIRE(synth.getRegionView(2)->randRange == Range<float>(0.5, 0.75)); REQUIRE(synth.getRegionView(2)->randRange == sfz::Range<float>(0.5, 0.75));
REQUIRE(synth.getRegionView(3)->randRange == Range<float>(0.75, 1.0)); REQUIRE(synth.getRegionView(3)->randRange == sfz::Range<float>(0.75, 1.0));
REQUIRE(synth.getRegionView(0)->sample == R"(../Samples/pizz/a0_vl4_rr1.wav)"); REQUIRE(synth.getRegionView(0)->sample == R"(../Samples/pizz/a0_vl4_rr1.wav)");
REQUIRE(synth.getRegionView(1)->sample == R"(../Samples/pizz/a0_vl4_rr2.wav)"); REQUIRE(synth.getRegionView(1)->sample == R"(../Samples/pizz/a0_vl4_rr2.wav)");
REQUIRE(synth.getRegionView(2)->sample == R"(../Samples/pizz/a0_vl4_rr3.wav)"); REQUIRE(synth.getRegionView(2)->sample == R"(../Samples/pizz/a0_vl4_rr3.wav)");

View file

@ -27,38 +27,38 @@ using namespace Catch::literals;
TEST_CASE("[Range] Equality operators") TEST_CASE("[Range] Equality operators")
{ {
Range<int> intRange { 1, 1 }; sfz::Range<int> intRange { 1, 1 };
REQUIRE(intRange == Range<int>(1, 1)); REQUIRE(intRange == sfz::Range<int>(1, 1));
REQUIRE(intRange == std::pair<int, int>(1, 1)); REQUIRE(intRange == std::pair<int, int>(1, 1));
REQUIRE(std::pair<int, int>(1, 1) == intRange); REQUIRE(std::pair<int, int>(1, 1) == intRange);
Range<float> floatRange { 1.0f, 1.0f }; sfz::Range<float> floatRange { 1.0f, 1.0f };
REQUIRE(floatRange == Range<float>(1.0f, 1.0f)); REQUIRE(floatRange == sfz::Range<float>(1.0f, 1.0f));
REQUIRE(floatRange == std::pair<float, float>(1.0f, 1.0f)); REQUIRE(floatRange == std::pair<float, float>(1.0f, 1.0f));
REQUIRE(std::pair<float, float>(1.0f, 1.0f) == floatRange); REQUIRE(std::pair<float, float>(1.0f, 1.0f) == floatRange);
} }
TEST_CASE("[Range] Default ranges for classical types") TEST_CASE("[Range] Default ranges for classical types")
{ {
Range<int> intRange; sfz::Range<int> intRange;
REQUIRE(intRange == Range<int>(0, 0)); REQUIRE(intRange == sfz::Range<int>(0, 0));
Range<int32_t> int32_tRange; sfz::Range<int32_t> int32_tRange;
REQUIRE(int32_tRange == Range<int32_t>(0, 0)); REQUIRE(int32_tRange == sfz::Range<int32_t>(0, 0));
Range<uint32_t> uint32_tRange; sfz::Range<uint32_t> uint32_tRange;
REQUIRE(uint32_tRange == Range<uint32_t>(0, 0)); REQUIRE(uint32_tRange == sfz::Range<uint32_t>(0, 0));
Range<int64_t> int64_tRange; sfz::Range<int64_t> int64_tRange;
REQUIRE(int64_tRange == Range<int64_t>(0, 0)); REQUIRE(int64_tRange == sfz::Range<int64_t>(0, 0));
Range<uint64_t> uint64_tRange; sfz::Range<uint64_t> uint64_tRange;
REQUIRE(uint64_tRange == Range<uint64_t>(0, 0)); REQUIRE(uint64_tRange == sfz::Range<uint64_t>(0, 0));
Range<float> floatRange; sfz::Range<float> floatRange;
REQUIRE(floatRange == Range<float>(0, 0)); REQUIRE(floatRange == sfz::Range<float>(0, 0));
Range<double> doubleRange; sfz::Range<double> doubleRange;
REQUIRE(doubleRange == Range<double>(0, 0)); REQUIRE(doubleRange == sfz::Range<double>(0, 0));
} }
TEST_CASE("[Range] Contains") TEST_CASE("[Range] Contains")
{ {
Range<int> intRange { 1, 10 }; sfz::Range<int> intRange { 1, 10 };
REQUIRE(!intRange.contains(0)); REQUIRE(!intRange.contains(0));
REQUIRE(intRange.contains(1)); REQUIRE(intRange.contains(1));
REQUIRE(intRange.contains(5)); REQUIRE(intRange.contains(5));
@ -68,7 +68,7 @@ TEST_CASE("[Range] Contains")
REQUIRE(intRange.containsWithEnd(5)); REQUIRE(intRange.containsWithEnd(5));
REQUIRE(intRange.containsWithEnd(10)); REQUIRE(intRange.containsWithEnd(10));
Range<float> floatRange { 1.0, 10.0 }; sfz::Range<float> floatRange { 1.0, 10.0 };
REQUIRE(!floatRange.contains(0.0)); REQUIRE(!floatRange.contains(0.0));
REQUIRE(floatRange.contains(1.0)); REQUIRE(floatRange.contains(1.0));
REQUIRE(floatRange.contains(5.0)); REQUIRE(floatRange.contains(5.0));
@ -81,14 +81,14 @@ TEST_CASE("[Range] Contains")
TEST_CASE("[Range] Clamp") TEST_CASE("[Range] Clamp")
{ {
Range<int> intRange { 1, 10 }; sfz::Range<int> intRange { 1, 10 };
REQUIRE(intRange.clamp(0) == 1); REQUIRE(intRange.clamp(0) == 1);
REQUIRE(intRange.clamp(1) == 1); REQUIRE(intRange.clamp(1) == 1);
REQUIRE(intRange.clamp(5) == 5); REQUIRE(intRange.clamp(5) == 5);
REQUIRE(intRange.clamp(10) == 10); REQUIRE(intRange.clamp(10) == 10);
REQUIRE(intRange.clamp(11) == 10); REQUIRE(intRange.clamp(11) == 10);
Range<float> floatRange { 1.0, 10.0 }; sfz::Range<float> floatRange { 1.0, 10.0 };
REQUIRE(floatRange.clamp(0.0) == 1.0_a); REQUIRE(floatRange.clamp(0.0) == 1.0_a);
REQUIRE(floatRange.clamp(1.0) == 1.0_a); REQUIRE(floatRange.clamp(1.0) == 1.0_a);
REQUIRE(floatRange.clamp(5.0) == 5.0_a); REQUIRE(floatRange.clamp(5.0) == 5.0_a);
@ -98,17 +98,17 @@ TEST_CASE("[Range] Clamp")
TEST_CASE("[Range] shrinkIfSmaller") TEST_CASE("[Range] shrinkIfSmaller")
{ {
Range<int> intRange { 2, 10 }; sfz::Range<int> intRange { 2, 10 };
intRange.shrinkIfSmaller(0, 10); intRange.shrinkIfSmaller(0, 10);
REQUIRE(intRange == Range<int>(2, 10)); REQUIRE(intRange == sfz::Range<int>(2, 10));
intRange.shrinkIfSmaller(2, 11); intRange.shrinkIfSmaller(2, 11);
REQUIRE(intRange == Range<int>(2, 10)); REQUIRE(intRange == sfz::Range<int>(2, 10));
intRange.shrinkIfSmaller(2, 9); intRange.shrinkIfSmaller(2, 9);
REQUIRE(intRange == Range<int>(2, 9)); REQUIRE(intRange == sfz::Range<int>(2, 9));
intRange.shrinkIfSmaller(3, 9); intRange.shrinkIfSmaller(3, 9);
REQUIRE(intRange == Range<int>(3, 9)); REQUIRE(intRange == sfz::Range<int>(3, 9));
intRange.shrinkIfSmaller(4, 7); intRange.shrinkIfSmaller(4, 7);
REQUIRE(intRange == Range<int>(4, 7)); REQUIRE(intRange == sfz::Range<int>(4, 7));
intRange.shrinkIfSmaller(6, 5); intRange.shrinkIfSmaller(6, 5);
REQUIRE(intRange == Range<int>(5, 6)); REQUIRE(intRange == sfz::Range<int>(5, 6));
} }

View file

@ -125,36 +125,36 @@ TEST_CASE("[Region] Parsing opcodes")
SECTION("loop_end") SECTION("loop_end")
{ {
REQUIRE(region.loopRange == Range<uint32_t>(0, 4294967295)); REQUIRE(region.loopRange == sfz::Range<uint32_t>(0, 4294967295));
region.parseOpcode({ "loop_end", "184" }); region.parseOpcode({ "loop_end", "184" });
REQUIRE(region.loopRange == Range<uint32_t>(0, 184)); REQUIRE(region.loopRange == sfz::Range<uint32_t>(0, 184));
region.parseOpcode({ "loop_end", "-1" }); region.parseOpcode({ "loop_end", "-1" });
REQUIRE(region.loopRange == Range<uint32_t>(0, 0)); REQUIRE(region.loopRange == sfz::Range<uint32_t>(0, 0));
} }
SECTION("loop_start") SECTION("loop_start")
{ {
region.parseOpcode({ "loop_start", "184" }); region.parseOpcode({ "loop_start", "184" });
REQUIRE(region.loopRange == Range<uint32_t>(184, 4294967295)); REQUIRE(region.loopRange == sfz::Range<uint32_t>(184, 4294967295));
region.parseOpcode({ "loop_start", "-1" }); region.parseOpcode({ "loop_start", "-1" });
REQUIRE(region.loopRange == Range<uint32_t>(0, 4294967295)); REQUIRE(region.loopRange == sfz::Range<uint32_t>(0, 4294967295));
} }
SECTION("loopend") SECTION("loopend")
{ {
REQUIRE(region.loopRange == Range<uint32_t>(0, 4294967295)); REQUIRE(region.loopRange == sfz::Range<uint32_t>(0, 4294967295));
region.parseOpcode({ "loopend", "184" }); region.parseOpcode({ "loopend", "184" });
REQUIRE(region.loopRange == Range<uint32_t>(0, 184)); REQUIRE(region.loopRange == sfz::Range<uint32_t>(0, 184));
region.parseOpcode({ "loopend", "-1" }); region.parseOpcode({ "loopend", "-1" });
REQUIRE(region.loopRange == Range<uint32_t>(0, 0)); REQUIRE(region.loopRange == sfz::Range<uint32_t>(0, 0));
} }
SECTION("loopstart") SECTION("loopstart")
{ {
region.parseOpcode({ "loopstart", "184" }); region.parseOpcode({ "loopstart", "184" });
REQUIRE(region.loopRange == Range<uint32_t>(184, 4294967295)); REQUIRE(region.loopRange == sfz::Range<uint32_t>(184, 4294967295));
region.parseOpcode({ "loopstart", "-1" }); region.parseOpcode({ "loopstart", "-1" });
REQUIRE(region.loopRange == Range<uint32_t>(0, 4294967295)); REQUIRE(region.loopRange == sfz::Range<uint32_t>(0, 4294967295));
} }
SECTION("group") SECTION("group")
@ -188,117 +188,117 @@ TEST_CASE("[Region] Parsing opcodes")
SECTION("lokey, hikey, and key") SECTION("lokey, hikey, and key")
{ {
REQUIRE(region.keyRange == Range<uint8_t>(0, 127)); REQUIRE(region.keyRange == sfz::Range<uint8_t>(0, 127));
region.parseOpcode({ "lokey", "37" }); region.parseOpcode({ "lokey", "37" });
REQUIRE(region.keyRange == Range<uint8_t>(37, 127)); REQUIRE(region.keyRange == sfz::Range<uint8_t>(37, 127));
region.parseOpcode({ "lokey", "c4" }); region.parseOpcode({ "lokey", "c4" });
REQUIRE(region.keyRange == Range<uint8_t>(60, 127)); REQUIRE(region.keyRange == sfz::Range<uint8_t>(60, 127));
region.parseOpcode({ "lokey", "128" }); region.parseOpcode({ "lokey", "128" });
REQUIRE(region.keyRange == Range<uint8_t>(127, 127)); REQUIRE(region.keyRange == sfz::Range<uint8_t>(127, 127));
region.parseOpcode({ "lokey", "-3" }); region.parseOpcode({ "lokey", "-3" });
REQUIRE(region.keyRange == Range<uint8_t>(0, 127)); REQUIRE(region.keyRange == sfz::Range<uint8_t>(0, 127));
region.parseOpcode({ "hikey", "65" }); region.parseOpcode({ "hikey", "65" });
REQUIRE(region.keyRange == Range<uint8_t>(0, 65)); REQUIRE(region.keyRange == sfz::Range<uint8_t>(0, 65));
region.parseOpcode({ "hikey", "c4" }); region.parseOpcode({ "hikey", "c4" });
REQUIRE(region.keyRange == Range<uint8_t>(0, 60)); REQUIRE(region.keyRange == sfz::Range<uint8_t>(0, 60));
region.parseOpcode({ "hikey", "-1" }); region.parseOpcode({ "hikey", "-1" });
REQUIRE(region.keyRange == Range<uint8_t>(0, 0)); REQUIRE(region.keyRange == sfz::Range<uint8_t>(0, 0));
region.parseOpcode({ "hikey", "128" }); region.parseOpcode({ "hikey", "128" });
REQUIRE(region.keyRange == Range<uint8_t>(0, 127)); REQUIRE(region.keyRange == sfz::Range<uint8_t>(0, 127));
region.parseOpcode({ "key", "26" }); region.parseOpcode({ "key", "26" });
REQUIRE(region.keyRange == Range<uint8_t>(26, 26)); REQUIRE(region.keyRange == sfz::Range<uint8_t>(26, 26));
REQUIRE(region.pitchKeycenter == 26); REQUIRE(region.pitchKeycenter == 26);
region.parseOpcode({ "key", "-26" }); region.parseOpcode({ "key", "-26" });
REQUIRE(region.keyRange == Range<uint8_t>(0, 0)); REQUIRE(region.keyRange == sfz::Range<uint8_t>(0, 0));
REQUIRE(region.pitchKeycenter == 0); REQUIRE(region.pitchKeycenter == 0);
region.parseOpcode({ "key", "234" }); region.parseOpcode({ "key", "234" });
REQUIRE(region.keyRange == Range<uint8_t>(127, 127)); REQUIRE(region.keyRange == sfz::Range<uint8_t>(127, 127));
REQUIRE(region.pitchKeycenter == 127); REQUIRE(region.pitchKeycenter == 127);
region.parseOpcode({ "key", "c4" }); region.parseOpcode({ "key", "c4" });
REQUIRE(region.keyRange == Range<uint8_t>(60, 60)); REQUIRE(region.keyRange == sfz::Range<uint8_t>(60, 60));
REQUIRE(region.pitchKeycenter == 60); REQUIRE(region.pitchKeycenter == 60);
} }
SECTION("lovel, hivel") SECTION("lovel, hivel")
{ {
REQUIRE(region.velocityRange == Range<uint8_t>(0, 127)); REQUIRE(region.velocityRange == sfz::Range<uint8_t>(0, 127));
region.parseOpcode({ "lovel", "37" }); region.parseOpcode({ "lovel", "37" });
REQUIRE(region.velocityRange == Range<uint8_t>(37, 127)); REQUIRE(region.velocityRange == sfz::Range<uint8_t>(37, 127));
region.parseOpcode({ "lovel", "128" }); region.parseOpcode({ "lovel", "128" });
REQUIRE(region.velocityRange == Range<uint8_t>(127, 127)); REQUIRE(region.velocityRange == sfz::Range<uint8_t>(127, 127));
region.parseOpcode({ "lovel", "-3" }); region.parseOpcode({ "lovel", "-3" });
REQUIRE(region.velocityRange == Range<uint8_t>(0, 127)); REQUIRE(region.velocityRange == sfz::Range<uint8_t>(0, 127));
region.parseOpcode({ "hivel", "65" }); region.parseOpcode({ "hivel", "65" });
REQUIRE(region.velocityRange == Range<uint8_t>(0, 65)); REQUIRE(region.velocityRange == sfz::Range<uint8_t>(0, 65));
region.parseOpcode({ "hivel", "-1" }); region.parseOpcode({ "hivel", "-1" });
REQUIRE(region.velocityRange == Range<uint8_t>(0, 0)); REQUIRE(region.velocityRange == sfz::Range<uint8_t>(0, 0));
region.parseOpcode({ "hivel", "128" }); region.parseOpcode({ "hivel", "128" });
REQUIRE(region.velocityRange == Range<uint8_t>(0, 127)); REQUIRE(region.velocityRange == sfz::Range<uint8_t>(0, 127));
} }
SECTION("lochan, hichan") SECTION("lochan, hichan")
{ {
REQUIRE(region.channelRange == Range<uint8_t>(1, 16)); REQUIRE(region.channelRange == sfz::Range<uint8_t>(1, 16));
region.parseOpcode({ "lochan", "4" }); region.parseOpcode({ "lochan", "4" });
REQUIRE(region.channelRange == Range<uint8_t>(4, 16)); REQUIRE(region.channelRange == sfz::Range<uint8_t>(4, 16));
region.parseOpcode({ "lochan", "128" }); region.parseOpcode({ "lochan", "128" });
REQUIRE(region.channelRange == Range<uint8_t>(16, 16)); REQUIRE(region.channelRange == sfz::Range<uint8_t>(16, 16));
region.parseOpcode({ "lochan", "-3" }); region.parseOpcode({ "lochan", "-3" });
REQUIRE(region.channelRange == Range<uint8_t>(1, 16)); REQUIRE(region.channelRange == sfz::Range<uint8_t>(1, 16));
region.parseOpcode({ "hichan", "13" }); region.parseOpcode({ "hichan", "13" });
REQUIRE(region.channelRange == Range<uint8_t>(1, 13)); REQUIRE(region.channelRange == sfz::Range<uint8_t>(1, 13));
region.parseOpcode({ "hichan", "-1" }); region.parseOpcode({ "hichan", "-1" });
REQUIRE(region.channelRange == Range<uint8_t>(1, 1)); REQUIRE(region.channelRange == sfz::Range<uint8_t>(1, 1));
region.parseOpcode({ "hichan", "128" }); region.parseOpcode({ "hichan", "128" });
REQUIRE(region.channelRange == Range<uint8_t>(1, 16)); REQUIRE(region.channelRange == sfz::Range<uint8_t>(1, 16));
} }
SECTION("lobend, hibend") SECTION("lobend, hibend")
{ {
REQUIRE(region.bendRange == Range<int>(-8192, 8192)); REQUIRE(region.bendRange == sfz::Range<int>(-8192, 8192));
region.parseOpcode({ "lobend", "4" }); region.parseOpcode({ "lobend", "4" });
REQUIRE(region.bendRange == Range<int>(4, 8192)); REQUIRE(region.bendRange == sfz::Range<int>(4, 8192));
region.parseOpcode({ "lobend", "-128" }); region.parseOpcode({ "lobend", "-128" });
REQUIRE(region.bendRange == Range<int>(-128, 8192)); REQUIRE(region.bendRange == sfz::Range<int>(-128, 8192));
region.parseOpcode({ "lobend", "-10000" }); region.parseOpcode({ "lobend", "-10000" });
REQUIRE(region.bendRange == Range<int>(-8192, 8192)); REQUIRE(region.bendRange == sfz::Range<int>(-8192, 8192));
region.parseOpcode({ "hibend", "13" }); region.parseOpcode({ "hibend", "13" });
REQUIRE(region.bendRange == Range<int>(-8192, 13)); REQUIRE(region.bendRange == sfz::Range<int>(-8192, 13));
region.parseOpcode({ "hibend", "-1" }); region.parseOpcode({ "hibend", "-1" });
REQUIRE(region.bendRange == Range<int>(-8192, -1)); REQUIRE(region.bendRange == sfz::Range<int>(-8192, -1));
region.parseOpcode({ "hibend", "10000" }); region.parseOpcode({ "hibend", "10000" });
REQUIRE(region.bendRange == Range<int>(-8192, 8192)); REQUIRE(region.bendRange == sfz::Range<int>(-8192, 8192));
} }
SECTION("locc, hicc") SECTION("locc, hicc")
{ {
REQUIRE(region.ccConditions.getWithDefault(0) == Range<uint8_t>(0, 127)); REQUIRE(region.ccConditions.getWithDefault(0) == sfz::Range<uint8_t>(0, 127));
REQUIRE(region.ccConditions[127] == Range<uint8_t>(0, 127)); REQUIRE(region.ccConditions[127] == sfz::Range<uint8_t>(0, 127));
region.parseOpcode({ "locc6", "4" }); region.parseOpcode({ "locc6", "4" });
REQUIRE(region.ccConditions[6] == Range<uint8_t>(4, 127)); REQUIRE(region.ccConditions[6] == sfz::Range<uint8_t>(4, 127));
region.parseOpcode({ "locc12", "-128" }); region.parseOpcode({ "locc12", "-128" });
REQUIRE(region.ccConditions[12] == Range<uint8_t>(0, 127)); REQUIRE(region.ccConditions[12] == sfz::Range<uint8_t>(0, 127));
region.parseOpcode({ "hicc65", "39" }); region.parseOpcode({ "hicc65", "39" });
REQUIRE(region.ccConditions[65] == Range<uint8_t>(0, 39)); REQUIRE(region.ccConditions[65] == sfz::Range<uint8_t>(0, 39));
region.parseOpcode({ "hicc127", "135" }); region.parseOpcode({ "hicc127", "135" });
REQUIRE(region.ccConditions[127] == Range<uint8_t>(0, 127)); REQUIRE(region.ccConditions[127] == sfz::Range<uint8_t>(0, 127));
} }
SECTION("sw_lokey, sw_hikey") SECTION("sw_lokey, sw_hikey")
{ {
REQUIRE(region.keyswitchRange == Range<uint8_t>(0, 127)); REQUIRE(region.keyswitchRange == sfz::Range<uint8_t>(0, 127));
region.parseOpcode({ "sw_lokey", "4" }); region.parseOpcode({ "sw_lokey", "4" });
REQUIRE(region.keyswitchRange == Range<uint8_t>(4, 127)); REQUIRE(region.keyswitchRange == sfz::Range<uint8_t>(4, 127));
region.parseOpcode({ "sw_lokey", "128" }); region.parseOpcode({ "sw_lokey", "128" });
REQUIRE(region.keyswitchRange == Range<uint8_t>(127, 127)); REQUIRE(region.keyswitchRange == sfz::Range<uint8_t>(127, 127));
region.parseOpcode({ "sw_lokey", "0" }); region.parseOpcode({ "sw_lokey", "0" });
REQUIRE(region.keyswitchRange == Range<uint8_t>(0, 127)); REQUIRE(region.keyswitchRange == sfz::Range<uint8_t>(0, 127));
region.parseOpcode({ "sw_hikey", "39" }); region.parseOpcode({ "sw_hikey", "39" });
REQUIRE(region.keyswitchRange == Range<uint8_t>(0, 39)); REQUIRE(region.keyswitchRange == sfz::Range<uint8_t>(0, 39));
region.parseOpcode({ "sw_hikey", "135" }); region.parseOpcode({ "sw_hikey", "135" });
REQUIRE(region.keyswitchRange == Range<uint8_t>(0, 127)); REQUIRE(region.keyswitchRange == sfz::Range<uint8_t>(0, 127));
region.parseOpcode({ "sw_hikey", "-1" }); region.parseOpcode({ "sw_hikey", "-1" });
REQUIRE(region.keyswitchRange == Range<uint8_t>(0, 0)); REQUIRE(region.keyswitchRange == sfz::Range<uint8_t>(0, 0));
} }
SECTION("sw_last") SECTION("sw_last")
@ -368,53 +368,53 @@ TEST_CASE("[Region] Parsing opcodes")
SECTION("lochanaft, hichanaft") SECTION("lochanaft, hichanaft")
{ {
REQUIRE(region.aftertouchRange == Range<uint8_t>(0, 127)); REQUIRE(region.aftertouchRange == sfz::Range<uint8_t>(0, 127));
region.parseOpcode({ "lochanaft", "4" }); region.parseOpcode({ "lochanaft", "4" });
REQUIRE(region.aftertouchRange == Range<uint8_t>(4, 127)); REQUIRE(region.aftertouchRange == sfz::Range<uint8_t>(4, 127));
region.parseOpcode({ "lochanaft", "128" }); region.parseOpcode({ "lochanaft", "128" });
REQUIRE(region.aftertouchRange == Range<uint8_t>(127, 127)); REQUIRE(region.aftertouchRange == sfz::Range<uint8_t>(127, 127));
region.parseOpcode({ "lochanaft", "0" }); region.parseOpcode({ "lochanaft", "0" });
REQUIRE(region.aftertouchRange == Range<uint8_t>(0, 127)); REQUIRE(region.aftertouchRange == sfz::Range<uint8_t>(0, 127));
region.parseOpcode({ "hichanaft", "39" }); region.parseOpcode({ "hichanaft", "39" });
REQUIRE(region.aftertouchRange == Range<uint8_t>(0, 39)); REQUIRE(region.aftertouchRange == sfz::Range<uint8_t>(0, 39));
region.parseOpcode({ "hichanaft", "135" }); region.parseOpcode({ "hichanaft", "135" });
REQUIRE(region.aftertouchRange == Range<uint8_t>(0, 127)); REQUIRE(region.aftertouchRange == sfz::Range<uint8_t>(0, 127));
region.parseOpcode({ "hichanaft", "-1" }); region.parseOpcode({ "hichanaft", "-1" });
REQUIRE(region.aftertouchRange == Range<uint8_t>(0, 0)); REQUIRE(region.aftertouchRange == sfz::Range<uint8_t>(0, 0));
} }
SECTION("lobpm, hibpm") SECTION("lobpm, hibpm")
{ {
REQUIRE(region.bpmRange == Range<float>(0, 500)); REQUIRE(region.bpmRange == sfz::Range<float>(0, 500));
region.parseOpcode({ "lobpm", "47.5" }); region.parseOpcode({ "lobpm", "47.5" });
REQUIRE(region.bpmRange == Range<float>(47.5, 500)); REQUIRE(region.bpmRange == sfz::Range<float>(47.5, 500));
region.parseOpcode({ "lobpm", "594" }); region.parseOpcode({ "lobpm", "594" });
REQUIRE(region.bpmRange == Range<float>(500, 500)); REQUIRE(region.bpmRange == sfz::Range<float>(500, 500));
region.parseOpcode({ "lobpm", "0" }); region.parseOpcode({ "lobpm", "0" });
REQUIRE(region.bpmRange == Range<float>(0, 500)); REQUIRE(region.bpmRange == sfz::Range<float>(0, 500));
region.parseOpcode({ "hibpm", "78" }); region.parseOpcode({ "hibpm", "78" });
REQUIRE(region.bpmRange == Range<float>(0, 78)); REQUIRE(region.bpmRange == sfz::Range<float>(0, 78));
region.parseOpcode({ "hibpm", "895.4" }); region.parseOpcode({ "hibpm", "895.4" });
REQUIRE(region.bpmRange == Range<float>(0, 500)); REQUIRE(region.bpmRange == sfz::Range<float>(0, 500));
region.parseOpcode({ "hibpm", "-1" }); region.parseOpcode({ "hibpm", "-1" });
REQUIRE(region.bpmRange == Range<float>(0, 0)); REQUIRE(region.bpmRange == sfz::Range<float>(0, 0));
} }
SECTION("lorand, hirand") SECTION("lorand, hirand")
{ {
REQUIRE(region.randRange == Range<float>(0, 1)); REQUIRE(region.randRange == sfz::Range<float>(0, 1));
region.parseOpcode({ "lorand", "0.5" }); region.parseOpcode({ "lorand", "0.5" });
REQUIRE(region.randRange == Range<float>(0.5, 1)); REQUIRE(region.randRange == sfz::Range<float>(0.5, 1));
region.parseOpcode({ "lorand", "4" }); region.parseOpcode({ "lorand", "4" });
REQUIRE(region.randRange == Range<float>(1, 1)); REQUIRE(region.randRange == sfz::Range<float>(1, 1));
region.parseOpcode({ "lorand", "0" }); region.parseOpcode({ "lorand", "0" });
REQUIRE(region.randRange == Range<float>(0, 1)); REQUIRE(region.randRange == sfz::Range<float>(0, 1));
region.parseOpcode({ "hirand", "39" }); region.parseOpcode({ "hirand", "39" });
REQUIRE(region.randRange == Range<float>(0, 1)); REQUIRE(region.randRange == sfz::Range<float>(0, 1));
region.parseOpcode({ "hirand", "0.7" }); region.parseOpcode({ "hirand", "0.7" });
REQUIRE(region.randRange == Range<float>(0, 0.7f)); REQUIRE(region.randRange == sfz::Range<float>(0, 0.7f));
region.parseOpcode({ "hirand", "-1" }); region.parseOpcode({ "hirand", "-1" });
REQUIRE(region.randRange == Range<float>(0, 0)); REQUIRE(region.randRange == sfz::Range<float>(0, 0));
} }
SECTION("seq_length") SECTION("seq_length")
@ -459,10 +459,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] == Range<uint8_t>(15, 127)); REQUIRE(region.ccTriggers[45] == sfz::Range<uint8_t>(15, 127));
region.parseOpcode({ "on_hicc4", "47" }); region.parseOpcode({ "on_hicc4", "47" });
REQUIRE(region.ccTriggers.contains(45)); REQUIRE(region.ccTriggers.contains(45));
REQUIRE(region.ccTriggers[4] == Range<uint8_t>(0, 47)); REQUIRE(region.ccTriggers[4] == sfz::Range<uint8_t>(0, 47));
} }
SECTION("volume") SECTION("volume")
@ -604,116 +604,116 @@ TEST_CASE("[Region] Parsing opcodes")
SECTION("xfin_lokey, xfin_hikey") SECTION("xfin_lokey, xfin_hikey")
{ {
REQUIRE(region.crossfadeKeyInRange == Range<uint8_t>(0, 0)); REQUIRE(region.crossfadeKeyInRange == sfz::Range<uint8_t>(0, 0));
region.parseOpcode({ "xfin_lokey", "4" }); region.parseOpcode({ "xfin_lokey", "4" });
REQUIRE(region.crossfadeKeyInRange == Range<uint8_t>(4, 4)); REQUIRE(region.crossfadeKeyInRange == sfz::Range<uint8_t>(4, 4));
region.parseOpcode({ "xfin_lokey", "128" }); region.parseOpcode({ "xfin_lokey", "128" });
REQUIRE(region.crossfadeKeyInRange == Range<uint8_t>(127, 127)); REQUIRE(region.crossfadeKeyInRange == sfz::Range<uint8_t>(127, 127));
region.parseOpcode({ "xfin_lokey", "59" }); region.parseOpcode({ "xfin_lokey", "59" });
REQUIRE(region.crossfadeKeyInRange == Range<uint8_t>(59, 127)); REQUIRE(region.crossfadeKeyInRange == sfz::Range<uint8_t>(59, 127));
region.parseOpcode({ "xfin_hikey", "59" }); region.parseOpcode({ "xfin_hikey", "59" });
REQUIRE(region.crossfadeKeyInRange == Range<uint8_t>(59, 59)); REQUIRE(region.crossfadeKeyInRange == sfz::Range<uint8_t>(59, 59));
region.parseOpcode({ "xfin_hikey", "128" }); region.parseOpcode({ "xfin_hikey", "128" });
REQUIRE(region.crossfadeKeyInRange == Range<uint8_t>(59, 127)); REQUIRE(region.crossfadeKeyInRange == sfz::Range<uint8_t>(59, 127));
region.parseOpcode({ "xfin_hikey", "0" }); region.parseOpcode({ "xfin_hikey", "0" });
REQUIRE(region.crossfadeKeyInRange == Range<uint8_t>(0, 0)); REQUIRE(region.crossfadeKeyInRange == sfz::Range<uint8_t>(0, 0));
region.parseOpcode({ "xfin_hikey", "-1" }); region.parseOpcode({ "xfin_hikey", "-1" });
REQUIRE(region.crossfadeKeyInRange == Range<uint8_t>(0, 0)); REQUIRE(region.crossfadeKeyInRange == sfz::Range<uint8_t>(0, 0));
} }
SECTION("xfin_lovel, xfin_hivel") SECTION("xfin_lovel, xfin_hivel")
{ {
REQUIRE(region.crossfadeVelInRange == Range<uint8_t>(0, 0)); REQUIRE(region.crossfadeVelInRange == sfz::Range<uint8_t>(0, 0));
region.parseOpcode({ "xfin_lovel", "4" }); region.parseOpcode({ "xfin_lovel", "4" });
REQUIRE(region.crossfadeVelInRange == Range<uint8_t>(4, 4)); REQUIRE(region.crossfadeVelInRange == sfz::Range<uint8_t>(4, 4));
region.parseOpcode({ "xfin_lovel", "128" }); region.parseOpcode({ "xfin_lovel", "128" });
REQUIRE(region.crossfadeVelInRange == Range<uint8_t>(127, 127)); REQUIRE(region.crossfadeVelInRange == sfz::Range<uint8_t>(127, 127));
region.parseOpcode({ "xfin_lovel", "59" }); region.parseOpcode({ "xfin_lovel", "59" });
REQUIRE(region.crossfadeVelInRange == Range<uint8_t>(59, 127)); REQUIRE(region.crossfadeVelInRange == sfz::Range<uint8_t>(59, 127));
region.parseOpcode({ "xfin_hivel", "59" }); region.parseOpcode({ "xfin_hivel", "59" });
REQUIRE(region.crossfadeVelInRange == Range<uint8_t>(59, 59)); REQUIRE(region.crossfadeVelInRange == sfz::Range<uint8_t>(59, 59));
region.parseOpcode({ "xfin_hivel", "128" }); region.parseOpcode({ "xfin_hivel", "128" });
REQUIRE(region.crossfadeVelInRange == Range<uint8_t>(59, 127)); REQUIRE(region.crossfadeVelInRange == sfz::Range<uint8_t>(59, 127));
region.parseOpcode({ "xfin_hivel", "0" }); region.parseOpcode({ "xfin_hivel", "0" });
REQUIRE(region.crossfadeVelInRange == Range<uint8_t>(0, 0)); REQUIRE(region.crossfadeVelInRange == sfz::Range<uint8_t>(0, 0));
region.parseOpcode({ "xfin_hivel", "-1" }); region.parseOpcode({ "xfin_hivel", "-1" });
REQUIRE(region.crossfadeVelInRange == Range<uint8_t>(0, 0)); REQUIRE(region.crossfadeVelInRange == sfz::Range<uint8_t>(0, 0));
} }
SECTION("xfout_lokey, xfout_hikey") SECTION("xfout_lokey, xfout_hikey")
{ {
REQUIRE(region.crossfadeKeyOutRange == Range<uint8_t>(127, 127)); REQUIRE(region.crossfadeKeyOutRange == sfz::Range<uint8_t>(127, 127));
region.parseOpcode({ "xfout_lokey", "4" }); region.parseOpcode({ "xfout_lokey", "4" });
REQUIRE(region.crossfadeKeyOutRange == Range<uint8_t>(4, 127)); REQUIRE(region.crossfadeKeyOutRange == sfz::Range<uint8_t>(4, 127));
region.parseOpcode({ "xfout_lokey", "128" }); region.parseOpcode({ "xfout_lokey", "128" });
REQUIRE(region.crossfadeKeyOutRange == Range<uint8_t>(127, 127)); REQUIRE(region.crossfadeKeyOutRange == sfz::Range<uint8_t>(127, 127));
region.parseOpcode({ "xfout_lokey", "59" }); region.parseOpcode({ "xfout_lokey", "59" });
REQUIRE(region.crossfadeKeyOutRange == Range<uint8_t>(59, 127)); REQUIRE(region.crossfadeKeyOutRange == sfz::Range<uint8_t>(59, 127));
region.parseOpcode({ "xfout_hikey", "59" }); region.parseOpcode({ "xfout_hikey", "59" });
REQUIRE(region.crossfadeKeyOutRange == Range<uint8_t>(59, 59)); REQUIRE(region.crossfadeKeyOutRange == sfz::Range<uint8_t>(59, 59));
region.parseOpcode({ "xfout_hikey", "128" }); region.parseOpcode({ "xfout_hikey", "128" });
REQUIRE(region.crossfadeKeyOutRange == Range<uint8_t>(59, 127)); REQUIRE(region.crossfadeKeyOutRange == sfz::Range<uint8_t>(59, 127));
region.parseOpcode({ "xfout_hikey", "0" }); region.parseOpcode({ "xfout_hikey", "0" });
REQUIRE(region.crossfadeKeyOutRange == Range<uint8_t>(0, 0)); REQUIRE(region.crossfadeKeyOutRange == sfz::Range<uint8_t>(0, 0));
region.parseOpcode({ "xfout_hikey", "-1" }); region.parseOpcode({ "xfout_hikey", "-1" });
REQUIRE(region.crossfadeKeyOutRange == Range<uint8_t>(0, 0)); REQUIRE(region.crossfadeKeyOutRange == sfz::Range<uint8_t>(0, 0));
} }
SECTION("xfout_lovel, xfout_hivel") SECTION("xfout_lovel, xfout_hivel")
{ {
REQUIRE(region.crossfadeVelOutRange == Range<uint8_t>(127, 127)); REQUIRE(region.crossfadeVelOutRange == sfz::Range<uint8_t>(127, 127));
region.parseOpcode({ "xfout_lovel", "4" }); region.parseOpcode({ "xfout_lovel", "4" });
REQUIRE(region.crossfadeVelOutRange == Range<uint8_t>(4, 127)); REQUIRE(region.crossfadeVelOutRange == sfz::Range<uint8_t>(4, 127));
region.parseOpcode({ "xfout_lovel", "128" }); region.parseOpcode({ "xfout_lovel", "128" });
REQUIRE(region.crossfadeVelOutRange == Range<uint8_t>(127, 127)); REQUIRE(region.crossfadeVelOutRange == sfz::Range<uint8_t>(127, 127));
region.parseOpcode({ "xfout_lovel", "59" }); region.parseOpcode({ "xfout_lovel", "59" });
REQUIRE(region.crossfadeVelOutRange == Range<uint8_t>(59, 127)); REQUIRE(region.crossfadeVelOutRange == sfz::Range<uint8_t>(59, 127));
region.parseOpcode({ "xfout_hivel", "59" }); region.parseOpcode({ "xfout_hivel", "59" });
REQUIRE(region.crossfadeVelOutRange == Range<uint8_t>(59, 59)); REQUIRE(region.crossfadeVelOutRange == sfz::Range<uint8_t>(59, 59));
region.parseOpcode({ "xfout_hivel", "128" }); region.parseOpcode({ "xfout_hivel", "128" });
REQUIRE(region.crossfadeVelOutRange == Range<uint8_t>(59, 127)); REQUIRE(region.crossfadeVelOutRange == sfz::Range<uint8_t>(59, 127));
region.parseOpcode({ "xfout_hivel", "0" }); region.parseOpcode({ "xfout_hivel", "0" });
REQUIRE(region.crossfadeVelOutRange == Range<uint8_t>(0, 0)); REQUIRE(region.crossfadeVelOutRange == sfz::Range<uint8_t>(0, 0));
region.parseOpcode({ "xfout_hivel", "-1" }); region.parseOpcode({ "xfout_hivel", "-1" });
REQUIRE(region.crossfadeVelOutRange == Range<uint8_t>(0, 0)); REQUIRE(region.crossfadeVelOutRange == sfz::Range<uint8_t>(0, 0));
} }
SECTION("xfin_locc, xfin_hicc") SECTION("xfin_locc, xfin_hicc")
{ {
REQUIRE(!region.crossfadeCCInRange.contains(4)); REQUIRE(!region.crossfadeCCInRange.contains(4));
region.parseOpcode({ "xfin_locc4", "4" }); region.parseOpcode({ "xfin_locc4", "4" });
REQUIRE(region.crossfadeCCInRange[4] == Range<uint8_t>(4, 4)); REQUIRE(region.crossfadeCCInRange[4] == sfz::Range<uint8_t>(4, 4));
region.parseOpcode({ "xfin_locc4", "128" }); region.parseOpcode({ "xfin_locc4", "128" });
REQUIRE(region.crossfadeCCInRange[4] == Range<uint8_t>(127, 127)); REQUIRE(region.crossfadeCCInRange[4] == sfz::Range<uint8_t>(127, 127));
region.parseOpcode({ "xfin_locc4", "59" }); region.parseOpcode({ "xfin_locc4", "59" });
REQUIRE(region.crossfadeCCInRange[4] == Range<uint8_t>(59, 127)); REQUIRE(region.crossfadeCCInRange[4] == sfz::Range<uint8_t>(59, 127));
region.parseOpcode({ "xfin_hicc4", "59" }); region.parseOpcode({ "xfin_hicc4", "59" });
REQUIRE(region.crossfadeCCInRange[4] == Range<uint8_t>(59, 59)); REQUIRE(region.crossfadeCCInRange[4] == sfz::Range<uint8_t>(59, 59));
region.parseOpcode({ "xfin_hicc4", "128" }); region.parseOpcode({ "xfin_hicc4", "128" });
REQUIRE(region.crossfadeCCInRange[4] == Range<uint8_t>(59, 127)); REQUIRE(region.crossfadeCCInRange[4] == sfz::Range<uint8_t>(59, 127));
region.parseOpcode({ "xfin_hicc4", "0" }); region.parseOpcode({ "xfin_hicc4", "0" });
REQUIRE(region.crossfadeCCInRange[4] == Range<uint8_t>(0, 0)); REQUIRE(region.crossfadeCCInRange[4] == sfz::Range<uint8_t>(0, 0));
region.parseOpcode({ "xfin_hicc4", "-1" }); region.parseOpcode({ "xfin_hicc4", "-1" });
REQUIRE(region.crossfadeCCInRange[4] == Range<uint8_t>(0, 0)); REQUIRE(region.crossfadeCCInRange[4] == sfz::Range<uint8_t>(0, 0));
} }
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] == Range<uint8_t>(4, 127)); REQUIRE(region.crossfadeCCOutRange[4] == sfz::Range<uint8_t>(4, 127));
region.parseOpcode({ "xfout_locc4", "128" }); region.parseOpcode({ "xfout_locc4", "128" });
REQUIRE(region.crossfadeCCOutRange[4] == Range<uint8_t>(127, 127)); REQUIRE(region.crossfadeCCOutRange[4] == sfz::Range<uint8_t>(127, 127));
region.parseOpcode({ "xfout_locc4", "59" }); region.parseOpcode({ "xfout_locc4", "59" });
REQUIRE(region.crossfadeCCOutRange[4] == Range<uint8_t>(59, 127)); REQUIRE(region.crossfadeCCOutRange[4] == sfz::Range<uint8_t>(59, 127));
region.parseOpcode({ "xfout_hicc4", "59" }); region.parseOpcode({ "xfout_hicc4", "59" });
REQUIRE(region.crossfadeCCOutRange[4] == Range<uint8_t>(59, 59)); REQUIRE(region.crossfadeCCOutRange[4] == sfz::Range<uint8_t>(59, 59));
region.parseOpcode({ "xfout_hicc4", "128" }); region.parseOpcode({ "xfout_hicc4", "128" });
REQUIRE(region.crossfadeCCOutRange[4] == Range<uint8_t>(59, 127)); REQUIRE(region.crossfadeCCOutRange[4] == sfz::Range<uint8_t>(59, 127));
region.parseOpcode({ "xfout_hicc4", "0" }); region.parseOpcode({ "xfout_hicc4", "0" });
REQUIRE(region.crossfadeCCOutRange[4] == Range<uint8_t>(0, 0)); REQUIRE(region.crossfadeCCOutRange[4] == sfz::Range<uint8_t>(0, 0));
region.parseOpcode({ "xfout_hicc4", "-1" }); region.parseOpcode({ "xfout_hicc4", "-1" });
REQUIRE(region.crossfadeCCOutRange[4] == Range<uint8_t>(0, 0)); REQUIRE(region.crossfadeCCOutRange[4] == sfz::Range<uint8_t>(0, 0));
} }
SECTION("xf_keycurve") SECTION("xf_keycurve")