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