From 4dc429a572df1ab95461aba6b7a4c75414c49075 Mon Sep 17 00:00:00 2001 From: Jean Pierre Cimalando Date: Fri, 19 Mar 2021 14:26:47 +0100 Subject: [PATCH] Make the aftertouch opcode normalized --- src/sfizz/Defaults.cpp | 4 ++-- src/sfizz/Defaults.h | 4 ++-- src/sfizz/Region.cpp | 2 +- src/sfizz/Region.h | 4 ++-- src/sfizz/Synth.cpp | 15 ++++++++++----- src/sfizz/Synth.h | 8 ++++++++ src/sfizz/SynthMessaging.cpp | 6 +++--- tests/RegionActivationT.cpp | 8 ++++---- tests/RegionValuesT.cpp | 10 +++++----- 9 files changed, 37 insertions(+), 24 deletions(-) diff --git a/src/sfizz/Defaults.cpp b/src/sfizz/Defaults.cpp index b20b7db7..6921be22 100644 --- a/src/sfizz/Defaults.cpp +++ b/src/sfizz/Defaults.cpp @@ -49,8 +49,8 @@ FloatSpec loCC { 0, {0.0f, 127.0f}, kNormalizeMidi }; FloatSpec hiCC { 127, {0.0f, 127.0f}, kNormalizeMidi }; FloatSpec loVel { 0, {0.0f, 127.0f}, kNormalizeMidi }; FloatSpec hiVel { 127, {0.0f, 127.0f}, kNormalizeMidi }; -UInt8Spec loChannelAftertouch { 0, {0, 127}, 0 }; -UInt8Spec hiChannelAftertouch { 127, {0, 127}, 0 }; +FloatSpec loChannelAftertouch { 0, {0, 127}, kNormalizeMidi }; +FloatSpec hiChannelAftertouch { 127, {0, 127}, kNormalizeMidi }; FloatSpec loBend { -8192, {-8192.0f, 8192.0f}, kNormalizeBend }; FloatSpec hiBend { 8192, {-8192.0f, 8192.0f}, kNormalizeBend }; FloatSpec loNormalized { 0.0f, {0.0f, 1.0f}, 0 }; diff --git a/src/sfizz/Defaults.h b/src/sfizz/Defaults.h index a4692622..6f8d31f1 100644 --- a/src/sfizz/Defaults.h +++ b/src/sfizz/Defaults.h @@ -153,8 +153,8 @@ namespace Default extern const OpcodeSpec hiNormalized; extern const OpcodeSpec loBipolar; extern const OpcodeSpec hiBipolar; - extern const OpcodeSpec loChannelAftertouch; - extern const OpcodeSpec hiChannelAftertouch; + extern const OpcodeSpec loChannelAftertouch; + extern const OpcodeSpec hiChannelAftertouch; extern const OpcodeSpec ccNumber; extern const OpcodeSpec curveCC; extern const OpcodeSpec smoothCC; diff --git a/src/sfizz/Region.cpp b/src/sfizz/Region.cpp index 40e80fed..02ed7293 100644 --- a/src/sfizz/Region.cpp +++ b/src/sfizz/Region.cpp @@ -1565,7 +1565,7 @@ void sfz::Region::registerPitchWheel(float pitch) noexcept pitchSwitched = false; } -void sfz::Region::registerAftertouch(uint8_t aftertouch) noexcept +void sfz::Region::registerAftertouch(float aftertouch) noexcept { if (aftertouchRange.containsWithEnd(aftertouch)) aftertouchSwitched = true; diff --git a/src/sfizz/Region.h b/src/sfizz/Region.h index fd983db3..6244424f 100644 --- a/src/sfizz/Region.h +++ b/src/sfizz/Region.h @@ -150,7 +150,7 @@ struct Region { * * @param aftertouch */ - void registerAftertouch(uint8_t aftertouch) noexcept; + void registerAftertouch(float aftertouch) noexcept; /** * @brief Register tempo * @@ -409,7 +409,7 @@ struct Region { float sustainThreshold { Default::sustainThreshold }; // sustain_cc // Region logic: internal conditions - Range aftertouchRange { Default::loChannelAftertouch, Default::hiChannelAftertouch }; // hichanaft and lochanaft + Range aftertouchRange { Default::loChannelAftertouch, Default::hiChannelAftertouch }; // hichanaft and lochanaft Range bpmRange { Default::loBPM, Default::hiBPM }; // hibpm and lobpm Range randRange { Default::loNormalized, Default::hiNormalized }; // hirand and lorand uint8_t sequenceLength { Default::sequence }; // seq_length diff --git a/src/sfizz/Synth.cpp b/src/sfizz/Synth.cpp index d1808b3d..abdefb14 100644 --- a/src/sfizz/Synth.cpp +++ b/src/sfizz/Synth.cpp @@ -1257,22 +1257,27 @@ void Synth::pitchWheel(int delay, int pitch) noexcept } void Synth::aftertouch(int delay, uint8_t aftertouch) noexcept +{ + const float normalizedAftertouch = normalize7Bits(aftertouch); + hdAftertouch(delay, normalizedAftertouch); +} + +void Synth::hdAftertouch(int delay, float normAftertouch) noexcept { Impl& impl = *impl_; ScopedTiming logger { impl.dispatchDuration_, ScopedTiming::Operation::addToDuration }; - const auto normalizedAftertouch = normalize7Bits(aftertouch); - impl.resources_.midiState.channelAftertouchEvent(delay, normalizedAftertouch); + impl.resources_.midiState.channelAftertouchEvent(delay, normAftertouch); for (auto& region : impl.regions_) { - region->registerAftertouch(aftertouch); + region->registerAftertouch(normAftertouch); } for (auto& voice : impl.voiceManager_) { - voice.registerAftertouch(delay, aftertouch); + voice.registerAftertouch(delay, normAftertouch); } - impl.performHdcc(delay, ExtendedCCs::channelAftertouch, normalizedAftertouch, false); + impl.performHdcc(delay, ExtendedCCs::channelAftertouch, normAftertouch, false); } void Synth::tempo(int delay, float secondsPerBeat) noexcept diff --git a/src/sfizz/Synth.h b/src/sfizz/Synth.h index 168900f9..a213cf2d 100644 --- a/src/sfizz/Synth.h +++ b/src/sfizz/Synth.h @@ -389,6 +389,14 @@ public: * @param aftertouch the aftertouch value */ void aftertouch(int delay, uint8_t aftertouch) noexcept; + /** + * @brief Send a high precision aftertouch event to the synth + * + * @param delay the delay at which the event occurs; this should be lower than the size of + * the block in the next call to renderBlock(). + * @param normAftertouch the normalized aftertouch value, in domain 0 to 1 + */ + void hdAftertouch(int delay, float normAftertouch) noexcept; /** * @brief Send a tempo event to the synth * diff --git a/src/sfizz/SynthMessaging.cpp b/src/sfizz/SynthMessaging.cpp index 3b4b18bf..9b2bcd54 100644 --- a/src/sfizz/SynthMessaging.cpp +++ b/src/sfizz/SynthMessaging.cpp @@ -374,9 +374,9 @@ void sfz::Synth::dispatchMessage(Client& client, int delay, const char* path, co MATCH("/region&/chanaft_range", "") { GET_REGION_OR_BREAK(indices[0]) sfizz_arg_t args[2]; - args[0].i = region.aftertouchRange.getStart(); - args[1].i = region.aftertouchRange.getEnd(); - client.receive(delay, path, "ii", args); + args[0].f = region.aftertouchRange.getStart(); + args[1].f = region.aftertouchRange.getEnd(); + client.receive(delay, path, "ff", args); } break; MATCH("/region&/bpm_range", "") { diff --git a/tests/RegionActivationT.cpp b/tests/RegionActivationT.cpp index 89a4254a..13f6b660 100644 --- a/tests/RegionActivationT.cpp +++ b/tests/RegionActivationT.cpp @@ -90,13 +90,13 @@ TEST_CASE("Region activation", "Region tests") { region.parseOpcode({ "lochanaft", "56" }); region.parseOpcode({ "hichanaft", "68" }); - region.registerAftertouch(0); + region.registerAftertouch(sfz::normalize7Bits(0)); REQUIRE(!region.isSwitchedOn()); - region.registerAftertouch(56); + region.registerAftertouch(sfz::normalize7Bits(56)); REQUIRE(region.isSwitchedOn()); - region.registerAftertouch(68); + region.registerAftertouch(sfz::normalize7Bits(68)); REQUIRE(region.isSwitchedOn()); - region.registerAftertouch(98); + region.registerAftertouch(sfz::normalize7Bits(98)); REQUIRE(!region.isSwitchedOn()); } diff --git a/tests/RegionValuesT.cpp b/tests/RegionValuesT.cpp index 5c0ae4b3..c1944e55 100644 --- a/tests/RegionValuesT.cpp +++ b/tests/RegionValuesT.cpp @@ -869,11 +869,11 @@ TEST_CASE("[Values] Aftertouch range") synth.dispatchMessage(client, 0, "/region3/chanaft_range", "", nullptr); synth.dispatchMessage(client, 0, "/region4/chanaft_range", "", nullptr); std::vector expected { - "/region0/chanaft_range,ii : { 0, 127 }", - "/region1/chanaft_range,ii : { 34, 60 }", - "/region2/chanaft_range,ii : { 0, 60 }", - "/region3/chanaft_range,ii : { 20, 127 }", - "/region4/chanaft_range,ii : { 10, 10 }", + "/region0/chanaft_range,ff : { 0, 1 }", + "/region1/chanaft_range,ff : { 0.267717, 0.472441 }", + "/region2/chanaft_range,ff : { 0, 0.472441 }", + "/region3/chanaft_range,ff : { 0.15748, 1 }", + "/region4/chanaft_range,ff : { 0.0787402, 0.0787402 }", }; REQUIRE(messageList == expected); }