From 8721c34e1423a90590b026d188a5c13c4556bee8 Mon Sep 17 00:00:00 2001 From: Paul Fd Date: Sun, 23 May 2021 14:50:07 +0200 Subject: [PATCH] Add the FlexEG cancellation --- src/sfizz/FlexEnvelope.cpp | 36 +++++++++++++++---- src/sfizz/FlexEnvelope.h | 5 +++ .../modulations/sources/FlexEnvelope.cpp | 20 +++++++++++ src/sfizz/modulations/sources/FlexEnvelope.h | 1 + 4 files changed, 56 insertions(+), 6 deletions(-) diff --git a/src/sfizz/FlexEnvelope.cpp b/src/sfizz/FlexEnvelope.cpp index 4158978f..98e09552 100644 --- a/src/sfizz/FlexEnvelope.cpp +++ b/src/sfizz/FlexEnvelope.cpp @@ -49,6 +49,7 @@ struct FlexEnvelope::Impl { // void process(absl::Span out); + bool advanceToStage(unsigned stageNumber); bool advanceToNextStage(); }; @@ -114,6 +115,25 @@ void FlexEnvelope::release(unsigned releaseDelay) impl.currentFramesUntilRelease_ = releaseDelay; } +void FlexEnvelope::cancelRelease(unsigned delay) +{ + Impl& impl = *impl_; + const FlexEGDescription& desc = *impl.desc_; + + if (impl.currentFramesUntilRelease_) { + // Cancel the future release + impl.currentFramesUntilRelease_ = absl::nullopt; + return; + } + + if (!impl.isReleased_) + return; + + impl.isReleased_ = false; + impl.advanceToStage(desc.sustain); + impl.stageTargetLevel_ = impl.currentLevel_; +} + unsigned FlexEnvelope::getRemainingDelay() const noexcept { const Impl& impl = *impl_; @@ -226,25 +246,29 @@ void FlexEnvelope::Impl::process(absl::Span out) } } -bool FlexEnvelope::Impl::advanceToNextStage() +bool FlexEnvelope::Impl::advanceToStage(unsigned stageNumber) { const FlexEGDescription& desc = *desc_; - unsigned nextStageNo = currentStageNumber_ + 1; - currentStageNumber_ = nextStageNo; + currentStageNumber_ = stageNumber; - if (nextStageNo >= desc.points.size()) + if (stageNumber >= desc.points.size()) return false; - const FlexEGPoint& point = desc.points[nextStageNo]; + const FlexEGPoint& point = desc.points[stageNumber]; stageSourceLevel_ = currentLevel_; stageTargetLevel_ = point.level; stageTime_ = point.time; - stageSustained_ = int(nextStageNo) == desc.sustain; + stageSustained_ = int(stageNumber) == desc.sustain; stageCurve_ = &point.curve(); currentTime_ = 0; return true; }; +bool FlexEnvelope::Impl::advanceToNextStage() +{ + return advanceToStage(currentStageNumber_ + 1); +} + } // namespace sfz diff --git a/src/sfizz/FlexEnvelope.h b/src/sfizz/FlexEnvelope.h index d8cc2bf0..6a737cf1 100644 --- a/src/sfizz/FlexEnvelope.h +++ b/src/sfizz/FlexEnvelope.h @@ -47,6 +47,11 @@ public: */ void release(unsigned releaseDelay); + /** + Cancel the release + */ + void cancelRelease(unsigned delay); + /** Get the remaining delay samples */ diff --git a/src/sfizz/modulations/sources/FlexEnvelope.cpp b/src/sfizz/modulations/sources/FlexEnvelope.cpp index 5184bc5e..b3e85cfc 100644 --- a/src/sfizz/modulations/sources/FlexEnvelope.cpp +++ b/src/sfizz/modulations/sources/FlexEnvelope.cpp @@ -66,6 +66,26 @@ void FlexEnvelopeSource::release(const ModKey& sourceKey, NumericId voice eg->release(delay); } +void FlexEnvelopeSource::cancelRelease(const ModKey& sourceKey, NumericId voiceId, unsigned delay) +{ + unsigned egIndex = sourceKey.parameters().N; + + Voice* voice = voiceManager_.getVoiceById(voiceId); + if (!voice) { + ASSERTFALSE; + return; + } + + const Region* region = voice->getRegion(); + if (egIndex >= region->flexEGs.size()) { + ASSERTFALSE; + return; + } + + FlexEnvelope* eg = voice->getFlexEG(egIndex); + eg->cancelRelease(delay); +} + void FlexEnvelopeSource::generate(const ModKey& sourceKey, NumericId voiceId, absl::Span buffer) { unsigned egIndex = sourceKey.parameters().N; diff --git a/src/sfizz/modulations/sources/FlexEnvelope.h b/src/sfizz/modulations/sources/FlexEnvelope.h index 1868ab10..81b7a2f7 100644 --- a/src/sfizz/modulations/sources/FlexEnvelope.h +++ b/src/sfizz/modulations/sources/FlexEnvelope.h @@ -16,6 +16,7 @@ public: explicit FlexEnvelopeSource(VoiceManager& manager); void init(const ModKey& sourceKey, NumericId voiceId, unsigned delay) override; void release(const ModKey& sourceKey, NumericId voiceId, unsigned delay) override; + void cancelRelease(const ModKey& sourceKey, NumericId voiceId, unsigned delay) override; void generate(const ModKey& sourceKey, NumericId voiceId, absl::Span buffer) override; private: