Audacity  2.2.2
Equalization.h
Go to the documentation of this file.
1 /**********************************************************************
2 
3  Audacity: A Digital Audio Editor
4 
5  Equalization.h
6 
7  Mitch Golden
8  Vaughan Johnson (Preview)
9 
10 ***********************************************************************/
11 
12 #ifndef __AUDACITY_EFFECT_EQUALIZATION__
13 #define __AUDACITY_EFFECT_EQUALIZATION__
14 #define NUMBER_OF_BANDS 31
15 #define NUM_PTS 180
16 #define PANELBORDER 1 // only increase from '1' for testing purposes - MJS
17 
18 #include "../Experimental.h"
19 
20 #include <wx/button.h>
21 #include <wx/panel.h>
22 #include <wx/dialog.h>
23 #include <wx/intl.h>
24 #include <wx/listctrl.h>
25 #include <wx/stattext.h>
26 #include <wx/slider.h>
27 #include <wx/sizer.h>
28 #include <wx/string.h>
29 #include <wx/bitmap.h>
30 #include <wx/choice.h>
31 #include <wx/radiobut.h>
32 #include <wx/checkbox.h>
33 
34 #if wxUSE_ACCESSIBILITY
35 #include <wx/access.h>
36 #include "../widgets/WindowAccessible.h"
37 #endif
38 
39 #include "Effect.h"
40 #include "../xml/XMLTagHandler.h"
41 #include "../widgets/Grid.h"
42 #include "../widgets/Ruler.h"
43 #include "../RealFFTf.h"
44 #include "../SampleFormat.h"
45 
46 #define EQUALIZATION_PLUGIN_SYMBOL IdentInterfaceSymbol{ XO("Equalization") }
47 
48 
49 class Envelope;
50 class EnvelopeEditor;
51 class EqualizationPanel;
52 
53 //
54 // One point in a curve
55 //
56 class EQPoint
57 {
58 public:
59  EQPoint( const double f, const double d ) { Freq = f; dB = d; }
60 
61  bool operator < (const EQPoint &p1) const
62  {
63  return Freq < p1.Freq;
64  }
65 
66  double Freq;
67  double dB;
68 };
69 
70 //
71 // One curve in a list
72 //
73 // LLL: This "really" isn't needed as the array of points could be
74 // attached as wxClientData to the wxChoice entries. I
75 // didn't realize this until after the fact and am too
76 // lazy to change it. (But, hollar if you want me to.)
77 //
78 class EQCurve
79 {
80 public:
81  EQCurve( const wxString & name = wxEmptyString ) { Name = name; }
82  EQCurve( const wxChar * name ) { Name = name; }
83 
84  bool operator < (const EQCurve &that) const
85  {
86  return Name.CmpNoCase(that.Name) < 0;
87  }
88 
89  wxString Name;
90  std::vector<EQPoint> points;
91 };
92 
93 using EQCurveArray = std::vector<EQCurve>;
94 
95 #ifdef EXPERIMENTAL_EQ_SSE_THREADED
96 class EffectEqualization48x;
97 #endif
98 
99 class EffectEqualization final : public Effect,
100  public XMLTagHandler
101 {
102 public:
104  virtual ~EffectEqualization();
105 
106  // IdentInterface implementation
107 
108  IdentInterfaceSymbol GetSymbol() override;
109  wxString GetDescription() override;
110  wxString ManualPage() override;
111 
112  // EffectDefinitionInterface implementation
113 
114  EffectType GetType() override;
115 
116  // EffectClientInterface implementation
117 
118  bool DefineParams( ShuttleParams & S ) override;
119  bool GetAutomationParameters(CommandParameters & parms) override;
120  bool SetAutomationParameters(CommandParameters & parms) override;
121  bool LoadFactoryDefaults() override;
122 
123  // EffectUIClientInterface implementation
124 
125  bool ValidateUI() override;
126 
127  // Effect implementation
128 
129  bool Startup() override;
130  bool Init() override;
131  bool Process() override;
132 
133  bool PopulateUI(wxWindow *parent) override;
134  bool CloseUI() override;
135  void PopulateOrExchange(ShuttleGui & S) override;
136  bool TransferDataToWindow() override;
137  bool TransferDataFromWindow() override;
138 
139 private:
140  // EffectEqualization implementation
141 
142  // Number of samples in an FFT window
143  static const size_t windowSize = 16384u; //MJS - work out the optimum for this at run time? Have a dialog box for it?
144 
145  // Low frequency of the FFT. 20Hz is the
146  // low range of human hearing
147  enum {loFreqI=20};
148 
149  bool ProcessOne(int count, WaveTrack * t,
150  sampleCount start, sampleCount len);
151  bool CalcFilter();
152  void Filter(size_t len, float *buffer);
153 
154  void Flatten();
155  void ForceRecalc();
156  void EnvelopeUpdated();
157  void EnvelopeUpdated(Envelope *env, bool lin);
158  bool IsLinear();
159 
160  void LoadCurves(const wxString &fileName = wxEmptyString, bool append = false);
161  void SaveCurves(const wxString &fileName = wxEmptyString);
162  // Merge NEW curves only or update all factory presets.
163  void UpdateDefaultCurves( bool updateAll = false);
164  void Select(int sel);
165  void setCurve(int currentCurve);
166  void setCurve(const wxString &curveName);
167  void setCurve(void);
168  bool GetDefaultFileName(wxFileName &fileName);
169 
170  // XMLTagHandler callback methods for loading and saving
171  bool HandleXMLTag(const wxChar *tag, const wxChar **attrs) override;
172  XMLTagHandler *HandleXMLChild(const wxChar *tag) override;
173  void WriteXML(XMLWriter &xmlFile) const;
174 
175  void UpdateCurves();
176  void UpdateDraw();
177 
178  void LayoutEQSliders();
179  void UpdateGraphic(void);
180  void EnvLogToLin(void);
181  void EnvLinToLog(void);
182  void ErrMin(void);
183  void GraphicEQ(Envelope *env);
184  void spline(double x[], double y[], size_t n, double y2[]);
185  double splint(double x[], double y[], size_t n, double y2[], double xr);
186 
187  void OnSize( wxSizeEvent & event );
188  void OnSlider( wxCommandEvent & event );
189  void OnInterp( wxCommandEvent & event );
190  void OnSliderM( wxCommandEvent & event );
191  void OnSliderDBMAX( wxCommandEvent & event );
192  void OnSliderDBMIN( wxCommandEvent & event );
193  void OnDrawMode( wxCommandEvent &event );
194  void OnGraphicMode( wxCommandEvent &event );
195  void OnCurve( wxCommandEvent & event );
196  void OnManage( wxCommandEvent & event );
197  void OnClear( wxCommandEvent & event );
198  void OnInvert( wxCommandEvent & event );
199  void OnGridOnOff( wxCommandEvent & event );
200  void OnLinFreq( wxCommandEvent & event );
201 #ifdef EXPERIMENTAL_EQ_SSE_THREADED
202  void OnProcessingRadio( wxCommandEvent & event );
203  void OnBench( wxCommandEvent & event );
204 #endif
205 
206 private:
209  size_t mM;
210  wxString mCurveName;
211  bool mLin;
212  float mdBMax;
213  float mdBMin;
214  bool mDrawMode;
215  int mInterp;
216  bool mDrawGrid;
217 
218  double mWhens[NUM_PTS];
220  size_t mBandsInUse;
223 
225  double mLoFreq;
226  double mHiFreq;
227  size_t mWindowSize;
228  bool mDirty;
231 
233 
234  std::unique_ptr<Envelope> mLogEnvelope, mLinEnvelope;
236 
237 #ifdef EXPERIMENTAL_EQ_SSE_THREADED
238  bool mBench;
239  std::unique_ptr<EffectEqualization48x> mEffectEqualization48x;
240  friend class EffectEqualization48x;
241 #endif
242 
243  wxSizer *szrC;
244  wxSizer *szrG;
245  wxSizer *szrV;
246  wxSizer *szrH;
247  wxSizer *szrI;
248  wxSizer *szrL;
249  wxSizer *szr1;
250  wxSizer *szr2;
251  wxSizer *szr3;
252  wxSizer *szr4;
253  wxSizer *szr5;
254 
255  wxSizerItem *mLeftSpacer;
256 
258  wxPanel *mGraphicPanel;
259  wxRadioButton *mDraw;
260  wxRadioButton *mGraphic;
261  wxCheckBox *mLinFreq;
262  wxCheckBox *mGridOnOff;
263  wxChoice *mInterpChoice;
264  wxChoice *mCurve;
265  wxButton *mManage;
266  wxStaticText *mMText;
267  wxSlider *mMSlider;
268  wxSlider *mdBMinSlider;
269  wxSlider *mdBMaxSlider;
271 
272 #ifdef EXPERIMENTAL_EQ_SSE_THREADED
273  wxRadioButton *mMathProcessingType[5]; // default, sse, sse threaded, AVX, AVX threaded (note AVX is not implemented yet
274  wxBoxSizer *szrM;
275 #endif
276 
277  DECLARE_EVENT_TABLE()
278 
279  friend class EqualizationPanel;
280  friend class EditCurvesDialog;
281 };
282 
283 class EqualizationPanel final : public wxPanelWrapper
284 {
285 public:
287  wxWindow *parent, wxWindowID winid, EffectEqualization *effect);
288  ~EqualizationPanel();
289 
290  // We don't need or want to accept focus.
291  bool AcceptsFocus() const { return false; }
292  // So that wxPanel is not included in Tab traversal - see wxWidgets bug 15581
293  bool AcceptsFocusFromKeyboard() const { return false; }
294 
295  void ForceRecalc();
296 
297 private:
298  void Recalc();
299 
300  void OnMouseEvent(wxMouseEvent & event);
301  void OnCaptureLost(wxMouseCaptureLostEvent & event);
302  void OnPaint(wxPaintEvent & event);
303  void OnSize (wxSizeEvent & event);
304 
305 public:
306 // int & mM;
307 // float & mdBMax;
308 // float & mdBMin;
309 // Envelope & mEnvelope;
310 
311 private:
312  wxWindow *mParent;
314  std::unique_ptr<EnvelopeEditor> mLinEditor, mLogEditor;
315 
317 
318  std::unique_ptr<wxBitmap> mBitmap;
319  wxRect mEnvRect;
320  int mWidth;
321  int mHeight;
322 // size_t mWindowSize;
323 // float *mFilterFuncR;
324 // float *mFilterFuncI;
325  Floats mOutr, mOuti;
326 
327 // double mLoFreq;
328 // double mHiFreq;
329 
330  DECLARE_EVENT_TABLE()
331 };
332 
333 // EditCurvesDialog. Note that the 'modified' curve used to be called 'custom' but is now called 'unnamed'
334 // Some things that deal with 'unnamed' curves still use, for example, 'mCustomBackup' as variable names.
335 class EditCurvesDialog final : public wxDialogWrapper
336 {
337 public:
338  EditCurvesDialog(wxWindow * parent, EffectEqualization * effect, int position);
339  ~EditCurvesDialog();
340 
341 private:
342 
344  {
345  CurvesListID = 11000,
354  };
355 
356  wxListCtrl *mList; // List of curves.
357  EQCurveArray mEditCurves; // Copy of curves to muck about with
358  wxWindow *mParent; // the parent EQ Dialog
359  EffectEqualization *mEffect; // the parent EQ effect
360  int mPosition; // position of current curve in list
361  void Populate();
363  void PopulateList(int position);
364  void OnUp(wxCommandEvent &event);
365  void OnDown(wxCommandEvent &event);
366  long GetPreviousItem(long item);
367  void OnRename( wxCommandEvent &event );
368  void OnDelete( wxCommandEvent &event );
369  void OnImport( wxCommandEvent &event );
370  void OnExport( wxCommandEvent &event );
371  void OnLibrary( wxCommandEvent &event );
372  void OnDefaults( wxCommandEvent &event );
373  void OnOK(wxCommandEvent &event);
374 
375  void OnListSelectionChange( wxListEvent &event );
376  DECLARE_EVENT_TABLE()
377 };
378 
379 #if wxUSE_ACCESSIBILITY
380 
381 class SliderAx final : public WindowAccessible
382 {
383 public:
384  SliderAx(wxWindow * window, const wxString &fmt);
385 
386  virtual ~ SliderAx();
387 
388  // Retrieves the address of an IDispatch interface for the specified child.
389  // All objects must support this property.
390  wxAccStatus GetChild(int childId, wxAccessible** child) override;
391 
392  // Gets the number of children.
393  wxAccStatus GetChildCount(int* childCount) override;
394 
395  // Gets the default action for this object (0) or > 0 (the action for a child).
396  // Return wxACC_OK even if there is no action. actionName is the action, or the empty
397  // string if there is no action.
398  // The retrieved string describes the action that is performed on an object,
399  // not what the object does as a result. For example, a toolbar button that prints
400  // a document has a default action of "Press" rather than "Prints the current document."
401  wxAccStatus GetDefaultAction(int childId, wxString *actionName) override;
402 
403  // Returns the description for this object or a child.
404  wxAccStatus GetDescription(int childId, wxString *description) override;
405 
406  // Gets the window with the keyboard focus.
407  // If childId is 0 and child is NULL, no object in
408  // this subhierarchy has the focus.
409  // If this object has the focus, child should be 'this'.
410  wxAccStatus GetFocus(int *childId, wxAccessible **child) override;
411 
412  // Returns help text for this object or a child, similar to tooltip text.
413  wxAccStatus GetHelpText(int childId, wxString *helpText) override;
414 
415  // Returns the keyboard shortcut for this object or child.
416  // Return e.g. ALT+K
417  wxAccStatus GetKeyboardShortcut(int childId, wxString *shortcut) override;
418 
419  // Returns the rectangle for this object (id = 0) or a child element (id > 0).
420  // rect is in screen coordinates.
421  wxAccStatus GetLocation(wxRect& rect, int elementId) override;
422 
423  // Gets the name of the specified object.
424  wxAccStatus GetName(int childId, wxString *name) override;
425 
426  // Returns a role constant.
427  wxAccStatus GetRole(int childId, wxAccRole *role) override;
428 
429  // Gets a variant representing the selected children
430  // of this object.
431  // Acceptable values:
432  // - a null variant (IsNull() returns TRUE)
433  // - a list variant (GetType() == wxT("list"))
434  // - an integer representing the selected child element,
435  // or 0 if this object is selected (GetType() == wxT("long"))
436  // - a "void*" pointer to a wxAccessible child object
437  wxAccStatus GetSelections(wxVariant *selections) override;
438 
439  // Returns a state constant.
440  wxAccStatus GetState(int childId, long* state) override;
441 
442  // Returns a localized string representing the value for the object
443  // or child.
444  wxAccStatus GetValue(int childId, wxString* strValue) override;
445 
446 private:
447  wxWindow *mParent;
448  wxString mFmt;
449 };
450 
451 #endif // wxUSE_ACCESSIBILITY
452 
453 #endif
void UpdateGraphic(void)
void OnExport(const wxString &Format)
bool TransferDataFromWindow() override
bool HandleXMLTag(const wxChar *tag, const wxChar **attrs) override
bool ValidateUI() override
double dB
Definition: Equalization.h:67
friend class EqualizationPanel
Definition: Equalization.h:279
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI...
Definition: ShuttleGui.h:409
virtual ~EffectEqualization()
wxRadioButton * mGraphic
Definition: Equalization.h:260
An Effect that modifies volume in different frequency bands.
Definition: Equalization.h:99
void Select(int sel)
EffectEqualization * mEffect
Definition: Equalization.h:359
wxChoice * mInterpChoice
Definition: Equalization.h:263
bool Process() override
bool TransferDataToWindow() override
IdentInterfaceSymbol GetSymbol() override
wxWindow * mParent
Definition: Equalization.h:312
Draggable curve used in TrackPanel for varying amplification.
Definition: Envelope.h:77
Base class for many of the effects in Audacity.
Definition: Effect.h:62
wxCheckBox * mGridOnOff
Definition: Equalization.h:262
void SaveCurves(const wxString &fileName=wxEmptyString)
void OnInvert(wxCommandEvent &event)
bool ProcessOne(int count, WaveTrack *t, sampleCount start, sampleCount len)
Shuttle that deals with parameters. This is a base class with lots of virtual functions that do nothi...
Definition: Shuttle.h:60
void OnSlider(wxCommandEvent &event)
double mWhenSliders[NUMBER_OF_BANDS+1]
Definition: Equalization.h:219
void OnGraphicMode(wxCommandEvent &event)
RulerPanel class allows you to work with a Ruler like any other wxWindow.
Definition: Ruler.h:246
void OnGridOnOff(wxCommandEvent &event)
void OnSliderDBMIN(wxCommandEvent &event)
EqualizationPanel is used with EqualizationDialog and controls a graph for EffectEqualization. We should look at amalgamating the various graphing code, such as provided by FreqWindow and FilterPanel.
Definition: Equalization.h:283
void WriteXML(XMLWriter &xmlFile) const
Envelope * mEnvelope
Definition: Equalization.h:235
void OnDelete(const CommandContext &context)
wxRadioButton * mDraw
Definition: Equalization.h:259
wxString ManualPage() override
void OnClear(wxCommandEvent &event)
bool GetAutomationParameters(CommandParameters &parms) override
EQCurve(const wxChar *name)
Definition: Equalization.h:82
An alternative to using wxWindowAccessible, which in wxWidgets 3.1.1 contained GetParent() which was ...
std::unique_ptr< FFTParam, FFTDeleter > HFFT
Definition: RealFFTf.h:24
void UpdateDefaultCurves(bool updateAll=false)
std::unique_ptr< wxBitmap > mBitmap
Definition: Equalization.h:318
RulerPanel * mFreqRuler
Definition: Equalization.h:222
void OnCurve(wxCommandEvent &event)
void PopulateOrExchange(ShuttleGui &S) override
void spline(double x[], double y[], size_t n, double y2[])
void OnImport(const CommandContext &context)
wxListCtrl * mList
Definition: Equalization.h:356
double Freq
Definition: Equalization.h:66
void OnLinFreq(wxCommandEvent &event)
CommandParameters, derived from wxFileConfig, is essentially doing the same things as the Shuttle cla...
double splint(double x[], double y[], size_t n, double y2[], double xr)
void OnDrawMode(wxCommandEvent &event)
wxString Name
Definition: Equalization.h:89
A Track that contains audio waveform data.
Definition: WaveTrack.h:60
static const size_t windowSize
Definition: Equalization.h:143
void OnSize(wxSizeEvent &event)
wxSlider * mdBMaxSlider
Definition: Equalization.h:269
void Filter(size_t len, float *buffer)
std::unique_ptr< Envelope > mLogEnvelope
Definition: Equalization.h:234
This class is an interface which should be implemented by classes which wish to be able to load and s...
Definition: XMLTagHandler.h:70
bool Init() override
bool operator<(const EQPoint &p1) const
Definition: Equalization.h:61
void OnSliderDBMAX(wxCommandEvent &event)
wxString GetDescription() override
double mWhens[NUM_PTS]
Definition: Equalization.h:218
std::vector< EQPoint > points
Definition: Equalization.h:90
IdentInterfaceSymbol pairs a persistent string identifier used internally with an optional...
bool operator<(const EQCurve &that) const
Definition: Equalization.h:84
EQCurve(const wxString &name=wxEmptyString)
Definition: Equalization.h:81
wxSlider * mSliders[NUMBER_OF_BANDS]
Definition: Equalization.h:270
void GraphicEQ(Envelope *env)
EQCurve is used with EffectEqualization.
Definition: Equalization.h:78
wxStaticText * mMText
Definition: Equalization.h:266
EQCurveArray mCurves
Definition: Equalization.h:232
XMLTagHandler * HandleXMLChild(const wxChar *tag) override
void LoadCurves(const wxString &fileName=wxEmptyString, bool append=false)
EffectType
const wxChar * name
Definition: Distortion.cpp:94
wxSlider * mMSlider
Definition: Equalization.h:267
friend class EditCurvesDialog
Definition: Equalization.h:280
EffectType GetType() override
void OnManage(wxCommandEvent &event)
#define NUMBER_OF_BANDS
Definition: Equalization.h:14
EQPoint(const double f, const double d)
Definition: Equalization.h:59
std::unique_ptr< Envelope > mLinEnvelope
Definition: Equalization.h:234
#define NUM_PTS
Definition: Equalization.h:15
wxSizerItem * mLeftSpacer
Definition: Equalization.h:255
RulerPanel * mdBRuler
Definition: Equalization.h:221
bool PopulateUI(wxWindow *parent) override
double mEQVals[NUMBER_OF_BANDS+1]
Definition: Equalization.h:230
wxPanel * mGraphicPanel
Definition: Equalization.h:258
wxButton * mManage
Definition: Equalization.h:265
bool AcceptsFocus() const
Definition: Equalization.h:291
wxCheckBox * mLinFreq
Definition: Equalization.h:261
int mSlidersOld[NUMBER_OF_BANDS]
Definition: Equalization.h:229
void OnInterp(wxCommandEvent &event)
bool CloseUI() override
Base class for XMLFileWriter and XMLStringWriter that provides the general functionality for creating...
Definition: XMLWriter.h:22
bool GetDefaultFileName(wxFileName &fileName)
EQCurveArray mEditCurves
Definition: Equalization.h:357
wxWindow * mParent
Definition: Equalization.h:358
std::vector< EQCurve > EQCurveArray
Definition: Equalization.h:93
EQPoint is used with EQCurve and hence EffectEqualization.
Definition: Equalization.h:56
bool Startup() override
EffectEqualization * mEffect
Definition: Equalization.h:313
EqualizationPanel * mPanel
Definition: Equalization.h:257
void OnSliderM(wxCommandEvent &event)
std::unique_ptr< EnvelopeEditor > mLogEditor
Definition: Equalization.h:314
bool AcceptsFocusFromKeyboard() const
Definition: Equalization.h:293
wxSlider * mdBMinSlider
Definition: Equalization.h:268
bool LoadFactoryDefaults() override
bool SetAutomationParameters(CommandParameters &parms) override
bool DefineParams(ShuttleParams &S) override