diff --git a/include/PeakController.h b/include/PeakController.h index 15f72f07f..fc9ea92d8 100644 --- a/include/PeakController.h +++ b/include/PeakController.h @@ -61,7 +61,8 @@ public: public slots: virtual ControllerDialog * createDialog( QWidget * _parent ); - void handleDestroyedEffect( ); + void handleDestroyedEffect( ); + void updateCoeffs(); protected: // The internal per-controller get-value function @@ -77,6 +78,10 @@ private: static int m_getCount; static int m_loadCount; static bool m_buggedFile; + + float m_attackCoeff; + float m_decayCoeff; + bool m_coeffNeedsUpdate; } ; diff --git a/plugins/peak_controller_effect/peak_controller_effect.cpp b/plugins/peak_controller_effect/peak_controller_effect.cpp index 9903bb635..aeb3677ad 100644 --- a/plugins/peak_controller_effect/peak_controller_effect.cpp +++ b/plugins/peak_controller_effect/peak_controller_effect.cpp @@ -131,7 +131,7 @@ bool PeakControllerEffect::processAudioBuffer( sampleFrame * _buf, float curRMS = sqrt_neg( sum / _frames ); const float amount = c.m_amountModel.value() * c.m_amountMultModel.value(); - m_lastSample = c.m_baseModel.value() + amount * curRMS; + m_lastSample = qBound( 0.0f, c.m_baseModel.value() + amount * curRMS, 1.0f ); return isRunning(); } diff --git a/src/core/PeakController.cpp b/src/core/PeakController.cpp index 53798ea83..25aaec456 100644 --- a/src/core/PeakController.cpp +++ b/src/core/PeakController.cpp @@ -60,6 +60,10 @@ PeakController::PeakController( Model * _parent, connect( m_peakEffect, SIGNAL( destroyed( ) ), this, SLOT( handleDestroyedEffect( ) ) ); } + connect( engine::mixer(), SIGNAL( sampleRateChanged() ), this, SLOT( updateCoeffs() ) ); + connect( m_peakEffect->attackModel(), SIGNAL( dataChanged() ), this, SLOT( updateCoeffs() ) ); + connect( m_peakEffect->decayModel(), SIGNAL( dataChanged() ), this, SLOT( updateCoeffs() ) ); + m_coeffNeedsUpdate = true; } @@ -80,6 +84,14 @@ PeakController::~PeakController() void PeakController::updateValueBuffer() { + if( m_coeffNeedsUpdate ) + { + const float ratio = 44100.0f / engine::mixer()->processingSampleRate(); + m_attackCoeff = 1.0f - powf( 10.0f, -0.5f * ( 1.0f - m_peakEffect->attackModel()->value() ) * ratio ); + m_decayCoeff = 1.0f - powf( 10.0f, -0.5f * ( 1.0f - m_peakEffect->decayModel()->value() ) * ratio ); + m_coeffNeedsUpdate = false; + } + if( m_peakEffect ) { float targetSample = m_peakEffect->lastSample(); @@ -87,24 +99,17 @@ void PeakController::updateValueBuffer() { const f_cnt_t frames = engine::mixer()->framesPerPeriod(); float * values = m_valueBuffer.values(); - - const float ratio = ( 44100.0 / 256.0 ) / engine::mixer()->processingSampleRate(); - const float v = m_currentSample >= targetSample - ? m_peakEffect->decayModel()->value() - : m_peakEffect->attackModel()->value(); - const float diff = ( targetSample - m_currentSample ) * ratio; - const float a = ( 1.0f - sqrt_neg( sqrt_neg( v ) ) ) * diff; - const bool att = m_currentSample < targetSample; for( f_cnt_t f = 0; f < frames; ++f ) { - if( att ) // going up... + const float diff = ( targetSample - m_currentSample ); + if( m_currentSample < targetSample ) // going up... { - m_currentSample = qMin( targetSample, m_currentSample + a ); // qmin prevents overshoot + m_currentSample += diff * m_attackCoeff; } - else + else if( m_currentSample > targetSample ) // going down { - m_currentSample = qMax( targetSample, m_currentSample + a ); // qmax prevents overshoot + m_currentSample += diff * m_decayCoeff; } values[f] = m_currentSample; } @@ -122,6 +127,12 @@ void PeakController::updateValueBuffer() } +void PeakController::updateCoeffs() +{ + m_coeffNeedsUpdate = true; +} + + void PeakController::handleDestroyedEffect( ) { // possible race condition...