diff --git a/src/effects/Phaser.cpp b/src/effects/Phaser.cpp index 24efb0feb..271a2a114 100644 --- a/src/effects/Phaser.cpp +++ b/src/effects/Phaser.cpp @@ -37,7 +37,8 @@ enum ID_Freq, ID_Phase, ID_Depth, - ID_Feedback + ID_Feedback, + ID_OutGain }; // Define keys, defaults, minimums, and maximums for the effect parameters @@ -49,6 +50,7 @@ Param( Freq, double, XO("Freq"), 0.4, 0.001,4.0, 10.0 ); Param( Phase, double, XO("Phase"), 0.0, 0.0, 360.0, 1 ); Param( Depth, int, XO("Depth"), 100, 0, 255, 1 ); Param( Feedback, int, XO("Feedback"), 0, -100, 100, 1 ); +Param( OutGain, double, XO("Gain"), -6.0, -30.0, 30.0, 1 ); // #define phaserlfoshape 4.0 @@ -70,12 +72,14 @@ BEGIN_EVENT_TABLE(EffectPhaser, wxEvtHandler) EVT_SLIDER(ID_Phase, EffectPhaser::OnPhaseSlider) EVT_SLIDER(ID_Depth, EffectPhaser::OnDepthSlider) EVT_SLIDER(ID_Feedback, EffectPhaser::OnFeedbackSlider) + EVT_SLIDER(ID_OutGain, EffectPhaser::OnGainSlider) EVT_TEXT(ID_Stages, EffectPhaser::OnStagesText) EVT_TEXT(ID_DryWet, EffectPhaser::OnDryWetText) EVT_TEXT(ID_Freq, EffectPhaser::OnFreqText) EVT_TEXT(ID_Phase, EffectPhaser::OnPhaseText) EVT_TEXT(ID_Depth, EffectPhaser::OnDepthText) EVT_TEXT(ID_Feedback, EffectPhaser::OnFeedbackText) + EVT_TEXT(ID_OutGain, EffectPhaser::OnGainText) END_EVENT_TABLE() EffectPhaser::EffectPhaser() @@ -86,6 +90,7 @@ EffectPhaser::EffectPhaser() mPhase = DEF_Phase; mDepth = DEF_Depth; mFeedback = DEF_Feedback; + mOutGain = DEF_OutGain; SetLinearEffectFlag(true); } @@ -194,6 +199,7 @@ bool EffectPhaser::GetAutomationParameters(EffectAutomationParameters & parms) parms.Write(KEY_Phase, mPhase); parms.Write(KEY_Depth, mDepth); parms.Write(KEY_Feedback, mFeedback); + parms.Write(KEY_OutGain, mOutGain); return true; } @@ -206,6 +212,7 @@ bool EffectPhaser::SetAutomationParameters(EffectAutomationParameters & parms) ReadAndVerifyDouble(Phase); ReadAndVerifyInt(Depth); ReadAndVerifyInt(Feedback); + ReadAndVerifyDouble(OutGain); if (Stages & 1) // must be even, but don't complain about it { @@ -218,6 +225,7 @@ bool EffectPhaser::SetAutomationParameters(EffectAutomationParameters & parms) mDryWet = DryWet; mDepth = Depth; mPhase = Phase; + mOutGain = OutGain; return true; } @@ -295,6 +303,16 @@ void EffectPhaser::PopulateOrExchange(ShuttleGui & S) mFeedbackS->SetName(_("Feedback in percent")); mFeedbackS->SetLineSize(10); mFeedbackS->SetMinSize(wxSize(100, -1)); + + FloatingPointValidator vldoutgain(1, &mOutGain); + vldoutgain.SetRange(MIN_OutGain, MAX_OutGain); + mOutGainT = S.Id(ID_OutGain).AddTextBox(_("Output gain (dB):"), wxT(""), 12); + mOutGainT->SetValidator(vldoutgain); + + S.SetStyle(wxSL_HORIZONTAL); + mOutGainS = S.Id(ID_OutGain).AddSlider(wxT(""), DEF_OutGain * SCL_OutGain, MAX_OutGain * SCL_OutGain, MIN_OutGain * SCL_OutGain); + mOutGainS->SetName(_("Output gain (dB)")); + mOutGainS->SetMinSize(wxSize(100, -1)); } S.EndMultiColumn(); } @@ -312,6 +330,7 @@ bool EffectPhaser::TransferDataToWindow() mPhaseS->SetValue((int) (mPhase * SCL_Phase)); mDepthS->SetValue((int) (mDepth * SCL_Depth)); mFeedbackS->SetValue((int) (mFeedback * SCL_Feedback)); + mOutGainS->SetValue((int) (mOutGain * SCL_OutGain)); return true; } @@ -347,6 +366,7 @@ void EffectPhaser::InstanceInit(EffectPhaserState & data, float sampleRate) data.gain = 0; data.fbout = 0; data.laststages = 0; + data.outgain = 0; return; } @@ -364,6 +384,7 @@ sampleCount EffectPhaser::InstanceProcess(EffectPhaserState & data, float **inBl data.lfoskip = mFreq * 2 * M_PI / data.samplerate; data.phase = mPhase * M_PI / 180; + data.outgain = DB_TO_LINEAR(mOutGain); for (sampleCount i = 0; i < blockLen; i++) { @@ -392,7 +413,7 @@ sampleCount EffectPhaser::InstanceProcess(EffectPhaserState & data, float **inBl } data.fbout = m; - obuf[i] = (float) ((m * mDryWet + in * (255 - mDryWet)) / 255); + obuf[i] = (float) (data.outgain * (m * mDryWet + in * (255 - mDryWet)) / 255); } return blockLen; @@ -448,6 +469,13 @@ void EffectPhaser::OnFeedbackSlider(wxCommandEvent & evt) EnableApply(mUIParent->Validate()); } +void EffectPhaser::OnGainSlider(wxCommandEvent & evt) +{ + mOutGain = evt.GetInt() / SCL_OutGain; + mOutGainT->GetValidator()->TransferToWindow(); + EnableApply(mUIParent->Validate()); +} + void EffectPhaser::OnStagesText(wxCommandEvent & WXUNUSED(evt)) { if (!EnableApply(mUIParent->TransferDataFromWindow())) @@ -507,3 +535,13 @@ void EffectPhaser::OnFeedbackText(wxCommandEvent & WXUNUSED(evt)) mFeedbackS->SetValue((int) (mFeedback * SCL_Feedback)); } + +void EffectPhaser::OnGainText(wxCommandEvent & WXUNUSED(evt)) +{ + if (!EnableApply(mUIParent->TransferDataFromWindow())) + { + return; + } + + mOutGainS->SetValue((int) (mOutGain * SCL_OutGain)); +} \ No newline at end of file diff --git a/src/effects/Phaser.h b/src/effects/Phaser.h index d02126fa4..fcec5610b 100644 --- a/src/effects/Phaser.h +++ b/src/effects/Phaser.h @@ -38,6 +38,7 @@ public: double old[NUM_STAGES]; // must be as large as MAX_STAGES double gain; double fbout; + double outgain; double lfoskip; double phase; int laststages; @@ -83,7 +84,7 @@ public: bool TransferDataToWindow(); bool TransferDataFromWindow(); -protected: +private: // EffectPhaser implementation void InstanceInit(EffectPhaserState & data, float sampleRate); @@ -95,12 +96,15 @@ protected: void OnDepthSlider(wxCommandEvent & evt); void OnPhaseSlider(wxCommandEvent & evt); void OnFreqSlider(wxCommandEvent & evt); + void OnGainSlider(wxCommandEvent & evt); + void OnStagesText(wxCommandEvent & evt); void OnDryWetText(wxCommandEvent & evt); void OnFeedbackText(wxCommandEvent & evt); void OnDepthText(wxCommandEvent & evt); void OnPhaseText(wxCommandEvent & evt); void OnFreqText(wxCommandEvent & evt); + void OnGainText(wxCommandEvent & evt); /* Phaser Parameters @@ -124,6 +128,7 @@ private: double mPhase; int mDepth; int mFeedback; + double mOutGain; wxTextCtrl *mStagesT; wxTextCtrl *mDryWetT; @@ -131,6 +136,7 @@ private: wxTextCtrl *mPhaseT; wxTextCtrl *mDepthT; wxTextCtrl *mFeedbackT; + wxTextCtrl *mOutGainT; wxSlider *mStagesS; wxSlider *mDryWetS; @@ -138,6 +144,7 @@ private: wxSlider *mPhaseS; wxSlider *mDepthS; wxSlider *mFeedbackS; + wxSlider *mOutGainS; DECLARE_EVENT_TABLE(); };