Extensions for peak controller. Fulfills request 144.
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@ private:
|
||||
|
||||
float m_lastSample;
|
||||
float m_lastRMS;
|
||||
bool m_lastRMSavail;
|
||||
|
||||
Controller * m_autoController;
|
||||
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -50,6 +50,10 @@ protected:
|
||||
knob * m_decayKnob;
|
||||
ledCheckBox * m_muteLed;
|
||||
|
||||
ledCheckBox * m_absLed;
|
||||
knob * m_amountMultKnob;
|
||||
ledCheckBox * m_muteOutputLed;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
@@ -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" );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user