Extensions for peak controller. Fulfills request 144.

This commit is contained in:
Johannes Lorenz
2014-01-17 20:47:03 +01:00
parent ce50313b72
commit 5e8dbb6157
6 changed files with 76 additions and 11 deletions

View File

@@ -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();
}

View File

@@ -55,6 +55,7 @@ private:
float m_lastSample;
float m_lastRMS;
bool m_lastRMSavail;
Controller * m_autoController;

View File

@@ -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 );
}

View File

@@ -50,6 +50,10 @@ protected:
knob * m_decayKnob;
ledCheckBox * m_muteLed;
ledCheckBox * m_absLed;
knob * m_amountMultKnob;
ledCheckBox * m_muteOutputLed;
} ;

View File

@@ -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" );
}

View File

@@ -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;