diff --git a/src/sfizz/MidiState.cpp b/src/sfizz/MidiState.cpp index 50ddb6be..f46167cd 100644 --- a/src/sfizz/MidiState.cpp +++ b/src/sfizz/MidiState.cpp @@ -91,4 +91,14 @@ void sfz::MidiState::reset() noexcept for (auto& bendValue: pitchBends) bendValue = 0; +} + +void sfz::MidiState::resetAllControllers(int channel) noexcept +{ + ASSERT(channel >= 0 && channel < 16); + + for (int idx = 0; idx < config::numCCs; idx++) + cc[channel][idx] = 0; + + pitchBends[channel] = 0; } \ No newline at end of file diff --git a/src/sfizz/MidiState.h b/src/sfizz/MidiState.h index d1cfee06..f23449ee 100644 --- a/src/sfizz/MidiState.h +++ b/src/sfizz/MidiState.h @@ -90,6 +90,13 @@ public: */ void reset() noexcept; + /** + * @brief Res + * + * @param channel + */ + void resetAllControllers(int channel) noexcept; + private: template using ChannelArray = std::array; diff --git a/src/sfizz/Synth.cpp b/src/sfizz/Synth.cpp index f8d89ecd..a0900485 100644 --- a/src/sfizz/Synth.cpp +++ b/src/sfizz/Synth.cpp @@ -443,16 +443,19 @@ void sfz::Synth::cc(int delay, int channel, int ccNumber, uint8_t ccValue) noexc ASSERT(ccNumber < config::numCCs); ASSERT(ccNumber >= 0); - AtomicGuard callbackGuard { inCallback }; if (!canEnterCallback) return; - midiState.ccEvent(channel, ccNumber, ccValue); + if (ccNumber == config::resetCC) { + resetAllControllers(delay, channel); + return; + } + + midiState.ccEvent(channel, ccNumber, ccValue); for (auto& voice : voices) voice->registerCC(delay, channel, ccNumber, ccValue); - for (auto& region : ccActivationLists[ccNumber]) { if (region->registerCC(channel, ccNumber, ccValue)) { auto voice = findFreeVoice(); @@ -607,3 +610,22 @@ void sfz::Synth::disableFreeWheeling() noexcept DBG("Disabling freewheeling"); } } + +void sfz::Synth::resetAllControllers(int delay, int channel) noexcept +{ + AtomicGuard callbackGuard { inCallback }; + if (!canEnterCallback) + return; + + midiState.resetAllControllers(channel); + for (auto& voice: voices) { + voice->registerPitchWheel(delay, channel, 0); + for (int cc = 0; cc < config::numCCs; ++cc) + voice->registerCC(delay, channel, cc, 0); + } + + for (auto& region: regions) { + for (int cc = 0; cc < config::numCCs; ++cc) + region->registerCC(channel, cc, 0); + } +} \ No newline at end of file diff --git a/src/sfizz/Synth.h b/src/sfizz/Synth.h index 798665c4..f65ac479 100644 --- a/src/sfizz/Synth.h +++ b/src/sfizz/Synth.h @@ -359,6 +359,15 @@ protected: void callback(absl::string_view header, const std::vector& members) final; private: + /** + * @brief Reset all CCs; to be used on CC 121 + * + * @param delay the delay for the controller reset + * @param channel the channel on which to reset the controller + * + */ + void resetAllControllers(int delay, int channel) noexcept; + int numGroups { 0 }; int numMasters { 0 }; int numCurves { 0 };