analyser now disabled when not in view.
band vu meters now disable when analyser is disabled.
display nema changed to Equalizer.
set sample rate before frequency on LinkWitzRiley filters.
Grouped the setting of filterparameters into one function, and calc coefficent
 once if needed.
Made suitable function inline.
in and out vu meters now using both stereo channels
This commit is contained in:
Dave French
2014-12-23 21:57:20 +00:00
parent 89d31629c8
commit 7527976804
6 changed files with 154 additions and 153 deletions

View File

@@ -70,6 +70,8 @@ public:
bool m_inProgress;
bool visable();

View File

@@ -161,6 +161,8 @@ EqControlsDialog::EqControlsDialog( EqControls *controls ) :
m_analyzeBox->move( cw*1 + ko + 5, 15 );
m_analyzeBox->setModel( &controls->m_analyzeModel );
}
void EqControlsDialog::mouseDoubleClickEvent(QMouseEvent *event)

View File

@@ -36,7 +36,7 @@ extern "C"
Plugin::Descriptor PLUGIN_EXPORT eq_plugin_descriptor =
{
STRINGIFY( PLUGIN_NAME ),
"Eq",
"Equalizer",
QT_TRANSLATE_NOOP( "pluginBrowser", "A native eq plugin" ),
"Dave French <contact/dot/dave/dot/french3/at/googlemail/dot/com>",
0x0100,
@@ -54,7 +54,7 @@ EqEffect::EqEffect(Model *parent, const Plugin::Descriptor::SubPluginFeatures::K
m_eqControls( this ),
m_upBufFrames( 0 )
{
m_dFilterCount = 4;
m_dFilterCount = 2;
m_downsampleFilters = new EqLinkwitzRiley[m_dFilterCount];
for( int i = 0; i < m_dFilterCount; i++)
{
@@ -101,114 +101,81 @@ bool EqEffect::processAudioBuffer(sampleFrame *buf, const fpp_t frames)
upsample( buf, frames );
gain(m_upBuf , m_upBufFrames, m_eqControls.m_inGainModel.value(), &m_inPeak );
m_eqControls.m_inPeakL = m_eqControls.m_inPeakL < m_inPeak[0] ? m_inPeak[0] : m_eqControls.m_inPeakL;
m_eqControls.m_inPeakR = m_eqControls.m_inPeakR < m_inPeak[1] ? m_inPeak[0] : m_eqControls.m_inPeakR;
m_eqControls.m_inPeakR = m_eqControls.m_inPeakR < m_inPeak[1] ? m_inPeak[1] : m_eqControls.m_inPeakR;
if(m_eqControls.m_hpActiveModel.value() ){
m_hp12.setSampleRate( sampleRate );
m_hp12.setFrequency( m_eqControls.m_hpFeqModel.value() );
m_hp12.setQ( m_eqControls.m_hpResModel.value() );
m_hp12.setParameters( sampleRate, m_eqControls.m_hpFeqModel.value(), m_eqControls.m_hpResModel.value(), 1 );
m_hp12.processBuffer( m_upBuf , m_upBufFrames );
if( m_eqControls.m_hp24Model.value() || m_eqControls.m_hp48Model.value() )
{
m_hp24.setSampleRate( sampleRate );
m_hp24.setFrequency( m_eqControls.m_hpFeqModel.value() );
m_hp24.setQ( m_eqControls.m_hpResModel.value() );
m_hp24.setParameters( sampleRate, m_eqControls.m_hpFeqModel.value(), m_eqControls.m_hpResModel.value(), 1 );
m_hp24.processBuffer( m_upBuf , m_upBufFrames );
}
if( m_eqControls.m_hp48Model.value() )
{
m_hp480.setSampleRate( sampleRate );
m_hp480.setFrequency( m_eqControls.m_hpFeqModel.value() );
m_hp480.setQ( m_eqControls.m_hpResModel.value() );
m_hp480.setParameters( sampleRate, m_eqControls.m_hpFeqModel.value(), m_eqControls.m_hpResModel.value(), 1 );
m_hp480.processBuffer( m_upBuf , m_upBufFrames );
m_hp481.setSampleRate( sampleRate );
m_hp481.setFrequency( m_eqControls.m_hpFeqModel.value() );
m_hp481.setQ( m_eqControls.m_hpResModel.value() );
m_hp481.setParameters( sampleRate, m_eqControls.m_hpFeqModel.value(), m_eqControls.m_hpResModel.value(), 1 );
m_hp481.processBuffer( m_upBuf , m_upBufFrames );
}
}
if( m_eqControls.m_lowShelfActiveModel.value() )
{
m_lowShelf.setSampleRate( sampleRate );
m_lowShelf.setFrequency( m_eqControls.m_lowShelfFreqModel.value() );
m_lowShelf.setQ( m_eqControls.m_lowShelfResModel .value() );
m_lowShelf.setGain( m_eqControls.m_lowShelfGainModel.value() );
m_lowShelf.setParameters( sampleRate, m_eqControls.m_lowShelfFreqModel.value(), m_eqControls.m_lowShelfResModel .value(), m_eqControls.m_lowShelfGainModel.value() );
m_lowShelf.processBuffer( m_upBuf , m_upBufFrames );
}
if( m_eqControls.m_para1ActiveModel.value() )
{
m_para1.setSampleRate(sampleRate );
m_para1.setFrequency( m_eqControls.m_para1FreqModel.value() );
m_para1.setQ( m_eqControls.m_para1ResModel.value() );
m_para1.setGain( m_eqControls.m_para1GainModel.value() );
m_para1.setParameters( sampleRate, m_eqControls.m_para1FreqModel.value(), m_eqControls.m_para1ResModel.value(), m_eqControls.m_para1GainModel.value() );
m_para1.processBuffer( m_upBuf , m_upBufFrames );
}
if( m_eqControls.m_para2ActiveModel.value() )
{
m_para2.setSampleRate( sampleRate );
m_para2.setFrequency( m_eqControls.m_para2FreqModel.value() );
m_para2.setQ( m_eqControls.m_para2ResModel.value() );
m_para2.setGain( m_eqControls.m_para2GainModel.value() );
m_para2.setParameters( sampleRate, m_eqControls.m_para2FreqModel.value(), m_eqControls.m_para2ResModel.value(), m_eqControls.m_para2GainModel.value() );
m_para2.processBuffer( m_upBuf , m_upBufFrames );
}
if( m_eqControls.m_para3ActiveModel.value() )
{
m_para3.setSampleRate( sampleRate);
m_para3.setFrequency( m_eqControls.m_para3FreqModel.value() );
m_para3.setQ( m_eqControls.m_para3ResModel.value() );
m_para3.setGain( m_eqControls.m_para3GainModel.value() );
m_para3.setParameters( sampleRate, m_eqControls.m_para3FreqModel.value(), m_eqControls.m_para3ResModel.value(), m_eqControls.m_para3GainModel.value() );
m_para3.processBuffer( m_upBuf , m_upBufFrames );
}
if( m_eqControls.m_para4ActiveModel.value() )
{
m_para4.setSampleRate( sampleRate );
m_para4.setFrequency( m_eqControls.m_para4FreqModel.value() );
m_para4.setQ( m_eqControls.m_para4ResModel.value() );
m_para4.setGain( m_eqControls.m_para4GainModel.value() );
m_para4.setParameters( sampleRate, m_eqControls.m_para4FreqModel.value(), m_eqControls.m_para4ResModel.value(), m_eqControls.m_para4GainModel.value() );
m_para4.processBuffer( m_upBuf , m_upBufFrames );
}
if( m_eqControls.m_highShelfActiveModel.value() )
{
m_highShelf.setSampleRate( sampleRate );
m_highShelf.setFrequency( m_eqControls.m_highShelfFreqModel.value() );
m_highShelf.setQ( m_eqControls.m_highShelfResModel.value() );
m_highShelf.setGain( m_eqControls.m_highShelfGainModel.value() );
m_highShelf.setParameters( sampleRate, m_eqControls.m_highShelfFreqModel.value(), m_eqControls.m_highShelfResModel.value(), m_eqControls.m_highShelfGainModel.value());
m_highShelf.processBuffer( m_upBuf , m_upBufFrames );
}
if(m_eqControls.m_lpActiveModel.value() ){
m_lp12.setSampleRate( sampleRate );
m_lp12.setFrequency( m_eqControls.m_lpFreqModel.value() );
m_lp12.setQ( m_eqControls.m_lpResModel.value() );
m_lp12.setParameters( sampleRate, m_eqControls.m_lpFreqModel.value(), m_eqControls.m_lpResModel.value(), 1 );
m_lp12.processBuffer( m_upBuf , m_upBufFrames );
if( m_eqControls.m_lp24Model.value() || m_eqControls.m_lp48Model.value() )
{
m_lp24.setSampleRate( sampleRate );
m_lp24.setFrequency( m_eqControls.m_lpFreqModel.value() );
m_lp24.setQ( m_eqControls.m_lpResModel.value() );
m_lp24.setParameters( sampleRate, m_eqControls.m_lpFreqModel.value(), m_eqControls.m_lpResModel.value(), 1 );
m_lp24.processBuffer( m_upBuf , m_upBufFrames );
}
if( m_eqControls.m_lp48Model.value() )
{
m_lp480.setSampleRate( sampleRate );
m_lp480.setFrequency( m_eqControls.m_lpFreqModel.value() );
m_lp480.setQ( m_eqControls.m_lpResModel.value() );
m_lp480.setParameters( sampleRate, m_eqControls.m_lpFreqModel.value(), m_eqControls.m_lpResModel.value(), 1 );
m_lp480.processBuffer( m_upBuf , m_upBufFrames );
m_lp481.setSampleRate( sampleRate );
m_lp481.setFrequency( m_eqControls.m_lpFreqModel.value() );
m_lp481.setQ( m_eqControls.m_lpResModel.value() );
m_lp481.setParameters( sampleRate, m_eqControls.m_lpFreqModel.value(), m_eqControls.m_lpResModel.value(), 1 );
m_lp481.processBuffer( m_upBuf , m_upBufFrames );
}
}
@@ -216,7 +183,7 @@ bool EqEffect::processAudioBuffer(sampleFrame *buf, const fpp_t frames)
sampleFrame outPeak = { 0, 0 };
gain( m_upBuf , m_upBufFrames, outGain, &outPeak );
m_eqControls.m_outPeakL = m_eqControls.m_outPeakL < outPeak[0] ? outPeak[0] : m_eqControls.m_outPeakL;
m_eqControls.m_outPeakR = m_eqControls.m_outPeakR < outPeak[1] ? outPeak[0] : m_eqControls.m_outPeakR;
m_eqControls.m_outPeakR = m_eqControls.m_outPeakR < outPeak[1] ? outPeak[1] : m_eqControls.m_outPeakR;
for( int i =0; i < m_dFilterCount; i++)
{
m_downsampleFilters[i].processBuffer(m_upBuf , m_upBufFrames );
@@ -230,12 +197,12 @@ bool EqEffect::processAudioBuffer(sampleFrame *buf, const fpp_t frames)
if(m_eqControls.m_analyzeModel.value() )
{
m_eqControls.m_outFftBands.analyze( buf, frames );
setBandPeaks( &m_eqControls.m_outFftBands , ( int )( sampleRate * 0.5 ) );
}
else
{
m_eqControls.m_outFftBands.clear();
}
setBandPeaks( &m_eqControls.m_outFftBands , ( int )( sampleRate * 0.5 ) );
m_eqControls.m_inProgress = false;
return isRunning();
}
@@ -243,67 +210,6 @@ bool EqEffect::processAudioBuffer(sampleFrame *buf, const fpp_t frames)
void EqEffect::gain( sampleFrame *buf, const fpp_t frames, float scale, sampleFrame* peak )
{
peak[0][0] = 0.0f; peak[0][1] = 0.0f;
for( fpp_t f = 0; f < frames; ++f )
{
buf[f][0] *= scale;
buf[f][1] *= scale;
if( fabs( buf[f][0] ) > peak[0][0] )
{
peak[0][0] = fabs( buf[f][0] );
}
if( fabs( buf[f][1] ) > peak[0][1] )
{
peak[0][1] = fabs( buf[f][0] );
}
}
}
sampleFrame m_lastUpFrame;
void EqEffect::upsample( sampleFrame *buf, const fpp_t frames )
{
if( m_upBufFrames != frames * 2 )
{
if( m_upBuf )
{
delete m_upBuf;
}
m_upBuf = new sampleFrame[frames * 2];
m_upBufFrames = frames * 2;
}
for( int f = 0, f2 = 0; f < frames; ++f, f2 += 2 )
{
m_upBuf[f2][0] = linearInterpolate( m_lastUpFrame[0],buf[f][0], 0.5 );
m_upBuf[f2][1] = linearInterpolate( m_lastUpFrame[1],buf[f][1], 0.5 );
m_upBuf[f2+1][0] = buf[f][0];
m_upBuf[f2+1][1] = buf[f][1];
m_lastUpFrame[0] = buf[f][0];
m_lastUpFrame[1] = buf[f][1];
}
}
void EqEffect::downSample( sampleFrame *buf, const fpp_t frames )
{
for( int f = 0, f2 = 0; f < frames; ++f, f2 += 2 )
{
buf[f][0] = m_upBuf[f2+1][0];
buf[f][1] = m_upBuf[f2+1][1];
}
}
float EqEffect::peakBand( float minF, float maxF, EqAnalyser *fft, int sr )
{
float peak = -60;

View File

@@ -43,7 +43,25 @@ public:
{
return &m_eqControls;
}
void gain( sampleFrame *buf, const fpp_t frames, float scale, sampleFrame* peak );
inline void gain( sampleFrame *buf, const fpp_t frames, float scale, sampleFrame* peak )
{
peak[0][0] = 0.0f; peak[0][1] = 0.0f;
for( fpp_t f = 0; f < frames; ++f )
{
buf[f][0] *= scale;
buf[f][1] *= scale;
if( fabs( buf[f][0] ) > peak[0][0] )
{
peak[0][0] = fabs( buf[f][0] );
}
if( fabs( buf[f][1] ) > peak[0][1] )
{
peak[0][1] = fabs( buf[f][0] );
}
}
}
private:
EqControls m_eqControls;
@@ -70,9 +88,46 @@ private:
int m_dFilterCount;
sampleFrame* m_upBuf;
fpp_t m_upBufFrames;
sampleFrame m_lastUpFrame;
inline void upsample( sampleFrame *buf, const fpp_t frames )
{
if( m_upBufFrames != frames * 2 )
{
if( m_upBuf )
{
delete m_upBuf;
}
m_upBuf = new sampleFrame[frames * 2];
m_upBufFrames = frames * 2;
}
for( int f = 0, f2 = 0; f < frames; ++f, f2 += 2 )
{
m_upBuf[f2][0] = linearInterpolate( m_lastUpFrame[0],buf[f][0], 0.5 );
m_upBuf[f2][1] = linearInterpolate( m_lastUpFrame[1],buf[f][1], 0.5 );
m_upBuf[f2+1][0] = buf[f][0];
m_upBuf[f2+1][1] = buf[f][1];
m_lastUpFrame[0] = buf[f][0];
m_lastUpFrame[1] = buf[f][1];
}
}
inline void downSample( sampleFrame *buf, const fpp_t frames )
{
for( int f = 0, f2 = 0; f < frames; ++f, f2 += 2 )
{
buf[f][0] = m_upBuf[f2+1][0];
buf[f][1] = m_upBuf[f2+1][1];
}
}
void upsample( sampleFrame *buf, const fpp_t frames );
void downSample( sampleFrame *buf, const fpp_t frames );
void analyze( sampleFrame *buf, const fpp_t frames, EqAnalyser* fft );
float peakBand(float minF, float maxF,EqAnalyser*, int);

View File

@@ -69,7 +69,7 @@ public:
virtual void setQ( float res )
virtual inline void setQ( float res )
{
if ( res != m_res )
{
@@ -81,7 +81,7 @@ public:
virtual void setGain( float gain )
virtual inline void setGain( float gain )
{
if ( gain != m_gain )
{
@@ -92,6 +92,35 @@ public:
virtual inline void setParameters( float sampleRate, float freq, float res, float gain )
{
bool hasChanged = false;
if( sampleRate != m_sampleRate )
{
m_sampleRate = sampleRate;
hasChanged = true;
}
if ( freq != m_freq )
{
m_freq = freq;
hasChanged = true;
}
if ( res != m_res )
{
m_res = res;
hasChanged = true;
}
if ( gain != m_gain )
{
m_gain = gain;
hasChanged = true;
}
if ( hasChanged ) { calcCoefficents(); }
}
///
/// \brief processBuffer
@@ -347,8 +376,8 @@ public:
if( sampleRate != m_sr )
{
m_sr = sampleRate;
setLowpass(m_freq);
setSampleRate( sampleRate );
setLowpass(m_freq);
}
}

View File

@@ -44,12 +44,14 @@ public:
float m_bands[MAX_BANDS];
float m_energy;
int m_sr;
bool m_active;
EqAnalyser() :
m_framesFilledUp ( 0 ),
m_energy ( 0 ),
m_sr ( 1 )
m_sr ( 1 ),
m_active ( true )
{
m_inProgress=false;
m_specBuf = (fftwf_complex *) fftwf_malloc( ( FFT_BUFFER_SIZE + 1 ) * sizeof( fftwf_complex ) );
@@ -83,42 +85,46 @@ public:
void analyze( sampleFrame *buf, const fpp_t frames )
{
m_inProgress=true;
const int FFT_BUFFER_SIZE = 2048;
fpp_t f = 0;
if( frames > FFT_BUFFER_SIZE )
if ( m_active )
{
m_inProgress=true;
const int FFT_BUFFER_SIZE = 2048;
fpp_t f = 0;
if( frames > FFT_BUFFER_SIZE )
{
m_framesFilledUp = 0;
f = frames - FFT_BUFFER_SIZE;
}
// meger channels
for( ; f < frames; ++f )
{
m_buffer[m_framesFilledUp] =
( buf[f][0] + buf[f][1] ) * 0.5;
++m_framesFilledUp;
}
if( m_framesFilledUp < FFT_BUFFER_SIZE )
{
m_inProgress = false;
return;
}
m_sr = Engine::mixer()->processingSampleRate();
const int LOWEST_FREQ = 0;
const int HIGHEST_FREQ = m_sr / 2;
fftwf_execute( m_fftPlan );
absspec( m_specBuf, m_absSpecBuf, FFT_BUFFER_SIZE+1 );
compressbands( m_absSpecBuf, m_bands, FFT_BUFFER_SIZE+1,
MAX_BANDS,
( int )( LOWEST_FREQ * ( FFT_BUFFER_SIZE + 1 ) / ( float )( m_sr / 2 ) ),
( int )( HIGHEST_FREQ * ( FFT_BUFFER_SIZE + 1) / ( float )( m_sr / 2 ) ) );
m_energy = maximum( m_bands, MAX_BANDS ) / maximum( m_buffer, FFT_BUFFER_SIZE );
m_framesFilledUp = 0;
f = frames - FFT_BUFFER_SIZE;
}
// meger channels
for( ; f < frames; ++f )
{
m_buffer[m_framesFilledUp] =
( buf[f][0] + buf[f][1] ) * 0.5;
++m_framesFilledUp;
}
if( m_framesFilledUp < FFT_BUFFER_SIZE )
{
m_inProgress = false;
return;
m_active = false;
}
m_sr = Engine::mixer()->processingSampleRate();
const int LOWEST_FREQ = 0;
const int HIGHEST_FREQ = m_sr / 2;
fftwf_execute( m_fftPlan );
absspec( m_specBuf, m_absSpecBuf, FFT_BUFFER_SIZE+1 );
compressbands( m_absSpecBuf, m_bands, FFT_BUFFER_SIZE+1,
MAX_BANDS,
( int )( LOWEST_FREQ * ( FFT_BUFFER_SIZE + 1 ) / ( float )( m_sr / 2 ) ),
( int )( HIGHEST_FREQ * ( FFT_BUFFER_SIZE + 1) / ( float )( m_sr / 2 ) ) );
m_energy = maximum( m_bands, MAX_BANDS ) / maximum( m_buffer, FFT_BUFFER_SIZE );
m_framesFilledUp = 0;
m_inProgress = false;
}
private:
bool m_inProgress;
@@ -160,6 +166,7 @@ public:
QPainterPath pp;
virtual void paintEvent( QPaintEvent* event )
{
m_sa->m_active = isVisible();
const int fh = height();
const int LOWER_Y = -60; // dB
QPainter p( this );