From 41093efcbe62ba0a8752f6e82a8b7295fbea2a11 Mon Sep 17 00:00:00 2001 From: cyberrumor <46626673+cyberrumor@users.noreply.github.com> Date: Fri, 2 May 2025 08:04:47 -0700 Subject: [PATCH] Revert "Fix PeakController attack/decay (#7566)" (#7871) Prior to commit b5de1d50e, audible zipper artifacts were present when using the PeakController on a bus to control the volume of another bus for sidechain compression. The bus that had its volume reduced was the one which produced audible artifacts. Commit b5de1d50e introduced LERP to PeakController to smooth out its signal, which eliminated the zipper artifacts. However, this had the side effect of increased latency even when both attack and decay settings were set to zero. Until a more robust solution is implemented, reverting this change eliminates the latency by eliminating the lerp, but reintroduces audible zipper artifacts. --- include/PeakController.h | 3 ++- .../PeakControllerEffect/PeakControllerEffect.cpp | 12 +----------- src/core/PeakController.cpp | 13 +++++++++++-- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/include/PeakController.h b/include/PeakController.h index a22257374..de9da3b1c 100644 --- a/include/PeakController.h +++ b/include/PeakController.h @@ -78,7 +78,8 @@ private: static int m_loadCount; static bool m_buggedFile; - float m_coeff; + float m_attackCoeff; + float m_decayCoeff; bool m_coeffNeedsUpdate; } ; diff --git a/plugins/PeakControllerEffect/PeakControllerEffect.cpp b/plugins/PeakControllerEffect/PeakControllerEffect.cpp index b6d053257..394a80efd 100644 --- a/plugins/PeakControllerEffect/PeakControllerEffect.cpp +++ b/plugins/PeakControllerEffect/PeakControllerEffect.cpp @@ -132,18 +132,8 @@ Effect::ProcessStatus PeakControllerEffect::processImpl(SampleFrame* buf, const float curRMS = sqrt_neg(sum / frames); const float tres = c.m_tresholdModel.value(); const float amount = c.m_amountModel.value() * c.m_amountMultModel.value(); - const float attack = 1.0f - c.m_attackModel.value(); - const float decay = 1.0f - c.m_decayModel.value(); - curRMS = qAbs( curRMS ) < tres ? 0.0f : curRMS; - float target = c.m_baseModel.value() + amount * curRMS; - // Use decay when the volume is decreasing, attack otherwise. - // Since direction can change as often as every sampleBuffer, it's difficult - // to witness attack/decay working in isolation unless using large buffer sizes. - const float t = target < m_lastSample ? decay : attack; - // Set m_lastSample to the interpolation between itself and target. - // When t is 1.0, m_lastSample snaps to target. When t is 0.0, m_lastSample shouldn't change. - m_lastSample = std::clamp(m_lastSample + t * (target - m_lastSample), 0.0f, 1.0f); + m_lastSample = qBound( 0.0f, c.m_baseModel.value() + amount * curRMS, 1.0f ); return ProcessStatus::Continue; } diff --git a/src/core/PeakController.cpp b/src/core/PeakController.cpp index 1b819982a..1c38cf4cb 100644 --- a/src/core/PeakController.cpp +++ b/src/core/PeakController.cpp @@ -80,7 +80,9 @@ void PeakController::updateValueBuffer() { if( m_coeffNeedsUpdate ) { - m_coeff = 100.0f / Engine::audioEngine()->outputSampleRate(); + const float ratio = 44100.0f / Engine::audioEngine()->outputSampleRate(); + m_attackCoeff = 1.0f - powf( 2.0f, -0.3f * ( 1.0f - m_peakEffect->attackModel()->value() ) * ratio ); + m_decayCoeff = 1.0f - powf( 2.0f, -0.3f * ( 1.0f - m_peakEffect->decayModel()->value() ) * ratio ); m_coeffNeedsUpdate = false; } @@ -95,7 +97,14 @@ void PeakController::updateValueBuffer() for( f_cnt_t f = 0; f < frames; ++f ) { const float diff = ( targetSample - m_currentSample ); - m_currentSample += diff * m_coeff; + if( m_currentSample < targetSample ) // going up... + { + m_currentSample += diff * m_attackCoeff; + } + else if( m_currentSample > targetSample ) // going down + { + m_currentSample += diff * m_decayCoeff; + } values[f] = m_currentSample; } }