Audacity 3.2.0
Wahwah.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 Wahwah.cpp
6
7 Effect programming:
8 Nasca Octavian Paul (Paul Nasca)
9
10 UI programming:
11 Dominic Mazzoni (with the help of wxDesigner)
12 Vaughan Johnson (Preview)
13
14*******************************************************************//*******************************************************************/
20
21
22#include "Wahwah.h"
23#include "EffectEditor.h"
24#include "LoadEffects.h"
25
26#include <math.h>
27
28#include <wx/slider.h>
29#include <wx/weakref.h>
30
31#include "ShuttleGui.h"
32#include "../widgets/valnum.h"
33
35
38{
39 Editor(const EffectUIServices& services,
41 ) : EffectEditor{ services, access }
43 {}
44 virtual ~Editor() = default;
45
46 bool ValidateUI() override;
47 bool UpdateUI() override;
48
50
51 void OnFreqSlider(wxCommandEvent& evt);
52 void OnPhaseSlider(wxCommandEvent& evt);
53 void OnDepthSlider(wxCommandEvent& evt);
54 void OnResonanceSlider(wxCommandEvent& evt);
55 void OnFreqOffSlider(wxCommandEvent& evt);
56 void OnGainSlider(wxCommandEvent& evt);
57
58 void OnFreqText(wxCommandEvent& evt);
59 void OnPhaseText(wxCommandEvent& evt);
60 void OnDepthText(wxCommandEvent& evt);
61 void OnResonanceText(wxCommandEvent& evt);
62 void OnFreqOffText(wxCommandEvent& evt);
63 void OnGainText(wxCommandEvent& evt);
64
65 wxTextCtrl* mFreqT;
66 wxTextCtrl* mPhaseT;
67 wxTextCtrl* mDepthT;
68 wxTextCtrl* mResT;
69 wxTextCtrl* mFreqOfsT;
70 wxTextCtrl* mOutGainT;
71
72 wxSlider* mFreqS;
73 wxSlider* mPhaseS;
74 wxSlider* mDepthS;
75 wxSlider* mResS;
76 wxSlider* mFreqOfsS;
77 wxSlider* mOutGainS;
78
79
80 wxWeakRef<wxWindow> mUIParent;
82
84 {
85 EnableApply(mUIParent, mUIParent->Validate());
86 }
87
89 {
90 return EnableApply(mUIParent, mUIParent->TransferDataFromWindow());
91 }
92};
93
94
96{
98 (
100 {
101 // pass back the modified settings to the MessageBuffer
103 return nullptr;
104 }
105 );
106
107 return true;
108}
109
110// Effect implementation
111
112std::unique_ptr<EffectEditor> EffectWahwah::MakeEditor(
114 const EffectOutputs *) const
115{
116 auto& settings = access.Get();
117 auto& myEffSettings = GetSettings(settings);
118 auto result = std::make_unique<Editor>(*this, access, myEffSettings);
119 result->PopulateOrExchange(S);
120 return result;
121}
122
124{
125 mUIParent = S.GetParent();
126 auto& ms = mSettings;
127
128 S.SetBorder(5);
129 S.AddSpace(0, 5);
130
131 S.StartMultiColumn(3, wxEXPAND);
132 {
133 S.SetStretchyCol(2);
134
135 mFreqT = S
136 .Validator<FloatingPointValidator<double>>(
137 5, &ms.mFreq, NumValidatorStyle::ONE_TRAILING_ZERO, Freq.min, Freq.max)
138 .AddTextBox(XXO("LFO Freq&uency (Hz):"), L"", 12);
139 BindTo(*mFreqT, wxEVT_TEXT, &Editor::OnFreqText);
140
141 mFreqS = S
142 .Name(XO("LFO frequency in hertz"))
143 .Style(wxSL_HORIZONTAL)
144 .MinSize( { 100, -1 } )
145 .AddSlider( {}, Freq.def * Freq.scale, Freq.max * Freq.scale, Freq.min * Freq.scale);
146 BindTo(*mFreqS, wxEVT_SLIDER, &Editor::OnFreqSlider);
147
148 mPhaseT = S
149 .Validator<FloatingPointValidator<double>>(
150 1, &ms.mPhase, NumValidatorStyle::DEFAULT, Phase.min, Phase.max)
151 .AddTextBox(XXO("LFO Sta&rt Phase (deg.):"), L"", 12);
152 BindTo(*mPhaseT, wxEVT_TEXT, &Editor::OnPhaseText);
153
154 mPhaseS = S
155 .Name(XO("LFO start phase in degrees"))
156 .Style(wxSL_HORIZONTAL)
157 .MinSize( { 100, -1 } )
158 .AddSlider( {}, Phase.def * Phase.scale, Phase.max * Phase.scale, Phase.min * Phase.scale);
159 mPhaseS->SetLineSize(10);
160 BindTo(*mPhaseS, wxEVT_SLIDER, &Editor::OnPhaseSlider);
161
162 mDepthT = S
163 .Validator<IntegerValidator<int>>(
164 &ms.mDepth, NumValidatorStyle::DEFAULT, Depth.min, Depth.max)
165 .AddTextBox(XXO("Dept&h (%):"), L"", 12);
166 BindTo(*mDepthT, wxEVT_TEXT, &Editor::OnDepthText);
167
168 mDepthS = S
169 .Name(XO("Depth in percent"))
170 .Style(wxSL_HORIZONTAL)
171 .MinSize( { 100, -1 } )
172 .AddSlider( {}, Depth.def * Depth.scale, Depth.max * Depth.scale, Depth.min * Depth.scale);
173 BindTo(*mDepthS, wxEVT_SLIDER, &Editor::OnDepthSlider);
174
175 mResT = S
176 .Validator<FloatingPointValidator<double>>(
177 1, &ms.mRes, NumValidatorStyle::DEFAULT, Res.min, Res.max)
178 .AddTextBox(XXO("Reso&nance:"), L"", 12);
179 BindTo(*mResT, wxEVT_TEXT, &Editor::OnResonanceText);
180
181 mResS = S
182 .Name(XO("Resonance"))
183 .Style(wxSL_HORIZONTAL)
184 .MinSize( { 100, -1 } )
185 .AddSlider( {}, Res.def * Res.scale, Res.max * Res.scale, Res.min * Res.scale);
186 BindTo(*mResS, wxEVT_SLIDER, &Editor::OnResonanceSlider);
187
188 mFreqOfsT = S
189 .Validator<IntegerValidator<int>>(
190 &ms.mFreqOfs, NumValidatorStyle::DEFAULT, FreqOfs.min, FreqOfs.max)
191 .AddTextBox(XXO("Wah Frequency Offse&t (%):"), L"", 12);
192 BindTo(*mFreqOfsT, wxEVT_TEXT, &Editor::OnFreqOffText);
193
194 mFreqOfsS = S
195 .Name(XO("Wah frequency offset in percent"))
196 .Style(wxSL_HORIZONTAL)
197 .MinSize( { 100, -1 } )
199 BindTo(*mFreqOfsS, wxEVT_SLIDER, &Editor::OnFreqOffSlider);
200
201 mOutGainT = S
202 .Validator<FloatingPointValidator<double>>(
203 1, &ms.mOutGain, NumValidatorStyle::DEFAULT, OutGain.min, OutGain.max)
204 .AddTextBox(XXO("&Output gain (dB):"), L"", 12);
205 BindTo(*mOutGainT, wxEVT_TEXT, &Editor::OnGainText);
206
207 mOutGainS = S
208 .Name(XO("Output gain (dB)"))
209 .Style(wxSL_HORIZONTAL)
210 .MinSize( { 100, -1 } )
212 BindTo(*mOutGainS, wxEVT_SLIDER, &Editor::OnGainSlider);
213 }
214 S.EndMultiColumn();
215}
216
218{
219 // get the settings from the MessageBuffer and write them to our local copy
220 const auto& settings = mAccess.Get();
221
222 mSettings = GetSettings(settings);
223
224 auto& ms = mSettings;
225
226 mFreqS->SetValue((int)(ms.mFreq * Freq.scale));
227 mPhaseS->SetValue((int)(ms.mPhase * Phase.scale));
228 mDepthS->SetValue((int)(ms.mDepth * Depth.scale));
229 mResS->SetValue((int)(ms.mRes * Res.scale));
230 mFreqOfsS->SetValue((int)(ms.mFreqOfs * FreqOfs.scale));
231 mOutGainS->SetValue((int)(ms.mOutGain * OutGain.scale));
232
233 return true;
234}
235
236void EffectWahwah::Editor::OnFreqSlider(wxCommandEvent& evt)
237{
238 auto& ms = mSettings;
239
240 ms.mFreq = (double)evt.GetInt() / Freq.scale;
241 mFreqT->GetValidator()->TransferToWindow();
242
243 EnableApplyFromValidate();
244 ValidateUI();
245 Publish(EffectSettingChanged{});
246}
247
248void EffectWahwah::Editor::OnPhaseSlider(wxCommandEvent& evt)
249{
250 auto& ms = mSettings;
251
252 int val = ((evt.GetInt() + 5) / 10) * 10; // round to nearest multiple of 10
253 val = val > Phase.max * Phase.scale ? Phase.max * Phase.scale : val;
254 mPhaseS->SetValue(val);
255 ms.mPhase = (double)val / Phase.scale;
256 mPhaseT->GetValidator()->TransferToWindow();
257
258 EnableApplyFromValidate();
259 ValidateUI();
260 Publish(EffectSettingChanged{});
261}
262
263void EffectWahwah::Editor::OnDepthSlider(wxCommandEvent& evt)
264{
265 auto& ms = mSettings;
266
267 ms.mDepth = evt.GetInt() / Depth.scale;
268 mDepthT->GetValidator()->TransferToWindow();
269
270 EnableApplyFromValidate();
271 ValidateUI();
272 Publish(EffectSettingChanged{});
273}
274
276{
277 auto& ms = mSettings;
278
279 ms.mRes = (double)evt.GetInt() / Res.scale;
280 mResT->GetValidator()->TransferToWindow();
281
282 EnableApplyFromValidate();
283 ValidateUI();
284 Publish(EffectSettingChanged{});
285}
286
288{
289 auto& ms = mSettings;
290
291 ms.mFreqOfs = evt.GetInt() / FreqOfs.scale;
292 mFreqOfsT->GetValidator()->TransferToWindow();
293
294 EnableApplyFromValidate();
295 ValidateUI();
296 Publish(EffectSettingChanged{});
297}
298
299void EffectWahwah::Editor::OnGainSlider(wxCommandEvent& evt)
300{
301 auto& ms = mSettings;
302
303 ms.mOutGain = evt.GetInt() / OutGain.scale;
304 mOutGainT->GetValidator()->TransferToWindow();
305
306 EnableApplyFromValidate();
307 ValidateUI();
308 Publish(EffectSettingChanged{});
309}
310
311void EffectWahwah::Editor::OnFreqText(wxCommandEvent& WXUNUSED(evt))
312{
313 auto& ms = mSettings;
314
315 if (!EnableApplyFromTransferDataToWindow())
316 {
317 return;
318 }
319
320 mFreqS->SetValue((int)(ms.mFreq * Freq.scale));
321 ValidateUI();
322 Publish(EffectSettingChanged{});
323}
324
325void EffectWahwah::Editor::OnPhaseText(wxCommandEvent& WXUNUSED(evt))
326{
327 auto& ms = mSettings;
328
329 if (!EnableApplyFromTransferDataToWindow())
330 {
331 return;
332 }
333
334 mPhaseS->SetValue((int)(ms.mPhase * Phase.scale));
335 ValidateUI();
336 Publish(EffectSettingChanged{});
337}
338
339void EffectWahwah::Editor::OnDepthText(wxCommandEvent& WXUNUSED(evt))
340{
341 auto& ms = mSettings;
342
343 if (!EnableApplyFromTransferDataToWindow())
344 {
345 return;
346 }
347
348 mDepthS->SetValue((int)(ms.mDepth * Depth.scale));
349 ValidateUI();
350 Publish(EffectSettingChanged{});
351}
352
353void EffectWahwah::Editor::OnResonanceText(wxCommandEvent& WXUNUSED(evt))
354{
355 auto& ms = mSettings;
356
357 if (!EnableApplyFromTransferDataToWindow())
358 {
359 return;
360 }
361
362 mResS->SetValue((int)(ms.mRes * Res.scale));
363 ValidateUI();
364 Publish(EffectSettingChanged{});
365}
366
367void EffectWahwah::Editor::OnFreqOffText(wxCommandEvent& WXUNUSED(evt))
368{
369 auto& ms = mSettings;
370
371 if (!EnableApplyFromTransferDataToWindow())
372 {
373 return;
374 }
375
376 mFreqOfsS->SetValue((int)(ms.mFreqOfs * FreqOfs.scale));
377 ValidateUI();
378 Publish(EffectSettingChanged{});
379}
380
381void EffectWahwah::Editor::OnGainText(wxCommandEvent& WXUNUSED(evt))
382{
383 auto& ms = mSettings;
384
385 if (!EnableApplyFromTransferDataToWindow())
386 {
387 return;
388 }
389
390 mOutGainS->SetValue((int)(ms.mOutGain * OutGain.scale));
391 ValidateUI();
392 Publish(EffectSettingChanged{});
393}
XO("Cut/Copy/Paste")
XXO("&Cut/Copy/Paste Toolbar")
#define S(N)
Definition: ToChars.cpp:64
static Settings & settings()
Definition: TrackInfo.cpp:51
bool ValidateUI(const EffectPlugin &context, EffectSettings &) const override
static bool EnableApply(wxWindow *parent, bool enable=true)
Enable or disable the Apply button of the dialog that contains parent.
EffectSettingsAccess & mAccess
Definition: EffectEditor.h:92
Performs effect computation.
Hold values to send to effect output meters.
void ModifySettings(Function &&function)
Do a correct read-modify-write of settings.
virtual const EffectSettings & Get()=0
std::unique_ptr< EffectEditor > MakeEditor(ShuttleGui &S, EffectInstance &instance, EffectSettingsAccess &access, const EffectOutputs *pOutputs) const override
Called only from PopulateUI, to add controls to effect panel.
Definition: Wahwah.cpp:112
static EffectWahwahSettings & GetSettings(EffectSettings &settings)
Assume settings originated from MakeSettings() and copies thereof.
Definition: Effect.h:166
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:640
static constexpr EffectParameter OutGain
Definition: WahWahBase.h:166
static constexpr EffectParameter FreqOfs
Definition: WahWahBase.h:158
static constexpr EffectParameter Phase
Definition: WahWahBase.h:138
static constexpr EffectParameter Freq
Definition: WahWahBase.h:132
static constexpr EffectParameter Depth
Definition: WahWahBase.h:144
static constexpr EffectParameter Res
Definition: WahWahBase.h:152
BuiltinEffectsModule::Registration< EffectWahwah > reg
Definition: Wahwah.cpp:34
const Type scale
Scaling factor, for slider control.
const Type def
Default value.
const Type min
Minimum value.
const Type max
Maximum value.
Message sent by EffectEditor when a setting is changed by the user.
Definition: EffectEditor.h:26
Externalized state of a plug-in.
void EnableApplyFromValidate()
Definition: Wahwah.cpp:83
wxSlider * mDepthS
Definition: Wahwah.cpp:74
virtual ~Editor()=default
void OnFreqOffText(wxCommandEvent &evt)
Definition: Wahwah.cpp:367
wxSlider * mOutGainS
Definition: Wahwah.cpp:77
Editor(const EffectUIServices &services, EffectSettingsAccess &access, const EffectWahwahSettings &settings)
Definition: Wahwah.cpp:39
void OnResonanceSlider(wxCommandEvent &evt)
Definition: Wahwah.cpp:275
wxTextCtrl * mPhaseT
Definition: Wahwah.cpp:66
wxTextCtrl * mOutGainT
Definition: Wahwah.cpp:70
wxSlider * mResS
Definition: Wahwah.cpp:75
void OnGainSlider(wxCommandEvent &evt)
Definition: Wahwah.cpp:299
wxTextCtrl * mFreqOfsT
Definition: Wahwah.cpp:69
void OnFreqOffSlider(wxCommandEvent &evt)
Definition: Wahwah.cpp:287
EffectWahwahSettings mSettings
Definition: Wahwah.cpp:81
bool UpdateUI() override
Update appearance of the panel for changes in settings.
Definition: Wahwah.cpp:217
bool EnableApplyFromTransferDataToWindow()
Definition: Wahwah.cpp:88
wxTextCtrl * mDepthT
Definition: Wahwah.cpp:67
void OnPhaseSlider(wxCommandEvent &evt)
Definition: Wahwah.cpp:248
void OnFreqSlider(wxCommandEvent &evt)
Definition: Wahwah.cpp:236
void OnDepthSlider(wxCommandEvent &evt)
Definition: Wahwah.cpp:263
wxTextCtrl * mResT
Definition: Wahwah.cpp:68
wxSlider * mPhaseS
Definition: Wahwah.cpp:73
wxTextCtrl * mFreqT
Definition: Wahwah.cpp:65
void OnDepthText(wxCommandEvent &evt)
Definition: Wahwah.cpp:339
bool ValidateUI() override
Get settings data from the panel; may make error dialogs and return false.
Definition: Wahwah.cpp:95
void OnFreqText(wxCommandEvent &evt)
Definition: Wahwah.cpp:311
void OnGainText(wxCommandEvent &evt)
Definition: Wahwah.cpp:381
void PopulateOrExchange(ShuttleGui &S)
Definition: Wahwah.cpp:123
wxSlider * mFreqOfsS
Definition: Wahwah.cpp:76
void OnResonanceText(wxCommandEvent &evt)
Definition: Wahwah.cpp:353
wxSlider * mFreqS
Definition: Wahwah.cpp:72
void OnPhaseText(wxCommandEvent &evt)
Definition: Wahwah.cpp:325
wxWeakRef< wxWindow > mUIParent
Definition: Wahwah.cpp:80