Multitap, filters, updates

This commit is contained in:
Vesa
2014-11-30 17:06:43 +02:00
parent 2a78769078
commit a9d0ba11d6
8 changed files with 48 additions and 17 deletions

View File

@@ -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<CHANNELS>;
friend class BasicFilters<CHANNELS>; // 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;

View File

@@ -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<int>( 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<int>( 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;
}

View File

@@ -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;

View File

@@ -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" ) );
}

View File

@@ -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;

View File

@@ -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;

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 66 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 10 KiB