20#include <wx/radiobut.h>
22#include <wx/checkbox.h>
23#include <wx/stattext.h>
25#include "../widgets/RulerPanel.h"
26#include "../widgets/LinearUpdater.h"
27#include "../widgets/LogarithmicUpdater.h"
28#include "../widgets/IntFormat.h"
29#include "../widgets/LinearDBFormat.h"
31#if wxUSE_ACCESSIBILITY
43 const auto ¶meters = mCurvesList.mParameters;
44 const auto &curveName = parameters.mCurveName;
45 auto &logEnvelope = parameters.mLogEnvelope;
46 const auto &curves = mCurvesList.mCurves;
51 if (mDisallowCustom && curveName ==
wxT(
"unnamed"))
57 XO(
"To use this filter curve in a macro, please choose a new name for it.\nChoose the 'Save/Manage Curves...' button and rename the 'unnamed' curve, then use that one."),
58 XO(
"Filter Curve EQ needs a different name") );
64 parameters.SaveConfig(mManager);
74 const auto &M = parameters.
mM;
75 const auto &loFreq = parameters.mLoFreq;
76 const auto &hiFreq = parameters.mHiFreq;
79 auto &drawMode = parameters.mDrawMode;
83 S.SetSizerProportion(1);
84 S.Prop(1).StartMultiColumn(1, wxEXPAND);
100 S.SetSizerProportion(1);
101 S.Prop(1).StartMultiColumn(3, wxEXPAND);
107 S.StartVerticalLay(wxEXPAND, 1);
111 S.GetParent(), wxID_ANY, wxHORIZONTAL,
120 .TicksAtExtremes(
true)
121 .TickColour( { 0, 0, 0 } )
125 S.GetParent(), wxID_ANY, wxVERTICAL,
132 .TicksAtExtremes(
true)
133 .TickColour( { 0, 0, 0 } )
136 S.Prop(0).AddSpace(0, 1);
144 parameters.ChooseEnvelope().Flatten(0.);
145 parameters.ChooseEnvelope().SetTrackLen(1.0);
150 .MinSize( { wxDefaultCoord, wxDefaultCoord } )
154 S.StartVerticalLay();
156 S.AddVariableText(
XO(
"+ dB"),
false, wxCENTER);
159 .Style(wxSL_VERTICAL | wxSL_INVERSE)
160 .AddSlider( {}, 30, 60, 0);
161#if wxUSE_ACCESSIBILITY
169 .Style(wxSL_VERTICAL | wxSL_INVERSE)
170 .AddSlider( {}, -30, -10, -120);
171 S.AddVariableText(
XO(
"- dB"),
false, wxCENTER);
172#if wxUSE_ACCESSIBILITY
190 .Position(wxEXPAND | wxALIGN_LEFT | wxALIGN_TOP | wxLEFT)
202 S.SetSizerProportion(1);
203 S.StartHorizontalLay(wxEXPAND, 1);
218 S.EndHorizontalLay();
223 S.SetSizerProportion(1);
224 S.Prop(1).StartMultiColumn(7, wxALIGN_CENTER_HORIZONTAL);
232 S.StartHorizontalLay(wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
234 S.AddPrompt(
XXO(
"&EQ Type:"));
236 S.EndHorizontalLay();
238 S.StartHorizontalLay(wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 1);
240 S.StartHorizontalLay(wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 1);
243 .Name(
XO(
"Draw Curves"))
244 .AddRadioButton(
XXO(
"&Draw"));
249 .Name(
XO(
"Graphic EQ"))
250 .AddRadioButtonToGroup(
XXO(
"&Graphic"));
254 S.EndHorizontalLay();
256 S.EndHorizontalLay();
259 S.StartHorizontalLay(wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 0);
263 S.StartHorizontalLay(wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 1);
268 .Name(
XO(
"Interpolation type"))
273#if wxUSE_ACCESSIBILITY
280 S.EndHorizontalLay();
282 S.StartHorizontalLay(wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 1);
287 .Name(
XO(
"Linear Frequency Scale"))
288 .AddCheckBox(
XXO(
"Li&near Frequency Scale"),
false);
292 S.EndHorizontalLay();
294 S.EndHorizontalLay();
301 S.StartHorizontalLay(wxEXPAND, 0);
303 S.StartHorizontalLay(wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 0);
305 S.AddPrompt(
XXO(
"Length of &Filter:"));
307 S.EndHorizontalLay();
309 S.StartHorizontalLay(wxEXPAND, 1);
312 .Name(
XO(
"Length of Filter"))
313 .Style(wxSL_HORIZONTAL)
314 .AddSlider( {}, (M - 1) / 2, 4095, 10);
318 S.EndHorizontalLay();
320 S.StartHorizontalLay(wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 0);
329 S.EndHorizontalLay();
331 S.EndHorizontalLay();
340 S.StartHorizontalLay(wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
342 S.AddPrompt(
XXO(
"&Select Curve:"));
344 S.EndHorizontalLay();
346 S.StartHorizontalLay(wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 1);
348 S.StartHorizontalLay(wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 1);
351 .Name(
XO(
"Select Curve"))
355 for (
const auto &curve : curves)
363 S.EndHorizontalLay();
365 S.EndHorizontalLay();
367 const auto pButton =
S
368 .AddButton(
XXO(
"S&ave/Manage Curves..."));
372 S.StartHorizontalLay(wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 1);
375 .AddButton(
XXO(
"Fla&tten"));
379 .AddButton(
XXO(
"&Invert"));
383 .Name(
XO(
"Show grid lines"))
384 .AddCheckBox(
XXO(
"Show g&rid lines"),
false);
388 S.EndHorizontalLay();
413 wxSize sz =
szrV->GetMinSize();
414 sz += wxSize( 30, 0);
425 wxSize sz =
szrV->GetMinSize();
426 sz += wxSize( 400, 100);
427 szrV->SetMinSize(sz);
437 const auto &lin = parameters.
mLin;
438 const auto &drawGrid = parameters.mDrawGrid;
439 const auto &M = parameters.mM;
440 const auto &dBMin = parameters.mdBMin;
441 const auto &dBMax = parameters.mdBMax;
442 const auto &interp = parameters.mInterp;
444 auto &drawMode = parameters.mDrawMode;
448 wxCommandEvent dummyEvent;
472 mDraw->SetValue(drawMode);
488 wxGetTopLevelParent(
mUIParent)->Layout();
496 const auto &dBMin = parameters.
mdBMin;
497 const auto &dBMax = parameters.mdBMax;
522 const auto &lin = parameters.mLin;
523 const auto &hiFreq = parameters.mHiFreq;
527 wxASSERT( currentCurve < (
int) curves.size() );
530 int numPoints = (int) curves[currentCurve].points.size();
532 auto &env = parameters.ChooseEnvelope();
534 env.SetTrackLen(1.0);
537 if (numPoints == 0) {
545 if (numPoints == 1) {
547 when = curves[currentCurve].points[0].Freq;
549 when = when / hiFreq;
553 double loLog = log10((
double)loFreqI);
554 double hiLog = log10(hiFreq);
555 double denom = hiLog - loLog;
557 (log10(std::max<double>(loFreqI, when))
560 value = curves[currentCurve].points[0].dB;
561 env.Insert(
std::min(1.0, std::max(0.0, when)), value);
567 std::sort(curves[currentCurve].points.begin(),
568 curves[currentCurve].points.end());
570 if (curves[currentCurve].points[0].Freq < 0) {
577 for(
int pointCount = 0; pointCount < numPoints; pointCount++) {
578 when = curves[currentCurve].points[pointCount].Freq / hiFreq;
579 value = curves[currentCurve].points[pointCount].dB;
581 env.Insert(when, value);
589 double nextDB = curves[currentCurve].points[pointCount].dB;
590 if (pointCount > 0) {
591 double nextF = curves[currentCurve].points[pointCount].Freq;
592 double lastF = curves[currentCurve].points[pointCount-1].Freq;
593 double lastDB = curves[currentCurve].points[pointCount-1].dB;
596 ((hiFreq - lastF) / (nextF - lastF)));
600 env.Insert(when, value);
606 double loLog = log10((
double) loFreqI);
607 double hiLog = log10(hiFreq);
608 double denom = hiLog - loLog;
613 for (firstAbove20Hz = 0; firstAbove20Hz < numPoints; firstAbove20Hz++) {
614 if (curves[currentCurve].points[firstAbove20Hz].Freq > loFreqI)
618 if (firstAbove20Hz == numPoints) {
621 value = curves[currentCurve].points[numPoints-1].dB;
622 env.Insert(when, value);
627 if (firstAbove20Hz > 0) {
630 double prevF = curves[currentCurve].points[firstAbove20Hz-1].Freq;
631 prevF = log10(std::max(1.0, prevF));
632 double prevDB = curves[currentCurve].points[firstAbove20Hz-1].dB;
633 double nextF = log10(curves[currentCurve].points[firstAbove20Hz].Freq);
634 double nextDB = curves[currentCurve].points[firstAbove20Hz].dB;
636 value = nextDB - ((nextDB - prevDB) * ((nextF - loLog) / (nextF - prevF)));
637 env.Insert(when, value);
641 for(
int pointCount = firstAbove20Hz; pointCount < numPoints; pointCount++)
643 double flog = log10(curves[currentCurve].points[pointCount].Freq);
644 wxASSERT(curves[currentCurve].points[pointCount].Freq >= loFreqI);
646 when = (flog - loLog)/denom;
647 value = curves[currentCurve].points[pointCount].dB;
649 env.Insert(when, value);
665 if (pointCount > 0) {
666 double lastDB = curves[currentCurve].points[pointCount-1].dB;
668 log10(curves[currentCurve].points[pointCount-1].Freq);
671 ((log10(hiFreq) - logLastF) / (flog - logLastF)));
673 env.Insert(when, value);
691 for( i = 0; i < curves.size(); i++ )
692 if( curveName == curves[ i ].Name )
694 if( i == curves.size())
697 XO(
"Requested curve not found, using 'unnamed'"),
698 XO(
"Curve not found"),
722 bool selectedCurveExists =
false;
723 for (
size_t i = 0, cnt = curves.size(); i < cnt; i++)
725 if (curveName == curves[ i ].Name)
726 selectedCurveExists =
true;
728 mCurve->Append(curves[ i ].Name);
731 if (!selectedCurveExists)
732 curveName = curves[ (int)curves.size() - 1 ].Name;
734 mCurve->SetStringSelection(curveName);
738 mCurve->SetMinSize({-1, -1});
747 const auto &lin = parameters.
mLin;
748 auto &linEnvelope = parameters.mLinEnvelope;
749 auto &logEnvelope = parameters.mLogEnvelope;
750 const auto &hiFreq = parameters.mHiFreq;
752 size_t numPoints = logEnvelope.GetNumberOfPoints();
755 double deltadB = 0.1;
756 double dx, dy, dx1, dy1, err;
758 logEnvelope.GetPoints( when.get(), value.get(), numPoints );
768 logEnvelope.GetPoints( when.get(), value.get(), numPoints );
769 for (
size_t j = 0; j + 2 < numPoints; j++)
771 dx = when[j+2+numDeleted] - when[j+numDeleted];
772 dy = value[j+2+numDeleted] - value[j+numDeleted];
773 dx1 = when[j+numDeleted+1] - when[j+numDeleted];
775 err = fabs(value[j+numDeleted+1] - (value[j+numDeleted] + dy1));
778 logEnvelope.Delete(j+1);
798 wxGetTopLevelParent(
mUIParent)->Layout();
805 const auto &lin = parameters.
mLin;
806 auto &linEnvelope = parameters.mLinEnvelope;
807 auto &logEnvelope = parameters.mLogEnvelope;
808 const auto &loFreq = parameters.mLoFreq;
809 const auto &hiFreq = parameters.mHiFreq;
811 auto &drawMode = parameters.mDrawMode;
815 double step = pow(2., 1./12.);
817 for(
double freq=10.; freq<hiFreq; freq*=step)
820 value = linEnvelope.GetValue(when);
821 linEnvelope.Insert(when, value);
836 wxGetTopLevelParent(
mUIParent)->Layout();
838 wxGetTopLevelParent(
mUIParent)->Layout();
878 size_t m = 2 *
mMSlider->GetValue() + 1;
880 wxASSERT( (m & 1) == 1 );
885 tip.Printf(
wxT(
"%d"), (
int)M);
902 tip.Printf(
_(
"%d dB"), (
int)dBMin);
916 tip.Printf(
_(
"%d dB"), (
int)dBMax);
928 wxASSERT(
mCurve != NULL );
941 curves,
mCurve->GetSelection());
943 wxGetTopLevelParent(
mUIParent)->Layout();
973 auto &lin = parameters.
mLin;
974 const auto &loFreq = parameters.mLoFreq;
975 const auto &hiFreq = parameters.mHiFreq;
978 if(parameters.IsLinear())
const int kEqOptionGraphic
XXO("&Cut/Copy/Paste Toolbar")
TranslatableStrings Msgids(const EnumValueSymbol strings[], size_t nStrings)
Convenience function often useful when adding choice controls.
static Settings & settings()
TranslatableString Verbatim(wxString str)
Require calls to the one-argument constructor to go through this distinct global function name.
std::vector< TranslatableString > TranslatableStrings
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....
void OnIdle(wxIdleEvent &event)
void OnSliderDBMAX(wxCommandEvent &event)
void OnDrawMode(wxCommandEvent &event)
void OnManage(wxCommandEvent &event)
EqualizationCurvesList & mCurvesList
void OnGraphicMode(wxCommandEvent &event)
wxWeakRef< EqualizationPanel > mPanel
void OnClear(wxCommandEvent &event)
void OnLinFreq(wxCommandEvent &event)
void OnInterp(wxCommandEvent &event)
void OnCurve(wxCommandEvent &event)
void BindTo(wxEvtHandler &src, const EventTag &eventType, void(Class::*pmf)(Event &))
void OnSliderDBMIN(wxCommandEvent &event)
EqualizationBandSliders mBands
void OnInvert(wxCommandEvent &event)
const wxWeakRef< wxWindow > & mUIParent
void OnSliderM(wxCommandEvent &event)
std::unique_ptr< EffectEditor > PopulateOrExchange(ShuttleGui &S, EffectInstance &instance, EffectSettingsAccess &access, const EffectOutputs *pOutputs)
bool TransferDataToWindow(const EffectSettings &settings)
void OnSize(wxSizeEvent &event)
wxWeakRef< wxChoice > mCurve
void OnGridOnOff(wxCommandEvent &event)
static const LinearUpdater & Instance()
static const LogarithmicUpdater & Instance()
void SetUpdater(const RulerUpdater *pUpdater)
void GetMaxSize(wxCoord *width, wxCoord *height)
void SetRange(double min, double max)
RulerPanel class allows you to work with a Ruler like any other wxWindow.
std::pair< double, double > Range
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
An alternative to using wxWindowAccessible, which in wxWidgets 3.1.1 contained GetParent() which was ...
int DoMessageBox(const TranslatableString &name, const TranslatableString &msg, const TranslatableString &titleStr, long style=wxOK|wxCENTRE)
Externalized state of a plug-in.
void AddBandSliders(ShuttleGui &S)
void GraphicEQ(Envelope &env)
EqualizationFilter & mParameters
static constexpr int loFreqI
static const EnumValueSymbol kInterpStrings[nInterpolations]
Options & LabelEdges(bool l)