diff --git a/include/PeakController.h b/include/PeakController.h index de9da3b1ce1..a22257374d6 100644 --- a/include/PeakController.h +++ b/include/PeakController.h @@ -78,8 +78,7 @@ public slots: static int m_loadCount; static bool m_buggedFile; - float m_attackCoeff; - float m_decayCoeff; + float m_coeff; bool m_coeffNeedsUpdate; } ; diff --git a/plugins/PeakControllerEffect/PeakControllerEffect.cpp b/plugins/PeakControllerEffect/PeakControllerEffect.cpp index 394a80efd4b..b6d05325770 100644 --- a/plugins/PeakControllerEffect/PeakControllerEffect.cpp +++ b/plugins/PeakControllerEffect/PeakControllerEffect.cpp @@ -132,8 +132,18 @@ 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; - m_lastSample = qBound( 0.0f, c.m_baseModel.value() + amount * curRMS, 1.0f ); + 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); return ProcessStatus::Continue; } diff --git a/src/core/PeakController.cpp b/src/core/PeakController.cpp index 1c38cf4cb33..1b819982a6c 100644 --- a/src/core/PeakController.cpp +++ b/src/core/PeakController.cpp @@ -80,9 +80,7 @@ void PeakController::updateValueBuffer() { if( m_coeffNeedsUpdate ) { - 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_coeff = 100.0f / Engine::audioEngine()->outputSampleRate(); m_coeffNeedsUpdate = false; } @@ -97,14 +95,7 @@ void PeakController::updateValueBuffer() for( f_cnt_t f = 0; f < frames; ++f ) { const float diff = ( targetSample - m_currentSample ); - if( m_currentSample < targetSample ) // going up... - { - m_currentSample += diff * m_attackCoeff; - } - else if( m_currentSample > targetSample ) // going down - { - m_currentSample += diff * m_decayCoeff; - } + m_currentSample += diff * m_coeff; values[f] = m_currentSample; } }