diff --git a/include/BasicFilters.h b/include/BasicFilters.h index ba04b609c..901fba802 100644 --- a/include/BasicFilters.h +++ b/include/BasicFilters.h @@ -87,7 +87,7 @@ private: float m_a1, m_a2, m_b0, m_b1, m_b2; float m_z1 [CHANNELS], m_z2 [CHANNELS]; - friend class BasicFilters; + friend class BasicFilters; // needed for subfilter stuff in BasicFilters }; typedef BiQuad<2> StereoBiQuad; @@ -115,7 +115,7 @@ public: inline float update( float s, ch_cnt_t ch ) { - if( s < 1.0e-10f && m_z1[ch] < 1.0e-10f ) return 0.0f; + if( qAbs( s ) < 1.0e-10f && qAbs( m_z1[ch] ) < 1.0e-10f ) return 0.0f; return m_z1[ch] = s * m_a0 + m_z1[ch] * m_b1; } @@ -516,6 +516,7 @@ public: case Formantfilter: case FastFormant: { + if( qAbs( _in0 ) < 1.0e-10f && qAbs( m_vflast[0][_chnl] ) < 1.0e-10f ) { return 0.0f; } // performance hack - skip processing when the numbers get too small sample_t hp, bp, in; out = 0; diff --git a/plugins/MultitapEcho/MultitapEcho.cpp b/plugins/MultitapEcho/MultitapEcho.cpp index e3da02075..d6664a63a 100644 --- a/plugins/MultitapEcho/MultitapEcho.cpp +++ b/plugins/MultitapEcho/MultitapEcho.cpp @@ -48,6 +48,7 @@ Plugin::Descriptor PLUGIN_EXPORT multitapecho_plugin_descriptor = MultitapEchoEffect::MultitapEchoEffect( Model* parent, const Descriptor::SubPluginFeatures::Key* key ) : Effect( &multitapecho_plugin_descriptor, parent, key ), + m_stages( 1 ), m_controls( this ), m_buffer( 20100.0f ), m_sampleRate( Engine::mixer()->processingSampleRate() ), @@ -55,6 +56,7 @@ MultitapEchoEffect::MultitapEchoEffect( Model* parent, const Descriptor::SubPlug { m_work = MM_ALLOC( sampleFrame, Engine::mixer()->framesPerPeriod() ); m_buffer.reset(); + m_stages = static_cast( m_controls.m_stages.value() ); updateFilters( 0, 19 ); } @@ -69,7 +71,10 @@ void MultitapEchoEffect::updateFilters( int begin, int end ) { for( int i = begin; i <= end; ++i ) { - setFilterFreq( m_lpFreq[i] * m_sampleRatio, m_filter[i] ); + for( int s = 0; s < m_stages; ++s ) + { + setFilterFreq( m_lpFreq[i] * m_sampleRatio, m_filter[i][s] ); + } } } @@ -101,6 +106,13 @@ bool MultitapEchoEffect::processAudioBuffer( sampleFrame * buf, const fpp_t fram const float dryGain = dbvToAmp( m_controls.m_dryGain.value() ); const bool swapInputs = m_controls.m_swapInputs.value(); + // check if number of stages has changed + if( m_controls.m_stages.isValueChanged() ) + { + m_stages = static_cast( m_controls.m_stages.value() ); + updateFilters( 0, steps - 1 ); + } + // add dry buffer - never swap inputs for dry m_buffer.writeAddingMultiplied( buf, 0, frames, dryGain ); @@ -110,7 +122,10 @@ bool MultitapEchoEffect::processAudioBuffer( sampleFrame * buf, const fpp_t fram float offset = stepLength; for( int i = 0; i < steps; ++i ) // add all steps swapped { - runFilter( m_work, buf, m_filter[i], frames ); + for( int s = 0; s < m_stages; ++s ) + { + runFilter( m_work, buf, m_filter[i][s], frames ); + } m_buffer.writeSwappedAddingMultiplied( m_work, offset, frames, m_amp[i] ); offset += stepLength; } @@ -120,7 +135,10 @@ bool MultitapEchoEffect::processAudioBuffer( sampleFrame * buf, const fpp_t fram float offset = stepLength; for( int i = 0; i < steps; ++i ) // add all steps { - runFilter( m_work, buf, m_filter[i], frames ); + for( int s = 0; s < m_stages; ++s ) + { + runFilter( m_work, buf, m_filter[i][s], frames ); + } m_buffer.writeAddingMultiplied( m_work, offset, frames, m_amp[i] ); offset += stepLength; } diff --git a/plugins/MultitapEcho/MultitapEcho.h b/plugins/MultitapEcho/MultitapEcho.h index d1c4cdfaa..661fbfaed 100644 --- a/plugins/MultitapEcho/MultitapEcho.h +++ b/plugins/MultitapEcho/MultitapEcho.h @@ -55,13 +55,15 @@ private: f.setCoeffs( 1.0f - b1, b1 ); } + int m_stages; + MultitapEchoControls m_controls; - float m_amp [20]; - float m_lpFreq [20]; + float m_amp [32]; + float m_lpFreq [32]; RingBuffer m_buffer; - StereoOnePole m_filter [20]; + StereoOnePole m_filter [32][4]; float m_sampleRate; float m_sampleRatio; diff --git a/plugins/MultitapEcho/MultitapEchoControlDialog.cpp b/plugins/MultitapEcho/MultitapEchoControlDialog.cpp index df235f66e..7780bf94c 100644 --- a/plugins/MultitapEcho/MultitapEchoControlDialog.cpp +++ b/plugins/MultitapEcho/MultitapEchoControlDialog.cpp @@ -73,27 +73,32 @@ MultitapEchoControlDialog::MultitapEchoControlDialog( MultitapEchoControls * con // steps spinbox LcdSpinBox * steps = new LcdSpinBox( 2, this, "Steps" ); - steps->move( 20, 240 ); + steps->move( 20, 245 ); steps->setModel( & controls->m_steps ); // knobs TempoSyncKnob * stepLength = new TempoSyncKnob( knobBright_26, this ); - stepLength->move( 130, 240 ); + stepLength->move( 100, 245 ); stepLength->setModel( & controls->m_stepLength ); stepLength->setLabel( tr( "Length" ) ); - stepLength->setHintText( tr( "Step length:" ) + " ", "ms" ); + stepLength->setHintText( tr( "Step length:" ) + " ", " ms" ); Knob * dryGain = new Knob( knobBright_26, this ); - dryGain->move( 180, 240 ); + dryGain->move( 150, 245 ); dryGain->setModel( & controls->m_dryGain ); dryGain->setLabel( tr( "Dry" ) ); - dryGain->setHintText( tr( "Dry Gain:" ) + " ", "dBV" ); - + dryGain->setHintText( tr( "Dry Gain:" ) + " ", " dBV" ); + + Knob * stages = new Knob( knobBright_26, this ); + stages->move( 200, 245 ); + stages->setModel( & controls->m_stages ); + stages->setLabel( tr( "Stages" ) ); + stages->setHintText( tr( "Lowpass stages:" ) + " ", "x" ); // switch led LedCheckBox * swapInputs = new LedCheckBox( "Swap inputs", this, tr( "Swap inputs" ), LedCheckBox::Green ); - swapInputs->move( 20, 270 ); + swapInputs->move( 20, 275 ); swapInputs->setModel( & controls->m_swapInputs ); ToolTip::add( swapInputs, tr( "Swap left and right input channel for reflections" ) ); } diff --git a/plugins/MultitapEcho/MultitapEchoControls.cpp b/plugins/MultitapEcho/MultitapEchoControls.cpp index d83fd9ec4..70ad2cad0 100644 --- a/plugins/MultitapEcho/MultitapEchoControls.cpp +++ b/plugins/MultitapEcho/MultitapEchoControls.cpp @@ -34,13 +34,15 @@ MultitapEchoControls::MultitapEchoControls( MultitapEchoEffect * eff ) : EffectControls( eff ), m_effect( eff ), - m_steps( 16, 4, 20, this, "Steps" ), + m_steps( 16, 4, 32, this, "Steps" ), m_stepLength( 100.0f, 1.0f, 1000.0f, 0.1f, 1000.0f, this, "Step length" ), m_dryGain( 0.0f, -80.0f, 20.0f, 0.1f, this, "Dry gain" ), m_swapInputs( false, this, "Swap inputs" ), + m_stages( 1.0f, 1.0f, 4.0f, 1.0f, this, "Lowpass stages" ), m_ampGraph( -60.0f, 0.0f, 16, this ), m_lpGraph( 0.0f, 3.0f, 16, this ) { + m_stages.setStrictStepSize( true ); connect( &m_ampGraph, SIGNAL( samplesChanged( int, int ) ), this, SLOT( ampSamplesChanged( int, int ) ) ); connect( &m_lpGraph, SIGNAL( samplesChanged( int, int ) ), this, SLOT( lpSamplesChanged( int, int ) ) ); @@ -63,6 +65,7 @@ void MultitapEchoControls::saveSettings( QDomDocument & doc, QDomElement & paren m_stepLength.saveSettings( doc, parent, "steplength" ); m_dryGain.saveSettings( doc, parent, "drygain" ); m_swapInputs.saveSettings( doc, parent, "swapinputs" ); + m_stages.saveSettings( doc, parent, "stages" ); QString ampString; base64::encode( (const char *) m_ampGraph.samples(), m_ampGraph.length() * sizeof(float), ampString ); @@ -80,6 +83,7 @@ void MultitapEchoControls::loadSettings( const QDomElement & elem ) m_stepLength.loadSettings( elem, "steplength" ); m_dryGain.loadSettings( elem, "drygain" ); m_swapInputs.loadSettings( elem, "swapinputs" ); + m_stages.loadSettings( elem, "stages" ); int size = 0; char * dst = 0; diff --git a/plugins/MultitapEcho/MultitapEchoControls.h b/plugins/MultitapEcho/MultitapEchoControls.h index 645e66ac4..a4f78dd31 100644 --- a/plugins/MultitapEcho/MultitapEchoControls.h +++ b/plugins/MultitapEcho/MultitapEchoControls.h @@ -53,7 +53,7 @@ public: virtual int controlCount() { - return( 4 ); + return( 5 ); } virtual EffectControlDialog * createView() @@ -78,6 +78,7 @@ private: FloatModel m_dryGain; BoolModel m_swapInputs; + FloatModel m_stages; graphModel m_ampGraph; graphModel m_lpGraph; diff --git a/plugins/MultitapEcho/artwork.png b/plugins/MultitapEcho/artwork.png index e81d195ae..af74d65bf 100644 Binary files a/plugins/MultitapEcho/artwork.png and b/plugins/MultitapEcho/artwork.png differ diff --git a/plugins/MultitapEcho/graph_bg.png b/plugins/MultitapEcho/graph_bg.png index a336ac8f6..fee722640 100644 Binary files a/plugins/MultitapEcho/graph_bg.png and b/plugins/MultitapEcho/graph_bg.png differ