From 752797680487c19b3063086c6ba058c5f23d760d Mon Sep 17 00:00:00 2001 From: Dave French Date: Tue, 23 Dec 2014 21:57:20 +0000 Subject: [PATCH] EQ Fixes 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 --- plugins/Eq/EqControls.h | 2 + plugins/Eq/EqControlsDialog.cpp | 2 + plugins/Eq/EqEffect.cpp | 134 +++++--------------------------- plugins/Eq/EqEffect.h | 61 ++++++++++++++- plugins/Eq/EqFilter.h | 35 ++++++++- plugins/Eq/EqSpectrumView.h | 73 +++++++++-------- 6 files changed, 154 insertions(+), 153 deletions(-) diff --git a/plugins/Eq/EqControls.h b/plugins/Eq/EqControls.h index eec745b6f..ed3f6aab7 100644 --- a/plugins/Eq/EqControls.h +++ b/plugins/Eq/EqControls.h @@ -70,6 +70,8 @@ public: bool m_inProgress; + bool visable(); + diff --git a/plugins/Eq/EqControlsDialog.cpp b/plugins/Eq/EqControlsDialog.cpp index 950ed1272..bfcbde45e 100644 --- a/plugins/Eq/EqControlsDialog.cpp +++ b/plugins/Eq/EqControlsDialog.cpp @@ -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) diff --git a/plugins/Eq/EqEffect.cpp b/plugins/Eq/EqEffect.cpp index ee78f459d..b145fd1c9 100644 --- a/plugins/Eq/EqEffect.cpp +++ b/plugins/Eq/EqEffect.cpp @@ -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 ", 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; diff --git a/plugins/Eq/EqEffect.h b/plugins/Eq/EqEffect.h index 9a4cd9411..de6d2289d 100644 --- a/plugins/Eq/EqEffect.h +++ b/plugins/Eq/EqEffect.h @@ -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); diff --git a/plugins/Eq/EqFilter.h b/plugins/Eq/EqFilter.h index b703edc95..db5087739 100644 --- a/plugins/Eq/EqFilter.h +++ b/plugins/Eq/EqFilter.h @@ -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); } } diff --git a/plugins/Eq/EqSpectrumView.h b/plugins/Eq/EqSpectrumView.h index 71c64f5a4..306937399 100644 --- a/plugins/Eq/EqSpectrumView.h +++ b/plugins/Eq/EqSpectrumView.h @@ -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 );