Merge branch 'master' into ed_refac
Conflicts: include/AutomationEditor.h include/SongEditor.h plugins/delay/delaycontrols.cpp plugins/delay/delaycontrolsdialog.cpp src/gui/editors/AutomationEditor.cpp src/gui/editors/BBEditor.cpp src/gui/editors/PianoRoll.cpp
This commit is contained in:
@@ -83,7 +83,8 @@ bool AmplifierEffect::processAudioBuffer( sampleFrame* buf, const fpp_t frames )
|
||||
for( fpp_t f = 0; f < frames; ++f )
|
||||
{
|
||||
// qDebug( "offset %d, value %f", f, m_ampControls.m_volumeModel.value( f ) );
|
||||
|
||||
outSum += buf[f][0]*buf[f][0] + buf[f][1]*buf[f][1];
|
||||
|
||||
sample_t s[2] = { buf[f][0], buf[f][1] };
|
||||
|
||||
// vol knob
|
||||
@@ -122,7 +123,6 @@ bool AmplifierEffect::processAudioBuffer( sampleFrame* buf, const fpp_t frames )
|
||||
|
||||
buf[f][0] = d * buf[f][0] + w * s[0];
|
||||
buf[f][1] = d * buf[f][1] + w * s[1];
|
||||
outSum += buf[f][0]*buf[f][0] + buf[f][1]*buf[f][1];
|
||||
}
|
||||
|
||||
checkGate( outSum / frames );
|
||||
|
||||
@@ -88,13 +88,13 @@ bool BassBoosterEffect::processAudioBuffer( sampleFrame* buf, const fpp_t frames
|
||||
const float w = wetLevel();
|
||||
for( fpp_t f = 0; f < frames; ++f )
|
||||
{
|
||||
outSum += buf[f][0]*buf[f][0] + buf[f][1]*buf[f][1];
|
||||
|
||||
sample_t s[2] = { buf[f][0], buf[f][1] };
|
||||
m_bbFX.nextSample( s[0], s[1] );
|
||||
|
||||
buf[f][0] = d * buf[f][0] + w * s[0];
|
||||
buf[f][1] = d * buf[f][1] + w * s[1];
|
||||
|
||||
outSum += buf[f][0]*buf[f][0] + buf[f][1]*buf[f][1];
|
||||
}
|
||||
|
||||
checkGate( outSum / frames );
|
||||
|
||||
@@ -10,7 +10,8 @@ ADD_SUBDIRECTORY(CrossoverEQ)
|
||||
ADD_SUBDIRECTORY(delay)
|
||||
ADD_SUBDIRECTORY(DualFilter)
|
||||
ADD_SUBDIRECTORY(dynamics_processor)
|
||||
ADD_SUBDIRECTORY(flanger)
|
||||
ADD_SUBDIRECTORY(Eq)
|
||||
ADD_SUBDIRECTORY(Flanger)
|
||||
ADD_SUBDIRECTORY(flp_import)
|
||||
ADD_SUBDIRECTORY(HydrogenImport)
|
||||
ADD_SUBDIRECTORY(kicker)
|
||||
|
||||
@@ -196,9 +196,9 @@ bool CrossoverEQEffect::processAudioBuffer( sampleFrame* buf, const fpp_t frames
|
||||
double outSum = 0.0;
|
||||
for( int f = 0; f < frames; ++f )
|
||||
{
|
||||
outSum = buf[f][0] * buf[f][0] + buf[f][1] * buf[f][1];
|
||||
buf[f][0] = d * buf[f][0] + w * m_work[f][0];
|
||||
buf[f][1] = d * buf[f][1] + w * m_work[f][1];
|
||||
outSum = buf[f][0] * buf[f][0] + buf[f][1] * buf[f][1];
|
||||
}
|
||||
|
||||
checkGate( outSum );
|
||||
|
||||
@@ -155,11 +155,11 @@ bool DualFilterEffect::processAudioBuffer( sampleFrame* buf, const fpp_t frames
|
||||
s[0] += ( s2[0] * mix2 );
|
||||
s[1] += ( s2[1] * mix2 );
|
||||
}
|
||||
outSum += buf[f][0]*buf[f][0] + buf[f][1]*buf[f][1];
|
||||
|
||||
// do another mix with dry signal
|
||||
buf[f][0] = d * buf[f][0] + w * s[0];
|
||||
buf[f][1] = d * buf[f][1] + w * s[1];
|
||||
outSum += buf[f][0]*buf[f][0] + buf[f][1]*buf[f][1];
|
||||
}
|
||||
|
||||
checkGate( outSum / frames );
|
||||
|
||||
6
plugins/Eq/CMakeLists.txt
Normal file
6
plugins/Eq/CMakeLists.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
INCLUDE(BuildPlugin)
|
||||
INCLUDE_DIRECTORIES(${FFTW3F_INCLUDE_DIRS})
|
||||
LINK_DIRECTORIES(${FFTW3F_LIBRARY_DIRS})
|
||||
LINK_LIBRARIES(${FFTW3F_LIBRARIES})
|
||||
BUILD_PLUGIN(eq EqEffect.cpp EqControls.cpp EqControlsDialog.cpp EqFilter.h EqParameterWidget.cpp EqFader.h EqSpectrumView.h DBvModel.cpp DBvModel.h
|
||||
MOCFILES EqControls.h EqParameterWidget.h EqFader.h DBvModel.h EMBEDDED_RESOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.png")
|
||||
14
plugins/Eq/DBvModel.cpp
Normal file
14
plugins/Eq/DBvModel.cpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#include "DBvModel.h"
|
||||
|
||||
DBvModel::DBvModel(float val, float min, float max, float step,
|
||||
Model *parent, const QString &displayName,
|
||||
bool defaultConstructed) :
|
||||
FloatModel( val, min, max, step, parent, displayName, defaultConstructed )
|
||||
{
|
||||
connect(this, SIGNAL( dataChanged() ), this,SLOT( calcAmp() ) );
|
||||
}
|
||||
|
||||
void DBvModel::calcAmp()
|
||||
{
|
||||
m_amp = dbvToAmp( value() );
|
||||
}
|
||||
31
plugins/Eq/DBvModel.h
Normal file
31
plugins/Eq/DBvModel.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#ifndef DBVMODEL
|
||||
#define DBVMODEL
|
||||
|
||||
#include "AutomatableModel.h"
|
||||
|
||||
|
||||
class DBvModel : public FloatModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
DBvModel( float val = 0, float min = 0, float max = 0, float step = 0,
|
||||
Model * parent = NULL,
|
||||
const QString& displayName = QString(),
|
||||
bool defaultConstructed = false );
|
||||
inline float getAmp() const
|
||||
{
|
||||
return m_amp;
|
||||
}
|
||||
|
||||
private slots:
|
||||
void calcAmp();
|
||||
|
||||
private:
|
||||
float m_amp;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // DBVMODEL
|
||||
|
||||
196
plugins/Eq/EqControls.cpp
Normal file
196
plugins/Eq/EqControls.cpp
Normal file
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* eqcontrols.cpp - defination of EqControls class.
|
||||
*
|
||||
* Copyright (c) 2014 David French <dave/dot/french3/at/googlemail/dot/com>
|
||||
*
|
||||
* This file is part of LMMS - http://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 <QtXml/QDomElement>
|
||||
#include "EqControls.h"
|
||||
#include "EqEffect.h"
|
||||
|
||||
|
||||
|
||||
|
||||
EqControls::EqControls( EqEffect *effect ) :
|
||||
EffectControls( effect ),
|
||||
m_effect( effect ),
|
||||
m_inGainModel( 0.0, -60.0, 20.0, 0.01, this, tr( "Input gain") ),
|
||||
m_outGainModel( -.0, -60.0, 20.0, 0.01, this, tr( "Output gain" ) ),
|
||||
m_lowShelfGainModel( 0.0 , -40, 40, 0.001, this, tr( "Low shelf gain" ) ),
|
||||
m_para1GainModel( 0.0 , -40, 40, 0.001, this, tr( "Peak 1 gain" ) ),
|
||||
m_para2GainModel( 0.0 , -40, 40, 0.001, this, tr( "Peak 2 gain" ) ),
|
||||
m_para3GainModel( 0.0 , -40, 40, 0.001, this, tr( "Peak 3 gain" ) ),
|
||||
m_para4GainModel( 0.0 , -40, 40, 0.001, this, tr( "Peak 4 gain" ) ),
|
||||
m_highShelfGainModel( 0.0 , -40, 40, 0.001, this, tr( "High Shelf gain" ) ),
|
||||
m_hpResModel( 0.707,0.003, 10.0 , 0.001, this, tr( "HP res" ) ),
|
||||
m_lowShelfResModel( 1.4,0.55, 10.0 , 0.001, this , tr( "Low Shelf res" ) ),
|
||||
m_para1BwModel( 0.3, 0.1, 4 , 0.001, this , tr( "Peak 1 BW" ) ),
|
||||
m_para2BwModel( 0.3, 0.1, 4 , 0.001, this , tr( "Peak 2 BW" ) ),
|
||||
m_para3BwModel( 0.3, 0.1, 4 , 0.001, this , tr( "Peak 3 BW" ) ),
|
||||
m_para4BwModel( 0.3, 0.1, 4 , 0.001, this , tr( "Peak 4 BW" ) ),
|
||||
m_highShelfResModel( 1.4, 0.55, 10.0 , 0.001, this , tr( "High Shelf res" ) ),
|
||||
m_lpResModel( 0.707,0.003, 10.0 , 0.001, this , tr( "LP res" ) ),
|
||||
m_hpFeqModel( 31.0, 30.0, 20000, 0.001, this , tr( "HP freq" ) ),
|
||||
m_lowShelfFreqModel( 80.0, 25.0, 20000, 0.001, this , tr( "Low Shelf freq" ) ),
|
||||
m_para1FreqModel( 120.0, 27.0, 20000, 0.001, this , tr( "Peak 1 freq" ) ),
|
||||
m_para2FreqModel( 250.0, 27.0, 20000, 0.001, this, tr( "Peak 2 freq" ) ),
|
||||
m_para3FreqModel( 2000.0, 27.0, 20000, 0.001, this , tr( "Peak 3 freq" ) ),
|
||||
m_para4FreqModel( 4000.0, 27.0, 20000, 0.001, this , tr( "Peak 4 freq" ) ),
|
||||
m_highShelfFreqModel( 12000.0, 27.0, 20000, 0.001, this , tr( "High shelf freq" ) ),
|
||||
m_lpFreqModel( 18000.0, 27.0, 20000, 0.001, this , tr( "LP freq" ) ),
|
||||
m_hpActiveModel( false, this , tr( "HP active" ) ),
|
||||
m_lowShelfActiveModel( false, this , tr( "Low shelf active" ) ),
|
||||
m_para1ActiveModel(false, this , tr( "Peak 1 active" ) ),
|
||||
m_para2ActiveModel( false, this , tr( "Peak 2 active" ) ),
|
||||
m_para3ActiveModel( false, this , tr( "Peak 3 active" ) ),
|
||||
m_para4ActiveModel( false, this , tr( "Peak 4 active" ) ),
|
||||
m_highShelfActiveModel( false, this , tr( "High shelf active" ) ),
|
||||
m_lpActiveModel( false, this , tr( "LP active" ) ),
|
||||
m_lp12Model( false, this , tr( "LP 12" ) ),
|
||||
m_lp24Model( false, this , tr( "LP 24" ) ),
|
||||
m_lp48Model( false, this , tr( "LP 48" ) ),
|
||||
m_hp12Model( false, this , tr( "HP 12" ) ),
|
||||
m_hp24Model( false, this , tr( "HP 24" ) ),
|
||||
m_hp48Model( false, this , tr( "HP 48" ) ),
|
||||
m_lpTypeModel( 0,0,2,this, tr( "low pass type") ) ,
|
||||
m_hpTypeModel( 0,0,2,this, tr( "high pass type") )
|
||||
{
|
||||
m_hpFeqModel.setScaleLogarithmic( true );
|
||||
m_lowShelfFreqModel.setScaleLogarithmic( true );
|
||||
m_para1FreqModel.setScaleLogarithmic( true );
|
||||
m_para2FreqModel.setScaleLogarithmic( true );
|
||||
m_para3FreqModel.setScaleLogarithmic( true );
|
||||
m_para4FreqModel.setScaleLogarithmic( true );
|
||||
m_highShelfFreqModel.setScaleLogarithmic( true );
|
||||
m_lpFreqModel.setScaleLogarithmic( true );
|
||||
m_para1GainModel.setScaleLogarithmic( true );
|
||||
m_inPeakL = 0;
|
||||
m_inPeakR = 0;
|
||||
m_outPeakL = 0;
|
||||
m_outPeakR = 0;
|
||||
m_lowShelfPeakL = 0; m_lowShelfPeakR = 0;
|
||||
m_para1PeakL = 0; m_para1PeakR = 0;
|
||||
m_para2PeakL = 0; m_para2PeakR = 0;
|
||||
m_para3PeakL = 0; m_para3PeakR = 0;
|
||||
m_para4PeakL = 0; m_para4PeakR = 0;
|
||||
m_highShelfPeakL = 0; m_highShelfPeakR = 0;
|
||||
m_inProgress = false;
|
||||
m_analyseIn = true;
|
||||
m_analyseOut = true;
|
||||
|
||||
m_inGainModel.setScaleLogarithmic( true );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void EqControls::loadSettings( const QDomElement &_this )
|
||||
{
|
||||
m_inGainModel.loadSettings( _this, "Inputgain" );
|
||||
m_outGainModel.loadSettings( _this, "Outputgain");
|
||||
m_lowShelfGainModel.loadSettings( _this , "Lowshelfgain" );
|
||||
m_para1GainModel.loadSettings( _this, "Peak1gain" );
|
||||
m_para2GainModel.loadSettings( _this, "Peak2gain" );
|
||||
m_para3GainModel.loadSettings( _this, "Peak3gain" );
|
||||
m_para4GainModel.loadSettings( _this, "Peak4gain" );
|
||||
m_highShelfGainModel.loadSettings( _this , "HighShelfgain");
|
||||
m_hpResModel.loadSettings( _this ,"HPres");
|
||||
m_lowShelfResModel.loadSettings( _this, "LowShelfres" );
|
||||
m_para1BwModel.loadSettings( _this ,"Peak1bw" );
|
||||
m_para2BwModel.loadSettings( _this ,"Peak2bw" );
|
||||
m_para3BwModel.loadSettings( _this ,"Peak3bw" );
|
||||
m_para4BwModel.loadSettings( _this ,"Peak4bw" );
|
||||
m_highShelfResModel.loadSettings( _this, "HighShelfres" );
|
||||
m_lpResModel.loadSettings( _this, "LPres");
|
||||
m_hpFeqModel.loadSettings( _this, "HPfreq" );
|
||||
m_lowShelfFreqModel.loadSettings( _this, "LowShelffreq" );
|
||||
m_para1FreqModel.loadSettings( _this, "Peak1freq" );
|
||||
m_para2FreqModel.loadSettings( _this, "Peak2freq" );
|
||||
m_para3FreqModel.loadSettings( _this, "Peak3freq" );
|
||||
m_para4FreqModel.loadSettings( _this, "Peak4freq" );
|
||||
m_highShelfFreqModel.loadSettings( _this, "Highshelffreq" );
|
||||
m_lpFreqModel.loadSettings( _this, "LPfreq" );
|
||||
m_hpActiveModel.loadSettings( _this, "HPactive" );
|
||||
m_lowShelfActiveModel.loadSettings( _this, "Lowshelfactive" );
|
||||
m_para1ActiveModel.loadSettings( _this, "Peak1active");
|
||||
m_para2ActiveModel.loadSettings( _this, "Peak2active");
|
||||
m_para3ActiveModel.loadSettings( _this, "Peak3active");
|
||||
m_para4ActiveModel.loadSettings( _this, "Peak4active");
|
||||
m_highShelfActiveModel.loadSettings( _this, "Highshelfactive" );
|
||||
m_lpActiveModel.loadSettings( _this, "LPactive" );
|
||||
m_lp12Model.loadSettings( _this , "LP12" );
|
||||
m_lp24Model.loadSettings( _this , "LP24" );
|
||||
m_lp48Model.loadSettings( _this , "LP48" );
|
||||
m_hp12Model.loadSettings( _this , "HP12" );
|
||||
m_hp24Model.loadSettings( _this , "HP24" );
|
||||
m_hp48Model.loadSettings( _this , "HP48" );
|
||||
m_lpTypeModel.loadSettings( _this, "LP" );
|
||||
m_hpTypeModel.loadSettings( _this, "HP" );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void EqControls::saveSettings( QDomDocument &doc, QDomElement &parent )
|
||||
{
|
||||
|
||||
m_inGainModel.saveSettings( doc, parent, "Inputgain" );
|
||||
m_outGainModel.saveSettings( doc, parent, "Outputgain");
|
||||
m_lowShelfGainModel.saveSettings( doc, parent , "Lowshelfgain" );
|
||||
m_para1GainModel.saveSettings( doc, parent, "Peak1gain" );
|
||||
m_para2GainModel.saveSettings( doc, parent, "Peak2gain" );
|
||||
m_para3GainModel.saveSettings( doc, parent, "Peak3gain" );
|
||||
m_para4GainModel.saveSettings( doc, parent, "Peak4gain" );
|
||||
m_highShelfGainModel.saveSettings( doc, parent, "HighShelfgain");
|
||||
m_hpResModel.saveSettings( doc, parent ,"HPres");
|
||||
m_lowShelfResModel.saveSettings( doc, parent, "LowShelfres" );
|
||||
m_para1BwModel.saveSettings( doc, parent,"Peak1bw" );
|
||||
m_para2BwModel.saveSettings( doc, parent,"Peak2bw" );
|
||||
m_para3BwModel.saveSettings( doc, parent,"Peak3bw" );
|
||||
m_para4BwModel.saveSettings( doc, parent,"Peak4bw" );
|
||||
m_highShelfResModel.saveSettings( doc, parent, "HighShelfres" );
|
||||
m_lpResModel.saveSettings( doc, parent, "LPres");
|
||||
m_hpFeqModel.saveSettings( doc, parent, "HPfreq" );
|
||||
m_lowShelfFreqModel.saveSettings( doc, parent, "LowShelffreq" );
|
||||
m_para1FreqModel.saveSettings( doc, parent, "Peak1freq" );
|
||||
m_para2FreqModel.saveSettings( doc, parent, "Peak2freq" );
|
||||
m_para3FreqModel.saveSettings( doc, parent, "Peak3freq" );
|
||||
m_para4FreqModel.saveSettings( doc, parent, "Peak4freq" );
|
||||
m_highShelfFreqModel.saveSettings( doc, parent, "Highshelffreq" );
|
||||
m_lpFreqModel.saveSettings( doc, parent, "LPfreq" );
|
||||
m_hpActiveModel.saveSettings( doc, parent, "HPactive" );
|
||||
m_lowShelfActiveModel.saveSettings( doc, parent, "Lowshelfactive" );
|
||||
m_para1ActiveModel.saveSettings( doc, parent, "Peak1active" );
|
||||
m_para2ActiveModel.saveSettings( doc, parent, "Peak2active" );
|
||||
m_para3ActiveModel.saveSettings( doc, parent, "Peak3active" );
|
||||
m_para4ActiveModel.saveSettings( doc, parent, "Peak4active" );
|
||||
m_highShelfActiveModel.saveSettings( doc, parent, "Highshelfactive" );
|
||||
m_lpActiveModel.saveSettings( doc, parent, "LPactive" );
|
||||
m_lp12Model.saveSettings( doc, parent, "LP12" );
|
||||
m_lp24Model.saveSettings( doc, parent, "LP24" );
|
||||
m_lp48Model.saveSettings( doc, parent, "LP48" );
|
||||
m_hp12Model.saveSettings( doc, parent, "HP12" );
|
||||
m_hp24Model.saveSettings( doc, parent, "HP24" );
|
||||
m_hp48Model.saveSettings( doc, parent, "HP48" );
|
||||
m_lpTypeModel.saveSettings( doc, parent, "LP" );
|
||||
m_hpTypeModel.saveSettings( doc, parent, "HP" );
|
||||
}
|
||||
|
||||
138
plugins/Eq/EqControls.h
Normal file
138
plugins/Eq/EqControls.h
Normal file
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* eqcontrols.h - defination of EqControls class.
|
||||
*
|
||||
* Copyright (c) 2014 David French <dave/dot/french3/at/googlemail/dot/com>
|
||||
*
|
||||
* This file is part of LMMS - http://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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef EQCONTROLS_H
|
||||
#define EQCONTROLS_H
|
||||
|
||||
#include "EffectControls.h"
|
||||
#include "EqControlsDialog.h"
|
||||
#include "Knob.h"
|
||||
#include "DBvModel.h"
|
||||
|
||||
class EqEffect;
|
||||
|
||||
|
||||
class EqControls : public EffectControls
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit EqControls( EqEffect* effect );
|
||||
virtual ~EqControls()
|
||||
{
|
||||
}
|
||||
virtual void saveSettings ( QDomDocument& doc, QDomElement& parent );
|
||||
virtual void loadSettings ( const QDomElement &_this );
|
||||
inline virtual QString nodeName() const
|
||||
{
|
||||
return "Eq";
|
||||
}
|
||||
virtual int controlCount()
|
||||
{
|
||||
return 39;
|
||||
}
|
||||
virtual EffectControlDialog* createView()
|
||||
{
|
||||
return new EqControlsDialog( this );
|
||||
}
|
||||
|
||||
float m_inPeakL;
|
||||
float m_inPeakR;
|
||||
float m_outPeakL;
|
||||
float m_outPeakR;
|
||||
float m_lowShelfPeakL, m_lowShelfPeakR;
|
||||
float m_para1PeakL, m_para1PeakR;
|
||||
float m_para2PeakL, m_para2PeakR;
|
||||
float m_para3PeakL, m_para3PeakR;
|
||||
float m_para4PeakL, m_para4PeakR;
|
||||
float m_highShelfPeakL, m_highShelfPeakR;
|
||||
bool m_analyseIn;
|
||||
bool m_analyseOut;
|
||||
|
||||
EqAnalyser m_inFftBands;
|
||||
EqAnalyser m_outFftBands;
|
||||
|
||||
bool m_inProgress;
|
||||
|
||||
bool visable();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private:
|
||||
EqEffect* m_effect;
|
||||
|
||||
DBvModel m_inGainModel;
|
||||
DBvModel m_outGainModel;
|
||||
FloatModel m_lowShelfGainModel;
|
||||
FloatModel m_para1GainModel;
|
||||
FloatModel m_para2GainModel;
|
||||
FloatModel m_para3GainModel;
|
||||
FloatModel m_para4GainModel;
|
||||
FloatModel m_highShelfGainModel;
|
||||
|
||||
FloatModel m_hpResModel;
|
||||
FloatModel m_lowShelfResModel;
|
||||
FloatModel m_para1BwModel;
|
||||
FloatModel m_para2BwModel;
|
||||
FloatModel m_para3BwModel;
|
||||
FloatModel m_para4BwModel;
|
||||
FloatModel m_highShelfResModel;
|
||||
FloatModel m_lpResModel;
|
||||
|
||||
FloatModel m_hpFeqModel;
|
||||
FloatModel m_lowShelfFreqModel;
|
||||
FloatModel m_para1FreqModel;
|
||||
FloatModel m_para2FreqModel;
|
||||
FloatModel m_para3FreqModel;
|
||||
FloatModel m_para4FreqModel;
|
||||
FloatModel m_highShelfFreqModel;
|
||||
FloatModel m_lpFreqModel;
|
||||
|
||||
BoolModel m_hpActiveModel;
|
||||
BoolModel m_lowShelfActiveModel;
|
||||
BoolModel m_para1ActiveModel;
|
||||
BoolModel m_para2ActiveModel;
|
||||
BoolModel m_para3ActiveModel;
|
||||
BoolModel m_para4ActiveModel;
|
||||
BoolModel m_highShelfActiveModel;
|
||||
BoolModel m_lpActiveModel;
|
||||
|
||||
BoolModel m_lp12Model;
|
||||
BoolModel m_lp24Model;
|
||||
BoolModel m_lp48Model;
|
||||
|
||||
BoolModel m_hp12Model;
|
||||
BoolModel m_hp24Model;
|
||||
BoolModel m_hp48Model;
|
||||
|
||||
IntModel m_lpTypeModel;
|
||||
IntModel m_hpTypeModel;
|
||||
|
||||
friend class EqControlsDialog;
|
||||
friend class EqEffect;
|
||||
|
||||
};
|
||||
|
||||
#endif // EQCONTROLS_H
|
||||
172
plugins/Eq/EqControlsDialog.cpp
Normal file
172
plugins/Eq/EqControlsDialog.cpp
Normal file
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* eqcontrolsdialog.cpp - defination of EqControlsDialog class.
|
||||
*
|
||||
* Copyright (c) 2014 David French <dave/dot/french3/at/googlemail/dot/com>
|
||||
*
|
||||
* This file is part of LMMS - http://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 "EqControlsDialog.h"
|
||||
#include "EqControls.h"
|
||||
#include "embed.h"
|
||||
#include "Fader.h"
|
||||
#include "EqFader.h"
|
||||
#include "Engine.h"
|
||||
#include "AutomatableButton.h"
|
||||
#include "QWidget"
|
||||
#include "MainWindow.h"
|
||||
#include "LedCheckbox.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
EqControlsDialog::EqControlsDialog( EqControls *controls ) :
|
||||
EffectControlDialog( controls )
|
||||
|
||||
{
|
||||
m_controls = controls;
|
||||
setAutoFillBackground( true );
|
||||
QPalette pal;
|
||||
pal.setBrush( backgroundRole(), PLUGIN_NAME::getIconPixmap( "artwork" ) );
|
||||
setPalette( pal );
|
||||
setFixedSize( 350, 275 );
|
||||
m_inSpec = new EqSpectrumView( &controls->m_inFftBands, this);
|
||||
m_inSpec->move( 51, 2 );
|
||||
m_inSpec->color = QColor( 238, 154, 120, 80 );
|
||||
m_outSpec = new EqSpectrumView( &controls->m_outFftBands, this);
|
||||
m_outSpec->move( 51, 2 );
|
||||
m_outSpec->color = QColor(145, 205, 22, 80);
|
||||
m_parameterWidget = new EqParameterWidget( this , controls );
|
||||
m_parameterWidget->move( 51, 2 );
|
||||
|
||||
setBand( 0, &controls->m_hpActiveModel, &controls->m_hpFeqModel, &controls->m_hpResModel, 0, QColor(255 ,255, 255), tr( "HP" ) ,0,0);
|
||||
setBand( 1, &controls->m_lowShelfActiveModel, &controls->m_lowShelfFreqModel, &controls->m_lowShelfResModel, &controls->m_lowShelfGainModel, QColor(255 ,255, 255), tr( "Low Shelf" ), &controls->m_lowShelfPeakL , &controls->m_lowShelfPeakR );
|
||||
setBand( 2, &controls->m_para1ActiveModel, &controls->m_para1FreqModel, &controls->m_para1BwModel, &controls->m_para1GainModel, QColor(255 ,255, 255), tr( "Peak 1" ), &controls->m_para1PeakL, &controls->m_para1PeakR );
|
||||
setBand( 3, &controls->m_para2ActiveModel, &controls->m_para2FreqModel, &controls->m_para2BwModel, &controls->m_para2GainModel, QColor(255 ,255, 255), tr( "Peak 2" ), &controls->m_para2PeakL, &controls->m_para2PeakR );
|
||||
setBand( 4, &controls->m_para3ActiveModel, &controls->m_para3FreqModel, &controls->m_para3BwModel, &controls->m_para3GainModel, QColor(255 ,255, 255), tr( "Peak 3" ), &controls->m_para3PeakL, &controls->m_para3PeakR );
|
||||
setBand( 5, &controls->m_para4ActiveModel, &controls->m_para4FreqModel, &controls->m_para4BwModel, &controls->m_para4GainModel, QColor(255 ,255, 255), tr( "Peak 4" ), &controls->m_para4PeakL, &controls->m_para4PeakR );
|
||||
setBand( 6, &controls->m_highShelfActiveModel, &controls->m_highShelfFreqModel, &controls->m_highShelfResModel, &controls->m_highShelfGainModel, QColor(255 ,255, 255), tr( "High Shelf" ), &controls->m_highShelfPeakL, &controls->m_highShelfPeakR );
|
||||
setBand( 7, &controls->m_lpActiveModel, &controls->m_lpFreqModel, &controls->m_lpResModel, 0, QColor(255 ,255, 255), tr( "LP" ) ,0,0);
|
||||
int cw = width()/8; //the chanel width in pixels
|
||||
int ko = ( cw * 0.5 ) - ((new Knob( knobBright_26, 0 ))->width() * 0.5 );
|
||||
|
||||
m_inGainFader = new EqFader( &controls->m_inGainModel, tr( "In Gain" ), this, &controls->m_inPeakL, &controls->m_inPeakR);
|
||||
m_inGainFader->move( 10, 5 );
|
||||
m_inGainFader->setDisplayConversion( false );
|
||||
m_inGainFader->setHintText( tr( "Gain" ), "dBv");
|
||||
|
||||
|
||||
|
||||
m_outGainFader = new EqFader( &controls->m_outGainModel, tr( "Out Gain" ), this, &controls->m_outPeakL, &controls->m_outPeakR );
|
||||
m_outGainFader->move( 315, 5 );
|
||||
m_outGainFader->setDisplayConversion( false );
|
||||
m_outGainFader->setHintText( tr( "Gain" ), "dBv");
|
||||
//gain faders
|
||||
|
||||
int fo = (cw * 0.5) - (m_outGainFader->width() * 0.5 );
|
||||
|
||||
for( int i = 1; i < m_parameterWidget->bandCount() - 1; i++)
|
||||
{
|
||||
m_gainFader = new EqFader( m_parameterWidget->getBandModels(i)->gain, tr( "" ), this ,m_parameterWidget->getBandModels( i )->peakL, m_parameterWidget->getBandModels( i )->peakR );
|
||||
m_gainFader->move( cw * i + fo , 123 );
|
||||
m_gainFader->setMinimumHeight(80);
|
||||
m_gainFader->resize(m_gainFader->width() , 80);
|
||||
m_gainFader->setDisplayConversion( false );
|
||||
m_gainFader->setHintText( tr( "Gain") , "dB");
|
||||
}
|
||||
|
||||
for( int i = 0; i < m_parameterWidget->bandCount() ; i++)
|
||||
{
|
||||
m_resKnob = new Knob( knobBright_26, this );
|
||||
if(i ==0 || i == 7)
|
||||
{
|
||||
m_resKnob->move( cw * i + ko , 190 );
|
||||
} else
|
||||
{
|
||||
m_resKnob->move( cw * i + ko , 205 );
|
||||
}
|
||||
m_resKnob->setVolumeKnob(false);
|
||||
m_resKnob->setModel( m_parameterWidget->getBandModels( i )->res );
|
||||
if(i > 1 && i < 6) { m_resKnob->setHintText( tr( "Bandwidth: " ) , " Octave" ); }
|
||||
else { m_resKnob->setHintText( tr( "Resonance : " ) , "" ); }
|
||||
|
||||
m_freqKnob = new Knob( knobBright_26, this );
|
||||
if( i == 0 || i == 7 )
|
||||
{
|
||||
m_freqKnob->move( cw * i + ko, 222 );
|
||||
} else
|
||||
{
|
||||
m_freqKnob->move(cw * i + ko, 235 );
|
||||
}
|
||||
m_freqKnob->setVolumeKnob( false );
|
||||
m_freqKnob->setModel( m_parameterWidget->getBandModels( i )->freq );
|
||||
m_freqKnob->setHintText( tr( "Frequency:" ), "Hz" );
|
||||
|
||||
m_activeBox = new LedCheckBox( m_parameterWidget->getBandModels( i )->name , this , "" , LedCheckBox::Green );
|
||||
m_activeBox->move( cw * i + fo + 3, 260 );
|
||||
m_activeBox->setModel( m_parameterWidget->getBandModels( i )->active );
|
||||
}
|
||||
|
||||
//hp filter type
|
||||
|
||||
m_hp12Box = new LedCheckBox( tr( "12dB" ), this , "" , LedCheckBox::Green );
|
||||
m_hp12Box->move( cw*0 + ko, 170 );
|
||||
m_hp12Box->setModel( &controls->m_hp12Model );
|
||||
m_hp24Box = new LedCheckBox( tr( "24dB" ), this , "" , LedCheckBox::Green );
|
||||
m_hp24Box->move( cw*0 + ko, 150 );
|
||||
m_hp24Box->setModel( &controls->m_hp24Model );
|
||||
|
||||
m_hp48Box = new LedCheckBox( tr( "48dB" ), this , "" , LedCheckBox::Green );
|
||||
m_hp48Box->move( cw*0 + ko, 130 );
|
||||
m_hp48Box->setModel( &controls->m_hp48Model );
|
||||
|
||||
//LP filter type
|
||||
|
||||
m_lp12Box = new LedCheckBox( tr( "12dB"), this , "" , LedCheckBox::Green );
|
||||
m_lp12Box->move( cw*7 + ko -5 , 170 );
|
||||
m_lp12Box->setModel( &controls->m_lp12Model );
|
||||
m_lp24Box = new LedCheckBox( tr( "24dB"), this , "" , LedCheckBox::Green );
|
||||
m_lp24Box->move( cw*7 + ko - 5, 150 );
|
||||
m_lp24Box->setModel( &controls->m_lp24Model );
|
||||
m_lp48Box = new LedCheckBox( tr( "48dB"), this , "" , LedCheckBox::Green );
|
||||
m_lp48Box->move( cw*7 + ko - 5, 130 );
|
||||
m_lp48Box->setModel( &controls->m_lp48Model );
|
||||
|
||||
automatableButtonGroup *lpBtnGrp = new automatableButtonGroup(this,tr ( "lp grp" ) );
|
||||
lpBtnGrp->addButton( m_lp12Box);
|
||||
lpBtnGrp->addButton( m_lp24Box );
|
||||
lpBtnGrp->addButton( m_lp48Box );
|
||||
lpBtnGrp->setModel( &m_controls->m_lpTypeModel, false);
|
||||
|
||||
automatableButtonGroup *hpBtnGrp = new automatableButtonGroup( this, tr( "hp grp" ) );
|
||||
hpBtnGrp->addButton( m_hp12Box );
|
||||
hpBtnGrp->addButton( m_hp24Box );
|
||||
hpBtnGrp->addButton( m_hp48Box );
|
||||
hpBtnGrp->setModel( &m_controls->m_hpTypeModel,false);
|
||||
|
||||
}
|
||||
|
||||
void EqControlsDialog::mouseDoubleClickEvent(QMouseEvent *event)
|
||||
{
|
||||
m_originalHeight = parentWidget()->height() == 150 ? m_originalHeight : parentWidget()->height() ;
|
||||
parentWidget()->setFixedHeight( parentWidget()->height() == m_originalHeight ? 150 : m_originalHeight );
|
||||
update();
|
||||
}
|
||||
94
plugins/Eq/EqControlsDialog.h
Normal file
94
plugins/Eq/EqControlsDialog.h
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* eqcontrolsdialog.h - defination of EqControlsDialog class.
|
||||
*
|
||||
* Copyright (c) 2014 David French <dave/dot/french3/at/googlemail/dot/com>
|
||||
*
|
||||
* This file is part of LMMS - http://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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef EQCONTROLSDIALOG_H
|
||||
#define EQCONTROLSDIALOG_H
|
||||
|
||||
#include "EffectControlDialog.h"
|
||||
#include "Fader.h"
|
||||
#include "Knob.h"
|
||||
#include "LedCheckbox.h"
|
||||
#include "EqParameterWidget.h"
|
||||
#include "MainWindow.h"
|
||||
#include "qpushbutton.h"
|
||||
#include "EqSpectrumView.h"
|
||||
|
||||
|
||||
class EqControls;
|
||||
|
||||
class EqControlsDialog : public EffectControlDialog
|
||||
{
|
||||
|
||||
public:
|
||||
EqControlsDialog( EqControls* controls );
|
||||
virtual ~EqControlsDialog()
|
||||
{
|
||||
}
|
||||
|
||||
EqBand * setBand(EqControls *controls);
|
||||
|
||||
private slots:
|
||||
void updateVuMeters();
|
||||
|
||||
private:
|
||||
EqControls * m_controls;
|
||||
|
||||
Fader* m_inGainFader;
|
||||
Fader* m_outGainFader;
|
||||
Fader* m_gainFader;
|
||||
Knob* m_resKnob;
|
||||
Knob* m_freqKnob;
|
||||
LedCheckBox* m_activeBox;
|
||||
LedCheckBox* m_lp12Box;
|
||||
LedCheckBox* m_lp24Box;
|
||||
LedCheckBox* m_lp48Box;
|
||||
LedCheckBox* m_hp12Box;
|
||||
LedCheckBox* m_hp24Box;
|
||||
LedCheckBox* m_hp48Box;
|
||||
LedCheckBox* m_analyzeBox;
|
||||
EqParameterWidget* m_parameterWidget;
|
||||
EqSpectrumView* m_inSpec;
|
||||
EqSpectrumView* m_outSpec;
|
||||
|
||||
virtual void mouseDoubleClickEvent(QMouseEvent *event);
|
||||
|
||||
EqBand* setBand( int index, BoolModel* active, FloatModel* freq, FloatModel* res, FloatModel* gain, QColor color, QString name, float* peakL, float* peakR)
|
||||
{
|
||||
EqBand* filterModels = m_parameterWidget->getBandModels( index );
|
||||
filterModels->active = active;
|
||||
filterModels->freq = freq;
|
||||
filterModels->res = res;
|
||||
filterModels->color = color;
|
||||
filterModels->gain = gain;
|
||||
filterModels->peakL = peakL;
|
||||
filterModels->peakR = peakR;
|
||||
return filterModels;
|
||||
}
|
||||
|
||||
int m_originalHeight;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // EQCONTROLSDIALOG_H
|
||||
265
plugins/Eq/EqEffect.cpp
Normal file
265
plugins/Eq/EqEffect.cpp
Normal file
@@ -0,0 +1,265 @@
|
||||
/*
|
||||
* eqeffect.cpp - defination of EqEffect class.
|
||||
*
|
||||
* Copyright (c) 2014 David French <dave/dot/french3/at/googlemail/dot/com>
|
||||
*
|
||||
* This file is part of LMMS - http://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 "EqEffect.h"
|
||||
#include "embed.cpp"
|
||||
#include "lmms_math.h"
|
||||
#include "BasicFilters.h"
|
||||
#include "interpolation.h"
|
||||
#include "Engine.h"
|
||||
#include "MainWindow.h"
|
||||
#include "EqFader.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
Plugin::Descriptor PLUGIN_EXPORT eq_plugin_descriptor =
|
||||
{
|
||||
STRINGIFY( PLUGIN_NAME ),
|
||||
"Equalizer",
|
||||
QT_TRANSLATE_NOOP( "pluginBrowser", "A native eq plugin" ),
|
||||
"Dave French <contact/dot/dave/dot/french3/at/googlemail/dot/com>",
|
||||
0x0100,
|
||||
Plugin::Effect,
|
||||
new PluginPixmapLoader( "logo" ),
|
||||
NULL,
|
||||
NULL
|
||||
} ;
|
||||
|
||||
}
|
||||
|
||||
|
||||
EqEffect::EqEffect(Model *parent, const Plugin::Descriptor::SubPluginFeatures::Key *key) :
|
||||
Effect( &eq_plugin_descriptor, parent, key ),
|
||||
m_eqControls( this )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
EqEffect::~EqEffect()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool EqEffect::processAudioBuffer(sampleFrame *buf, const fpp_t frames)
|
||||
{
|
||||
if( !isEnabled() || !isRunning () )
|
||||
{
|
||||
return( false );
|
||||
}
|
||||
m_eqControls.m_inProgress = true;
|
||||
double outSum = 0.0;
|
||||
for( fpp_t f = 0; f < frames; ++f )
|
||||
{
|
||||
outSum += buf[f][0]*buf[f][0] + buf[f][1]*buf[f][1];
|
||||
}
|
||||
const float outGain = m_eqControls.m_outGainModel.getAmp();
|
||||
const int sampleRate = Engine::mixer()->processingSampleRate();
|
||||
sampleFrame m_inPeak = { 0, 0 };
|
||||
|
||||
if(m_eqControls.m_analyseIn )
|
||||
{
|
||||
m_eqControls.m_inFftBands.analyze( buf, frames );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_eqControls.m_inFftBands.clear();
|
||||
}
|
||||
gain(buf , frames, m_eqControls.m_inGainModel.getAmp() , &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[1] : m_eqControls.m_inPeakR;
|
||||
|
||||
if(m_eqControls.m_hpActiveModel.value() ){
|
||||
|
||||
m_hp12.setParameters( sampleRate, m_eqControls.m_hpFeqModel.value(), m_eqControls.m_hpResModel.value(), 1 );
|
||||
m_hp12.processBuffer( buf, frames );
|
||||
|
||||
if( m_eqControls.m_hp24Model.value() || m_eqControls.m_hp48Model.value() )
|
||||
{
|
||||
m_hp24.setParameters( sampleRate, m_eqControls.m_hpFeqModel.value(), m_eqControls.m_hpResModel.value(), 1 );
|
||||
m_hp24.processBuffer( buf, frames );
|
||||
}
|
||||
|
||||
if( m_eqControls.m_hp48Model.value() )
|
||||
{
|
||||
m_hp480.setParameters( sampleRate, m_eqControls.m_hpFeqModel.value(), m_eqControls.m_hpResModel.value(), 1 );
|
||||
m_hp480.processBuffer( buf, frames );
|
||||
|
||||
m_hp481.setParameters( sampleRate, m_eqControls.m_hpFeqModel.value(), m_eqControls.m_hpResModel.value(), 1 );
|
||||
m_hp481.processBuffer( buf, frames );
|
||||
}
|
||||
}
|
||||
|
||||
if( m_eqControls.m_lowShelfActiveModel.value() )
|
||||
{
|
||||
m_lowShelf.setParameters( sampleRate, m_eqControls.m_lowShelfFreqModel.value(), m_eqControls.m_lowShelfResModel .value(), m_eqControls.m_lowShelfGainModel.value() );
|
||||
m_lowShelf.processBuffer( buf, frames );
|
||||
}
|
||||
|
||||
if( m_eqControls.m_para1ActiveModel.value() )
|
||||
{
|
||||
m_para1.setParameters( sampleRate, m_eqControls.m_para1FreqModel.value(), m_eqControls.m_para1BwModel.value(), m_eqControls.m_para1GainModel.value() );
|
||||
m_para1.processBuffer( buf, frames );
|
||||
}
|
||||
|
||||
if( m_eqControls.m_para2ActiveModel.value() )
|
||||
{
|
||||
m_para2.setParameters( sampleRate, m_eqControls.m_para2FreqModel.value(), m_eqControls.m_para2BwModel.value(), m_eqControls.m_para2GainModel.value() );
|
||||
m_para2.processBuffer( buf, frames );
|
||||
}
|
||||
|
||||
if( m_eqControls.m_para3ActiveModel.value() )
|
||||
{
|
||||
m_para3.setParameters( sampleRate, m_eqControls.m_para3FreqModel.value(), m_eqControls.m_para3BwModel.value(), m_eqControls.m_para3GainModel.value() );
|
||||
m_para3.processBuffer( buf, frames );
|
||||
}
|
||||
|
||||
if( m_eqControls.m_para4ActiveModel.value() )
|
||||
{
|
||||
m_para4.setParameters( sampleRate, m_eqControls.m_para4FreqModel.value(), m_eqControls.m_para4BwModel.value(), m_eqControls.m_para4GainModel.value() );
|
||||
m_para4.processBuffer( buf, frames );
|
||||
}
|
||||
|
||||
if( m_eqControls.m_highShelfActiveModel.value() )
|
||||
{
|
||||
m_highShelf.setParameters( sampleRate, m_eqControls.m_highShelfFreqModel.value(), m_eqControls.m_highShelfResModel.value(), m_eqControls.m_highShelfGainModel.value());
|
||||
m_highShelf.processBuffer( buf, frames );
|
||||
}
|
||||
|
||||
if(m_eqControls.m_lpActiveModel.value() ){
|
||||
m_lp12.setParameters( sampleRate, m_eqControls.m_lpFreqModel.value(), m_eqControls.m_lpResModel.value(), 1 );
|
||||
m_lp12.processBuffer( buf, frames );
|
||||
|
||||
if( m_eqControls.m_lp24Model.value() || m_eqControls.m_lp48Model.value() )
|
||||
{
|
||||
m_lp24.setParameters( sampleRate, m_eqControls.m_lpFreqModel.value(), m_eqControls.m_lpResModel.value(), 1 );
|
||||
m_lp24.processBuffer( buf, frames );
|
||||
}
|
||||
|
||||
if( m_eqControls.m_lp48Model.value() )
|
||||
{
|
||||
m_lp480.setParameters( sampleRate, m_eqControls.m_lpFreqModel.value(), m_eqControls.m_lpResModel.value(), 1 );
|
||||
m_lp480.processBuffer( buf, frames );
|
||||
|
||||
m_lp481.setParameters( sampleRate, m_eqControls.m_lpFreqModel.value(), m_eqControls.m_lpResModel.value(), 1 );
|
||||
m_lp481.processBuffer( buf, frames );
|
||||
}
|
||||
}
|
||||
|
||||
sampleFrame outPeak = { 0, 0 };
|
||||
gain( buf, frames, 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[1] : m_eqControls.m_outPeakR;
|
||||
|
||||
checkGate( outSum / frames );
|
||||
if(m_eqControls.m_analyseOut )
|
||||
{
|
||||
m_eqControls.m_outFftBands.analyze( buf, frames );
|
||||
setBandPeaks( &m_eqControls.m_outFftBands , ( int )( sampleRate * 0.5 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_eqControls.m_outFftBands.clear();
|
||||
}
|
||||
m_eqControls.m_inProgress = false;
|
||||
return isRunning();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
float EqEffect::peakBand( float minF, float maxF, EqAnalyser *fft, int sr )
|
||||
{
|
||||
float peak = -60;
|
||||
float * b = fft->m_bands;
|
||||
float h = 0;
|
||||
for(int x = 0; x < MAX_BANDS; x++, b++)
|
||||
{
|
||||
if( bandToFreq( x ,sr) >= minF && bandToFreq( x,sr ) <= maxF )
|
||||
{
|
||||
h = 20*( log10( *b / fft->m_energy ) );
|
||||
peak = h > peak ? h : peak;
|
||||
}
|
||||
}
|
||||
return (peak+100)/100;
|
||||
}
|
||||
|
||||
void EqEffect::setBandPeaks(EqAnalyser *fft, int samplerate )
|
||||
{
|
||||
m_eqControls.m_lowShelfPeakR = m_eqControls.m_lowShelfPeakL =
|
||||
peakBand( 0,
|
||||
m_eqControls.m_lowShelfFreqModel.value(), fft , samplerate );
|
||||
|
||||
m_eqControls.m_para1PeakL = m_eqControls.m_para1PeakR =
|
||||
peakBand( m_eqControls.m_para1FreqModel.value()
|
||||
- (m_eqControls.m_para1FreqModel.value() * m_eqControls.m_para1BwModel.value() * 0.5),
|
||||
m_eqControls.m_para1FreqModel.value()
|
||||
+ (m_eqControls.m_para1FreqModel.value() * m_eqControls.m_para1BwModel.value() * 0.5),
|
||||
fft , samplerate );
|
||||
|
||||
m_eqControls.m_para2PeakL = m_eqControls.m_para2PeakR =
|
||||
peakBand( m_eqControls.m_para2FreqModel.value()
|
||||
- (m_eqControls.m_para2FreqModel.value() * m_eqControls.m_para2BwModel.value() * 0.5),
|
||||
m_eqControls.m_para2FreqModel.value()
|
||||
+ (m_eqControls.m_para2FreqModel.value() * m_eqControls.m_para2BwModel.value() * 0.5),
|
||||
fft , samplerate );
|
||||
|
||||
m_eqControls.m_para3PeakL = m_eqControls.m_para3PeakR =
|
||||
peakBand( m_eqControls.m_para3FreqModel.value()
|
||||
- (m_eqControls.m_para3FreqModel.value() * m_eqControls.m_para3BwModel.value() * 0.5),
|
||||
m_eqControls.m_para3FreqModel.value()
|
||||
+ (m_eqControls.m_para3FreqModel.value() * m_eqControls.m_para3BwModel.value() * 0.5),
|
||||
fft , samplerate );
|
||||
|
||||
m_eqControls.m_para4PeakL = m_eqControls.m_para4PeakR =
|
||||
peakBand( m_eqControls.m_para4FreqModel.value()
|
||||
- (m_eqControls.m_para4FreqModel.value() * m_eqControls.m_para4BwModel.value() * 0.5),
|
||||
m_eqControls.m_para4FreqModel.value()
|
||||
+ (m_eqControls.m_para4FreqModel.value() * m_eqControls.m_para4BwModel.value() * 0.5),
|
||||
fft , samplerate );
|
||||
|
||||
m_eqControls.m_highShelfPeakL = m_eqControls.m_highShelfPeakR =
|
||||
peakBand( m_eqControls.m_highShelfFreqModel.value(),
|
||||
samplerate * 0.5 , fft, samplerate );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
//needed for getting plugin out of shared lib
|
||||
Plugin * PLUGIN_EXPORT lmms_plugin_main( Model* parent, void* data )
|
||||
{
|
||||
return new EqEffect( parent , static_cast<const Plugin::Descriptor::SubPluginFeatures::Key *>( data ) );
|
||||
}
|
||||
|
||||
}
|
||||
104
plugins/Eq/EqEffect.h
Normal file
104
plugins/Eq/EqEffect.h
Normal file
@@ -0,0 +1,104 @@
|
||||
/* eqeffect.h - defination of EqEffect class.
|
||||
*
|
||||
* Copyright (c) 2014 David French <dave/dot/french3/at/googlemail/dot/com>
|
||||
*
|
||||
* This file is part of LMMS - http://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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef EQEFFECT_H
|
||||
#define EQEFFECT_H
|
||||
|
||||
#include "Effect.h"
|
||||
#include "EqControls.h"
|
||||
#include "lmms_math.h"
|
||||
#include "BasicFilters.h"
|
||||
#include "EqFilter.h"
|
||||
|
||||
|
||||
|
||||
class EqEffect : public Effect
|
||||
{
|
||||
public:
|
||||
EqEffect( Model* parent , const Descriptor::SubPluginFeatures::Key* key );
|
||||
virtual ~EqEffect();
|
||||
virtual bool processAudioBuffer( sampleFrame *buf, const fpp_t frames );
|
||||
virtual EffectControls* controls()
|
||||
{
|
||||
return &m_eqControls;
|
||||
}
|
||||
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;
|
||||
|
||||
EqHp12Filter m_hp12;
|
||||
EqHp12Filter m_hp24;
|
||||
EqHp12Filter m_hp480;
|
||||
EqHp12Filter m_hp481;
|
||||
|
||||
EqLowShelfFilter m_lowShelf;
|
||||
|
||||
EqPeakFilter m_para1;
|
||||
EqPeakFilter m_para2;
|
||||
EqPeakFilter m_para3;
|
||||
EqPeakFilter m_para4;
|
||||
|
||||
EqHighShelfFilter m_highShelf;
|
||||
|
||||
EqLp12Filter m_lp12;
|
||||
EqLp12Filter m_lp24;
|
||||
EqLp12Filter m_lp480;
|
||||
EqLp12Filter m_lp481;
|
||||
|
||||
|
||||
|
||||
|
||||
void analyze( sampleFrame *buf, const fpp_t frames, EqAnalyser* fft );
|
||||
float peakBand(float minF, float maxF,EqAnalyser*, int);
|
||||
|
||||
inline float bandToFreq ( int index , int sampleRate )
|
||||
{
|
||||
return index * sampleRate / (MAX_BANDS * 2);
|
||||
}
|
||||
|
||||
void setBandPeaks( EqAnalyser *fft , int);
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // EQEFFECT_H
|
||||
101
plugins/Eq/EqFader.h
Normal file
101
plugins/Eq/EqFader.h
Normal file
@@ -0,0 +1,101 @@
|
||||
/* eqfader.h - defination of EqFader class.
|
||||
*
|
||||
* Copyright (c) 2014 David French <dave/dot/french3/at/googlemail/dot/com>
|
||||
*
|
||||
* This file is part of LMMS - http://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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef EQFADER_H
|
||||
#define EQFADER_H
|
||||
#include "Fader.h"
|
||||
#include "EffectControls.h"
|
||||
#include "MainWindow.h"
|
||||
#include "qwidget.h"
|
||||
#include "TextFloat.h"
|
||||
#include "qlist.h"
|
||||
|
||||
|
||||
|
||||
class EqFader : public Fader
|
||||
{
|
||||
|
||||
public:
|
||||
Q_OBJECT
|
||||
public:
|
||||
EqFader( FloatModel * model, const QString & name, QWidget * parent, float* lPeak, float* rPeak ) :
|
||||
Fader( model, name, parent)
|
||||
{
|
||||
setMinimumSize( 23, 116 );
|
||||
setMaximumSize( 23, 116 );
|
||||
resize( 23, 116 );
|
||||
m_lPeak = lPeak;
|
||||
m_rPeak = rPeak;
|
||||
connect( Engine::mainWindow(), SIGNAL( periodicUpdate() ), this, SLOT( updateVuMeters() ) );
|
||||
m_model = model;
|
||||
setPeak_L( 0 );
|
||||
setPeak_R( 0 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
~EqFader()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
private slots:
|
||||
|
||||
void updateVuMeters()
|
||||
{
|
||||
const float opl = getPeak_L();
|
||||
const float opr = getPeak_R();
|
||||
const float fall_off = 1.2;
|
||||
if( *m_lPeak > opl )
|
||||
{
|
||||
setPeak_L( *m_lPeak );
|
||||
*m_lPeak = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
setPeak_L( opl/fall_off );
|
||||
}
|
||||
|
||||
if( *m_rPeak > opr )
|
||||
{
|
||||
setPeak_R( *m_rPeak );
|
||||
*m_rPeak = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
setPeak_R( opr/fall_off );
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private:
|
||||
float* m_lPeak;
|
||||
float* m_rPeak;
|
||||
FloatModel* m_model;
|
||||
|
||||
};
|
||||
#endif // EQFADER_H
|
||||
445
plugins/Eq/EqFilter.h
Normal file
445
plugins/Eq/EqFilter.h
Normal file
@@ -0,0 +1,445 @@
|
||||
/*
|
||||
* eqfilter.cpp - defination of EqFilterclass.
|
||||
*
|
||||
* Copyright (c) 2014 David French <dave/dot/french3/at/googlemail/dot/com>
|
||||
*
|
||||
* This file is part of LMMS - http://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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef EQFILTER_H
|
||||
#define EQFILTER_H
|
||||
|
||||
#include "BasicFilters.h"
|
||||
#include "lmms_math.h"
|
||||
|
||||
///
|
||||
/// \brief The EqFilter class.
|
||||
/// A wrapper for the StereoBiQuad class, giving it freq, res, and gain controls.
|
||||
/// It is designed to process periods in one pass, with recalculation of coefficents
|
||||
/// upon parameter changes. The intention is to use this as a bass class, children override
|
||||
/// the calcCoefficents() function, providing the coefficents a1, a2, b0, b1, b2.
|
||||
///
|
||||
class EqFilter : public StereoBiQuad
|
||||
{
|
||||
public:
|
||||
EqFilter()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
virtual inline void setSampleRate( int sampleRate )
|
||||
{
|
||||
if( sampleRate != m_sampleRate )
|
||||
{
|
||||
m_sampleRate = sampleRate;
|
||||
calcCoefficents();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
virtual inline void setFrequency( float freq ){
|
||||
if ( freq != m_freq )
|
||||
{
|
||||
m_freq = freq;
|
||||
calcCoefficents();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
virtual inline void setQ( float res )
|
||||
{
|
||||
if ( res != m_res )
|
||||
{
|
||||
m_res = res;
|
||||
calcCoefficents();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
virtual inline void setGain( float gain )
|
||||
{
|
||||
if ( gain != m_gain )
|
||||
{
|
||||
m_gain = gain;
|
||||
calcCoefficents();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
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
|
||||
/// \param buf Audio Buffer
|
||||
/// \param frames Count of sampleFrames in Audio Buffer
|
||||
///
|
||||
virtual void processBuffer( sampleFrame* buf, const fpp_t frames )
|
||||
{
|
||||
for ( fpp_t f = 0 ; f < frames ; ++f)
|
||||
{
|
||||
buf[f][0] = update( buf[f][0] , 0);
|
||||
buf[f][1] = update( buf[f][1] , 1);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
///
|
||||
/// \brief calcCoefficents
|
||||
/// Override this in child classes to provide the coefficents, based on
|
||||
/// Freq, Res and Gain
|
||||
virtual void calcCoefficents(){
|
||||
setCoeffs( 0, 0, 0, 0, 0 );
|
||||
|
||||
}
|
||||
|
||||
float m_sampleRate;
|
||||
float m_freq;
|
||||
float m_res;
|
||||
float m_gain;
|
||||
float m_bw;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
///
|
||||
/// \brief The EqHp12Filter class
|
||||
/// A 2 pole High Pass Filter
|
||||
/// Coefficent calculations from http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt
|
||||
class EqHp12Filter : public EqFilter
|
||||
{
|
||||
public :
|
||||
virtual void calcCoefficents()
|
||||
{
|
||||
|
||||
// calc intermediate
|
||||
float w0 = F_2PI * m_freq / m_sampleRate;
|
||||
float c = cosf( w0 );
|
||||
float s = sinf( w0 );
|
||||
float alpha = s / ( 2 * m_res );
|
||||
|
||||
float a0, a1, a2, b0, b1, b2; // coeffs to calculate
|
||||
|
||||
//calc coefficents
|
||||
b0 = ( 1 + c ) * 0.5;
|
||||
b1 = ( -( 1 + c ) );
|
||||
b2 = ( 1 + c ) * 0.5;
|
||||
a0 = 1 + alpha;
|
||||
a1 = ( -2 * c );
|
||||
a2 = 1 - alpha;
|
||||
|
||||
//normalise
|
||||
b0 /= a0;
|
||||
b1 /= a0;
|
||||
b2 /= a0;
|
||||
a1 /= a0;
|
||||
a2 /= a0;
|
||||
|
||||
a0 = 1;
|
||||
|
||||
setCoeffs( a1, a2, b0, b1, b2 );
|
||||
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
///
|
||||
/// \brief The EqLp12Filter class.
|
||||
/// A 2 pole low pass filter
|
||||
/// Coefficent calculations from http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt
|
||||
///
|
||||
class EqLp12Filter : public EqFilter
|
||||
{
|
||||
public :
|
||||
virtual void calcCoefficents()
|
||||
{
|
||||
|
||||
// calc intermediate
|
||||
float w0 = F_2PI * m_freq / m_sampleRate;
|
||||
float c = cosf( w0 );
|
||||
float s = sinf( w0 );
|
||||
float alpha = s / ( 2 * m_res );
|
||||
|
||||
float a0, a1, a2, b0, b1, b2; // coeffs to calculate
|
||||
|
||||
//calc coefficents
|
||||
b0 = ( 1 - c ) * 0.5;
|
||||
b1 = 1 - c;
|
||||
b2 = ( 1 - c ) * 0.5;
|
||||
a0 = 1 + alpha;
|
||||
a1 = -2 * c;
|
||||
a2 = 1 - alpha;
|
||||
|
||||
//normalise
|
||||
b0 /= a0;
|
||||
b1 /= a0;
|
||||
b2 /= a0;
|
||||
a1 /= a0;
|
||||
a2 /= a0;
|
||||
|
||||
a0 = 1;
|
||||
|
||||
setCoeffs( a1, a2, b0, b1, b2 );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
///
|
||||
/// \brief The EqPeakFilter class
|
||||
/// A Peak Filter
|
||||
/// Coefficent calculations from http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt
|
||||
///
|
||||
class EqPeakFilter : public EqFilter
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
virtual void calcCoefficents()
|
||||
{
|
||||
// calc intermediate
|
||||
float w0 = F_2PI * m_freq / m_sampleRate;
|
||||
float c = cosf( w0 );
|
||||
float s = sinf( w0 );
|
||||
float A = pow( 10, m_gain * 0.025);
|
||||
float alpha = s * sinh( log( 2 ) / 2 * m_bw * w0 / sinf(w0) );
|
||||
|
||||
float a0, a1, a2, b0, b1, b2; // coeffs to calculate
|
||||
|
||||
//calc coefficents
|
||||
b0 = 1 + alpha*A;
|
||||
b1 = -2*c;
|
||||
b2 = 1 - alpha*A;
|
||||
a0 = 1 + alpha/A;
|
||||
a1 = -2*c;
|
||||
a2 = 1 - alpha/A;
|
||||
|
||||
//normalise
|
||||
b0 /= a0;
|
||||
b1 /= a0;
|
||||
b2 /= a0;
|
||||
a1 /= a0;
|
||||
a2 /= a0;
|
||||
a0 = 1;
|
||||
|
||||
setCoeffs( a1, a2, b0, b1, b2 );
|
||||
}
|
||||
|
||||
virtual inline void setParameters( float sampleRate, float freq, float bw, float gain )
|
||||
{
|
||||
bool hasChanged = false;
|
||||
if( sampleRate != m_sampleRate )
|
||||
{
|
||||
m_sampleRate = sampleRate;
|
||||
hasChanged = true;
|
||||
}
|
||||
if ( freq != m_freq )
|
||||
{
|
||||
m_freq = freq;
|
||||
hasChanged = true;
|
||||
}
|
||||
if ( bw != m_bw )
|
||||
{
|
||||
m_bw = bw;
|
||||
hasChanged = true;
|
||||
}
|
||||
if ( gain != m_gain )
|
||||
{
|
||||
m_gain = gain;
|
||||
hasChanged = true;
|
||||
}
|
||||
|
||||
if ( hasChanged ) { calcCoefficents(); }
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class EqLowShelfFilter : public EqFilter
|
||||
{
|
||||
public :
|
||||
virtual void calcCoefficents()
|
||||
{
|
||||
|
||||
// calc intermediate
|
||||
float w0 = F_2PI * m_freq / m_sampleRate;
|
||||
float c = cosf( w0 );
|
||||
float s = sinf( w0 );
|
||||
float A = pow( 10, m_gain * 0.025);
|
||||
// float alpha = s / ( 2 * m_res );
|
||||
float beta = sqrt( A ) / m_res;
|
||||
|
||||
float a0, a1, a2, b0, b1, b2; // coeffs to calculate
|
||||
|
||||
//calc coefficents
|
||||
b0 = A * ( ( A+1 ) - ( A-1 ) * c + beta * s );
|
||||
b1 = 2 * A * ( ( A - 1 ) - ( A + 1 ) * c) ;
|
||||
b2 = A * ( ( A + 1 ) - ( A - 1 ) * c - beta * s);
|
||||
a0 = ( A + 1 ) + ( A - 1 ) * c + beta * s;
|
||||
a1 = -2 * ( ( A - 1 ) + ( A + 1 ) * c );
|
||||
a2 = ( A + 1 ) + ( A - 1) * c - beta * s;
|
||||
|
||||
//normalise
|
||||
b0 /= a0;
|
||||
b1 /= a0;
|
||||
b2 /= a0;
|
||||
a1 /= a0;
|
||||
a2 /= a0;
|
||||
|
||||
a0 = 1;
|
||||
|
||||
setCoeffs( a1, a2, b0, b1, b2 );
|
||||
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
class EqHighShelfFilter : public EqFilter
|
||||
{
|
||||
public :
|
||||
virtual void calcCoefficents()
|
||||
{
|
||||
|
||||
// calc intermediate
|
||||
float w0 = F_2PI * m_freq / m_sampleRate;
|
||||
float c = cosf( w0 );
|
||||
float s = sinf( w0 );
|
||||
float A = pow( 10, m_gain * 0.025 );
|
||||
float beta = sqrt( A ) / m_res;
|
||||
|
||||
float a0, a1, a2, b0, b1, b2; // coeffs to calculate
|
||||
|
||||
//calc coefficents
|
||||
b0 = A *( ( A +1 ) + ( A - 1 ) * c + beta * s);
|
||||
b1 = -2 * A * ( ( A - 1 ) + ( A + 1 ) * c );
|
||||
b2 = A * ( ( A + 1 ) + ( A - 1 ) * c - beta * s);
|
||||
a0 = ( A + 1 ) - ( A - 1 ) * c + beta * s;
|
||||
a1 = 2 * ( ( A - 1 ) - ( A + 1 ) * c );
|
||||
a2 = ( A + 1) - ( A - 1 ) * c - beta * s;
|
||||
//normalise
|
||||
b0 /= a0;
|
||||
b1 /= a0;
|
||||
b2 /= a0;
|
||||
a1 /= a0;
|
||||
a2 /= a0;
|
||||
a0 = 1;
|
||||
|
||||
setCoeffs( a1, a2, b0, b1, b2 );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class EqLinkwitzRiley : public StereoLinkwitzRiley
|
||||
{
|
||||
public:
|
||||
EqLinkwitzRiley() :
|
||||
StereoLinkwitzRiley( 44100),
|
||||
m_freq(0 ),
|
||||
m_sr( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
virtual inline void setSR( int sampleRate )
|
||||
{
|
||||
if( sampleRate != m_sr )
|
||||
{
|
||||
m_sr = sampleRate;
|
||||
setSampleRate( sampleRate );
|
||||
setLowpass(m_freq);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
virtual inline void setFrequency( float freq ){
|
||||
if ( freq != m_freq )
|
||||
{
|
||||
m_freq = freq;
|
||||
setLowpass(m_freq);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
virtual void processBuffer( sampleFrame* buf, const fpp_t frames )
|
||||
{
|
||||
for ( fpp_t f = 0 ; f < frames ; ++f)
|
||||
{
|
||||
buf[f][0] = update( buf[f][0] , 0);
|
||||
buf[f][1] = update( buf[f][1] , 1);
|
||||
}
|
||||
}
|
||||
protected:
|
||||
|
||||
float m_freq;
|
||||
int m_sr;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // EQFILTER_H
|
||||
255
plugins/Eq/EqParameterWidget.cpp
Normal file
255
plugins/Eq/EqParameterWidget.cpp
Normal file
@@ -0,0 +1,255 @@
|
||||
/*
|
||||
* eqparameterwidget.cpp - defination of EqParameterWidget class.
|
||||
*
|
||||
* Copyright (c) 2014 David French <dave/dot/french3/at/googlemail/dot/com>
|
||||
*
|
||||
* This file is part of LMMS - http://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 "EqParameterWidget.h"
|
||||
#include "QPainter"
|
||||
#include "qwidget.h"
|
||||
#include "lmms_math.h"
|
||||
#include "MainWindow.h"
|
||||
#include "QMouseEvent"
|
||||
#include "EqControls.h"
|
||||
|
||||
EqParameterWidget::EqParameterWidget( QWidget *parent, EqControls * controls ) :
|
||||
QWidget( parent ),
|
||||
m_bands ( 0 ),
|
||||
m_selectedBand ( 0 )
|
||||
{
|
||||
m_bands = new EqBand[8];
|
||||
resize( 250, 116 );
|
||||
// connect( Engine::mainWindow(), SIGNAL( periodicUpdate() ), this, SLOT( update() ) );
|
||||
QTimer *timer = new QTimer(this);
|
||||
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
|
||||
timer->start(100);
|
||||
float totalLength = log10( 21000 );
|
||||
m_pixelsPerUnitWidth = width( ) / totalLength ;
|
||||
float totalHeight = 80;
|
||||
m_pixelsPerUnitHeight = (height() - 4) / ( totalHeight );
|
||||
m_scale = 1.5;
|
||||
m_pixelsPerOctave = freqToXPixel( 10000 ) - freqToXPixel( 5000 );
|
||||
m_controls = controls;
|
||||
tf = new TextFloat();
|
||||
tf->hide();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
EqParameterWidget::~EqParameterWidget()
|
||||
{
|
||||
if(m_bands)
|
||||
{
|
||||
delete[] m_bands;
|
||||
m_bands = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void EqParameterWidget::paintEvent( QPaintEvent *event )
|
||||
{
|
||||
QPainter painter( this );
|
||||
//Draw Frequecy maker lines
|
||||
painter.setPen( QPen( QColor( 100, 100, 100, 200 ), 1, Qt::SolidLine, Qt::RoundCap, Qt::BevelJoin ) );
|
||||
for( int x = 20 ; x < 100; x += 10)
|
||||
{
|
||||
painter.drawLine( freqToXPixel( x ) , 0, freqToXPixel( x ) , height() );
|
||||
}
|
||||
for( int x = 100 ; x < 1000; x += 100)
|
||||
{
|
||||
painter.drawLine( freqToXPixel( x ) , 0, freqToXPixel( x ) , height() );
|
||||
}
|
||||
for( int x = 1000 ; x < 11000; x += 1000)
|
||||
{
|
||||
painter.drawLine( freqToXPixel( x ) , 0, freqToXPixel( x ) , height() );
|
||||
}
|
||||
//draw 0dB line
|
||||
painter.drawLine(0, gainToYPixel( 0 ) , width(), gainToYPixel( 0 ) );
|
||||
|
||||
for( int i = 0 ; i < bandCount() ; i++ )
|
||||
{
|
||||
m_bands[i].color.setAlpha( m_bands[i].active->value() ? activeAplha() : inactiveAlpha() );
|
||||
painter.setPen( QPen( m_bands[i].color, 1, Qt::SolidLine, Qt::RoundCap, Qt::BevelJoin ) );
|
||||
float x = freqToXPixel( m_bands[i].freq->value() );
|
||||
float y = height() * 0.5;
|
||||
float gain = 1;
|
||||
if( m_bands[i].gain )
|
||||
{
|
||||
gain = m_bands[i].gain->value();
|
||||
}
|
||||
y = gainToYPixel( gain );
|
||||
float bw = m_bands[i].freq->value() * m_bands[i].res->value();
|
||||
m_bands[i].x = x; m_bands[i].y = y;
|
||||
const int radius = 7;
|
||||
painter.drawEllipse( x - radius , y - radius, radius * 2 ,radius * 2 );
|
||||
QString msg = QString ( "%1" ).arg ( QString::number (i + 1) );
|
||||
painter.drawText(x - ( radius * 0.5 ), y + ( radius * 0.85 ), msg );
|
||||
painter.setPen( QPen( m_bands[i].color, 1, Qt::SolidLine, Qt::SquareCap, Qt::BevelJoin ) );
|
||||
if( i == 0 || i == bandCount() - 1 )
|
||||
{
|
||||
painter.drawLine(x , y, x, y - (m_bands[i].res->value() * 4 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
painter.drawLine(freqToXPixel(m_bands[i].freq->value()-(bw * 0.5)),y,freqToXPixel(m_bands[i].freq->value()+(bw * 0.5)),y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void EqParameterWidget::mousePressEvent( QMouseEvent *event )
|
||||
{
|
||||
m_oldX = event->x(); m_oldY = event->y();
|
||||
m_selectedBand = selectNearestHandle( event->x(), event->y() );
|
||||
m_mouseAction = none;
|
||||
if ( event->button() == Qt::LeftButton ) m_mouseAction = drag;
|
||||
if ( event->button() == Qt::RightButton ) m_mouseAction = res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void EqParameterWidget::mouseReleaseEvent( QMouseEvent *event )
|
||||
{
|
||||
m_selectedBand = 0;
|
||||
m_mouseAction = none;
|
||||
const int inXmin = 228;
|
||||
const int inXmax = 250;
|
||||
const int inYmin = 20;
|
||||
const int inYmax = 30;
|
||||
|
||||
const int outXmin = 228;
|
||||
const int outXmax = 250;
|
||||
const int outYmin = 30;
|
||||
const int outYmax = 40;
|
||||
|
||||
if(event->x() > inXmin && event->x() < inXmax && event->y() > inYmin && event->y() < inYmax )
|
||||
{
|
||||
m_controls->m_analyseIn = !m_controls->m_analyseIn;
|
||||
}
|
||||
|
||||
if(event->x() > outXmin && event->x() < outXmax && event->y() > outYmin && event->y() < outYmax )
|
||||
{
|
||||
m_controls->m_analyseOut = !m_controls->m_analyseOut;
|
||||
}
|
||||
|
||||
tf->hide();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void EqParameterWidget::mouseMoveEvent( QMouseEvent *event )
|
||||
{
|
||||
int deltaX = event->x() - m_oldX;
|
||||
int deltaR = event->y() - m_oldY;
|
||||
m_oldX = event->x(); m_oldY = event->y();
|
||||
if(m_selectedBand && m_selectedBand->active->value() )
|
||||
{
|
||||
switch ( m_mouseAction ) {
|
||||
case none :
|
||||
break;
|
||||
case drag:
|
||||
if( m_selectedBand->freq ) m_selectedBand->freq->setValue( xPixelToFreq( m_oldX ) );
|
||||
if( m_selectedBand->gain )m_selectedBand->gain->setValue( yPixelToGain( m_oldY ) );
|
||||
break;
|
||||
case res:
|
||||
if( m_selectedBand->res )m_selectedBand->res->incValue( ( deltaX) * resPixelMultiplyer() );
|
||||
if( m_selectedBand->res )m_selectedBand->res->incValue( (-deltaR) * resPixelMultiplyer() );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( m_oldX > 0 && m_oldX < width() && m_oldY > 0 && m_oldY < height() )
|
||||
{
|
||||
tf->setText( QString::number(xPixelToFreq( m_oldX )) + tr( "Hz ") );
|
||||
tf->show();
|
||||
const int x = event->x() > width() * 0.5 ?
|
||||
m_oldX - tf->width() :
|
||||
m_oldX;
|
||||
tf->moveGlobal(this, QPoint( x, m_oldY - tf->height() ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void EqParameterWidget::mouseDoubleClickEvent( QMouseEvent *event )
|
||||
{
|
||||
EqBand* selected = selectNearestHandle( event->x() , event->y() );
|
||||
if( selected )
|
||||
{
|
||||
selected->active->setValue( selected->active->value() ? 0 : 1 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
EqBand* EqParameterWidget::selectNearestHandle( const int x, const int y )
|
||||
{
|
||||
EqBand* selectedModel = 0;
|
||||
float* distanceToHandles = new float[bandCount()];
|
||||
//calc distance to each handle
|
||||
for( int i = 0 ; i < bandCount() ; i++ )
|
||||
{
|
||||
int xOffset = m_bands[i].x - x;
|
||||
int yOffset = m_bands[i].y - y;
|
||||
distanceToHandles[i] = fabs( sqrt( ( xOffset * xOffset ) + ( yOffset * yOffset ) ) );
|
||||
}
|
||||
//select band
|
||||
int shortestBand = 0;
|
||||
for ( int i = 1 ; i < bandCount() ; i++ )
|
||||
{
|
||||
if ( distanceToHandles [i] < distanceToHandles[shortestBand] ){
|
||||
shortestBand = i;
|
||||
}
|
||||
}
|
||||
if(distanceToHandles[shortestBand] < maxDistanceFromHandle() )
|
||||
{
|
||||
selectedModel = &m_bands[shortestBand];
|
||||
}
|
||||
delete distanceToHandles;
|
||||
return selectedModel;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
EqBand::EqBand() :
|
||||
gain ( 0 ),
|
||||
res ( 0 ),
|
||||
freq ( 0 ),
|
||||
color ( QColor( 255, 255, 255 ) ),
|
||||
x( 0 ),
|
||||
y( 0 ),
|
||||
name ( QString( "" ) ),
|
||||
peakL( 0 ),
|
||||
peakR( 0 )
|
||||
{
|
||||
}
|
||||
166
plugins/Eq/EqParameterWidget.h
Normal file
166
plugins/Eq/EqParameterWidget.h
Normal file
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* eqparameterwidget.cpp - defination of EqParameterWidget class.
|
||||
*
|
||||
* Copyright (c) 2014 David French <dave/dot/french3/at/googlemail/dot/com>
|
||||
*
|
||||
* This file is part of LMMS - http://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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef EQPARAMETERWIDGET_H
|
||||
#define EQPARAMETERWIDGET_H
|
||||
#include <QWidget>
|
||||
#include "EffectControls.h"
|
||||
#include "TextFloat.h"
|
||||
|
||||
class EqControls;
|
||||
|
||||
|
||||
class EqBand
|
||||
{
|
||||
public :
|
||||
EqBand();
|
||||
FloatModel* gain;
|
||||
FloatModel* res;
|
||||
FloatModel* freq;
|
||||
BoolModel* active;
|
||||
QColor color;
|
||||
int x;
|
||||
int y;
|
||||
QString name;
|
||||
float* peakL;
|
||||
float* peakR;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
class EqParameterWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit EqParameterWidget( QWidget *parent = 0, EqControls * controls = 0);
|
||||
~EqParameterWidget();
|
||||
const int bandCount()
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const int maxDistanceFromHandle()
|
||||
{
|
||||
return 20;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
EqBand* getBandModels( int i )
|
||||
{
|
||||
return &m_bands[i];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
const int activeAplha()
|
||||
{
|
||||
return 200;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
const int inactiveAlpha()
|
||||
{
|
||||
return 100;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
const float resPixelMultiplyer()
|
||||
{
|
||||
return 100;
|
||||
}
|
||||
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
|
||||
protected:
|
||||
virtual void paintEvent ( QPaintEvent * event );
|
||||
virtual void mousePressEvent(QMouseEvent * event );
|
||||
virtual void mouseReleaseEvent(QMouseEvent * event);
|
||||
virtual void mouseMoveEvent(QMouseEvent * event);
|
||||
virtual void mouseDoubleClickEvent(QMouseEvent * event);
|
||||
|
||||
private:
|
||||
EqBand *m_bands;
|
||||
EqControls *m_controls;
|
||||
float m_pixelsPerUnitWidth;
|
||||
float m_pixelsPerUnitHeight;
|
||||
float m_pixelsPerOctave;
|
||||
float m_scale;
|
||||
EqBand* m_selectedBand;
|
||||
TextFloat *tf;
|
||||
|
||||
EqBand* selectNearestHandle( const int x, const int y );
|
||||
|
||||
enum MouseAction { none, drag, res } m_mouseAction;
|
||||
int m_oldX, m_oldY;
|
||||
int *m_xGridBands;
|
||||
|
||||
|
||||
inline int freqToXPixel( float freq )
|
||||
{
|
||||
return ( log10( freq ) * m_pixelsPerUnitWidth * m_scale ) - ( width() * 0.5 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
inline float xPixelToFreq( int x )
|
||||
{
|
||||
return pow( 10, ( x + ( width() * 0.5 ) ) / ( m_pixelsPerUnitWidth * m_scale ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
inline int gainToYPixel( float gain )
|
||||
{
|
||||
return ( height() - 3) - ( gain * m_pixelsPerUnitHeight ) - ( (height() -3 ) * 0.5);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
inline float yPixelToGain( int y )
|
||||
{
|
||||
return ( ( 0.5 * height() ) - y) / m_pixelsPerUnitHeight;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // EQPARAMETERWIDGET_H
|
||||
225
plugins/Eq/EqSpectrumView.h
Normal file
225
plugins/Eq/EqSpectrumView.h
Normal file
@@ -0,0 +1,225 @@
|
||||
/* eqspectrumview.h - defination of EqSpectrumView class.
|
||||
*
|
||||
* Copyright (c) 2014 David French <dave/dot/french3/at/googlemail/dot/com>
|
||||
*
|
||||
* This file is part of LMMS - http://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.
|
||||
*
|
||||
*/
|
||||
#ifndef EQSPECTRUMVIEW_H
|
||||
#define EQSPECTRUMVIEW_H
|
||||
|
||||
#include "qpainter.h"
|
||||
//#include "eqeffect.h"
|
||||
#include "qwidget.h"
|
||||
#include "fft_helpers.h"
|
||||
#include "Engine.h"
|
||||
|
||||
|
||||
const int MAX_BANDS = 2048;
|
||||
|
||||
class EqAnalyser
|
||||
{
|
||||
public:
|
||||
|
||||
fftwf_plan m_fftPlan;
|
||||
fftwf_complex * m_specBuf;
|
||||
float m_absSpecBuf[FFT_BUFFER_SIZE+1];
|
||||
float m_buffer[FFT_BUFFER_SIZE*2];
|
||||
int m_framesFilledUp;
|
||||
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_active ( true )
|
||||
{
|
||||
m_inProgress=false;
|
||||
m_specBuf = (fftwf_complex *) fftwf_malloc( ( FFT_BUFFER_SIZE + 1 ) * sizeof( fftwf_complex ) );
|
||||
m_fftPlan = fftwf_plan_dft_r2c_1d( FFT_BUFFER_SIZE*2, m_buffer, m_specBuf, FFTW_MEASURE );
|
||||
clear();
|
||||
}
|
||||
|
||||
virtual ~EqAnalyser()
|
||||
{
|
||||
fftwf_destroy_plan( m_fftPlan );
|
||||
fftwf_free( m_specBuf );
|
||||
}
|
||||
|
||||
|
||||
bool getInProgress()
|
||||
{
|
||||
return m_inProgress;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void clear()
|
||||
{
|
||||
m_framesFilledUp = 0;
|
||||
m_energy = 0;
|
||||
memset( m_buffer, 0, sizeof( m_buffer ) );
|
||||
memset( m_bands, 0, sizeof( m_bands ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void analyze( sampleFrame *buf, const fpp_t frames )
|
||||
{
|
||||
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;
|
||||
m_inProgress = false;
|
||||
m_active = false;
|
||||
}
|
||||
}
|
||||
private:
|
||||
bool m_inProgress;
|
||||
};
|
||||
|
||||
|
||||
class EqSpectrumView : public QWidget
|
||||
{
|
||||
|
||||
public:
|
||||
explicit EqSpectrumView( EqAnalyser * b, QWidget * _parent = 0 ):
|
||||
QWidget( _parent ),
|
||||
m_sa( b )
|
||||
{
|
||||
setFixedSize( 250, 116 );
|
||||
QTimer *timer = new QTimer(this);
|
||||
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
|
||||
timer->start(2000);
|
||||
setAttribute( Qt::WA_TranslucentBackground, true );
|
||||
m_skipBands = MAX_BANDS * 0.5;
|
||||
float totalLength = log10( 21000);
|
||||
m_pixelsPerUnitWidth = width( ) / totalLength ;
|
||||
m_scale = 1.5;
|
||||
color = QColor( 255, 255, 255, 255 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
virtual ~EqSpectrumView()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
QColor color;
|
||||
EqAnalyser *m_sa;
|
||||
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 );
|
||||
p.setPen( QPen( color, 1, Qt::SolidLine, Qt::RoundCap, Qt::BevelJoin ) );
|
||||
const float e = m_sa->m_energy;
|
||||
if( e <= 0 )
|
||||
{
|
||||
//dont draw anything
|
||||
return;
|
||||
}
|
||||
if(m_sa->getInProgress() ){
|
||||
p.fillPath( pp ,QBrush( color ) );
|
||||
return;
|
||||
}
|
||||
pp = QPainterPath();
|
||||
float * b = m_sa->m_bands;
|
||||
int h;
|
||||
pp.moveTo( 0,height() );
|
||||
for( int x = 0; x < MAX_BANDS; ++x, ++b )
|
||||
{
|
||||
h = (int)( fh * 2.0 / 3.0 * ( 20 * ( log10 ( *b / e ) ) - LOWER_Y ) / (-LOWER_Y ) );
|
||||
if( h < 0 ) h = 0; else if( h >= fh ) continue;
|
||||
pp.lineTo( freqToXPixel(bandToFreq( x ) ), fh-h );
|
||||
}
|
||||
pp.lineTo( width(), height() );
|
||||
pp.closeSubpath();
|
||||
p.fillPath( pp, QBrush( color ) );
|
||||
p.drawPath( pp );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
inline int bandToXPixel( float band )
|
||||
{
|
||||
return ( log10( band - m_skipBands ) * m_pixelsPerUnitWidth * m_scale );
|
||||
}
|
||||
|
||||
inline float bandToFreq ( int index )
|
||||
{
|
||||
return index * m_sa->m_sr / (MAX_BANDS * 2 );
|
||||
}
|
||||
|
||||
|
||||
inline int freqToXPixel( float freq )
|
||||
{
|
||||
return ( log10( freq ) * m_pixelsPerUnitWidth * m_scale ) - ( width() * 0.5 );
|
||||
}
|
||||
private:
|
||||
float m_pixelsPerUnitWidth;
|
||||
float m_scale;
|
||||
int m_skipBands;
|
||||
} ;
|
||||
|
||||
|
||||
#endif // EQSPECTRUMVIEW_H
|
||||
BIN
plugins/Eq/artwork.png
Normal file
BIN
plugins/Eq/artwork.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
3
plugins/Flanger/CMakeLists.txt
Normal file
3
plugins/Flanger/CMakeLists.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
INCLUDE(BuildPlugin)
|
||||
|
||||
BUILD_PLUGIN(flanger FlangerEffect.cpp FlangerControls.cpp FlangerControlsDialog.cpp Noise.cpp QuadratureLfo.cpp MonoDelay.cpp MOCFILES FlangerControls.h EMBEDDED_RESOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.png")
|
||||
83
plugins/Flanger/FlangerControls.cpp
Normal file
83
plugins/Flanger/FlangerControls.cpp
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* flangercontrols.cpp - defination of FlangerControls class.
|
||||
*
|
||||
* Copyright (c) 2014 David French <dave/dot/french3/at/googlemail/dot/com>
|
||||
*
|
||||
* This file is part of LMMS - http://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 <QtXml/QDomElement>
|
||||
|
||||
#include "FlangerControls.h"
|
||||
#include "FlangerEffect.h"
|
||||
#include "Engine.h"
|
||||
#include "Song.h"
|
||||
|
||||
|
||||
|
||||
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, 5, 0.0001, 20000.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" ) )
|
||||
|
||||
{
|
||||
connect( Engine::mixer(), SIGNAL( sampleRateChanged() ), this, SLOT( changedSampleRate() ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void FlangerControls::loadSettings( const QDomElement &_this )
|
||||
{
|
||||
m_delayTimeModel.loadSettings( _this, "DelayTimeSamples" );
|
||||
m_lfoFrequencyModel.loadSettings( _this, "LfoFrequency" );
|
||||
m_lfoAmountModel.loadSettings( _this, "LfoAmount" );
|
||||
m_feedbackModel.loadSettings( _this, "Feedback" );
|
||||
m_whiteNoiseAmountModel.loadSettings( _this, "WhiteNoise" );
|
||||
m_invertFeedbackModel.loadSettings( _this, "Invert" );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
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_feedbackModel.saveSettings( doc, parent, "Feedback" ) ;
|
||||
m_whiteNoiseAmountModel.saveSettings( doc, parent , "WhiteNoise" ) ;
|
||||
m_invertFeedbackModel.saveSettings( doc, parent, "Invert" );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void FlangerControls::changedSampleRate()
|
||||
{
|
||||
m_effect->changeSampleRate();
|
||||
}
|
||||
|
||||
|
||||
@@ -27,48 +27,48 @@
|
||||
|
||||
#include "EffectControls.h"
|
||||
#include "Knob.h"
|
||||
#include "flangercontrolsdialog.h"
|
||||
#include "FlangerControlsDialog.h"
|
||||
|
||||
|
||||
class FlangerEffect;
|
||||
|
||||
class FlangerControls : public EffectControls
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
FlangerControls( FlangerEffect* effect );
|
||||
virtual ~FlangerControls()
|
||||
{
|
||||
}
|
||||
virtual void saveSettings ( QDomDocument& doc, QDomElement& parent );
|
||||
virtual void loadSettings ( const QDomElement &_this );
|
||||
inline virtual QString nodeName() const
|
||||
{
|
||||
return "Flanger";
|
||||
}
|
||||
virtual int controlCount()
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
virtual EffectControlDialog* createView()
|
||||
{
|
||||
return new FlangerControlsDialog( this );
|
||||
}
|
||||
FlangerControls( FlangerEffect* effect );
|
||||
virtual ~FlangerControls()
|
||||
{
|
||||
}
|
||||
virtual void saveSettings ( QDomDocument& doc, QDomElement& parent );
|
||||
virtual void loadSettings ( const QDomElement &_this );
|
||||
inline virtual QString nodeName() const
|
||||
{
|
||||
return "Flanger";
|
||||
}
|
||||
virtual int controlCount()
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
virtual EffectControlDialog* createView()
|
||||
{
|
||||
return new FlangerControlsDialog( this );
|
||||
}
|
||||
|
||||
private slots:
|
||||
void changedSampleRate();
|
||||
void changedSampleRate();
|
||||
|
||||
private:
|
||||
FlangerEffect* m_effect;
|
||||
FloatModel m_delayTimeModel;
|
||||
TempoSyncKnobModel m_lfoFrequencyModel;
|
||||
FloatModel m_lfoAmountModel;
|
||||
FloatModel m_feedbackModel;
|
||||
FloatModel m_whiteNoiseAmountModel;
|
||||
BoolModel m_invertFeedbackModel;
|
||||
FlangerEffect* m_effect;
|
||||
FloatModel m_delayTimeModel;
|
||||
TempoSyncKnobModel m_lfoFrequencyModel;
|
||||
FloatModel m_lfoAmountModel;
|
||||
FloatModel m_feedbackModel;
|
||||
FloatModel m_whiteNoiseAmountModel;
|
||||
BoolModel m_invertFeedbackModel;
|
||||
|
||||
friend class FlangerControlsDialog;
|
||||
friend class FlangerEffect;
|
||||
friend class FlangerControlsDialog;
|
||||
friend class FlangerEffect;
|
||||
|
||||
};
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "flangercontrolsdialog.h"
|
||||
#include "flangercontrols.h"
|
||||
#include "FlangerControlsDialog.h"
|
||||
#include "FlangerControls.h"
|
||||
#include "embed.h"
|
||||
#include "LedCheckbox.h"
|
||||
#include "TempoSyncKnob.h"
|
||||
@@ -32,10 +32,10 @@ class FlangerControls;
|
||||
class FlangerControlsDialog : public EffectControlDialog
|
||||
{
|
||||
public:
|
||||
FlangerControlsDialog( FlangerControls* controls );
|
||||
virtual ~FlangerControlsDialog()
|
||||
{
|
||||
}
|
||||
FlangerControlsDialog( FlangerControls* controls );
|
||||
virtual ~FlangerControlsDialog()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
#endif // FLANGERCONTROLSDIALOG_H
|
||||
151
plugins/Flanger/FlangerEffect.cpp
Normal file
151
plugins/Flanger/FlangerEffect.cpp
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* flangereffect.cpp - defination of FlangerEffect class.
|
||||
*
|
||||
* Copyright (c) 2014 David French <dave/dot/french3/at/googlemail/dot/com>
|
||||
*
|
||||
* This file is part of LMMS - http://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 "FlangerEffect.h"
|
||||
#include "Engine.h"
|
||||
#include "embed.cpp"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
Plugin::Descriptor PLUGIN_EXPORT flanger_plugin_descriptor =
|
||||
{
|
||||
STRINGIFY( PLUGIN_NAME ),
|
||||
"Flanger",
|
||||
QT_TRANSLATE_NOOP( "pluginBrowser", "A native flanger plugin" ),
|
||||
"Dave French <contact/dot/dave/dot/french3/at/googlemail/dot/com>",
|
||||
0x0100,
|
||||
Plugin::Effect,
|
||||
new PluginPixmapLoader( "logo" ),
|
||||
NULL,
|
||||
NULL
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
FlangerEffect::FlangerEffect( Model *parent, const Plugin::Descriptor::SubPluginFeatures::Key *key ) :
|
||||
Effect( &flanger_plugin_descriptor, parent, key ),
|
||||
m_flangerControls( this )
|
||||
{
|
||||
m_lfo = new QuadratureLfo( Engine::mixer()->processingSampleRate() );
|
||||
m_lDelay = new MonoDelay( 1, Engine::mixer()->processingSampleRate() );
|
||||
m_rDelay = new MonoDelay( 1, Engine::mixer()->processingSampleRate() );
|
||||
m_noise = new Noise;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
FlangerEffect::~FlangerEffect()
|
||||
{
|
||||
if(m_lDelay )
|
||||
{
|
||||
delete m_lDelay;
|
||||
}
|
||||
if( m_rDelay )
|
||||
{
|
||||
delete m_rDelay;
|
||||
}
|
||||
if(m_lfo )
|
||||
{
|
||||
delete m_lfo;
|
||||
}
|
||||
if(m_noise)
|
||||
{
|
||||
delete m_noise;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool FlangerEffect::processAudioBuffer( sampleFrame *buf, const fpp_t frames )
|
||||
{
|
||||
if( !isEnabled() || !isRunning () )
|
||||
{
|
||||
return( false );
|
||||
}
|
||||
double outSum = 0.0;
|
||||
const float d = dryLevel();
|
||||
const float w = wetLevel();
|
||||
const float length = m_flangerControls.m_delayTimeModel.value() * Engine::mixer()->processingSampleRate();
|
||||
const float noise = m_flangerControls.m_whiteNoiseAmountModel.value();
|
||||
float amplitude = m_flangerControls.m_lfoAmountModel.value() * Engine::mixer()->processingSampleRate();
|
||||
bool invertFeedback = m_flangerControls.m_invertFeedbackModel.value();
|
||||
m_lfo->setFrequency( m_flangerControls.m_lfoFrequencyModel.value() );
|
||||
m_lDelay->setFeedback( m_flangerControls.m_feedbackModel.value() );
|
||||
m_rDelay->setFeedback( m_flangerControls.m_feedbackModel.value() );
|
||||
sample_t dryS[2];
|
||||
float leftLfo;
|
||||
float rightLfo;
|
||||
for( fpp_t f = 0; f < frames; ++f )
|
||||
{
|
||||
buf[f][0] += m_noise->tick() * noise;
|
||||
buf[f][1] += m_noise->tick() * noise;
|
||||
dryS[0] = buf[f][0];
|
||||
dryS[1] = buf[f][1];
|
||||
m_lfo->tick(&leftLfo, &rightLfo);
|
||||
m_lDelay->setLength( ( float )length + ( amplitude * leftLfo ) );
|
||||
m_rDelay->setLength( ( float )length+ ( amplitude * rightLfo ) );
|
||||
if(invertFeedback)
|
||||
{
|
||||
m_lDelay->tick( &buf[f][1] );
|
||||
m_rDelay->tick(&buf[f][0] );
|
||||
} else
|
||||
{
|
||||
m_lDelay->tick( &buf[f][0] );
|
||||
m_rDelay->tick( &buf[f][1] );
|
||||
}
|
||||
|
||||
buf[f][0] = ( d * dryS[0] ) + ( w * buf[f][0] );
|
||||
buf[f][1] = ( d * dryS[1] ) + ( w * buf[f][1] );
|
||||
outSum += buf[f][0]*buf[f][0] + buf[f][1]*buf[f][1];
|
||||
}
|
||||
checkGate( outSum / frames );
|
||||
return isRunning();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void FlangerEffect::changeSampleRate()
|
||||
{
|
||||
m_lfo->setSampleRate( Engine::mixer()->processingSampleRate() );
|
||||
m_lDelay->setSampleRate( Engine::mixer()->processingSampleRate() );
|
||||
m_rDelay->setSampleRate( Engine::mixer()->processingSampleRate() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
//needed for getting plugin out of shared lib
|
||||
Plugin * PLUGIN_EXPORT lmms_plugin_main( Model* parent, void* data )
|
||||
{
|
||||
return new FlangerEffect( parent , static_cast<const Plugin::Descriptor::SubPluginFeatures::Key *>( data ) );
|
||||
}
|
||||
|
||||
}}
|
||||
@@ -27,30 +27,30 @@
|
||||
#define FLANGEREFFECT_H
|
||||
|
||||
#include "Effect.h"
|
||||
#include "flangercontrols.h"
|
||||
#include "quadraturelfo.h"
|
||||
#include "monodelay.h"
|
||||
#include "noise.h"
|
||||
#include "FlangerControls.h"
|
||||
#include "QuadratureLfo.h"
|
||||
#include "MonoDelay.h"
|
||||
#include "Noise.h"
|
||||
|
||||
|
||||
class FlangerEffect : public Effect
|
||||
{
|
||||
public:
|
||||
FlangerEffect( Model* parent , const Descriptor::SubPluginFeatures::Key* key );
|
||||
virtual ~FlangerEffect();
|
||||
virtual bool processAudioBuffer( sampleFrame *buf, const fpp_t frames );
|
||||
virtual EffectControls* controls()
|
||||
{
|
||||
return &m_flangerControls;
|
||||
}
|
||||
void changeSampleRate();
|
||||
FlangerEffect( Model* parent , const Descriptor::SubPluginFeatures::Key* key );
|
||||
virtual ~FlangerEffect();
|
||||
virtual bool processAudioBuffer( sampleFrame *buf, const fpp_t frames );
|
||||
virtual EffectControls* controls()
|
||||
{
|
||||
return &m_flangerControls;
|
||||
}
|
||||
void changeSampleRate();
|
||||
|
||||
private:
|
||||
FlangerControls m_flangerControls;
|
||||
MonoDelay* m_lDelay;
|
||||
MonoDelay* m_rDelay;
|
||||
QuadratureLfo* m_lfo;
|
||||
Noise* m_noise;
|
||||
FlangerControls m_flangerControls;
|
||||
MonoDelay* m_lDelay;
|
||||
MonoDelay* m_rDelay;
|
||||
QuadratureLfo* m_lfo;
|
||||
Noise* m_noise;
|
||||
|
||||
};
|
||||
|
||||
@@ -22,20 +22,20 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "monodelay.h"
|
||||
#include "MonoDelay.h"
|
||||
#include "interpolation.h"
|
||||
#include "lmms_math.h"
|
||||
|
||||
MonoDelay::MonoDelay( int maxTime , int sampleRate )
|
||||
{
|
||||
m_buffer = 0;
|
||||
m_maxTime = maxTime;
|
||||
m_maxLength = maxTime * sampleRate;
|
||||
m_length = m_maxLength;
|
||||
m_buffer = 0;
|
||||
m_maxTime = maxTime;
|
||||
m_maxLength = maxTime * sampleRate;
|
||||
m_length = m_maxLength;
|
||||
|
||||
m_index = 0;
|
||||
m_feedback = 0.0f;
|
||||
setSampleRate( sampleRate );
|
||||
m_index = 0;
|
||||
m_feedback = 0.0f;
|
||||
setSampleRate( sampleRate );
|
||||
}
|
||||
|
||||
|
||||
@@ -43,10 +43,10 @@ MonoDelay::MonoDelay( int maxTime , int sampleRate )
|
||||
|
||||
MonoDelay::~MonoDelay()
|
||||
{
|
||||
if( m_buffer )
|
||||
{
|
||||
delete m_buffer;
|
||||
}
|
||||
if( m_buffer )
|
||||
{
|
||||
delete m_buffer;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -54,24 +54,24 @@ MonoDelay::~MonoDelay()
|
||||
|
||||
void MonoDelay::tick( sample_t* sample )
|
||||
{
|
||||
m_buffer[m_index] = *sample;
|
||||
int readIndex = m_index - ( int )m_length;
|
||||
if(readIndex < 0)
|
||||
{
|
||||
readIndex += m_maxLength;
|
||||
}
|
||||
float fract = fraction( m_length );
|
||||
if(readIndex != m_maxLength-1 )
|
||||
{
|
||||
*sample = linearInterpolate(m_buffer[readIndex] ,
|
||||
m_buffer[readIndex+1], fract );
|
||||
} else
|
||||
{
|
||||
*sample = linearInterpolate(m_buffer[readIndex] ,
|
||||
m_buffer[0], fract );
|
||||
}
|
||||
m_buffer[m_index] += *sample * m_feedback;
|
||||
m_index = ( m_index +1 ) % m_maxLength;
|
||||
m_buffer[m_index] = *sample;
|
||||
int readIndex = m_index - ( int )m_length - 1;
|
||||
if(readIndex < 0)
|
||||
{
|
||||
readIndex += m_maxLength;
|
||||
}
|
||||
float fract = 1.0f - fraction( m_length );
|
||||
if(readIndex != m_maxLength-1 )
|
||||
{
|
||||
*sample = linearInterpolate(m_buffer[readIndex] ,
|
||||
m_buffer[readIndex+1], fract );
|
||||
} else
|
||||
{
|
||||
*sample = linearInterpolate(m_buffer[readIndex] ,
|
||||
m_buffer[0], fract );
|
||||
}
|
||||
m_buffer[m_index] += *sample * m_feedback;
|
||||
m_index = ( m_index +1 ) % m_maxLength;
|
||||
}
|
||||
|
||||
|
||||
@@ -79,11 +79,11 @@ void MonoDelay::tick( sample_t* sample )
|
||||
|
||||
void MonoDelay::setSampleRate( int sampleRate )
|
||||
{
|
||||
if( m_buffer )
|
||||
{
|
||||
delete m_buffer;
|
||||
}
|
||||
if( m_buffer )
|
||||
{
|
||||
delete m_buffer;
|
||||
}
|
||||
|
||||
|
||||
m_buffer = new sample_t[( int )( sampleRate * m_maxTime )];
|
||||
m_buffer = new sample_t[( int )( sampleRate * m_maxTime )];
|
||||
}
|
||||
@@ -30,31 +30,31 @@
|
||||
class MonoDelay
|
||||
{
|
||||
public:
|
||||
MonoDelay( int maxTime , int sampleRate );
|
||||
~MonoDelay();
|
||||
inline void setLength( float length )
|
||||
{
|
||||
if( length <= m_maxLength && length >= 0 )
|
||||
{
|
||||
m_length = length;
|
||||
}
|
||||
}
|
||||
MonoDelay( int maxTime , int sampleRate );
|
||||
~MonoDelay();
|
||||
inline void setLength( float length )
|
||||
{
|
||||
if( length <= m_maxLength && length >= 0 )
|
||||
{
|
||||
m_length = length;
|
||||
}
|
||||
}
|
||||
|
||||
inline void setFeedback( float feedback )
|
||||
{
|
||||
m_feedback = feedback;
|
||||
}
|
||||
inline void setFeedback( float feedback )
|
||||
{
|
||||
m_feedback = feedback;
|
||||
}
|
||||
|
||||
void tick( sample_t* sample );
|
||||
void setSampleRate( int sampleRate );
|
||||
void tick( sample_t* sample );
|
||||
void setSampleRate( int sampleRate );
|
||||
|
||||
private:
|
||||
sample_t* m_buffer;
|
||||
int m_maxLength;
|
||||
float m_length;
|
||||
int m_index;
|
||||
float m_feedback;
|
||||
float m_maxTime;
|
||||
sample_t* m_buffer;
|
||||
int m_maxLength;
|
||||
float m_length;
|
||||
int m_index;
|
||||
float m_feedback;
|
||||
float m_maxTime;
|
||||
};
|
||||
|
||||
#endif // MONODELAY_H
|
||||
@@ -22,12 +22,12 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "noise.h"
|
||||
#include "Noise.h"
|
||||
#include "lmms_math.h"
|
||||
|
||||
Noise::Noise()
|
||||
{
|
||||
inv_randmax = 1.0/FAST_RAND_MAX; /* for range of 0 - 1.0 */
|
||||
inv_randmax = 1.0/FAST_RAND_MAX; /* for range of 0 - 1.0 */
|
||||
}
|
||||
|
||||
|
||||
@@ -35,5 +35,5 @@ Noise::Noise()
|
||||
|
||||
float Noise::tick()
|
||||
{
|
||||
return (float) ((2.0 * fast_rand() * inv_randmax) - 1.0);
|
||||
return (float) ((2.0 * fast_rand() * inv_randmax) - 1.0);
|
||||
}
|
||||
@@ -28,10 +28,10 @@
|
||||
class Noise
|
||||
{
|
||||
public:
|
||||
Noise();
|
||||
float tick();
|
||||
Noise();
|
||||
float tick();
|
||||
private:
|
||||
double inv_randmax;
|
||||
double inv_randmax;
|
||||
};
|
||||
|
||||
#endif // NOISE_H
|
||||
@@ -22,17 +22,17 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "quadraturelfo.h"
|
||||
#include "QuadratureLfo.h"
|
||||
|
||||
QuadratureLfo::QuadratureLfo( int sampleRate )
|
||||
{
|
||||
setSampleRate(sampleRate);
|
||||
setSampleRate(sampleRate);
|
||||
}
|
||||
|
||||
void QuadratureLfo::tick( float *s, float *c )
|
||||
{
|
||||
*s = sinf( m_phase );
|
||||
*c = cosf( m_phase );
|
||||
m_phase += m_increment;
|
||||
*s = sinf( m_phase );
|
||||
*c = cosf( m_phase );
|
||||
m_phase += m_increment;
|
||||
|
||||
}
|
||||
@@ -30,44 +30,44 @@
|
||||
class QuadratureLfo
|
||||
{
|
||||
public:
|
||||
QuadratureLfo( int sampleRate );
|
||||
~QuadratureLfo()
|
||||
{
|
||||
}
|
||||
QuadratureLfo( int sampleRate );
|
||||
~QuadratureLfo()
|
||||
{
|
||||
}
|
||||
|
||||
inline void setFrequency( double frequency )
|
||||
{
|
||||
if( frequency < 0 || frequency > ( m_samplerate / 2.0 ) || frequency == m_frequency )
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_frequency = frequency;
|
||||
m_increment = m_frequency * m_twoPiOverSr;
|
||||
inline void setFrequency( double 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;
|
||||
}
|
||||
}
|
||||
if( m_phase >= F_2PI )
|
||||
{
|
||||
m_phase -= F_2PI;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
inline void setSampleRate ( int samplerate )
|
||||
{
|
||||
m_samplerate = samplerate;
|
||||
m_twoPiOverSr = F_2PI / samplerate;
|
||||
m_increment = m_frequency * m_twoPiOverSr;
|
||||
}
|
||||
inline void setSampleRate ( int samplerate )
|
||||
{
|
||||
m_samplerate = samplerate;
|
||||
m_twoPiOverSr = F_2PI / samplerate;
|
||||
m_increment = m_frequency * m_twoPiOverSr;
|
||||
}
|
||||
|
||||
void tick( float *s, float *c );
|
||||
void tick( float *s, float *c );
|
||||
|
||||
private:
|
||||
double m_frequency;
|
||||
double m_phase;
|
||||
double m_increment;
|
||||
double m_twoPiOverSr;
|
||||
int m_samplerate;
|
||||
double m_frequency;
|
||||
double m_phase;
|
||||
double m_increment;
|
||||
double m_twoPiOverSr;
|
||||
int m_samplerate;
|
||||
|
||||
};
|
||||
|
||||
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
BIN
plugins/Flanger/logo.png
Normal file
BIN
plugins/Flanger/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.1 KiB |
@@ -567,6 +567,22 @@ lookahead_limiter::lookahead_limiter() {
|
||||
asc_coeff = 1.f;
|
||||
}
|
||||
|
||||
lookahead_limiter::~lookahead_limiter()
|
||||
{
|
||||
if( buffer != NULL)
|
||||
{
|
||||
free(buffer);
|
||||
}
|
||||
if( nextpos != NULL)
|
||||
{
|
||||
free(nextpos);
|
||||
}
|
||||
if( nextdelta != NULL)
|
||||
{
|
||||
free(nextdelta);
|
||||
}
|
||||
}
|
||||
|
||||
void lookahead_limiter::activate()
|
||||
{
|
||||
is_active = true;
|
||||
|
||||
@@ -608,6 +608,7 @@ public:
|
||||
void reset_asc();
|
||||
bool get_asc();
|
||||
lookahead_limiter();
|
||||
~lookahead_limiter();
|
||||
void set_multi(bool set);
|
||||
void process(float &left, float &right, float *multi_buffer);
|
||||
void set_sample_rate(uint32_t sr);
|
||||
|
||||
@@ -47,6 +47,7 @@ struct ladspa_instance: public plugin_ctl_iface
|
||||
#endif
|
||||
|
||||
ladspa_instance(audio_module_iface *_module, ladspa_plugin_metadata_set *_ladspa, int sample_rate);
|
||||
virtual ~ladspa_instance();
|
||||
virtual const line_graph_iface *get_line_graph_iface() const { return module->get_line_graph_iface(); }
|
||||
virtual float get_param_value(int param_no);
|
||||
virtual void set_param_value(int param_no, float value);
|
||||
|
||||
@@ -263,6 +263,7 @@ class mono_audio_module:
|
||||
}
|
||||
public:
|
||||
mono_audio_module();
|
||||
~mono_audio_module();
|
||||
void params_changed();
|
||||
void activate();
|
||||
void set_sample_rate(uint32_t sr);
|
||||
@@ -291,6 +292,7 @@ class stereo_audio_module:
|
||||
}
|
||||
public:
|
||||
stereo_audio_module();
|
||||
~stereo_audio_module();
|
||||
void params_changed();
|
||||
void activate();
|
||||
void set_sample_rate(uint32_t sr);
|
||||
|
||||
@@ -84,6 +84,7 @@ public:
|
||||
uint32_t srate;
|
||||
bool is_active;
|
||||
multibandlimiter_audio_module();
|
||||
~multibandlimiter_audio_module();
|
||||
void activate();
|
||||
void deactivate();
|
||||
void params_changed();
|
||||
|
||||
@@ -460,6 +460,14 @@ stereo_audio_module::stereo_audio_module() {
|
||||
meter_outR = 0.f;
|
||||
}
|
||||
|
||||
stereo_audio_module::~stereo_audio_module()
|
||||
{
|
||||
if( buffer != NULL )
|
||||
{
|
||||
free(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
void stereo_audio_module::activate() {
|
||||
active = true;
|
||||
}
|
||||
@@ -686,6 +694,14 @@ mono_audio_module::mono_audio_module() {
|
||||
meter_outR = 0.f;
|
||||
}
|
||||
|
||||
mono_audio_module::~mono_audio_module()
|
||||
{
|
||||
if( buffer != NULL )
|
||||
{
|
||||
free(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
void mono_audio_module::activate() {
|
||||
active = true;
|
||||
}
|
||||
|
||||
@@ -252,6 +252,14 @@ multibandlimiter_audio_module::multibandlimiter_audio_module()
|
||||
asc_old = true;
|
||||
}
|
||||
|
||||
multibandlimiter_audio_module::~multibandlimiter_audio_module()
|
||||
{
|
||||
if( buffer != NULL)
|
||||
{
|
||||
free(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
void multibandlimiter_audio_module::activate()
|
||||
{
|
||||
is_active = true;
|
||||
|
||||
@@ -54,6 +54,11 @@ ladspa_instance::ladspa_instance(audio_module_iface *_module, ladspa_plugin_meta
|
||||
module->post_instantiate();
|
||||
}
|
||||
|
||||
ladspa_instance::~ladspa_instance()
|
||||
{
|
||||
delete module;
|
||||
}
|
||||
|
||||
float ladspa_instance::get_param_value(int param_no)
|
||||
{
|
||||
// XXXKF hack
|
||||
|
||||
@@ -116,6 +116,8 @@ static void activateDj_eq_mono(LADSPA_Handle instance) {
|
||||
}
|
||||
|
||||
static void cleanupDj_eq_mono(LADSPA_Handle instance) {
|
||||
Dj_eq_mono *plugin_data = (Dj_eq_mono *)instance;
|
||||
free(plugin_data->filters);
|
||||
free(instance);
|
||||
}
|
||||
|
||||
@@ -283,6 +285,8 @@ static void activateDj_eq(LADSPA_Handle instance) {
|
||||
}
|
||||
|
||||
static void cleanupDj_eq(LADSPA_Handle instance) {
|
||||
Dj_eq *plugin_data = (Dj_eq *)instance;
|
||||
free(plugin_data->filters);
|
||||
free(instance);
|
||||
}
|
||||
|
||||
|
||||
@@ -137,6 +137,7 @@ static void cleanupFastLookaheadLimiter(LADSPA_Handle instance) {
|
||||
#line 188 "fast_lookahead_limiter_1913.xml"
|
||||
FastLookaheadLimiter *plugin_data = (FastLookaheadLimiter *)instance;
|
||||
free(plugin_data->buffer);
|
||||
free(plugin_data->chunks);
|
||||
free(instance);
|
||||
}
|
||||
|
||||
|
||||
@@ -202,6 +202,11 @@ static void cleanupImp(LADSPA_Handle instance) {
|
||||
local_free(plugin_data->op);
|
||||
local_free(plugin_data->overlap);
|
||||
local_free(plugin_data->opc);
|
||||
unsigned int i;
|
||||
for (i=0; i<IMPULSES; i++) {
|
||||
local_free(plugin_data->impulse_freq[i]);
|
||||
}
|
||||
local_free(plugin_data->impulse_freq);
|
||||
free(instance);
|
||||
}
|
||||
|
||||
|
||||
@@ -163,6 +163,7 @@ static void cleanupVynil(LADSPA_Handle instance) {
|
||||
free(plugin_data->buffer_m);
|
||||
free(plugin_data->buffer_s);
|
||||
free(plugin_data->click_buffer);
|
||||
free(plugin_data->highp);
|
||||
free(plugin_data->lowp_m);
|
||||
free(plugin_data->lowp_s);
|
||||
free(plugin_data->noise_filt);
|
||||
|
||||
@@ -145,7 +145,8 @@ activate_eq(LADSPA_Handle instance) {
|
||||
static
|
||||
void
|
||||
cleanup_eq(LADSPA_Handle instance) {
|
||||
|
||||
eq *plugin_data = (eq *)instance;
|
||||
free(plugin_data->filters);
|
||||
free(instance);
|
||||
}
|
||||
|
||||
|
||||
@@ -167,7 +167,8 @@ activate_eq(LADSPA_Handle instance) {
|
||||
static
|
||||
void
|
||||
cleanup_eq(LADSPA_Handle instance) {
|
||||
|
||||
eq *plugin_data = (eq *)instance;
|
||||
free(plugin_data->filters);
|
||||
free(instance);
|
||||
}
|
||||
|
||||
|
||||
@@ -150,7 +150,7 @@ bool SpectrumAnalyzer::processAudioBuffer( sampleFrame* _buf, const fpp_t _frame
|
||||
|
||||
m_framesFilledUp = 0;
|
||||
|
||||
checkGate( 0 );
|
||||
checkGate( 1 );
|
||||
|
||||
return isRunning();
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "ConfigManager.h"
|
||||
|
||||
|
||||
|
||||
VstSubPluginFeatures::VstSubPluginFeatures( Plugin::PluginTypes _type ) :
|
||||
SubPluginFeatures( _type )
|
||||
{
|
||||
@@ -52,16 +53,40 @@ void VstSubPluginFeatures::fillDescriptionWidget( QWidget * _parent,
|
||||
void VstSubPluginFeatures::listSubPluginKeys( const Plugin::Descriptor * _desc,
|
||||
KeyList & _kl ) const
|
||||
{
|
||||
QStringList dlls = QDir( ConfigManager::inst()->vstDir() ).
|
||||
entryList( QStringList() << "*.dll",
|
||||
QDir::Files, QDir::Name );
|
||||
QStringList *dlls = new QStringList();
|
||||
const QString path = QString("");
|
||||
addPluginsFromDir(dlls, path );
|
||||
// TODO: eval m_type
|
||||
for( QStringList::ConstIterator it = dlls.begin();
|
||||
it != dlls.end(); ++it )
|
||||
for( QStringList::ConstIterator it = dlls->begin();
|
||||
it != dlls->end(); ++it )
|
||||
{
|
||||
EffectKey::AttributeMap am;
|
||||
am["file"] = *it;
|
||||
_kl.push_back( Key( _desc, QFileInfo( *it ).baseName(), am ) );
|
||||
}
|
||||
delete dlls;
|
||||
}
|
||||
|
||||
void VstSubPluginFeatures::addPluginsFromDir( QStringList* filenames, QString path ) const
|
||||
{
|
||||
QStringList dirs = QDir ( ConfigManager::inst()->vstDir() + path ).
|
||||
entryList( QStringList() << "*" ,
|
||||
QDir::Dirs, QDir::Name );
|
||||
for( int i = 0; i < dirs.size(); i++ )
|
||||
{
|
||||
if( dirs.at( i )[0] != '.' )
|
||||
{
|
||||
addPluginsFromDir( filenames, path+QDir::separator() + dirs.at( i ) );
|
||||
}
|
||||
}
|
||||
QStringList dlls = QDir( ConfigManager::inst()->vstDir() + path ).
|
||||
entryList( QStringList() << "*.dll",
|
||||
QDir::Files, QDir::Name );
|
||||
for( int i = 0; i < dlls.size(); i++ )
|
||||
{
|
||||
QString fName = path + QDir::separator() + dlls.at( i );
|
||||
fName.remove( 0, 1 );
|
||||
filenames->append( fName );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,8 +40,13 @@ public:
|
||||
|
||||
virtual void listSubPluginKeys( const Plugin::Descriptor * _desc,
|
||||
KeyList & _kl ) const;
|
||||
|
||||
private:
|
||||
void addPluginsFromDir(QStringList* filenames, QString path) const;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -71,4 +71,3 @@ DelayControlsDialog::DelayControlsDialog( DelayControls *controls ) :
|
||||
}
|
||||
|
||||
|
||||
#include "moc_delaycontrols.cxx"
|
||||
|
||||
@@ -214,11 +214,10 @@ bool dynProcEffect::processAudioBuffer( sampleFrame * _buf,
|
||||
s[0] *= outputGain;
|
||||
s[1] *= outputGain;
|
||||
|
||||
out_sum += _buf[f][0]*_buf[f][0] + _buf[f][1]*_buf[f][1];
|
||||
// mix wet/dry signals
|
||||
_buf[f][0] = d * _buf[f][0] + w * s[0];
|
||||
_buf[f][1] = d * _buf[f][1] + w * s[1];
|
||||
|
||||
out_sum += _buf[f][0]*_buf[f][0] + _buf[f][1]*_buf[f][1];
|
||||
}
|
||||
|
||||
checkGate( out_sum / _frames );
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
INCLUDE(BuildPlugin)
|
||||
|
||||
BUILD_PLUGIN(flanger flangereffect.cpp flangercontrols.cpp flangercontrolsdialog.cpp noise.cpp quadraturelfo.cpp monodelay.cpp MOCFILES flangercontrols.h EMBEDDED_RESOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.png")
|
||||
@@ -1,83 +0,0 @@
|
||||
/*
|
||||
* flangercontrols.cpp - defination of FlangerControls class.
|
||||
*
|
||||
* Copyright (c) 2014 David French <dave/dot/french3/at/googlemail/dot/com>
|
||||
*
|
||||
* This file is part of LMMS - http://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 <QtXml/QDomElement>
|
||||
|
||||
#include "flangercontrols.h"
|
||||
#include "flangereffect.h"
|
||||
#include "Engine.h"
|
||||
#include "Song.h"
|
||||
|
||||
|
||||
|
||||
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, 5, 0.0001, 20000.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" ) )
|
||||
|
||||
{
|
||||
connect( Engine::mixer(), SIGNAL( sampleRateChanged() ), this, SLOT( changedSampleRate() ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void FlangerControls::loadSettings( const QDomElement &_this )
|
||||
{
|
||||
m_delayTimeModel.loadSettings( _this, "DelayTimeSamples" );
|
||||
m_lfoFrequencyModel.loadSettings( _this, "LfoFrequency" );
|
||||
m_lfoAmountModel.loadSettings( _this, "LfoAmount" );
|
||||
m_feedbackModel.loadSettings( _this, "Feedback" );
|
||||
m_whiteNoiseAmountModel.loadSettings( _this, "WhiteNoise" );
|
||||
m_invertFeedbackModel.loadSettings( _this, "Invert" );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
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_feedbackModel.saveSettings( doc, parent, "Feedback" ) ;
|
||||
m_whiteNoiseAmountModel.saveSettings( doc, parent , "WhiteNoise" ) ;
|
||||
m_invertFeedbackModel.saveSettings( doc, parent, "Invert" );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void FlangerControls::changedSampleRate()
|
||||
{
|
||||
m_effect->changeSampleRate();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,151 +0,0 @@
|
||||
/*
|
||||
* flangereffect.cpp - defination of FlangerEffect class.
|
||||
*
|
||||
* Copyright (c) 2014 David French <dave/dot/french3/at/googlemail/dot/com>
|
||||
*
|
||||
* This file is part of LMMS - http://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 "flangereffect.h"
|
||||
#include "Engine.h"
|
||||
#include "embed.cpp"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
Plugin::Descriptor PLUGIN_EXPORT flanger_plugin_descriptor =
|
||||
{
|
||||
STRINGIFY( PLUGIN_NAME ),
|
||||
"Flanger",
|
||||
QT_TRANSLATE_NOOP( "pluginBrowser", "A native flanger plugin" ),
|
||||
"Dave French <contact/dot/dave/dot/french3/at/googlemail/dot/com>",
|
||||
0x0100,
|
||||
Plugin::Effect,
|
||||
new PluginPixmapLoader( "logo" ),
|
||||
NULL,
|
||||
NULL
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
FlangerEffect::FlangerEffect( Model *parent, const Plugin::Descriptor::SubPluginFeatures::Key *key ) :
|
||||
Effect( &flanger_plugin_descriptor, parent, key ),
|
||||
m_flangerControls( this )
|
||||
{
|
||||
m_lfo = new QuadratureLfo( Engine::mixer()->processingSampleRate() );
|
||||
m_lDelay = new MonoDelay( 1, Engine::mixer()->processingSampleRate() );
|
||||
m_rDelay = new MonoDelay( 1, Engine::mixer()->processingSampleRate() );
|
||||
m_noise = new Noise;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
FlangerEffect::~FlangerEffect()
|
||||
{
|
||||
if(m_lDelay )
|
||||
{
|
||||
delete m_lDelay;
|
||||
}
|
||||
if( m_rDelay )
|
||||
{
|
||||
delete m_rDelay;
|
||||
}
|
||||
if(m_lfo )
|
||||
{
|
||||
delete m_lfo;
|
||||
}
|
||||
if(m_noise)
|
||||
{
|
||||
delete m_noise;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool FlangerEffect::processAudioBuffer( sampleFrame *buf, const fpp_t frames )
|
||||
{
|
||||
if( !isEnabled() || !isRunning () )
|
||||
{
|
||||
return( false );
|
||||
}
|
||||
double outSum = 0.0;
|
||||
const float d = dryLevel();
|
||||
const float w = wetLevel();
|
||||
const float length = m_flangerControls.m_delayTimeModel.value() * Engine::mixer()->processingSampleRate();
|
||||
const float noise = m_flangerControls.m_whiteNoiseAmountModel.value();
|
||||
float amplitude = m_flangerControls.m_lfoAmountModel.value() * Engine::mixer()->processingSampleRate();
|
||||
bool invertFeedback = m_flangerControls.m_invertFeedbackModel.value();
|
||||
m_lfo->setFrequency( m_flangerControls.m_lfoFrequencyModel.value() );
|
||||
m_lDelay->setFeedback( m_flangerControls.m_feedbackModel.value() );
|
||||
m_rDelay->setFeedback( m_flangerControls.m_feedbackModel.value() );
|
||||
sample_t dryS[2];
|
||||
float leftLfo;
|
||||
float rightLfo;
|
||||
for( fpp_t f = 0; f < frames; ++f )
|
||||
{
|
||||
buf[f][0] += m_noise->tick() * noise;
|
||||
buf[f][1] += m_noise->tick() * noise;
|
||||
dryS[0] = buf[f][0];
|
||||
dryS[1] = buf[f][1];
|
||||
m_lfo->tick(&leftLfo, &rightLfo);
|
||||
m_lDelay->setLength( ( float )length + ( amplitude * leftLfo ) );
|
||||
m_rDelay->setLength( ( float )length+ ( amplitude * rightLfo ) );
|
||||
if(invertFeedback)
|
||||
{
|
||||
m_lDelay->tick( &buf[f][1] );
|
||||
m_rDelay->tick(&buf[f][0] );
|
||||
} else
|
||||
{
|
||||
m_lDelay->tick( &buf[f][0] );
|
||||
m_rDelay->tick( &buf[f][1] );
|
||||
}
|
||||
|
||||
buf[f][0] = ( d * dryS[0] ) + ( w * buf[f][0] );
|
||||
buf[f][1] = ( d * dryS[1] ) + ( w * buf[f][1] );
|
||||
outSum += buf[f][0]*buf[f][0] + buf[f][1]*buf[f][1];
|
||||
}
|
||||
checkGate( outSum / frames );
|
||||
return isRunning();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void FlangerEffect::changeSampleRate()
|
||||
{
|
||||
m_lfo->setSampleRate( Engine::mixer()->processingSampleRate() );
|
||||
m_lDelay->setSampleRate( Engine::mixer()->processingSampleRate() );
|
||||
m_rDelay->setSampleRate( Engine::mixer()->processingSampleRate() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
//needed for getting plugin out of shared lib
|
||||
Plugin * PLUGIN_EXPORT lmms_plugin_main( Model* parent, void* data )
|
||||
{
|
||||
return new FlangerEffect( parent , static_cast<const Plugin::Descriptor::SubPluginFeatures::Key *>( data ) );
|
||||
}
|
||||
|
||||
}}
|
||||
@@ -172,10 +172,11 @@ void VstPlugin::tryLoad( const QString &remoteVstPluginExecutable )
|
||||
|
||||
|
||||
QString p = m_plugin;
|
||||
if( QFileInfo( p ).dir().isRelative() )
|
||||
{
|
||||
p = ConfigManager::inst()->vstDir() + QDir::separator() + p;
|
||||
}
|
||||
if( QFileInfo( p ).dir().isRelative() )
|
||||
{
|
||||
p = ConfigManager::inst()->vstDir() + p;
|
||||
}
|
||||
|
||||
|
||||
sendMessage( message( IdVstLoadPlugin ).addString( QSTR_TO_STDSTR( p ) ) );
|
||||
|
||||
|
||||
@@ -130,11 +130,10 @@ bool waveShaperEffect::processAudioBuffer( sampleFrame * _buf,
|
||||
s[0] *= output;
|
||||
s[1] *= output;
|
||||
|
||||
out_sum += _buf[f][0]*_buf[f][0] + _buf[f][1]*_buf[f][1];
|
||||
// mix wet/dry signals
|
||||
_buf[f][0] = d * _buf[f][0] + w * s[0];
|
||||
_buf[f][1] = d * _buf[f][1] + w * s[1];
|
||||
|
||||
out_sum += _buf[f][0]*_buf[f][0] + _buf[f][1]*_buf[f][1];
|
||||
}
|
||||
|
||||
checkGate( out_sum / _frames );
|
||||
|
||||
Reference in New Issue
Block a user