Read and parse sostenuto-related stuff

This commit is contained in:
Paul Fd 2021-03-23 12:52:09 +01:00
parent 9386ed2f09
commit df07f3ac82
6 changed files with 68 additions and 0 deletions

View file

@ -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 };

View file

@ -161,9 +161,11 @@ namespace Default
extern const OpcodeSpec<uint8_t> curveCC;
extern const OpcodeSpec<uint16_t> smoothCC;
extern const OpcodeSpec<uint8_t> sustainCC;
extern const OpcodeSpec<uint8_t> sostenutoCC;
extern const OpcodeSpec<bool> checkSustain;
extern const OpcodeSpec<bool> checkSostenuto;
extern const OpcodeSpec<float> sustainThreshold;
extern const OpcodeSpec<float> sostenutoThreshold;
extern const OpcodeSpec<float> loBPM;
extern const OpcodeSpec<float> hiBPM;
extern const OpcodeSpec<uint8_t> sequence;

View file

@ -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;

View file

@ -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<float> aftertouchRange { Default::loChannelAftertouch, Default::hiChannelAftertouch }; // hichanaft and lochanaft

View file

@ -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);

View file

@ -2425,6 +2425,52 @@ TEST_CASE("[Values] Sustain low")
REQUIRE(messageList == expected);
}
TEST_CASE("[Values] Sostenuto CC")
{
Synth synth;
std::vector<std::string> messageList;
Client client(&messageList);
client.setReceiveCallback(&simpleMessageReceiver);
synth.loadSfzString(fs::current_path() / "tests/TestFiles/value_tests.sfz", R"(
<region> sample=kick.wav
<region> sample=kick.wav sostenuto_cc=10
<region> 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<std::string> 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<std::string> messageList;
Client client(&messageList);
client.setReceiveCallback(&simpleMessageReceiver);
synth.loadSfzString(fs::current_path() / "tests/TestFiles/value_tests.sfz", R"(
<region> sample=kick.wav
<region> sample=kick.wav sostenuto_lo=10
<region> 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<std::string> 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;