From 5e8dbb615728b89775a2ca6252f83623d4251e86 Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Fri, 17 Jan 2014 20:47:03 +0100 Subject: [PATCH] Extensions for peak controller. Fulfills request 144. --- .../peak_controller_effect.cpp | 37 ++++++++++++++++--- .../peak_controller_effect.h | 1 + .../peak_controller_effect_control_dialog.cpp | 29 +++++++++++++-- .../peak_controller_effect_control_dialog.h | 4 ++ .../peak_controller_effect_controls.cpp | 13 ++++++- .../peak_controller_effect_controls.h | 3 ++ 6 files changed, 76 insertions(+), 11 deletions(-) diff --git a/plugins/peak_controller_effect/peak_controller_effect.cpp b/plugins/peak_controller_effect/peak_controller_effect.cpp index 0d62c3933..a9fa56286 100644 --- a/plugins/peak_controller_effect/peak_controller_effect.cpp +++ b/plugins/peak_controller_effect/peak_controller_effect.cpp @@ -64,6 +64,7 @@ PeakControllerEffect::PeakControllerEffect( m_peakControls( this ), m_lastSample( 0 ), m_lastRMS( -1 ), + m_lastRMSavail(false), m_autoController( NULL ) { m_autoController = new PeakController( engine::getSong(), this ); @@ -83,13 +84,19 @@ PeakControllerEffect::~PeakControllerEffect() } } +//! returns 1.0f if val > 0.0f, -1.0 else +inline float my_sign(float val) { return -1.0f + 2.0f * (val > 0.0f); } +//! if val >= 0.0f, returns sqrtf(val), else: -sqrtf(-val) +inline float sqrt_neg(float val) { + return sqrtf(fabs(val)) * my_sign(val); +} bool PeakControllerEffect::processAudioBuffer( sampleFrame * _buf, const fpp_t _frames ) { PeakControllerEffectControls & c = m_peakControls; - + // This appears to be used for determining whether or not to continue processing // audio with this effect if( !isEnabled() || !isRunning() ) @@ -101,7 +108,12 @@ bool PeakControllerEffect::processAudioBuffer( sampleFrame * _buf, double sum = 0; for( int i = 0; i < _frames; ++i ) { - sum += _buf[i][0]*_buf[i][0] + _buf[i][1]*_buf[i][1]; + float sign_0 = (c.m_absModel.value()) + ? 1.0f : my_sign(_buf[i][0]); + float sign_1 = (c.m_absModel.value()) + ? 1.0f : my_sign(_buf[i][1]); + sum += _buf[i][0]*_buf[i][0]*sign_0 + + _buf[i][1]*_buf[i][1]*sign_1; } if( c.m_muteModel.value() ) @@ -112,19 +124,22 @@ bool PeakControllerEffect::processAudioBuffer( sampleFrame * _buf, } } - float curRMS = sqrtf( sum / _frames ); + float curRMS = sqrt_neg( sum / _frames ); const float origRMS = curRMS; - if( m_lastRMS < 0 ) + + if( !m_lastRMSavail ) { + m_lastRMSavail = true; m_lastRMS = curRMS; } const float v = ( curRMS >= m_lastRMS ) ? c.m_attackModel.value() : c.m_decayModel.value(); - const float a = sqrtf( sqrtf( v ) ); + const float a = sqrt_neg( sqrt_neg( v ) ); curRMS = (1-a)*curRMS + a*m_lastRMS; - m_lastSample = c.m_baseModel.value() + c.m_amountModel.value()*curRMS; + const float amount = c.m_amountModel.value() * c.m_amountMultModel.value(); + m_lastSample = c.m_baseModel.value() + amount*curRMS; m_lastRMS = curRMS; // on greater buffer sizes our LP is updated less frequently, therfore @@ -138,6 +153,16 @@ bool PeakControllerEffect::processAudioBuffer( sampleFrame * _buf, //checkGate( out_sum / _frames ); + // finally, mute the output if wanted + // TODO: avoid clips? + if( c.m_muteOutputModel.value() ) + { + for( int i = 0; i < _frames; ++i ) + { + _buf[i][0] = _buf[i][1] = 0.0f; + } + } + return isRunning(); } diff --git a/plugins/peak_controller_effect/peak_controller_effect.h b/plugins/peak_controller_effect/peak_controller_effect.h index 56a81c58a..06e241f21 100644 --- a/plugins/peak_controller_effect/peak_controller_effect.h +++ b/plugins/peak_controller_effect/peak_controller_effect.h @@ -55,6 +55,7 @@ private: float m_lastSample; float m_lastRMS; + bool m_lastRMSavail; Controller * m_autoController; diff --git a/plugins/peak_controller_effect/peak_controller_effect_control_dialog.cpp b/plugins/peak_controller_effect/peak_controller_effect_control_dialog.cpp index b16f666e7..d38bb93e5 100644 --- a/plugins/peak_controller_effect/peak_controller_effect_control_dialog.cpp +++ b/plugins/peak_controller_effect/peak_controller_effect_control_dialog.cpp @@ -44,10 +44,11 @@ PeakControllerEffectControlDialog::PeakControllerEffectControlDialog( pal.setBrush( backgroundRole(), PLUGIN_NAME::getIconPixmap( "artwork" ) ); setPalette( pal ); - setFixedSize( 144, 110 ); + setFixedSize( 288, 110 ); QVBoxLayout * tl = new QVBoxLayout( this ); tl->addSpacing( 25 ); + tl->addStretch(); QHBoxLayout * l = new QHBoxLayout; @@ -61,8 +62,13 @@ PeakControllerEffectControlDialog::PeakControllerEffectControlDialog( m_amountKnob->setModel( &_controls->m_amountModel ); m_amountKnob->setHintText( tr( "Modulation amount:" ) + " ", "" ); + m_amountMultKnob = new knob( knobBright_26, this ); + m_amountMultKnob->setLabel( tr( "MULT" ) ); + m_amountMultKnob->setModel( &_controls->m_amountMultModel ); + m_amountMultKnob->setHintText( tr( "Amount Multiplicator:" ) + " ", "" ); + m_attackKnob = new knob( knobBright_26, this ); - m_attackKnob->setLabel( tr( "ATTACK" ) ); + m_attackKnob->setLabel( tr( "ATTCK" ) ); m_attackKnob->setModel( &_controls->m_attackModel ); m_attackKnob->setHintText( tr( "Attack:" ) + " ", "" ); @@ -73,15 +79,30 @@ PeakControllerEffectControlDialog::PeakControllerEffectControlDialog( l->addWidget( m_baseKnob ); l->addWidget( m_amountKnob ); + l->addWidget( m_amountMultKnob ); l->addWidget( m_attackKnob ); l->addWidget( m_decayKnob ); + l->addStretch(); // expand, so other widgets have minimum width tl->addLayout( l ); - m_muteLed = new ledCheckBox( "Mute", this ); + l = new QHBoxLayout; // = 2nd hbox + + m_muteLed = new ledCheckBox( "Mute Effect", this ); m_muteLed->setModel( &_controls->m_muteModel ); + m_absLed = new ledCheckBox( "Abs Value", this ); + m_absLed->setModel( &_controls->m_absModel ); + + m_muteOutputLed = new ledCheckBox( "Mute Output", this ); + m_muteOutputLed->setModel( &_controls->m_muteOutputModel ); + tl->addSpacing( 5 ); - tl->addWidget( m_muteLed ); + + l->addWidget( m_muteLed ); + l->addWidget( m_absLed ); + l->addWidget( m_muteOutputLed ); + l->addStretch(); // expand, so other widgets have minimum width + tl->addLayout( l ); setLayout( tl ); } diff --git a/plugins/peak_controller_effect/peak_controller_effect_control_dialog.h b/plugins/peak_controller_effect/peak_controller_effect_control_dialog.h index 5e95bd654..40e7abc1f 100644 --- a/plugins/peak_controller_effect/peak_controller_effect_control_dialog.h +++ b/plugins/peak_controller_effect/peak_controller_effect_control_dialog.h @@ -50,6 +50,10 @@ protected: knob * m_decayKnob; ledCheckBox * m_muteLed; + ledCheckBox * m_absLed; + knob * m_amountMultKnob; + ledCheckBox * m_muteOutputLed; + } ; diff --git a/plugins/peak_controller_effect/peak_controller_effect_controls.cpp b/plugins/peak_controller_effect/peak_controller_effect_controls.cpp index a07d52358..69c8f15b9 100644 --- a/plugins/peak_controller_effect/peak_controller_effect_controls.cpp +++ b/plugins/peak_controller_effect/peak_controller_effect_controls.cpp @@ -39,7 +39,10 @@ PeakControllerEffectControls( PeakControllerEffect * _eff ) : m_amountModel( 1.0, -1.0, 1.0, 0.005, this, tr( "Modulation amount" ) ), m_attackModel( 0, 0, 0.999, 0.001, this, tr( "Attack" ) ), m_decayModel( 0, 0, 0.999, 0.001, this, tr( "Release" ) ), - m_muteModel( false, this, tr( "Mute output" ) ) + m_muteModel( false, this, tr( "Mute output" ) ), + m_absModel( true, this, tr("Abs Value") ), + m_amountMultModel( 1.0, 0, 32, 0.2, this, tr("Amount Multiplicator") ), + m_muteOutputModel( false, this, tr("Mute Output") ) { } @@ -54,6 +57,10 @@ void PeakControllerEffectControls::loadSettings( const QDomElement & _this ) m_attackModel.loadSettings( _this, "attack" ); m_decayModel.loadSettings( _this, "decay" ); + m_absModel.loadSettings( _this, "abs" ); + m_amountMultModel.loadSettings( _this, "amountmult" ); + m_muteOutputModel.loadSettings( _this, "muteout" ); + int effectId = _this.attribute( "effectId" ).toInt(); if( effectId > PeakController::s_lastEffectId ) { @@ -82,6 +89,10 @@ void PeakControllerEffectControls::saveSettings( QDomDocument & _doc, m_attackModel.saveSettings( _doc, _this, "attack" ); m_decayModel.saveSettings( _doc, _this, "decay" ); + + m_absModel.saveSettings( _doc, _this, "abs" ); + m_amountMultModel.saveSettings( _doc, _this, "amountmult" ); + m_muteOutputModel.saveSettings( _doc, _this, "muteout" ); } diff --git a/plugins/peak_controller_effect/peak_controller_effect_controls.h b/plugins/peak_controller_effect/peak_controller_effect_controls.h index 7a8111795..4a4de0401 100644 --- a/plugins/peak_controller_effect/peak_controller_effect_controls.h +++ b/plugins/peak_controller_effect/peak_controller_effect_controls.h @@ -66,6 +66,9 @@ private: FloatModel m_attackModel; FloatModel m_decayModel; BoolModel m_muteModel; + BoolModel m_absModel; + FloatModel m_amountMultModel; + BoolModel m_muteOutputModel; friend class PeakControllerEffectControlDialog; friend class PeakControllerEffect;