From 86363819c556a63e7666d173118a50013eb93ce9 Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Sat, 27 Apr 2024 21:17:12 +0200 Subject: [PATCH] Fix Kicker's release stage (#7226) When applying its release stage Kicker did not take the frames before the release into account but instead always applied the release to the full buffer. This potentially lead to a jump in the attenuation values instead of a clean linear decay. See #7225 for more details. --- plugins/Kicker/Kicker.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/plugins/Kicker/Kicker.cpp b/plugins/Kicker/Kicker.cpp index 85fbf8e2bf8..5cbb18105f7 100644 --- a/plugins/Kicker/Kicker.cpp +++ b/plugins/Kicker/Kicker.cpp @@ -188,13 +188,22 @@ void KickerInstrument::playNote( NotePlayHandle * _n, if( _n->isReleased() ) { - const float done = _n->releaseFramesDone(); + // We need this to check if the release has ended const float desired = desiredReleaseFrames(); - for( fpp_t f = 0; f < frames; ++f ) + + // This can be considered the current release frame in the "global" context of the release. + // We need it with the desired number of release frames to compute the linear decay. + fpp_t currentReleaseFrame = _n->releaseFramesDone(); + + // Start applying the release at the correct frame + const float framesBeforeRelease = _n->framesBeforeRelease(); + for (fpp_t f = framesBeforeRelease; f < frames; ++f, ++currentReleaseFrame) { - const float fac = ( done+f < desired ) ? ( 1.0f - ( ( done+f ) / desired ) ) : 0; - _working_buffer[f+offset][0] *= fac; - _working_buffer[f+offset][1] *= fac; + const bool releaseStillActive = currentReleaseFrame < desired; + const float attenuation = releaseStillActive ? (1.0f - (currentReleaseFrame / desired)) : 0.f; + + _working_buffer[f + offset][0] *= attenuation; + _working_buffer[f + offset][1] *= attenuation; } } }