From dd8134277c45c283d89d25817aa8abfce9ca345c Mon Sep 17 00:00:00 2001 From: Paul Ferrand Date: Fri, 21 Aug 2020 11:36:09 +0200 Subject: [PATCH] Clamp the tracking factors to avoid blowups --- src/sfizz/Voice.cpp | 12 ++++++++++-- src/sfizz/Voice.h | 6 ++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/sfizz/Voice.cpp b/src/sfizz/Voice.cpp index 54c5ebc2..caaa718f 100644 --- a/src/sfizz/Voice.cpp +++ b/src/sfizz/Voice.cpp @@ -237,6 +237,14 @@ void sfz::Voice::registerTempo(int delay, float secondsPerQuarter) noexcept UNUSED(secondsPerQuarter); } +void sfz::Voice::updateTrackingFactor() noexcept +{ + // Protect the envelope follower against blowups + const auto maxTrackingFactor = sampleRate / samplesPerBlock; + attackTrackingFactor = min(config::powerFollowerAttackFactor, maxTrackingFactor) / sampleRate; + releaseTrackingFactor = min(config::powerFollowerReleaseFactor, maxTrackingFactor) / sampleRate; +} + void sfz::Voice::setSampleRate(float sampleRate) noexcept { this->sampleRate = sampleRate; @@ -249,13 +257,13 @@ void sfz::Voice::setSampleRate(float sampleRate) noexcept for (auto& lfo : lfos) lfo->setSampleRate(sampleRate); - attackTrackingFactor = config::powerFollowerAttackFactor / sampleRate; - releaseTrackingFactor = config::powerFollowerReleaseFactor / sampleRate; + updateTrackingFactor(); } void sfz::Voice::setSamplesPerBlock(int samplesPerBlock) noexcept { this->samplesPerBlock = samplesPerBlock; + updateTrackingFactor(); } void sfz::Voice::renderBlock(AudioSpan buffer) noexcept diff --git a/src/sfizz/Voice.h b/src/sfizz/Voice.h index c2b3d1c4..5881e79c 100644 --- a/src/sfizz/Voice.h +++ b/src/sfizz/Voice.h @@ -485,6 +485,12 @@ private: Smoother xfadeSmoother; void resetSmoothers() noexcept; + /** + * @brief Update and clamp the tracking factors to ensure the power + * follower does not blow up. + * + */ + void updateTrackingFactor() noexcept; float attackTrackingFactor { config::powerFollowerAttackFactor / config::defaultSampleRate }; float releaseTrackingFactor { config::powerFollowerReleaseFactor / config::defaultSampleRate }; float meanChannelPower;