2010-01-23 19:44:49 +00:00
|
|
|
/**********************************************************************
|
|
|
|
|
|
|
|
Audacity: A Digital Audio Editor
|
|
|
|
|
|
|
|
Wahwah.cpp
|
|
|
|
|
|
|
|
Effect programming:
|
2013-06-21 22:23:47 +00:00
|
|
|
Nasca Octavian Paul (Paul Nasca)
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
UI programming:
|
|
|
|
Dominic Mazzoni (with the help of wxDesigner)
|
|
|
|
Vaughan Johnson (Preview)
|
|
|
|
|
|
|
|
*******************************************************************//**
|
|
|
|
|
|
|
|
\class EffectWahwah
|
2015-05-09 16:36:54 +00:00
|
|
|
\brief An Effect that adds a 'spectral glide'.
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
*//*******************************************************************/
|
|
|
|
|
|
|
|
#include "../Audacity.h"
|
2015-06-18 14:24:36 +00:00
|
|
|
#include "Wahwah.h"
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
#include <math.h>
|
|
|
|
|
|
|
|
#include <wx/intl.h>
|
2015-04-17 03:53:42 +00:00
|
|
|
|
2015-06-18 14:24:36 +00:00
|
|
|
#include "../ShuttleGui.h"
|
2015-04-17 03:53:42 +00:00
|
|
|
#include "../widgets/valnum.h"
|
|
|
|
|
2015-08-31 19:50:50 +00:00
|
|
|
#include "../Experimental.h"
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
ID_Freq = 10000,
|
|
|
|
ID_Phase,
|
|
|
|
ID_Depth,
|
|
|
|
ID_Res,
|
2015-08-03 19:07:17 +00:00
|
|
|
ID_FreqOfs,
|
|
|
|
ID_OutGain
|
2015-04-17 03:53:42 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// Define keys, defaults, minimums, and maximums for the effect parameters
|
|
|
|
//
|
2015-04-19 03:49:05 +00:00
|
|
|
// Name Type Key Def Min Max Scale
|
2017-10-03 22:07:04 +00:00
|
|
|
Param( Freq, double, wxT("Freq"), 1.5, 0.1, 4.0, 10 );
|
|
|
|
Param( Phase, double, wxT("Phase"), 0.0, 0.0, 360.0, 1 );
|
|
|
|
Param( Depth, int, wxT("Depth"), 70, 0, 100, 1 ); // scaled to 0-1 before processing
|
|
|
|
Param( Res, double, wxT("Resonance"), 2.5, 0.1, 10.0, 10 );
|
|
|
|
Param( FreqOfs, int, wxT("Offset"), 30, 0, 100, 1 ); // scaled to 0-1 before processing
|
|
|
|
Param( OutGain, double, wxT("Gain"), -6.0, -30.0, 30.0, 1 );
|
2015-04-17 03:53:42 +00:00
|
|
|
|
|
|
|
// How many samples are processed before recomputing the lfo value again
|
|
|
|
#define lfoskipsamples 30
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
//
|
|
|
|
// EffectWahwah
|
|
|
|
//
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
BEGIN_EVENT_TABLE(EffectWahwah, wxEvtHandler)
|
|
|
|
EVT_SLIDER(ID_Freq, EffectWahwah::OnFreqSlider)
|
|
|
|
EVT_SLIDER(ID_Phase, EffectWahwah::OnPhaseSlider)
|
|
|
|
EVT_SLIDER(ID_Depth, EffectWahwah::OnDepthSlider)
|
|
|
|
EVT_SLIDER(ID_Res, EffectWahwah::OnResonanceSlider)
|
|
|
|
EVT_SLIDER(ID_FreqOfs, EffectWahwah::OnFreqOffSlider)
|
2015-08-03 19:07:17 +00:00
|
|
|
EVT_SLIDER(ID_OutGain, EffectWahwah::OnGainSlider)
|
2015-04-17 03:53:42 +00:00
|
|
|
EVT_TEXT(ID_Freq, EffectWahwah::OnFreqText)
|
|
|
|
EVT_TEXT(ID_Phase, EffectWahwah::OnPhaseText)
|
|
|
|
EVT_TEXT(ID_Depth, EffectWahwah::OnDepthText)
|
|
|
|
EVT_TEXT(ID_Res, EffectWahwah::OnResonanceText)
|
|
|
|
EVT_TEXT(ID_FreqOfs, EffectWahwah::OnFreqOffText)
|
2015-08-03 19:07:17 +00:00
|
|
|
EVT_TEXT(ID_OutGain, EffectWahwah::OnGainText)
|
2015-04-17 03:53:42 +00:00
|
|
|
END_EVENT_TABLE();
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
EffectWahwah::EffectWahwah()
|
|
|
|
{
|
2015-04-17 03:53:42 +00:00
|
|
|
mFreq = DEF_Freq;
|
|
|
|
mPhase = DEF_Phase;
|
|
|
|
mDepth = DEF_Depth;
|
|
|
|
mRes = DEF_Res;
|
|
|
|
mFreqOfs = DEF_FreqOfs;
|
2015-08-03 19:07:17 +00:00
|
|
|
mOutGain = DEF_OutGain;
|
2015-05-15 11:47:51 +00:00
|
|
|
|
|
|
|
SetLinearEffectFlag(true);
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
EffectWahwah::~EffectWahwah()
|
|
|
|
{
|
2014-06-03 20:30:19 +00:00
|
|
|
}
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
// IdentInterface implementation
|
|
|
|
|
|
|
|
wxString EffectWahwah::GetSymbol()
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2015-04-17 03:53:42 +00:00
|
|
|
return WAHWAH_PLUGIN_SYMBOL;
|
|
|
|
}
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
wxString EffectWahwah::GetDescription()
|
|
|
|
{
|
2018-01-08 00:45:20 +00:00
|
|
|
return _("Rapid tone quality variations, like that guitar sound so popular in the 1970's");
|
2015-04-17 03:53:42 +00:00
|
|
|
}
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2017-05-20 13:40:09 +00:00
|
|
|
wxString EffectWahwah::ManualPage()
|
|
|
|
{
|
|
|
|
return wxT("Wahwah");
|
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
// EffectIdentInterface implementation
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
EffectType EffectWahwah::GetType()
|
|
|
|
{
|
|
|
|
return EffectTypeProcess;
|
|
|
|
}
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2015-08-01 12:03:02 +00:00
|
|
|
bool EffectWahwah::SupportsRealtime()
|
|
|
|
{
|
|
|
|
#if defined(EXPERIMENTAL_REALTIME_AUDACITY_EFFECTS)
|
|
|
|
return true;
|
|
|
|
#else
|
|
|
|
return false;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
// EffectClientInterface implementation
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2016-09-02 19:53:09 +00:00
|
|
|
unsigned EffectWahwah::GetAudioInCount()
|
2015-04-17 03:53:42 +00:00
|
|
|
{
|
|
|
|
return 1;
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
2016-09-02 19:53:09 +00:00
|
|
|
unsigned EffectWahwah::GetAudioOutCount()
|
2014-06-03 20:30:19 +00:00
|
|
|
{
|
2015-04-17 03:53:42 +00:00
|
|
|
return 1;
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
bool EffectWahwah::ProcessInitialize(sampleCount WXUNUSED(totalLen), ChannelNames chanMap)
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2015-08-01 12:03:02 +00:00
|
|
|
InstanceInit(mMaster, mSampleRate);
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
if (chanMap[0] == ChannelNameFrontRight)
|
|
|
|
{
|
2015-08-01 12:03:02 +00:00
|
|
|
mMaster.phase += M_PI;
|
2015-04-17 03:53:42 +00:00
|
|
|
}
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-09-06 13:19:27 +00:00
|
|
|
size_t EffectWahwah::ProcessBlock(float **inBlock, float **outBlock, size_t blockLen)
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2015-08-01 12:03:02 +00:00
|
|
|
return InstanceProcess(mMaster, inBlock, outBlock, blockLen);
|
|
|
|
}
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2015-08-01 12:03:02 +00:00
|
|
|
bool EffectWahwah::RealtimeInitialize()
|
|
|
|
{
|
|
|
|
SetBlockSize(512);
|
2014-06-03 20:30:19 +00:00
|
|
|
|
2018-02-02 18:24:53 +00:00
|
|
|
mSlaves.clear();
|
2014-06-03 20:30:19 +00:00
|
|
|
|
2015-08-01 12:03:02 +00:00
|
|
|
return true;
|
|
|
|
}
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2016-09-02 19:53:09 +00:00
|
|
|
bool EffectWahwah::RealtimeAddProcessor(unsigned WXUNUSED(numChannels), float sampleRate)
|
2015-08-01 12:03:02 +00:00
|
|
|
{
|
|
|
|
EffectWahwahState slave;
|
|
|
|
|
|
|
|
InstanceInit(slave, sampleRate);
|
|
|
|
|
2018-02-02 18:24:53 +00:00
|
|
|
mSlaves.push_back(slave);
|
2015-08-01 12:03:02 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool EffectWahwah::RealtimeFinalize()
|
|
|
|
{
|
2018-02-02 18:24:53 +00:00
|
|
|
mSlaves.clear();
|
2015-08-01 12:03:02 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-09-06 13:19:27 +00:00
|
|
|
size_t EffectWahwah::RealtimeProcess(int group,
|
2015-08-01 12:03:02 +00:00
|
|
|
float **inbuf,
|
|
|
|
float **outbuf,
|
2016-09-06 13:19:27 +00:00
|
|
|
size_t numSamples)
|
2015-08-01 12:03:02 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
return InstanceProcess(mSlaves[group], inbuf, outbuf, numSamples);
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
bool EffectWahwah::GetAutomationParameters(EffectAutomationParameters & parms)
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2015-04-17 03:53:42 +00:00
|
|
|
parms.Write(KEY_Freq, mFreq);
|
|
|
|
parms.Write(KEY_Phase, mPhase);
|
|
|
|
parms.Write(KEY_Depth, mDepth);
|
|
|
|
parms.Write(KEY_Res, mRes);
|
|
|
|
parms.Write(KEY_FreqOfs, mFreqOfs);
|
2015-08-03 19:07:17 +00:00
|
|
|
parms.Write(KEY_OutGain, mOutGain);
|
2015-04-17 03:53:42 +00:00
|
|
|
|
|
|
|
return true;
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
bool EffectWahwah::SetAutomationParameters(EffectAutomationParameters & parms)
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2015-04-17 03:53:42 +00:00
|
|
|
ReadAndVerifyDouble(Freq);
|
|
|
|
ReadAndVerifyDouble(Phase);
|
|
|
|
ReadAndVerifyInt(Depth);
|
|
|
|
ReadAndVerifyDouble(Res);
|
|
|
|
ReadAndVerifyInt(FreqOfs);
|
2015-08-03 19:07:17 +00:00
|
|
|
ReadAndVerifyDouble(OutGain);
|
2015-04-17 03:53:42 +00:00
|
|
|
|
|
|
|
mFreq = Freq;
|
|
|
|
mPhase = Phase;
|
|
|
|
mDepth = Depth;
|
|
|
|
mRes = Res;
|
|
|
|
mFreqOfs = FreqOfs;
|
2015-08-03 19:07:17 +00:00
|
|
|
mOutGain = OutGain;
|
2015-04-17 03:53:42 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Effect implementation
|
2013-06-21 22:10:50 +00:00
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
void EffectWahwah::PopulateOrExchange(ShuttleGui & S)
|
|
|
|
{
|
2010-01-23 19:44:49 +00:00
|
|
|
S.SetBorder(5);
|
2013-06-21 22:10:50 +00:00
|
|
|
S.AddSpace(0, 5);
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
S.StartMultiColumn(3, wxEXPAND);
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2015-04-17 03:53:42 +00:00
|
|
|
S.SetStretchyCol(2);
|
|
|
|
|
2017-10-30 16:18:10 +00:00
|
|
|
FloatingPointValidator<double> vldfreq(5, &mFreq, NumValidatorStyle::ONE_TRAILING_ZERO);
|
2015-04-17 03:53:42 +00:00
|
|
|
vldfreq.SetRange(MIN_Freq, MAX_Freq);
|
2016-09-27 18:22:00 +00:00
|
|
|
mFreqT = S.Id(ID_Freq).AddTextBox(_("LFO Freq&uency (Hz):"), wxT(""), 12);
|
2015-04-17 03:53:42 +00:00
|
|
|
mFreqT->SetValidator(vldfreq);
|
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
S.SetStyle(wxSL_HORIZONTAL);
|
2017-09-28 01:20:14 +00:00
|
|
|
mFreqS = S.Id(ID_Freq).AddSlider( {}, DEF_Freq * SCL_Freq, MAX_Freq * SCL_Freq, MIN_Freq * SCL_Freq);
|
2015-04-17 03:53:42 +00:00
|
|
|
mFreqS->SetName(_("LFO frequency in hertz"));
|
|
|
|
mFreqS->SetMinSize(wxSize(100, -1));
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
FloatingPointValidator<double> vldphase(1, &mPhase);
|
|
|
|
vldphase.SetRange(MIN_Phase, MAX_Phase);
|
2016-09-27 18:22:00 +00:00
|
|
|
mPhaseT = S.Id(ID_Phase).AddTextBox(_("LFO Sta&rt Phase (deg.):"), wxT(""), 12);
|
2015-04-17 03:53:42 +00:00
|
|
|
mPhaseT->SetValidator(vldphase);
|
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
S.SetStyle(wxSL_HORIZONTAL);
|
2017-09-28 01:20:14 +00:00
|
|
|
mPhaseS = S.Id(ID_Phase).AddSlider( {}, DEF_Phase * SCL_Phase, MAX_Phase * SCL_Phase, MIN_Phase * SCL_Phase);
|
2015-04-17 03:53:42 +00:00
|
|
|
mPhaseS->SetName(_("LFO start phase in degrees"));
|
|
|
|
mPhaseS->SetLineSize(10);
|
|
|
|
mPhaseS->SetMinSize(wxSize(100, -1));
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
IntegerValidator<int> vlddepth(&mDepth);
|
|
|
|
vlddepth.SetRange(MIN_Depth, MAX_Depth);
|
2016-09-27 18:22:00 +00:00
|
|
|
mDepthT = S.Id(ID_Depth).AddTextBox(_("Dept&h (%):"), wxT(""), 12);
|
2015-04-17 03:53:42 +00:00
|
|
|
mDepthT->SetValidator(vlddepth);
|
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
S.SetStyle(wxSL_HORIZONTAL);
|
2017-09-28 01:20:14 +00:00
|
|
|
mDepthS = S.Id(ID_Depth).AddSlider( {}, DEF_Depth * SCL_Depth, MAX_Depth * SCL_Depth, MIN_Depth * SCL_Depth);
|
2015-04-17 03:53:42 +00:00
|
|
|
mDepthS->SetName(_("Depth in percent"));
|
|
|
|
mDepthS->SetMinSize(wxSize(100, -1));
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
FloatingPointValidator<double> vldres(1, &mRes);
|
|
|
|
vldres.SetRange(MIN_Res, MAX_Res);
|
2016-09-27 18:22:00 +00:00
|
|
|
mResT = S.Id(ID_Res).AddTextBox(_("Reso&nance:"), wxT(""), 12);
|
2015-04-17 03:53:42 +00:00
|
|
|
mResT->SetValidator(vldres);
|
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
S.SetStyle(wxSL_HORIZONTAL);
|
2017-09-28 01:20:14 +00:00
|
|
|
mResS = S.Id(ID_Res).AddSlider( {}, DEF_Res * SCL_Res, MAX_Res * SCL_Res, MIN_Res * SCL_Res);
|
2015-04-17 03:53:42 +00:00
|
|
|
mResS->SetName(_("Resonance"));
|
|
|
|
mResS->SetMinSize(wxSize(100, -1));
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
IntegerValidator<int> vldfreqoffset(&mFreqOfs);
|
|
|
|
vldfreqoffset.SetRange(MIN_FreqOfs, MAX_FreqOfs);
|
2016-09-27 18:22:00 +00:00
|
|
|
mFreqOfsT = S.Id(ID_FreqOfs).AddTextBox(_("Wah Frequency Offse&t (%):"), wxT(""), 12);
|
2015-04-17 03:53:42 +00:00
|
|
|
mFreqOfsT->SetValidator(vldfreqoffset);
|
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
S.SetStyle(wxSL_HORIZONTAL);
|
2017-09-28 01:20:14 +00:00
|
|
|
mFreqOfsS = S.Id(ID_FreqOfs).AddSlider( {}, DEF_FreqOfs * SCL_FreqOfs, MAX_FreqOfs * SCL_FreqOfs, MIN_FreqOfs * SCL_FreqOfs);
|
2015-04-17 03:53:42 +00:00
|
|
|
mFreqOfsT->SetName(_("Wah frequency offset in percent"));
|
|
|
|
mFreqOfsT->SetMinSize(wxSize(100, -1));
|
2015-08-03 19:07:17 +00:00
|
|
|
|
|
|
|
FloatingPointValidator<double> vldoutgain(1, &mOutGain);
|
|
|
|
vldoutgain.SetRange(MIN_OutGain, MAX_OutGain);
|
2016-09-27 18:22:00 +00:00
|
|
|
mOutGainT = S.Id(ID_OutGain).AddTextBox(_("&Output gain (dB):"), wxT(""), 12);
|
2015-08-03 19:07:17 +00:00
|
|
|
mOutGainT->SetValidator(vldoutgain);
|
|
|
|
|
|
|
|
S.SetStyle(wxSL_HORIZONTAL);
|
2017-09-28 01:20:14 +00:00
|
|
|
mOutGainS = S.Id(ID_OutGain).AddSlider( {}, DEF_OutGain * SCL_OutGain, MAX_OutGain * SCL_OutGain, MIN_OutGain * SCL_OutGain);
|
2015-08-03 19:07:17 +00:00
|
|
|
mOutGainS->SetName(_("Output gain (dB)"));
|
|
|
|
mOutGainS->SetMinSize(wxSize(100, -1));
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
S.EndMultiColumn();
|
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
bool EffectWahwah::TransferDataToWindow()
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2015-04-17 03:53:42 +00:00
|
|
|
if (!mUIParent->TransferDataToWindow())
|
|
|
|
{
|
|
|
|
return false;
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
2015-04-23 07:04:06 +00:00
|
|
|
mFreqS->SetValue((int) (mFreq * SCL_Freq));
|
|
|
|
mPhaseS->SetValue((int) (mPhase * SCL_Phase));
|
|
|
|
mDepthS->SetValue((int) (mDepth * SCL_Depth));
|
|
|
|
mResS->SetValue((int) (mRes * SCL_Res));
|
|
|
|
mFreqOfsS->SetValue((int) (mFreqOfs * SCL_FreqOfs));
|
2015-08-03 19:07:17 +00:00
|
|
|
mOutGainS->SetValue((int) (mOutGain * SCL_OutGain));
|
2015-04-23 07:04:06 +00:00
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
return true;
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
bool EffectWahwah::TransferDataFromWindow()
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2015-04-17 03:53:42 +00:00
|
|
|
if (!mUIParent->Validate() || !mUIParent->TransferDataFromWindow())
|
|
|
|
{
|
|
|
|
return false;
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
return true;
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
// EffectWahwah implementation
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2015-08-01 12:03:02 +00:00
|
|
|
void EffectWahwah::InstanceInit(EffectWahwahState & data, float sampleRate)
|
|
|
|
{
|
|
|
|
data.samplerate = sampleRate;
|
|
|
|
data.lfoskip = mFreq * 2 * M_PI / sampleRate;
|
|
|
|
data.skipcount = 0;
|
|
|
|
data.xn1 = 0;
|
|
|
|
data.xn2 = 0;
|
|
|
|
data.yn1 = 0;
|
|
|
|
data.yn2 = 0;
|
|
|
|
data.b0 = 0;
|
|
|
|
data.b1 = 0;
|
|
|
|
data.b2 = 0;
|
|
|
|
data.a0 = 0;
|
|
|
|
data.a1 = 0;
|
|
|
|
data.a2 = 0;
|
|
|
|
|
|
|
|
data.depth = mDepth / 100.0;
|
|
|
|
data.freqofs = mFreqOfs / 100.0;
|
|
|
|
data.phase = mPhase * M_PI / 180.0;
|
2015-08-03 19:07:17 +00:00
|
|
|
data.outgain = DB_TO_LINEAR(mOutGain);
|
2015-08-01 12:03:02 +00:00
|
|
|
}
|
|
|
|
|
2016-09-06 13:19:27 +00:00
|
|
|
size_t EffectWahwah::InstanceProcess(EffectWahwahState & data, float **inBlock, float **outBlock, size_t blockLen)
|
2015-08-01 12:03:02 +00:00
|
|
|
{
|
|
|
|
float *ibuf = inBlock[0];
|
|
|
|
float *obuf = outBlock[0];
|
|
|
|
double frequency, omega, sn, cs, alpha;
|
|
|
|
double in, out;
|
|
|
|
|
|
|
|
data.lfoskip = mFreq * 2 * M_PI / data.samplerate;
|
|
|
|
data.depth = mDepth / 100.0;
|
|
|
|
data.freqofs = mFreqOfs / 100.0;
|
|
|
|
|
|
|
|
data.phase = mPhase * M_PI / 180.0;
|
2015-08-03 19:07:17 +00:00
|
|
|
data.outgain = DB_TO_LINEAR(mOutGain);
|
2015-08-01 12:03:02 +00:00
|
|
|
|
2016-08-24 11:56:33 +00:00
|
|
|
for (decltype(blockLen) i = 0; i < blockLen; i++)
|
2015-08-01 12:03:02 +00:00
|
|
|
{
|
|
|
|
in = (double) ibuf[i];
|
|
|
|
|
|
|
|
if ((data.skipcount++) % lfoskipsamples == 0)
|
|
|
|
{
|
|
|
|
frequency = (1 + cos(data.skipcount * data.lfoskip + data.phase)) / 2;
|
|
|
|
frequency = frequency * data.depth * (1 - data.freqofs) + data.freqofs;
|
|
|
|
frequency = exp((frequency - 1) * 6);
|
|
|
|
omega = M_PI * frequency;
|
|
|
|
sn = sin(omega);
|
|
|
|
cs = cos(omega);
|
|
|
|
alpha = sn / (2 * mRes);
|
|
|
|
data.b0 = (1 - cs) / 2;
|
|
|
|
data.b1 = 1 - cs;
|
|
|
|
data.b2 = (1 - cs) / 2;
|
|
|
|
data.a0 = 1 + alpha;
|
|
|
|
data.a1 = -2 * cs;
|
|
|
|
data.a2 = 1 - alpha;
|
|
|
|
};
|
|
|
|
out = (data.b0 * in + data.b1 * data.xn1 + data.b2 * data.xn2 - data.a1 * data.yn1 - data.a2 * data.yn2) / data.a0;
|
|
|
|
data.xn2 = data.xn1;
|
|
|
|
data.xn1 = in;
|
|
|
|
data.yn2 = data.yn1;
|
|
|
|
data.yn1 = out;
|
2015-08-03 19:07:17 +00:00
|
|
|
out *= data.outgain;
|
2015-08-01 12:03:02 +00:00
|
|
|
|
|
|
|
obuf[i] = (float) out;
|
|
|
|
}
|
|
|
|
|
|
|
|
return blockLen;
|
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
void EffectWahwah::OnFreqSlider(wxCommandEvent & evt)
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2015-04-17 03:53:42 +00:00
|
|
|
mFreq = (double) evt.GetInt() / SCL_Freq;
|
|
|
|
mFreqT->GetValidator()->TransferToWindow();
|
|
|
|
EnableApply(mUIParent->Validate());
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
void EffectWahwah::OnPhaseSlider(wxCommandEvent & evt)
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2015-04-17 03:53:42 +00:00
|
|
|
int val = ((evt.GetInt() + 5) / 10) * 10; // round to nearest multiple of 10
|
|
|
|
val = val > MAX_Phase * SCL_Phase ? MAX_Phase * SCL_Phase : val;
|
|
|
|
mPhaseS->SetValue(val);
|
|
|
|
mPhase = (double) val / SCL_Phase;
|
|
|
|
mPhaseT->GetValidator()->TransferToWindow();
|
|
|
|
EnableApply(mUIParent->Validate());
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
void EffectWahwah::OnDepthSlider(wxCommandEvent & evt)
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2015-04-17 03:53:42 +00:00
|
|
|
mDepth = evt.GetInt() / SCL_Depth;
|
|
|
|
mDepthT->GetValidator()->TransferToWindow();
|
|
|
|
EnableApply(mUIParent->Validate());
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
void EffectWahwah::OnResonanceSlider(wxCommandEvent & evt)
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2015-04-17 03:53:42 +00:00
|
|
|
mRes = (double) evt.GetInt() / SCL_Res;
|
|
|
|
mResT->GetValidator()->TransferToWindow();
|
|
|
|
EnableApply(mUIParent->Validate());
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
void EffectWahwah::OnFreqOffSlider(wxCommandEvent & evt)
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2015-04-17 03:53:42 +00:00
|
|
|
mFreqOfs = evt.GetInt() / SCL_FreqOfs;
|
|
|
|
mFreqOfsT->GetValidator()->TransferToWindow();
|
|
|
|
EnableApply(mUIParent->Validate());
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
2015-08-03 19:07:17 +00:00
|
|
|
void EffectWahwah::OnGainSlider(wxCommandEvent & evt)
|
|
|
|
{
|
|
|
|
mOutGain = evt.GetInt() / SCL_OutGain;
|
|
|
|
mOutGainT->GetValidator()->TransferToWindow();
|
|
|
|
EnableApply(mUIParent->Validate());
|
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
void EffectWahwah::OnFreqText(wxCommandEvent & WXUNUSED(evt))
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2015-04-17 03:53:42 +00:00
|
|
|
if (!EnableApply(mUIParent->TransferDataFromWindow()))
|
|
|
|
{
|
|
|
|
return;
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
2015-04-17 03:53:42 +00:00
|
|
|
|
|
|
|
mFreqS->SetValue((int) (mFreq * SCL_Freq));
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
void EffectWahwah::OnPhaseText(wxCommandEvent & WXUNUSED(evt))
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2015-04-17 03:53:42 +00:00
|
|
|
if (!EnableApply(mUIParent->TransferDataFromWindow()))
|
|
|
|
{
|
|
|
|
return;
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
2015-04-17 03:53:42 +00:00
|
|
|
|
|
|
|
mPhaseS->SetValue((int) (mPhase * SCL_Phase));
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
void EffectWahwah::OnDepthText(wxCommandEvent & WXUNUSED(evt))
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2015-04-17 03:53:42 +00:00
|
|
|
if (!EnableApply(mUIParent->TransferDataFromWindow()))
|
|
|
|
{
|
|
|
|
return;
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
2015-04-17 03:53:42 +00:00
|
|
|
|
|
|
|
mDepthS->SetValue((int) (mDepth * SCL_Depth));
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
void EffectWahwah::OnResonanceText(wxCommandEvent & WXUNUSED(evt))
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2015-04-17 03:53:42 +00:00
|
|
|
if (!EnableApply(mUIParent->TransferDataFromWindow()))
|
|
|
|
{
|
|
|
|
return;
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
2015-04-17 03:53:42 +00:00
|
|
|
|
|
|
|
mResS->SetValue((int) (mRes * SCL_Res));
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
void EffectWahwah::OnFreqOffText(wxCommandEvent & WXUNUSED(evt))
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2015-04-17 03:53:42 +00:00
|
|
|
if (!EnableApply(mUIParent->TransferDataFromWindow()))
|
|
|
|
{
|
|
|
|
return;
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
mFreqOfsS->SetValue((int) (mFreqOfs * SCL_FreqOfs));
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
2015-08-03 19:07:17 +00:00
|
|
|
|
|
|
|
void EffectWahwah::OnGainText(wxCommandEvent & WXUNUSED(evt))
|
|
|
|
{
|
|
|
|
if (!EnableApply(mUIParent->TransferDataFromWindow()))
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
mOutGainS->SetValue((int) (mOutGain * SCL_OutGain));
|
|
|
|
}
|