From df07f3ac82f4f561645d88a45062cc85af58ee04 Mon Sep 17 00:00:00 2001 From: Paul Fd Date: Tue, 23 Mar 2021 12:52:09 +0100 Subject: [PATCH] Read and parse sostenuto-related stuff --- src/sfizz/Defaults.cpp | 2 ++ src/sfizz/Defaults.h | 2 ++ src/sfizz/Region.cpp | 6 +++++ src/sfizz/Region.h | 2 ++ src/sfizz/SynthMessaging.cpp | 10 ++++++++ tests/RegionValuesT.cpp | 46 ++++++++++++++++++++++++++++++++++++ 6 files changed, 68 insertions(+) diff --git a/src/sfizz/Defaults.cpp b/src/sfizz/Defaults.cpp index d3c6393d..9319083c 100644 --- a/src/sfizz/Defaults.cpp +++ b/src/sfizz/Defaults.cpp @@ -61,7 +61,9 @@ UInt16Spec ccNumber { 0, {0, config::numCCs}, 0 }; UInt16Spec smoothCC { 0, {0, 100}, kPermissiveUpperBound }; UInt8Spec curveCC { 0, {0, 255}, 0 }; UInt8Spec sustainCC { 64, {0, 127}, 0 }; +UInt8Spec sostenutoCC { 66, {0, 127}, 0 }; FloatSpec sustainThreshold { 1.0f, {0.0f, 127.0f}, kNormalizeMidi|kPermissiveBounds }; +FloatSpec sostenutoThreshold { 1.0f, {0.0f, 127.0f}, kNormalizeMidi|kPermissiveBounds }; BoolSpec checkSustain { true, {0, 1}, kEnforceBounds }; BoolSpec checkSostenuto { true, {0, 1}, kEnforceBounds }; FloatSpec loBPM { 0.0f, {0.0f, 500.0f}, kPermissiveBounds }; diff --git a/src/sfizz/Defaults.h b/src/sfizz/Defaults.h index 28dba5fa..70735abf 100644 --- a/src/sfizz/Defaults.h +++ b/src/sfizz/Defaults.h @@ -161,9 +161,11 @@ namespace Default extern const OpcodeSpec curveCC; extern const OpcodeSpec smoothCC; extern const OpcodeSpec sustainCC; + extern const OpcodeSpec sostenutoCC; extern const OpcodeSpec checkSustain; extern const OpcodeSpec checkSostenuto; extern const OpcodeSpec sustainThreshold; + extern const OpcodeSpec sostenutoThreshold; extern const OpcodeSpec loBPM; extern const OpcodeSpec hiBPM; extern const OpcodeSpec sequence; diff --git a/src/sfizz/Region.cpp b/src/sfizz/Region.cpp index e066e430..b8431e07 100644 --- a/src/sfizz/Region.cpp +++ b/src/sfizz/Region.cpp @@ -308,9 +308,15 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) case hash("sustain_cc"): sustainCC = opcode.read(Default::sustainCC); break; + case hash("sostenuto_cc"): + sostenutoCC = opcode.read(Default::sostenutoCC); + break; case hash("sustain_lo"): sustainThreshold = opcode.read(Default::sustainThreshold); break; + case hash("sostenuto_lo"): + sostenutoThreshold = opcode.read(Default::sostenutoThreshold); + break; case hash("sustain_sw"): checkSustain = opcode.read(Default::checkSustain); break; diff --git a/src/sfizz/Region.h b/src/sfizz/Region.h index 5cf21180..f885971c 100644 --- a/src/sfizz/Region.h +++ b/src/sfizz/Region.h @@ -406,7 +406,9 @@ struct Region { bool checkSustain { Default::checkSustain }; // sustain_sw bool checkSostenuto { Default::checkSostenuto }; // sostenuto_sw uint16_t sustainCC { Default::sustainCC }; // sustain_cc + uint16_t sostenutoCC { Default::sostenutoCC }; // sustain_cc float sustainThreshold { Default::sustainThreshold }; // sustain_cc + float sostenutoThreshold { Default::sostenutoThreshold }; // sustain_cc // Region logic: internal conditions UncheckedRange aftertouchRange { Default::loChannelAftertouch, Default::hiChannelAftertouch }; // hichanaft and lochanaft diff --git a/src/sfizz/SynthMessaging.cpp b/src/sfizz/SynthMessaging.cpp index bfeda787..26009d6c 100644 --- a/src/sfizz/SynthMessaging.cpp +++ b/src/sfizz/SynthMessaging.cpp @@ -1042,11 +1042,21 @@ void sfz::Synth::dispatchMessage(Client& client, int delay, const char* path, co client.receive<'i'>(delay, path, region.sustainCC); } break; + MATCH("/region&/sostenuto_cc", "") { + GET_REGION_OR_BREAK(indices[0]) + client.receive<'i'>(delay, path, region.sostenutoCC); + } break; + MATCH("/region&/sustain_lo", "") { GET_REGION_OR_BREAK(indices[0]) client.receive<'f'>(delay, path, region.sustainThreshold); } break; + MATCH("/region&/sostenuto_lo", "") { + GET_REGION_OR_BREAK(indices[0]) + client.receive<'f'>(delay, path, region.sostenutoThreshold); + } break; + MATCH("/region&/oscillator_phase", "") { GET_REGION_OR_BREAK(indices[0]) client.receive<'f'>(delay, path, region.oscillatorPhase); diff --git a/tests/RegionValuesT.cpp b/tests/RegionValuesT.cpp index 6b5dfbf5..1feb9cf1 100644 --- a/tests/RegionValuesT.cpp +++ b/tests/RegionValuesT.cpp @@ -2425,6 +2425,52 @@ TEST_CASE("[Values] Sustain low") REQUIRE(messageList == expected); } +TEST_CASE("[Values] Sostenuto CC") +{ + Synth synth; + std::vector messageList; + Client client(&messageList); + client.setReceiveCallback(&simpleMessageReceiver); + + synth.loadSfzString(fs::current_path() / "tests/TestFiles/value_tests.sfz", R"( + sample=kick.wav + sample=kick.wav sostenuto_cc=10 + sample=kick.wav sostenuto_cc=20 sostenuto_cc=-1 + )"); + synth.dispatchMessage(client, 0, "/region0/sostenuto_cc", "", nullptr); + synth.dispatchMessage(client, 0, "/region1/sostenuto_cc", "", nullptr); + synth.dispatchMessage(client, 0, "/region2/sostenuto_cc", "", nullptr); + std::vector expected { + "/region0/sostenuto_cc,i : { 66 }", + "/region1/sostenuto_cc,i : { 10 }", + "/region2/sostenuto_cc,i : { 66 }", + }; + REQUIRE(messageList == expected); +} + +TEST_CASE("[Values] Sostenuto low") +{ + Synth synth; + std::vector messageList; + Client client(&messageList); + client.setReceiveCallback(&simpleMessageReceiver); + + synth.loadSfzString(fs::current_path() / "tests/TestFiles/value_tests.sfz", R"( + sample=kick.wav + sample=kick.wav sostenuto_lo=10 + sample=kick.wav sostenuto_lo=10 sostenuto_lo=-1 + )"); + synth.dispatchMessage(client, 0, "/region0/sostenuto_lo", "", nullptr); + synth.dispatchMessage(client, 0, "/region1/sostenuto_lo", "", nullptr); + synth.dispatchMessage(client, 0, "/region2/sostenuto_lo", "", nullptr); + std::vector expected { + "/region0/sostenuto_lo,f : { 0.00787402 }", + "/region1/sostenuto_lo,f : { 0.0787402 }", + "/region2/sostenuto_lo,f : { -0.00787402 }", + }; + REQUIRE(messageList == expected); +} + TEST_CASE("[Values] Oscillator phase") { Synth synth;