From 3dcae02d86f71b0d24594e6779e46b0e666016e7 Mon Sep 17 00:00:00 2001 From: Lost Robot Date: Tue, 3 Sep 2019 21:54:51 -0600 Subject: [PATCH] Upgrade the Flanger effect (#5873) Updates QuadratureLfo and moves to include/ Co-authored-by: Hyunjin Song Co-authored-by: Dave French --- {plugins/Flanger => include}/QuadratureLfo.h | 40 +++++++++++++------- plugins/Flanger/CMakeLists.txt | 6 ++- plugins/Flanger/FlangerControls.cpp | 15 +++++--- plugins/Flanger/FlangerControls.h | 3 +- plugins/Flanger/FlangerControlsDialog.cpp | 13 +++++-- plugins/Flanger/FlangerEffect.cpp | 1 + plugins/Flanger/QuadratureLfo.cpp | 38 ------------------- 7 files changed, 54 insertions(+), 62 deletions(-) rename {plugins/Flanger => include}/QuadratureLfo.h (75%) delete mode 100644 plugins/Flanger/QuadratureLfo.cpp diff --git a/plugins/Flanger/QuadratureLfo.h b/include/QuadratureLfo.h similarity index 75% rename from plugins/Flanger/QuadratureLfo.h rename to include/QuadratureLfo.h index e7e27d14a..b530937b0 100644 --- a/plugins/Flanger/QuadratureLfo.h +++ b/include/QuadratureLfo.h @@ -30,37 +30,33 @@ class QuadratureLfo { public: - QuadratureLfo( int sampleRate ); - ~QuadratureLfo() + QuadratureLfo( int sampleRate ) : + m_frequency(0), + m_phase(0), + m_offset(D_PI / 2) { + setSampleRate(sampleRate); } + ~QuadratureLfo() = default; + inline void setFrequency( double frequency ) { - if( frequency < 0 || frequency > ( m_samplerate / 2.0 ) || frequency == m_frequency ) + if( frequency < 0 || frequency > m_samplerate / 2.0 || frequency == m_frequency ) { return; } m_frequency = frequency; m_increment = m_frequency * m_twoPiOverSr; - - if( m_phase >= F_2PI ) - { - m_phase -= F_2PI; - } } - - inline void restart() { m_phase = 0; } - - inline void setSampleRate ( int samplerate ) { m_samplerate = samplerate; @@ -68,13 +64,31 @@ public: m_increment = m_frequency * m_twoPiOverSr; } - void tick( float *s, float *c ); + + inline void setOffset( double offsetVal ) + { + m_offset = offsetVal; + } + + + void tick( float *l, float *r ) + { + *l = sinf( m_phase ); + *r = sinf( m_phase + m_offset ); + m_phase += m_increment; + + while (m_phase >= D_2PI) + { + m_phase -= D_2PI; + } + } private: double m_frequency; double m_phase; double m_increment; double m_twoPiOverSr; + double m_offset; int m_samplerate; }; diff --git a/plugins/Flanger/CMakeLists.txt b/plugins/Flanger/CMakeLists.txt index 2d11c50c4..92a9198e5 100644 --- a/plugins/Flanger/CMakeLists.txt +++ b/plugins/Flanger/CMakeLists.txt @@ -1,3 +1,7 @@ INCLUDE(BuildPlugin) -BUILD_PLUGIN(flanger FlangerEffect.cpp FlangerControls.cpp FlangerControlsDialog.cpp Noise.cpp QuadratureLfo.cpp MonoDelay.cpp MOCFILES FlangerControls.h FlangerControlsDialog.h EMBEDDED_RESOURCES artwork.png logo.png) +BUILD_PLUGIN( + flanger FlangerEffect.cpp FlangerControls.cpp FlangerControlsDialog.cpp Noise.cpp MonoDelay.cpp + MOCFILES FlangerControls.h FlangerControlsDialog.h + EMBEDDED_RESOURCES artwork.png logo.png +) diff --git a/plugins/Flanger/FlangerControls.cpp b/plugins/Flanger/FlangerControls.cpp index 5d2b5e2b1..c5ac1ab86 100644 --- a/plugins/Flanger/FlangerControls.cpp +++ b/plugins/Flanger/FlangerControls.cpp @@ -34,12 +34,13 @@ FlangerControls::FlangerControls( FlangerEffect *effect ) : EffectControls ( effect ), m_effect ( effect ), - m_delayTimeModel(0.001, 0.0001, 0.050, 0.0001, this, tr( "Delay samples" ) ) , - m_lfoFrequencyModel( 0.25, 0.01, 60, 0.0001, 60000.0 ,this, tr( "LFO frequency" ) ), - m_lfoAmountModel( 0.0, 0.0, 0.0025 , 0.0001 , this , tr( "Seconds" ) ), - m_feedbackModel( 0.0 , 0.0 , 1.0 , 0.0001, this, tr( "Regen" ) ), - m_whiteNoiseAmountModel( 0.0 , 0.0 , 0.05 , 0.0001, this, tr( "Noise" ) ), - m_invertFeedbackModel ( false , this, tr( "Invert" ) ) + m_delayTimeModel(0.001, 0.0001, 0.050, 0.0001, this, tr( "Delay samples" ) ), + m_lfoFrequencyModel( 0.25, 0.01, 60, 0.0001, 60000.0, this, tr( "LFO frequency" ) ), + m_lfoAmountModel( 0.0, 0.0, 0.0025, 0.0001, this, tr( "Seconds" ) ), + m_lfoPhaseModel( 90.0, 0.0, 360.0, 0.0001, this, tr( "Stereo phase" ) ), + m_feedbackModel( 0.0, -1.0, 1.0, 0.0001, this, tr( "Regen" ) ), + m_whiteNoiseAmountModel( 0.0, 0.0, 0.05, 0.0001, this, tr( "Noise" ) ), + m_invertFeedbackModel ( false, this, tr( "Invert" ) ) { connect( Engine::mixer(), SIGNAL( sampleRateChanged() ), this, SLOT( changedSampleRate() ) ); @@ -54,6 +55,7 @@ void FlangerControls::loadSettings( const QDomElement &_this ) m_delayTimeModel.loadSettings( _this, "DelayTimeSamples" ); m_lfoFrequencyModel.loadSettings( _this, "LfoFrequency" ); m_lfoAmountModel.loadSettings( _this, "LfoAmount" ); + m_lfoPhaseModel.loadSettings( _this, "LfoPhase" ); m_feedbackModel.loadSettings( _this, "Feedback" ); m_whiteNoiseAmountModel.loadSettings( _this, "WhiteNoise" ); m_invertFeedbackModel.loadSettings( _this, "Invert" ); @@ -68,6 +70,7 @@ void FlangerControls::saveSettings( QDomDocument &doc, QDomElement &parent ) m_delayTimeModel.saveSettings( doc , parent, "DelayTimeSamples" ); m_lfoFrequencyModel.saveSettings( doc, parent , "LfoFrequency" ); m_lfoAmountModel.saveSettings( doc, parent , "LfoAmount" ); + m_lfoPhaseModel.saveSettings( doc, parent , "LfoPhase" ); m_feedbackModel.saveSettings( doc, parent, "Feedback" ) ; m_whiteNoiseAmountModel.saveSettings( doc, parent , "WhiteNoise" ) ; m_invertFeedbackModel.saveSettings( doc, parent, "Invert" ); diff --git a/plugins/Flanger/FlangerControls.h b/plugins/Flanger/FlangerControls.h index d51141ed0..8397a69fa 100644 --- a/plugins/Flanger/FlangerControls.h +++ b/plugins/Flanger/FlangerControls.h @@ -48,7 +48,7 @@ public: } virtual int controlCount() { - return 5; + return 7; } virtual EffectControlDialog* createView() { @@ -64,6 +64,7 @@ private: FloatModel m_delayTimeModel; TempoSyncKnobModel m_lfoFrequencyModel; FloatModel m_lfoAmountModel; + FloatModel m_lfoPhaseModel; FloatModel m_feedbackModel; FloatModel m_whiteNoiseAmountModel; BoolModel m_invertFeedbackModel; diff --git a/plugins/Flanger/FlangerControlsDialog.cpp b/plugins/Flanger/FlangerControlsDialog.cpp index 860efd9a9..8b7fdcf10 100644 --- a/plugins/Flanger/FlangerControlsDialog.cpp +++ b/plugins/Flanger/FlangerControlsDialog.cpp @@ -38,7 +38,7 @@ FlangerControlsDialog::FlangerControlsDialog( FlangerControls *controls ) : QPalette pal; pal.setBrush( backgroundRole(), PLUGIN_NAME::getIconPixmap( "artwork" ) ); setPalette( pal ); - setFixedSize( 195, 75 ); + setFixedSize( 233, 75 ); Knob* delayKnob = new Knob( knobBright_26, this ); delayKnob->move( 10,10 ); @@ -61,15 +61,22 @@ FlangerControlsDialog::FlangerControlsDialog( FlangerControls *controls ) : lfoAmtKnob->setLabel( tr( "AMNT" ) ); lfoAmtKnob->setHintText( tr( "Amount:" ) , "" ); + Knob * lfoPhaseKnob = new Knob( knobBright_26, this ); + lfoPhaseKnob->move( 123,10 ); + lfoPhaseKnob->setVolumeKnob( false ); + lfoPhaseKnob->setModel( &controls->m_lfoPhaseModel ); + lfoPhaseKnob->setLabel( tr( "PHASE" ) ); + lfoPhaseKnob->setHintText( tr( "Phase:" ) , " degrees" ); + Knob * feedbackKnob = new Knob( knobBright_26, this ); - feedbackKnob->move( 122,10 ); + feedbackKnob->move( 160,10 ); feedbackKnob->setVolumeKnob( true) ; feedbackKnob->setModel( &controls->m_feedbackModel ); feedbackKnob->setLabel( tr( "FDBK" ) ); feedbackKnob->setHintText( tr( "Feedback amount:" ) , "" ); Knob * whiteNoiseKnob = new Knob( knobBright_26, this ); - whiteNoiseKnob->move( 156,10 ); + whiteNoiseKnob->move( 196,10 ); whiteNoiseKnob->setVolumeKnob( true) ; whiteNoiseKnob->setModel( &controls->m_whiteNoiseAmountModel ); whiteNoiseKnob->setLabel( tr( "NOISE" ) ); diff --git a/plugins/Flanger/FlangerEffect.cpp b/plugins/Flanger/FlangerEffect.cpp index 65b58ce49..a8bd4d2c8 100644 --- a/plugins/Flanger/FlangerEffect.cpp +++ b/plugins/Flanger/FlangerEffect.cpp @@ -97,6 +97,7 @@ bool FlangerEffect::processAudioBuffer( sampleFrame *buf, const fpp_t frames ) float amplitude = m_flangerControls.m_lfoAmountModel.value() * Engine::mixer()->processingSampleRate(); bool invertFeedback = m_flangerControls.m_invertFeedbackModel.value(); m_lfo->setFrequency( 1.0/m_flangerControls.m_lfoFrequencyModel.value() ); + m_lfo->setOffset( m_flangerControls.m_lfoPhaseModel.value() / 180 * D_PI ); m_lDelay->setFeedback( m_flangerControls.m_feedbackModel.value() ); m_rDelay->setFeedback( m_flangerControls.m_feedbackModel.value() ); sample_t dryS[2]; diff --git a/plugins/Flanger/QuadratureLfo.cpp b/plugins/Flanger/QuadratureLfo.cpp deleted file mode 100644 index d3b70c560..000000000 --- a/plugins/Flanger/QuadratureLfo.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* - * quadraturelfo.cpp - defination of QuadratureLfo class. - * - * Copyright (c) 2014 David French - * - * This file is part of LMMS - https://lmms.io - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program (see COPYING); if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA. - * - */ - -#include "QuadratureLfo.h" - -QuadratureLfo::QuadratureLfo( int sampleRate ) -{ - setSampleRate(sampleRate); -} - -void QuadratureLfo::tick( float *s, float *c ) -{ - *s = sinf( m_phase ); - *c = cosf( m_phase ); - m_phase += m_increment; - -}