From 3b1ce0e1641c5bb0db04790b68da9b0e3308c3cd Mon Sep 17 00:00:00 2001 From: Jean Pierre Cimalando Date: Wed, 12 Aug 2020 05:06:53 +0200 Subject: [PATCH] Implement the correct LFO fade in --- src/sfizz/LFO.cpp | 34 +++++++++++++++++++++++----------- src/sfizz/LFO.h | 5 +++++ 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/sfizz/LFO.cpp b/src/sfizz/LFO.cpp index cb7f0747..b14dba95 100644 --- a/src/sfizz/LFO.cpp +++ b/src/sfizz/LFO.cpp @@ -23,8 +23,7 @@ struct LFO::Impl { // state size_t delayFramesLeft_ = 0; - float fadeInPole_ = 0; - float fadeInMemory_ = 0; + float fadePosition_ = 0; std::array subPhases_ {{}}; std::array sampleHoldMem_ {{}}; }; @@ -62,9 +61,7 @@ void LFO::start() const float delay = desc.delay; impl.delayFramesLeft_ = (delay > 0) ? static_cast(std::ceil(sampleRate * delay)) : 0u; - const float fade = desc.fade; - impl.fadeInPole_ = (fade > 0) ? std::exp(-1.0 / (fade * sampleRate)) : 0.0f; - impl.fadeInMemory_ = 0; + impl.fadePosition_ = (desc.fade > 0) ? 0.0f : 1.0f; } template <> @@ -283,13 +280,28 @@ void LFO::process(absl::Span out) } } - float fadeIn = impl.fadeInMemory_; - const float fadeInPole = impl.fadeInPole_; - for (size_t i = 0; i < numFrames; ++i) { - out[i] *= fadeIn; - fadeIn = fadeInPole * fadeIn + (1 - fadeInPole); + processFadeIn(out); +} + +void LFO::processFadeIn(absl::Span out) +{ + Impl& impl = *impl_; + const LFODescription& desc = *impl.desc_; + const float samplePeriod = 1.0f / impl.sampleRate_; + size_t numFrames = out.size(); + + float fadePosition = impl.fadePosition_; + if (fadePosition >= 1.0f) + return; + + const float fadeTime = desc.fade; + + for (size_t i = 0; i < numFrames && fadePosition < 1; ++i) { + out[i] *= fadePosition; + fadePosition = std::min(1.0f, fadePosition + samplePeriod / fadeTime); } - impl.fadeInMemory_ = fadeIn; + + impl.fadePosition_ = fadePosition; } } // namespace sfz diff --git a/src/sfizz/LFO.h b/src/sfizz/LFO.h index fbd9dd14..3d75cad3 100644 --- a/src/sfizz/LFO.h +++ b/src/sfizz/LFO.h @@ -104,6 +104,11 @@ private: */ void processSteps(absl::Span out); + /** + Process the fade in gain, and apply it to the buffer. + */ + void processFadeIn(absl::Span out); + private: struct Impl; std::unique_ptr impl_;