Audacity 3.2.0
EqualizationUI.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 EqualizationUI.cpp
6
7 Mitch Golden
8 Vaughan Johnson (Preview)
9 Martyn Shaw (FIR filters, response curve, graphic EQ)
10
11 Paul Licameli split from Equalization.cpp
12
13**********************************************************************/
14#include "EqualizationUI.h"
16#include "EqualizationPanel.h"
17#include "EffectEditor.h"
18#include "BasicUI.h"
19#include <wx/button.h>
20#include <wx/choice.h>
21#include <wx/radiobut.h>
22#include <wx/sizer.h>
23#include <wx/checkbox.h>
24#include <wx/stattext.h>
25#include "ShuttleGui.h"
26#include "../widgets/RulerPanel.h"
27#include "../widgets/LinearUpdater.h"
28#include "../widgets/LogarithmicUpdater.h"
29#include "../widgets/IntFormat.h"
30#include "../widgets/LinearDBFormat.h"
31
32#if wxUSE_ACCESSIBILITY
33#include "WindowAccessible.h"
34#endif
35
36BEGIN_EVENT_TABLE(EqualizationUI, wxEvtHandler)
37 EVT_SIZE( EqualizationUI::OnSize )
39
41
42namespace
43{
44class EqualizationUIEditor : public EffectEditor, protected wxEvtHandler
45{
46public:
52 EqualizationUI& ui, EffectUIServices& services,
53 EffectSettingsAccess& access, wxWindow* pParent = nullptr)
54 : EffectEditor { services, access }
55 , mEqualizationUI { ui }
56 , mpParent { pParent }
57 {
58 if (mpParent)
59 mpParent->PushEventHandler(&ui);
60 }
63 {
64 Disconnect();
65 }
67 bool ValidateUI() override
68 {
69 bool result {};
70 mAccess.ModifySettings(
72 {
73 result = mEqualizationUI.ValidateUI(settings);
74 return nullptr;
75 });
76 return result;
77 }
78
79 void Disconnect() override
80 {
81 if (mpParent)
82 {
83 mpParent->PopEventHandler();
84 mpParent = nullptr;
85 }
86 }
87
88protected:
90 wxWindow* mpParent {};
91};
92} // namespace
93
95{
96 auto& parameters = mCurvesList.mParameters;
97 const auto &curveName = parameters.mCurveName;
98 auto &logEnvelope = parameters.mLogEnvelope;
99 const auto &curves = mCurvesList.mCurves;
100
101 EQCurveWriter{ curves }.SaveCurves();
102
103 parameters.SaveConfig();
104
105 return true;
106}
107
108std::unique_ptr<EffectEditor> EqualizationUI::PopulateOrExchange(
110 const EffectOutputs *)
111{
112 mBands.Init();
113
114 auto &parameters = mCurvesList.mParameters;
115 const auto &M = parameters.mM;
116 const auto &loFreq = parameters.mLoFreq;
117 const auto &hiFreq = parameters.mHiFreq;
118 const auto &curves = mCurvesList.mCurves;
119
120 auto &drawMode = parameters.mDrawMode;
121
122 S.SetBorder(0);
123
124 S.SetSizerProportion(1);
125 S.Prop(1).StartMultiColumn(1, wxEXPAND);
126 {
127 S.SetStretchyCol(0);
128 //S.SetStretchyRow(0); // The 5px Top border
129 S.SetStretchyRow(1); // The Graph
130 S.SetStretchyRow(2); // The EQ sliders
131 szrV = S.GetSizer();
132
133 // -------------------------------------------------------------------
134 // ROW 0: Top border
135 // -------------------------------------------------------------------
136 S.AddSpace(5);
137
138 // -------------------------------------------------------------------
139 // ROW 1: Equalization panel and sliders for vertical scale
140 // -------------------------------------------------------------------
141 S.SetSizerProportion(1);
142 S.Prop(1).StartMultiColumn(3, wxEXPAND);
143 {
144 S.SetStretchyCol(1);
145 S.SetStretchyRow(0);
146 szr1 = S.GetSizer();
147
148 S.StartVerticalLay(wxEXPAND, 1);
149 {
150 // Inserted into sizer later, but the EQ panel needs to point to it
152 S.GetParent(), wxID_ANY, wxHORIZONTAL,
153 wxSize{ 100, 100 }, // Ruler can't handle small sizes
154 RulerPanel::Range{ loFreq, hiFreq },
156 XO("Hz"),
158 .Log(true)
159 .Flip(true)
160 .LabelEdges(true)
161 .TicksAtExtremes(true)
162 .TickColour( { 0, 0, 0 } )
163 );
164
166 S.GetParent(), wxID_ANY, wxVERTICAL,
167 wxSize{ 100, 100 }, // Ruler can't handle small sizes
168 RulerPanel::Range{ 60.0, -120.0 },
170 XO("dB"),
172 .LabelEdges(true)
173 .TicksAtExtremes(true)
174 .TickColour( { 0, 0, 0 } )
175 );
176
177 S.Prop(0).AddSpace(0, 1);
178 S.Prop(1)
179 .Position(wxEXPAND)
180 .AddWindow(mdBRuler);
181 S.AddSpace(0, 1);
182 }
183 S.EndVerticalLay();
184
185 parameters.ChooseEnvelope().Flatten(0.);
186 parameters.ChooseEnvelope().SetTrackLen(1.0);
187 mPanel = safenew EqualizationPanel(S.GetParent(), wxID_ANY,
189 S.Prop(1)
190 .Position(wxEXPAND)
191 .MinSize( { wxDefaultCoord, wxDefaultCoord } )
192 .AddWindow(mPanel);
193
194 S.SetBorder(5);
195 S.StartVerticalLay();
196 {
197 S.AddVariableText(XO("+ dB"), false, wxCENTER);
199 .Name(XO("Max dB"))
200 .Style(wxSL_VERTICAL | wxSL_INVERSE)
201 .AddSlider( {}, 30, 60, 0);
202#if wxUSE_ACCESSIBILITY
203 mdBMaxSlider->SetAccessible(safenew SliderAx(mdBMaxSlider, XO("%d dB")));
204#endif
205 BindTo(*mdBMaxSlider, wxEVT_SLIDER,
207
209 .Name(XO("Min dB"))
210 .Style(wxSL_VERTICAL | wxSL_INVERSE)
211 .AddSlider( {}, -30, -10, -120);
212 S.AddVariableText(XO("- dB"), false, wxCENTER);
213#if wxUSE_ACCESSIBILITY
214 mdBMinSlider->SetAccessible(safenew SliderAx(mdBMinSlider, XO("%d dB")));
215#endif
216 BindTo(*mdBMinSlider, wxEVT_SLIDER,
218 }
219 S.EndVerticalLay();
220 S.SetBorder(0);
221
222 // -------------------------------------------------------------------
223 // Frequency ruler below graph
224 // -------------------------------------------------------------------
225
226 // Column 1 is empty
227 S.AddSpace(1, 1);
228
229 S.SetBorder(1);
230 S.Prop(1)
231 .Position(wxEXPAND | wxALIGN_LEFT | wxALIGN_TOP | wxLEFT)
232 .AddWindow(mFreqRuler);
233 S.SetBorder(0);
234
235 // Column 3 is empty
236 S.AddSpace(1, 1);
237 }
238 S.EndMultiColumn();
239
240 // -------------------------------------------------------------------
241 // ROW 2: Graphic EQ
242 // -------------------------------------------------------------------
243 S.SetSizerProportion(1);
244 S.StartHorizontalLay(wxEXPAND, 1);
245 {
246 szrG = S.GetSizer();
247
248 // Panel used to host the sliders since they will be positioned manually.
249 //mGraphicPanel = S.Prop(1)
250 //.Position(wxEXPAND)
251 //.Size( { -1, 150 } )
252 //.StartPanel();
253 S.AddSpace(15,0);
254 {
256 S.AddSpace(15,0);
257 } //S.EndPanel();
258 }
259 S.EndHorizontalLay();
260
261 // -------------------------------------------------------------------
262 // ROW 4: Various controls
263 // -------------------------------------------------------------------
264 S.SetSizerProportion(1);
265 S.Prop(1).StartMultiColumn(7, wxALIGN_CENTER_HORIZONTAL);
266 {
267 S.SetBorder(5);
268
269 S.AddSpace(5, 5);
270
271 if( mOptions == kEqLegacy )
272 {
273 S.StartHorizontalLay(wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
274 {
275 S.AddPrompt(XXO("&EQ Type:"));
276 }
277 S.EndHorizontalLay();
278
279 S.StartHorizontalLay(wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 1);
280 {
281 S.StartHorizontalLay(wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 1);
282 {
283 mDraw = S
284 .Name(XO("Draw Curves"))
285 .AddRadioButton(XXO("&Draw"));
286 BindTo(*mDraw, wxEVT_RADIOBUTTON,
288
289 mGraphic = S
290 .Name(XO("Graphic EQ"))
291 .AddRadioButtonToGroup(XXO("&Graphic"));
292 BindTo(*mGraphic, wxEVT_RADIOBUTTON,
294 }
295 S.EndHorizontalLay();
296 }
297 S.EndHorizontalLay();
298 }
299
300 S.StartHorizontalLay(wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 0);
301 {
302 szrH = S.GetSizer();
303
304 S.StartHorizontalLay(wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 1);
305 {
306 szrI = S.GetSizer();
307
309 .Name(XO("Interpolation type"))
310 .AddChoice( {},
313 0 );
314#if wxUSE_ACCESSIBILITY
315 // so that name can be set on a standard control
317#endif
318 BindTo(*mInterpChoice, wxEVT_CHOICE,
320 }
321 S.EndHorizontalLay();
322
323 S.StartHorizontalLay(wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 1);
324 {
325 szrL = S.GetSizer();
326
327 mLinFreq = S
328 .Name(XO("Linear Frequency Scale"))
329 .AddCheckBox(XXO("Li&near Frequency Scale"), false);
330 BindTo(*mLinFreq, wxEVT_CHECKBOX,
332 }
333 S.EndHorizontalLay();
334 }
335 S.EndHorizontalLay();
336
337 // -------------------------------------------------------------------
338 // Filter length grouping
339 // -------------------------------------------------------------------
340
341 if( mOptions == kEqLegacy ){
342 S.StartHorizontalLay(wxEXPAND, 0);
343 {
344 S.StartHorizontalLay(wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 0);
345 {
346 S.AddPrompt(XXO("Length of &Filter:"));
347 }
348 S.EndHorizontalLay();
349
350 S.StartHorizontalLay(wxEXPAND, 1);
351 {
352 mMSlider = S
353 .Name(XO("Length of Filter"))
354 .Style(wxSL_HORIZONTAL)
355 .AddSlider( {}, (M - 1) / 2, 4095, 10);
356 BindTo(*mMSlider, wxEVT_SLIDER,
358 }
359 S.EndHorizontalLay();
360
361 S.StartHorizontalLay(wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 0);
362 {
363 wxString label;
364 label.Printf(wxT("%ld"), M);
365 mMText = S.Name( Verbatim( label ) )
366 // fix for bug 577 (NVDA/Narrator screen readers do not
367 // read static text in dialogs)
368 .AddVariableText( Verbatim( label ) );
369 }
370 S.EndHorizontalLay();
371 }
372 S.EndHorizontalLay();
373
374 S.AddSpace(1, 1);
375 }
376
377 S.AddSpace(5, 5);
378
379 if( mOptions == kEqLegacy ){
380 S.AddSpace(5, 5);
381 S.StartHorizontalLay(wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
382 {
383 S.AddPrompt(XXO("&Select Curve:"));
384 }
385 S.EndHorizontalLay();
386
387 S.StartHorizontalLay(wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 1);
388 {
389 S.StartHorizontalLay(wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 1);
390 {
391 mCurve = S
392 .Name(XO("Select Curve"))
393 .AddChoice( {},
394 [&curves]{
396 for (const auto &curve : curves)
397 names.push_back( Verbatim( curve.Name ) );
398 return names;
399 }()
400 );
401 BindTo(*mCurve, wxEVT_CHOICE,
403 }
404 S.EndHorizontalLay();
405 }
406 S.EndHorizontalLay();
407
408 const auto pButton = S
409 .AddButton(XXO("S&ave/Manage Curves..."));
410 BindTo(*pButton, wxEVT_BUTTON, &EqualizationUI::OnManage);
411 }
412
413 S.StartHorizontalLay(wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 1);
414 {
415 auto pButton = S
416 .AddButton(XXO("Fla&tten"));
417 BindTo(*pButton, wxEVT_BUTTON, &EqualizationUI::OnClear);
418
419 pButton = S
420 .AddButton(XXO("&Invert"));
421 BindTo(*pButton, wxEVT_BUTTON, &EqualizationUI::OnInvert);
422
423 mGridOnOff = S
424 .Name(XO("Show grid lines"))
425 .AddCheckBox(XXO("Show g&rid lines"), false);
426 BindTo(*mGridOnOff, wxEVT_CHECKBOX,
428 }
429 S.EndHorizontalLay();
430
431 S.AddSpace(5, 5);
432 }
433 S.EndMultiColumn();
434 }
435 S.EndMultiColumn();
436
437 mUIParent->SetAutoLayout(false);
439 mUIParent->Layout();
440
442 drawMode = true;
444 drawMode = false;
445
446 // "show" settings for graphics mode before setting the size of the dialog
447 // as this needs more space than draw mode
448 szrV->Show(szrG,!drawMode); // eq sliders
449 szrH->Show(szrI,true); // interpolation choice
450 szrH->Show(szrL,false); // linear freq checkbox
451
453 mPanel->Show( false );
454 wxSize sz = szrV->GetMinSize();
455 sz += wxSize( 30, 0);
456 mUIParent->SetMinSize(sz);
457 }
458 else{
459 mPanel->Show( true );
460 szrV->Show(szr1, true);
461 // This sizing calculation is hacky.
462 // Rather than set the true minimum size we set a size we would
463 // like to have.
464 // This makes the default size of the dialog good, but has the
465 // downside that the user can't adjust the dialog smaller.
466 wxSize sz = szrV->GetMinSize();
467 sz += wxSize( 400, 100);
468 szrV->SetMinSize(sz);
469 }
471
472 return std::make_unique<EqualizationUIEditor>(*this, mUIServices, access, mUIParent);
473}
474
476{
477 auto &parameters = mCurvesList.mParameters;
478 const auto &lin = parameters.mLin;
479 const auto &drawGrid = parameters.mDrawGrid;
480 const auto &M = parameters.mM;
481 const auto &dBMin = parameters.mdBMin;
482 const auto &dBMax = parameters.mdBMax;
483 const auto &interp = parameters.mInterp;
484
485 auto &drawMode = parameters.mDrawMode;
486
487 // Set log or lin freq scale (affects interpolation as well)
488 mLinFreq->SetValue( lin );
489 wxCommandEvent dummyEvent;
490 OnLinFreq(dummyEvent); // causes a CalcFilter
491
492 mGridOnOff->SetValue( drawGrid ); // checks/unchecks the box on the interface
493
494 if( mMSlider )
495 mMSlider->SetValue((M - 1) / 2);
496
497 mdBMinSlider->SetValue((int)dBMin);
498 mdBMaxSlider->SetValue((int)dBMax);
499
500 // Reload the curve names
501 UpdateCurves();
502
503 // Set graphic interpolation mode
504 mInterpChoice->SetSelection(interp);
505
506 // Override draw mode, if we're not displaying the radio buttons.
508 drawMode = true;
510 drawMode = false;
511
512 if( mDraw )
513 mDraw->SetValue(drawMode);
514 szrV->Show(szr1,mOptions != kEqOptionGraphic); // Graph
515 szrV->Show(szrG,!drawMode); // eq sliders
516 szrH->Show(szrI,mOptions == kEqLegacy ); // interpolation choice
517 szrH->Show(szrL, drawMode); // linear freq checkbox
518 if( mGraphic)
519 mGraphic->SetValue(!drawMode);
520 mGridOnOff->Show( drawMode );
521
522 // Set Graphic (Fader) or Draw mode
523 if (!drawMode)
525
526 UpdateRuler();
527
528 mUIParent->Layout();
529 wxGetTopLevelParent(mUIParent)->Layout();
530
531 return true;
532}
533
535{
536 const auto &parameters = mCurvesList.mParameters;
537 const auto &dBMin = parameters.mdBMin;
538 const auto &dBMax = parameters.mdBMax;
539
540 // Refresh ruler when values have changed
541 int w1, w2, h;
542 mdBRuler->ruler.GetMaxSize(&w1, &h);
543 mdBRuler->ruler.SetRange(dBMax, dBMin);
544 mdBRuler->ruler.GetMaxSize(&w2, &h);
545 if( w1 != w2 ) // Reduces flicker
546 {
547 mdBRuler->SetSize(wxSize(w2,h));
548 mFreqRuler->Refresh(false);
549 }
550 mdBRuler->Refresh(false);
551
552 mPanel->Refresh(false);
553}
554
556//
557// All EffectEqualization methods beyond this point interact with the UI, so
558// can't be called while the UI is not displayed.
559//
561
563{
564 auto &parameters = mCurvesList.mParameters;
565 auto &curveName = parameters.mCurveName;
566 const auto &curves = mCurvesList.mCurves;
567
568 // Reload the curve names
569 if( mCurve )
570 mCurve->Clear();
571 bool selectedCurveExists = false;
572 for (size_t i = 0, cnt = curves.size(); i < cnt; i++)
573 {
574 if (curveName == curves[ i ].Name)
575 selectedCurveExists = true;
576 if( mCurve )
577 mCurve->Append(curves[ i ].Name);
578 }
579 // In rare circumstances, curveName may not exist (bug 1891)
580 if (!selectedCurveExists)
581 curveName = curves[ (int)curves.size() - 1 ].Name;
582 if( mCurve )
583 mCurve->SetStringSelection(curveName);
584
585 // Allow the control to resize
586 if( mCurve )
587 mCurve->SetMinSize({-1, -1});
588
589 // Set initial curve
590 mCurvesList.setCurve( curveName );
591}
592
594{
595 auto &parameters = mCurvesList.mParameters;
596 const auto &lin = parameters.mLin;
597 auto &linEnvelope = parameters.mLinEnvelope;
598 auto &logEnvelope = parameters.mLogEnvelope;
599 const auto &hiFreq = parameters.mHiFreq;
600
601 size_t numPoints = logEnvelope.GetNumberOfPoints();
602 Doubles when{ numPoints };
603 Doubles value{ numPoints };
604 double deltadB = 0.1;
605 double dx, dy, dx1, dy1, err;
606
607 logEnvelope.GetPoints( when.get(), value.get(), numPoints );
608
609 // set 'unnamed' as the selected curve
611
612 bool flag = true;
613 while (flag)
614 {
615 flag = false;
616 int numDeleted = 0;
617 logEnvelope.GetPoints( when.get(), value.get(), numPoints );
618 for (size_t j = 0; j + 2 < numPoints; j++)
619 {
620 dx = when[j+2+numDeleted] - when[j+numDeleted];
621 dy = value[j+2+numDeleted] - value[j+numDeleted];
622 dx1 = when[j+numDeleted+1] - when[j+numDeleted];
623 dy1 = dy * dx1 / dx;
624 err = fabs(value[j+numDeleted+1] - (value[j+numDeleted] + dy1));
625 if( err < deltadB )
626 { // within < deltadB dB?
627 logEnvelope.Delete(j+1);
628 numPoints--;
629 numDeleted++;
630 flag = true;
631 }
632 }
633 }
634
635 if(lin) // do not use IsLinear() here
636 {
639 mFreqRuler->ruler.SetRange(0, hiFreq);
640 }
641
642 szrV->Show(szrG,false);
643 szrH->Show(szrI,false);
644 szrH->Show(szrL,true);
645
646 mUIParent->Layout();
647 wxGetTopLevelParent(mUIParent)->Layout();
648 mCurvesList.ForceRecalc(); // it may have changed slightly due to the deletion of points
649}
650
652{
653 auto &parameters = mCurvesList.mParameters;
654 const auto &lin = parameters.mLin;
655 auto &linEnvelope = parameters.mLinEnvelope;
656 auto &logEnvelope = parameters.mLogEnvelope;
657 const auto &loFreq = parameters.mLoFreq;
658 const auto &hiFreq = parameters.mHiFreq;
659
660 auto &drawMode = parameters.mDrawMode;
661
662 if(lin) //going from lin to log freq scale - do not use IsLinear() here
663 { // add some extra points to the linear envelope for the graphic to follow
664 double step = pow(2., 1./12.); // twelve steps per octave
665 double when,value;
666 for(double freq=10.; freq<hiFreq; freq*=step)
667 {
668 when = freq/hiFreq;
669 value = linEnvelope.GetValue(when);
670 linEnvelope.Insert(when, value);
671 }
672
675 mFreqRuler->ruler.SetRange(loFreq, hiFreq);
676 }
677
678 mBands.ErrMin(); //move sliders to minimise error
679
680 szrV->Show(szrG,true); // eq sliders
681 szrH->Show(szrI,mOptions == kEqLegacy ); // interpolation choice
682 szrH->Show(szrL,false); // linear freq checkbox
683
684 mUIParent->Layout();
685 wxGetTopLevelParent(mUIParent)->Layout();
686 mUIParent->Layout();
687 wxGetTopLevelParent(mUIParent)->Layout();
688
689 mBands.GraphicEQ(logEnvelope);
690 drawMode = false;
691}
692
693void EqualizationUI::OnSize(wxSizeEvent & event)
694{
695 mUIParent->Layout();
696 event.Skip();
697}
698
699void EqualizationUI::OnInterp(wxCommandEvent & WXUNUSED(event))
700{
701 auto &parameters = mCurvesList.mParameters;
702 bool bIsGraphic = !parameters.mDrawMode;
703 if (bIsGraphic)
704 {
705 mBands.GraphicEQ(parameters.mLogEnvelope);
707 }
708 parameters.mInterp = mInterpChoice->GetSelection();
709}
710
711void EqualizationUI::OnDrawMode(wxCommandEvent & WXUNUSED(event))
712{
714 UpdateDraw();
715}
716
717void EqualizationUI::OnGraphicMode(wxCommandEvent & WXUNUSED(event))
718{
721}
722
723void EqualizationUI::OnSliderM(wxCommandEvent & WXUNUSED(event))
724{
725 auto &M = mCurvesList.mParameters.mM;
726
727 size_t m = 2 * mMSlider->GetValue() + 1;
728 // Must be odd
729 wxASSERT( (m & 1) == 1 );
730
731 if (m != M) {
732 M = m;
733 wxString tip;
734 tip.Printf(wxT("%d"), (int)M);
735 mMText->SetLabel(tip);
736 mMText->SetName(mMText->GetLabel()); // fix for bug 577 (NVDA/Narrator screen readers do not read static text in dialogs)
737 mMSlider->SetToolTip(tip);
738
740 }
741}
742
743void EqualizationUI::OnSliderDBMIN(wxCommandEvent & WXUNUSED(event))
744{
745 auto &dBMin = mCurvesList.mParameters.mdBMin;
746
747 float dB = mdBMinSlider->GetValue();
748 if (dB != dBMin) {
749 dBMin = dB;
750 wxString tip;
751 tip.Printf(_("%d dB"), (int)dBMin);
752 mdBMinSlider->SetToolTip(tip);
753 UpdateRuler();
754 }
755}
756
757void EqualizationUI::OnSliderDBMAX(wxCommandEvent & WXUNUSED(event))
758{
759 auto &dBMax = mCurvesList.mParameters.mdBMax;
760
761 float dB = mdBMaxSlider->GetValue();
762 if (dB != dBMax) {
763 dBMax = dB;
764 wxString tip;
765 tip.Printf(_("%d dB"), (int)dBMax);
766 mdBMaxSlider->SetToolTip(tip);
767 UpdateRuler();
768 }
769}
770
771//
772// New curve was selected
773//
774void EqualizationUI::OnCurve(wxCommandEvent & WXUNUSED(event))
775{
776 // Select NEW curve
777 wxASSERT( mCurve != NULL );
778 mCurvesList.setCurve( mCurve->GetCurrentSelection() );
781}
782
783//
784// User wants to modify the list in some way
785//
786void EqualizationUI::OnManage(wxCommandEvent & WXUNUSED(event))
787{
788 auto &curves = mCurvesList.mCurves;
790 curves, mCurve->GetSelection());
791 if (d.ShowModal()) {
792 wxGetTopLevelParent(mUIParent)->Layout();
794 }
795
796 // Reload the curve names
797 UpdateCurves();
798
799 // Allow control to resize
800 mUIParent->Layout();
801}
802
803void EqualizationUI::OnClear(wxCommandEvent & WXUNUSED(event))
804{
805 mBands.Flatten();
806}
807
808void EqualizationUI::OnInvert(wxCommandEvent & WXUNUSED(event))
809{
810 mBands.Invert();
811}
812
813void EqualizationUI::OnGridOnOff(wxCommandEvent & WXUNUSED(event))
814{
816 mPanel->Refresh(false);
817}
818
819void EqualizationUI::OnLinFreq(wxCommandEvent & WXUNUSED(event))
820{
821 auto &parameters = mCurvesList.mParameters;
822 auto &lin = parameters.mLin;
823 const auto &loFreq = parameters.mLoFreq;
824 const auto &hiFreq = parameters.mHiFreq;
825
826 lin = mLinFreq->IsChecked();
827 if(parameters.IsLinear()) //going from log to lin freq scale
828 {
830 mFreqRuler->ruler.SetRange(0, hiFreq);
832 lin = true;
833 }
834 else //going from lin to log freq scale
835 {
837 mFreqRuler->ruler.SetRange(loFreq, hiFreq);
839 lin = false;
840 }
841 mFreqRuler->Refresh(false);
843}
844
845void EqualizationUI::OnIdle(wxIdleEvent &event)
846{
847 event.Skip();
848 if (mCurve)
849 mCurve->SetStringSelection(mCurvesList.mParameters.mCurveName);
850}
wxT("CloseDown"))
Toolkit-neutral facade for basic user interface services.
END_EVENT_TABLE()
const int kEqLegacy
const int kEqOptionCurve
const int kEqOptionGraphic
XO("Cut/Copy/Paste")
XXO("&Cut/Copy/Paste Toolbar")
#define _(s)
Definition: Internat.h:73
#define safenew
Definition: MemoryX.h:10
TranslatableStrings Msgids(const EnumValueSymbol strings[], size_t nStrings)
Convenience function often useful when adding choice controls.
TranslatableString label
Definition: TagsEditor.cpp:165
static TranslatableStrings names
Definition: TagsEditor.cpp:153
#define S(N)
Definition: ToChars.cpp:64
static Settings & settings()
Definition: TrackInfo.cpp:51
TranslatableString Verbatim(wxString str)
Require calls to the one-argument constructor to go through this distinct global function name.
std::vector< TranslatableString > TranslatableStrings
static std::once_flag flag
Serializer of curves into XML files.
void SaveCurves(const wxString &fileName={})
Performs effect computation.
Hold values to send to effect output meters.
EqualizationCurvesDialog manages the available preset curves.
EqualizationPanel is used with EqualizationDialog and controls a graph for EffectEqualization....
wxSizer * szrH
void OnIdle(wxIdleEvent &event)
void OnSliderDBMAX(wxCommandEvent &event)
void OnDrawMode(wxCommandEvent &event)
void OnManage(wxCommandEvent &event)
EqualizationCurvesList & mCurvesList
void OnGraphicMode(wxCommandEvent &event)
wxRadioButton * mGraphic
wxWeakRef< EqualizationPanel > mPanel
wxSizer * szrV
wxCheckBox * mGridOnOff
void OnClear(wxCommandEvent &event)
wxChoice * mInterpChoice
wxStaticText * mMText
RulerPanel * mFreqRuler
void OnLinFreq(wxCommandEvent &event)
void OnInterp(wxCommandEvent &event)
EffectUIServices & mUIServices
void OnCurve(wxCommandEvent &event)
void BindTo(wxEvtHandler &src, const EventTag &eventType, void(Class::*pmf)(Event &))
const int mOptions
void OnSliderDBMIN(wxCommandEvent &event)
EqualizationBandSliders mBands
bool ValidateUI(EffectSettings &settings)
wxCheckBox * mLinFreq
wxSizer * szrG
void OnInvert(wxCommandEvent &event)
const wxWeakRef< wxWindow > & mUIParent
wxSlider * mdBMinSlider
wxSlider * mdBMaxSlider
void OnSliderM(wxCommandEvent &event)
std::unique_ptr< EffectEditor > PopulateOrExchange(ShuttleGui &S, EffectInstance &instance, EffectSettingsAccess &access, const EffectOutputs *pOutputs)
wxSlider * mMSlider
wxSizer * szrL
bool TransferDataToWindow(const EffectSettings &settings)
RulerPanel * mdBRuler
void OnSize(wxSizeEvent &event)
wxRadioButton * mDraw
TranslatableString mName
wxSizer * szr1
wxSizer * szrI
wxWeakRef< wxChoice > mCurve
void OnGridOnOff(wxCommandEvent &event)
static const IntFormat & Instance()
Definition: IntFormat.cpp:14
static const LinearDBFormat & Instance()
static const LinearUpdater & Instance()
static const LogarithmicUpdater & Instance()
void SetUpdater(const RulerUpdater *pUpdater)
Definition: Ruler.cpp:112
void GetMaxSize(wxCoord *width, wxCoord *height)
Definition: Ruler.cpp:612
void SetRange(double min, double max)
Definition: Ruler.cpp:152
RulerPanel class allows you to work with a Ruler like any other wxWindow.
Definition: RulerPanel.h:19
Ruler ruler
Definition: RulerPanel.h:79
std::pair< double, double > Range
Definition: RulerPanel.h:23
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:640
An alternative to using wxWindowAccessible, which in wxWidgets 3.1.1 contained GetParent() which was ...
void Disconnect() override
On the first call only, may disconnect from further event handling.
bool ValidateUI() override
Calls mServices.ValidateUI()
EqualizationUIEditor(EqualizationUI &ui, EffectUIServices &services, EffectSettingsAccess &access, wxWindow *pParent=nullptr)
Externalized state of a plug-in.
void AddBandSliders(ShuttleGui &S)
EqualizationFilter & mParameters
void setCurve(int currentCurve)
static const EnumValueSymbol kInterpStrings[nInterpolations]
Options & LabelEdges(bool l)
Definition: RulerPanel.h:41
Options & Log(bool l)
Definition: RulerPanel.h:35