From 6f052b2389c7d32eb476102d44b3fafc1224ad60 Mon Sep 17 00:00:00 2001 From: Paul Fd Date: Sat, 20 Nov 2021 22:34:44 +0100 Subject: [PATCH] sw_last is affected by octave/note offsets --- src/sfizz/Synth.cpp | 13 +++++++--- src/sfizz/SynthPrivate.h | 7 +++++ tests/RegionActivationT.cpp | 51 +++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 4 deletions(-) diff --git a/src/sfizz/Synth.cpp b/src/sfizz/Synth.cpp index e9f99d6a..004d518f 100644 --- a/src/sfizz/Synth.cpp +++ b/src/sfizz/Synth.cpp @@ -205,7 +205,7 @@ void Synth::Impl::buildRegion(const std::vector& regionOpcodes) previousKeyswitchLists_.push_back(lastLayer); if (lastRegion->defaultSwitch) - currentSwitch_ = *lastRegion->defaultSwitch; + setCurrentSwitch(*lastRegion->defaultSwitch); // There was a combination of group= and polyphony= on a region, so set the group polyphony if (lastRegion->group != Default::group && lastRegion->polyphony != config::maxVoices) { @@ -320,7 +320,7 @@ void Synth::Impl::handleMasterOpcodes(const std::vector& members) currentSet_->setPolyphonyLimit(member.read(Default::polyphony)); break; case hash("sw_default"): - currentSwitch_ = member.read(Default::key); + setCurrentSwitch(member.read(Default::key)); break; } } @@ -337,7 +337,7 @@ void Synth::Impl::handleGlobalOpcodes(const std::vector& members) currentSet_->setPolyphonyLimit(member.read(Default::polyphony)); break; case hash("sw_default"): - currentSwitch_ = member.read(Default::key); + setCurrentSwitch(member.read(Default::key)); break; case hash("volume"): // FIXME : Probably best not to mess with this and let the host control the volume @@ -363,7 +363,7 @@ void Synth::Impl::handleGroupOpcodes(const std::vector& members, const s maxPolyphony = member.read(Default::polyphony); break; case hash("sw_default"): - currentSwitch_ = member.read(Default::key); + setCurrentSwitch(member.read(Default::key)); break; } }; @@ -645,6 +645,11 @@ bool Synth::loadSfzString(const fs::path& path, absl::string_view text) return true; } +void Synth::Impl::setCurrentSwitch(uint8_t noteValue) +{ + currentSwitch_ = noteValue + 12 * octaveOffset_ + noteOffset_; +} + void Synth::Impl::finalizeSfzLoad() { FilePool& filePool = resources_.getFilePool(); diff --git a/src/sfizz/SynthPrivate.h b/src/sfizz/SynthPrivate.h index e1cd5468..e2f715d5 100644 --- a/src/sfizz/SynthPrivate.h +++ b/src/sfizz/SynthPrivate.h @@ -197,6 +197,13 @@ struct Synth::Impl final: public Parser::Listener { */ void finalizeSfzLoad(); + /** + * @brief Set the current keyswitch, taking into account octave offsets and the like. + * + * @param noteValue + */ + void setCurrentSwitch(uint8_t noteValue); + template static void collectUsedCCsFromCCMap(BitArray& usedCCs, const CCMap map) noexcept { diff --git a/tests/RegionActivationT.cpp b/tests/RegionActivationT.cpp index b8ae8218..f36dba8a 100644 --- a/tests/RegionActivationT.cpp +++ b/tests/RegionActivationT.cpp @@ -8,6 +8,7 @@ #include "sfizz/Region.h" #include "sfizz/Synth.h" #include "sfizz/SfzHelpers.h" +#include "TestHelpers.h" #include "catch2/catch.hpp" using namespace Catch::literals; using namespace sfz::literals; @@ -655,3 +656,53 @@ TEST_CASE("[Region activation] Polyphonic aftertouch") } } +TEST_CASE("[Keyswitches] sw_default with octave_offset") +{ + sfz::Synth synth; + std::vector messageList; + sfz::Client client(&messageList); + client.setReceiveCallback(&simpleMessageReceiver); + sfz::AudioBuffer buffer { 2, static_cast(synth.getSamplesPerBlock()) }; + std::vector expected { + "/sw/last/current,i : { 59 }", + }; + + SECTION("In ") { + synth.loadSfzString(fs::current_path() / "tests/TestFiles/sw_previous.sfz", R"( + octave_offset=1 note_offset=-1 + sw_default=48 + sample=*sine + )"); + synth.dispatchMessage(client, 0, "/sw/last/current", "", nullptr); + REQUIRE(messageList == expected); + } + + SECTION("In ") { + synth.loadSfzString(fs::current_path() / "tests/TestFiles/sw_previous.sfz", R"( + octave_offset=1 note_offset=-1 + sw_default=48 + sample=*sine + )"); + synth.dispatchMessage(client, 0, "/sw/last/current", "", nullptr); + REQUIRE(messageList == expected); + } + + SECTION("In ") { + synth.loadSfzString(fs::current_path() / "tests/TestFiles/sw_previous.sfz", R"( + octave_offset=1 note_offset=-1 + sw_default=48 + sample=*sine + )"); + synth.dispatchMessage(client, 0, "/sw/last/current", "", nullptr); + REQUIRE(messageList == expected); + } + + SECTION("In ") { + synth.loadSfzString(fs::current_path() / "tests/TestFiles/sw_previous.sfz", R"( + octave_offset=1 note_offset=-1 + sample=*sine sw_default=48 + )"); + synth.dispatchMessage(client, 0, "/sw/last/current", "", nullptr); + REQUIRE(messageList == expected); + } +}