mirror of
https://github.com/LMMS/lmms.git
synced 2026-05-24 14:47:15 -04:00
Multitap, filters, updates
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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" ) );
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 10 KiB |
Reference in New Issue
Block a user