Peak Controller: improve envelope calculation
This commit is contained in:
@@ -28,6 +28,7 @@
|
||||
#include "song.h"
|
||||
#include "PeakController.h"
|
||||
#include "peak_controller_effect.h"
|
||||
#include "lmms_math.h"
|
||||
|
||||
#include "embed.cpp"
|
||||
|
||||
@@ -63,9 +64,6 @@ PeakControllerEffect::PeakControllerEffect(
|
||||
m_effectId( rand() ),
|
||||
m_peakControls( this ),
|
||||
m_lastSample( 0 ),
|
||||
m_previousSample( 0 ),
|
||||
m_lastRMS( -1 ),
|
||||
m_lastRMSavail(false),
|
||||
m_autoController( NULL )
|
||||
{
|
||||
m_autoController = new PeakController( engine::getSong(), this );
|
||||
@@ -86,22 +84,6 @@ PeakControllerEffect::~PeakControllerEffect()
|
||||
}
|
||||
}
|
||||
|
||||
namespace helpers
|
||||
{
|
||||
|
||||
//! returns 1.0f if val > 0.0f, -1.0 else
|
||||
inline float 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 ) ) * helpers::sign( val );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool PeakControllerEffect::processAudioBuffer( sampleFrame * _buf,
|
||||
const fpp_t _frames )
|
||||
@@ -132,8 +114,8 @@ bool PeakControllerEffect::processAudioBuffer( sampleFrame * _buf,
|
||||
{
|
||||
// the value is absolute because of squaring,
|
||||
// so we need to correct it
|
||||
sum += _buf[i][0] * _buf[i][0] * helpers::sign( _buf[i][0] )
|
||||
+ _buf[i][1] * _buf[i][1] * helpers::sign( _buf[i][1] );
|
||||
sum += _buf[i][0] * _buf[i][0] * sign( _buf[i][0] )
|
||||
+ _buf[i][1] * _buf[i][1] * sign( _buf[i][1] );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,35 +129,9 @@ bool PeakControllerEffect::processAudioBuffer( sampleFrame * _buf,
|
||||
}
|
||||
}
|
||||
|
||||
float curRMS = helpers::sqrt_neg( sum / _frames );
|
||||
const float origRMS = curRMS;
|
||||
|
||||
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 = helpers::sqrt_neg( helpers::sqrt_neg( v ) );
|
||||
curRMS = (1-a)*curRMS + a*m_lastRMS;
|
||||
|
||||
float curRMS = sqrt_neg( sum / _frames );
|
||||
const float amount = c.m_amountModel.value() * c.m_amountMultModel.value();
|
||||
m_previousSample = m_lastSample;
|
||||
m_lastSample = c.m_baseModel.value() + amount*curRMS;
|
||||
m_lastRMS = curRMS;
|
||||
|
||||
// on greater buffer sizes our LP is updated less frequently, therfore
|
||||
// replay a certain number of passes so the LP state is as if it was
|
||||
// updated N times with buffer-size 1/N
|
||||
const int timeOversamp = (4*_frames) / DEFAULT_BUFFER_SIZE-1;
|
||||
for( int i = 0; i < timeOversamp; ++i )
|
||||
{
|
||||
m_lastRMS = (1-a)*origRMS + a*m_lastRMS;
|
||||
}
|
||||
|
||||
//checkGate( out_sum / _frames );
|
||||
m_lastSample = c.m_baseModel.value() + amount * curRMS;
|
||||
|
||||
return isRunning();
|
||||
}
|
||||
|
||||
@@ -48,15 +48,20 @@ public:
|
||||
return m_lastSample;
|
||||
}
|
||||
|
||||
float previousSample()
|
||||
{
|
||||
return m_previousSample;
|
||||
}
|
||||
|
||||
PeakController * controller()
|
||||
{
|
||||
return m_autoController;
|
||||
}
|
||||
|
||||
FloatModel * attackModel()
|
||||
{
|
||||
return &( m_peakControls.m_attackModel );
|
||||
}
|
||||
|
||||
FloatModel * decayModel()
|
||||
{
|
||||
return &( m_peakControls.m_decayModel );
|
||||
}
|
||||
|
||||
int m_effectId;
|
||||
|
||||
@@ -64,9 +69,6 @@ private:
|
||||
PeakControllerEffectControls m_peakControls;
|
||||
|
||||
float m_lastSample;
|
||||
float m_previousSample;
|
||||
float m_lastRMS;
|
||||
bool m_lastRMSavail;
|
||||
|
||||
PeakController * m_autoController;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user