From 0481862b100e1de828500c1ced38b00ebaaa68bf Mon Sep 17 00:00:00 2001 From: Jean Pierre Cimalando Date: Fri, 21 Aug 2020 14:49:36 +0200 Subject: [PATCH] Allow the modulations to be notified of release --- src/sfizz/Voice.cpp | 2 ++ src/sfizz/modulations/ModGenerator.h | 9 +++++++++ src/sfizz/modulations/ModMatrix.cpp | 11 +++++++++++ src/sfizz/modulations/ModMatrix.h | 6 ++++++ 4 files changed, 28 insertions(+) diff --git a/src/sfizz/Voice.cpp b/src/sfizz/Voice.cpp index 56d7e6ce..1b644066 100644 --- a/src/sfizz/Voice.cpp +++ b/src/sfizz/Voice.cpp @@ -174,6 +174,8 @@ void sfz::Voice::release(int delay) noexcept } else { egEnvelope.startRelease(delay); } + + resources.modMatrix.releaseVoice(id, region->getId(), delay); } void sfz::Voice::off(int delay) noexcept diff --git a/src/sfizz/modulations/ModGenerator.h b/src/sfizz/modulations/ModGenerator.h index 8c7a89e8..3d7aed12 100644 --- a/src/sfizz/modulations/ModGenerator.h +++ b/src/sfizz/modulations/ModGenerator.h @@ -40,6 +40,15 @@ public: */ virtual void init(const ModKey& sourceKey, NumericId voiceId, unsigned delay) = 0; + /** + * @brief Send the generator a release notification. + * + * @param sourceKey identifier of the source to release + * @param voiceId the particular voice to initialize, if per-voice + * @param delay the frame time when it happens + */ + virtual void release(const ModKey& sourceKey, NumericId voiceId, unsigned delay) { (void)sourceKey; (void)voiceId; (void)delay; } + /** * @brief Generate a cycle of the modulator * diff --git a/src/sfizz/modulations/ModMatrix.cpp b/src/sfizz/modulations/ModMatrix.cpp index 913f3095..9290ba2d 100644 --- a/src/sfizz/modulations/ModMatrix.cpp +++ b/src/sfizz/modulations/ModMatrix.cpp @@ -211,6 +211,17 @@ void ModMatrix::initVoice(NumericId voiceId, NumericId regionId, } } +void ModMatrix::releaseVoice(NumericId voiceId, NumericId regionId, unsigned delay) +{ + Impl& impl = *impl_; + + for (Impl::Source &source : impl.sources_) { + const int flags = source.key.flags(); + if ((flags & kModIsPerVoice) && source.key.region() == regionId) + source.gen->release(source.key, voiceId, delay); + } +} + void ModMatrix::beginCycle(unsigned numFrames) { Impl& impl = *impl_; diff --git a/src/sfizz/modulations/ModMatrix.h b/src/sfizz/modulations/ModMatrix.h index 21592360..211cf06f 100644 --- a/src/sfizz/modulations/ModMatrix.h +++ b/src/sfizz/modulations/ModMatrix.h @@ -108,6 +108,12 @@ public: */ void initVoice(NumericId voiceId, NumericId regionId, unsigned delay); + /** + * @brief Release modulation source for a given voice. + * This must be called when a voice enters released state. + */ + void releaseVoice(NumericId voiceId, NumericId regionId, unsigned delay); + /** * @brief Start modulation processing for the entire cycle. * This clears all the buffers.