Audacity  2.2.2
Public Member Functions | Private Types | Private Member Functions | Private Attributes | Static Private Attributes | Friends | List of all members
EffectEqualization Class Referencefinal

An Effect that modifies volume in different frequency bands. More...

#include <Equalization.h>

Inheritance diagram for EffectEqualization:
Effect XMLTagHandler

Public Member Functions

 EffectEqualization ()
 
virtual ~EffectEqualization ()
 
wxString GetSymbol () override
 
wxString GetDescription () override
 
wxString ManualPage () override
 
EffectType GetType () override
 
bool GetAutomationParameters (EffectAutomationParameters &parms) override
 
bool SetAutomationParameters (EffectAutomationParameters &parms) override
 
bool LoadFactoryDefaults () override
 
bool ValidateUI () override
 
bool Startup () override
 
bool Init () override
 
bool Process () override
 
bool PopulateUI (wxWindow *parent) override
 
bool CloseUI () override
 
void PopulateOrExchange (ShuttleGui &S) override
 
bool TransferDataToWindow () override
 
bool TransferDataFromWindow () override
 
- Public Member Functions inherited from Effect
 Effect ()
 
virtual ~Effect ()
 
wxString GetPath () override
 
wxString GetSymbol () override
 
wxString GetName () override
 
wxString GetVendor () override
 
wxString GetVersion () override
 
wxString GetDescription () override
 
EffectType GetType () override
 
wxString GetFamilyId () override
 
wxString GetFamilyName () override
 
bool IsInteractive () override
 
bool IsDefault () override
 
bool IsLegacy () override
 
bool SupportsRealtime () override
 
bool SupportsAutomation () override
 
bool SetHost (EffectHostInterface *host) override
 
unsigned GetAudioInCount () override
 
unsigned GetAudioOutCount () override
 
int GetMidiInCount () override
 
int GetMidiOutCount () override
 
sampleCount GetLatency () override
 
size_t GetTailSize () override
 
void SetSampleRate (double rate) override
 
size_t SetBlockSize (size_t maxBlockSize) override
 
bool IsReady () override
 
bool ProcessInitialize (sampleCount totalLen, ChannelNames chanMap=NULL) override
 
bool ProcessFinalize () override
 
size_t ProcessBlock (float **inBlock, float **outBlock, size_t blockLen) override
 
bool RealtimeInitialize () override
 
bool RealtimeAddProcessor (unsigned numChannels, float sampleRate) override
 
bool RealtimeFinalize () override
 
bool RealtimeSuspend () override
 
bool RealtimeResume () override
 
bool RealtimeProcessStart () override
 
size_t RealtimeProcess (int group, float **inbuf, float **outbuf, size_t numSamples) override
 
bool RealtimeProcessEnd () override
 
bool ShowInterface (wxWindow *parent, bool forceModal=false) override
 
bool GetAutomationParameters (EffectAutomationParameters &parms) override
 
bool SetAutomationParameters (EffectAutomationParameters &parms) override
 
bool LoadUserPreset (const wxString &name) override
 
bool SaveUserPreset (const wxString &name) override
 
wxArrayString GetFactoryPresets () override
 
bool LoadFactoryPreset (int id) override
 
bool LoadFactoryDefaults () override
 
void SetHostUI (EffectUIHostInterface *host) override
 
bool PopulateUI (wxWindow *parent) override
 
bool IsGraphicalUI () override
 
bool ValidateUI () override
 
bool HideUI () override
 
bool CloseUI () override
 
bool CanExportPresets () override
 
void ExportPresets () override
 
void ImportPresets () override
 
bool HasOptions () override
 
void ShowOptions () override
 
double GetDefaultDuration () override
 
double GetDuration () override
 
wxString GetDurationFormat () override
 
virtual wxString GetSelectionFormat ()
 
void SetDuration (double duration) override
 
bool Apply () override
 
void Preview () override
 
wxDialog * CreateUI (wxWindow *parent, EffectUIClientInterface *client) override
 
wxString GetUserPresetsGroup (const wxString &name) override
 
wxString GetCurrentSettingsGroup () override
 
wxString GetFactoryDefaultsGroup () override
 
virtual wxString GetSavedStateGroup ()
 
bool HasSharedConfigGroup (const wxString &group) override
 
bool GetSharedConfigSubgroups (const wxString &group, wxArrayString &subgroups) override
 
bool GetSharedConfig (const wxString &group, const wxString &key, wxString &value, const wxString &defval=wxEmptyString) override
 
bool GetSharedConfig (const wxString &group, const wxString &key, int &value, int defval=0) override
 
bool GetSharedConfig (const wxString &group, const wxString &key, bool &value, bool defval=false) override
 
bool GetSharedConfig (const wxString &group, const wxString &key, float &value, float defval=0.0) override
 
bool GetSharedConfig (const wxString &group, const wxString &key, double &value, double defval=0.0) override
 
bool SetSharedConfig (const wxString &group, const wxString &key, const wxString &value) override
 
bool SetSharedConfig (const wxString &group, const wxString &key, const int &value) override
 
bool SetSharedConfig (const wxString &group, const wxString &key, const bool &value) override
 
bool SetSharedConfig (const wxString &group, const wxString &key, const float &value) override
 
bool SetSharedConfig (const wxString &group, const wxString &key, const double &value) override
 
bool RemoveSharedConfigSubgroup (const wxString &group) override
 
bool RemoveSharedConfig (const wxString &group, const wxString &key) override
 
bool HasPrivateConfigGroup (const wxString &group) override
 
bool GetPrivateConfigSubgroups (const wxString &group, wxArrayString &subgroups) override
 
bool GetPrivateConfig (const wxString &group, const wxString &key, wxString &value, const wxString &defval=wxEmptyString) override
 
bool GetPrivateConfig (const wxString &group, const wxString &key, int &value, int defval=0) override
 
bool GetPrivateConfig (const wxString &group, const wxString &key, bool &value, bool defval=false) override
 
bool GetPrivateConfig (const wxString &group, const wxString &key, float &value, float defval=0.0) override
 
bool GetPrivateConfig (const wxString &group, const wxString &key, double &value, double defval=0.0) override
 
bool SetPrivateConfig (const wxString &group, const wxString &key, const wxString &value) override
 
bool SetPrivateConfig (const wxString &group, const wxString &key, const int &value) override
 
bool SetPrivateConfig (const wxString &group, const wxString &key, const bool &value) override
 
bool SetPrivateConfig (const wxString &group, const wxString &key, const float &value) override
 
bool SetPrivateConfig (const wxString &group, const wxString &key, const double &value) override
 
bool RemovePrivateConfigSubgroup (const wxString &group) override
 
bool RemovePrivateConfig (const wxString &group, const wxString &key) override
 
virtual PluginID GetID ()
 
virtual bool Startup (EffectClientInterface *client)
 
virtual bool GetAutomationParameters (wxString &parms)
 
virtual bool SetAutomationParameters (const wxString &parms)
 
virtual wxArrayString GetUserPresets ()
 
virtual bool HasCurrentSettings ()
 
virtual bool HasFactoryDefaults ()
 
virtual wxString GetPreset (wxWindow *parent, const wxString &parms)
 
virtual wxString HelpPage ()
 
virtual bool IsBatchProcessing ()
 
virtual void SetBatchProcessing (bool start)
 
void SetPresetParameters (const wxArrayString *Names, const wxArrayString *Values)
 
bool DoEffect (wxWindow *parent, double projectRate, TrackList *list, TrackFactory *factory, SelectedRegion *selectedRegion, bool shouldPrompt=true)
 
bool Delegate (Effect &delegate, wxWindow *parent, bool shouldPrompt)
 
bool RealtimeAddProcessor (int group, unsigned chans, float rate)
 
size_t RealtimeProcess (int group, unsigned chans, float **inbuf, float **outbuf, size_t numSamples)
 
bool IsRealtimeActive ()
 
virtual bool IsHidden ()
 
int MessageBox (const wxString &message, long style=DefaultMessageBoxStyle, const wxString &titleStr=wxString{})
 
- Public Member Functions inherited from XMLTagHandler
 XMLTagHandler ()
 
virtual ~XMLTagHandler ()
 
virtual void HandleXMLEndTag (const wxChar *WXUNUSED(tag))
 
virtual void HandleXMLContent (const wxString &WXUNUSED(content))
 
bool ReadXMLTag (const char *tag, const char **attrs)
 
void ReadXMLEndTag (const char *tag)
 
void ReadXMLContent (const char *s, int len)
 
XMLTagHandlerReadXMLChild (const char *tag)
 

Private Types

enum  { loFreqI =20 }
 

Private Member Functions

bool ProcessOne (int count, WaveTrack *t, sampleCount start, sampleCount len)
 
bool CalcFilter ()
 
void Filter (size_t len, float *buffer)
 
void Flatten ()
 
void ForceRecalc ()
 
void EnvelopeUpdated ()
 
void EnvelopeUpdated (Envelope *env, bool lin)
 
bool IsLinear ()
 
void LoadCurves (const wxString &fileName=wxEmptyString, bool append=false)
 
void SaveCurves (const wxString &fileName=wxEmptyString)
 
void UpdateDefaultCurves (bool updateAll=false)
 
void Select (int sel)
 
void setCurve (int currentCurve)
 
void setCurve (const wxString &curveName)
 
void setCurve (void)
 
bool GetDefaultFileName (wxFileName &fileName)
 
bool HandleXMLTag (const wxChar *tag, const wxChar **attrs) override
 
XMLTagHandlerHandleXMLChild (const wxChar *tag) override
 
void WriteXML (XMLWriter &xmlFile) const
 
void UpdateCurves ()
 
void UpdateDraw ()
 
void LayoutEQSliders ()
 
void UpdateGraphic (void)
 
void EnvLogToLin (void)
 
void EnvLinToLog (void)
 
void ErrMin (void)
 
void GraphicEQ (Envelope *env)
 
void spline (double x[], double y[], size_t n, double y2[])
 
double splint (double x[], double y[], size_t n, double y2[], double xr)
 
void OnSize (wxSizeEvent &event)
 
void OnSlider (wxCommandEvent &event)
 
void OnInterp (wxCommandEvent &event)
 
void OnSliderM (wxCommandEvent &event)
 
void OnSliderDBMAX (wxCommandEvent &event)
 
void OnSliderDBMIN (wxCommandEvent &event)
 
void OnDrawMode (wxCommandEvent &event)
 
void OnGraphicMode (wxCommandEvent &event)
 
void OnCurve (wxCommandEvent &event)
 
void OnManage (wxCommandEvent &event)
 
void OnClear (wxCommandEvent &event)
 
void OnInvert (wxCommandEvent &event)
 
void OnGridOnOff (wxCommandEvent &event)
 
void OnLinFreq (wxCommandEvent &event)
 

Private Attributes

HFFT hFFT
 
Floats mFFTBuffer
 
Floats mFilterFuncR
 
Floats mFilterFuncI
 
size_t mM
 
wxString mCurveName
 
bool mLin
 
float mdBMax
 
float mdBMin
 
bool mDrawMode
 
int mInterp
 
bool mDrawGrid
 
double mWhens [NUM_PTS]
 
double mWhenSliders [NUMBER_OF_BANDS+1]
 
size_t mBandsInUse
 
RulerPanelmdBRuler
 
RulerPanelmFreqRuler
 
wxArrayString mInterpolations
 
bool mDisallowCustom
 
double mLoFreq
 
double mHiFreq
 
size_t mWindowSize
 
bool mDirty
 
int mSlidersOld [NUMBER_OF_BANDS]
 
double mEQVals [NUMBER_OF_BANDS+1]
 
EQCurveArray mCurves
 
std::unique_ptr< EnvelopemLogEnvelope
 
std::unique_ptr< EnvelopemLinEnvelope
 
EnvelopemEnvelope
 
wxSizer * szrC
 
wxSizer * szrG
 
wxSizer * szrV
 
wxSizer * szrH
 
wxSizer * szrI
 
wxSizer * szrL
 
wxSizer * szr1
 
wxSizer * szr2
 
wxSizer * szr3
 
wxSizer * szr4
 
wxSizer * szr5
 
wxSizerItem * mLeftSpacer
 
EqualizationPanelmPanel
 
wxPanel * mGraphicPanel
 
wxRadioButton * mDraw
 
wxRadioButton * mGraphic
 
wxCheckBox * mLinFreq
 
wxCheckBox * mGridOnOff
 
wxChoice * mInterpChoice
 
wxChoice * mCurve
 
wxButton * mManage
 
wxStaticText * mMText
 
wxSlider * mMSlider
 
wxSlider * mdBMinSlider
 
wxSlider * mdBMaxSlider
 
wxSlider * mSliders [NUMBER_OF_BANDS]
 

Static Private Attributes

static const size_t windowSize = 16384u
 

Friends

class EqualizationPanel
 
class EditCurvesDialog
 

Additional Inherited Members

- Public Types inherited from Effect
enum  : long { DefaultMessageBoxStyle = wxOK | wxCENTRE }
 
- Protected Member Functions inherited from Effect
virtual bool PromptUser (wxWindow *parent)
 
virtual bool CheckWhetherSkipEffect ()
 
virtual bool ProcessPass ()
 
virtual bool InitPass1 ()
 
virtual bool InitPass2 ()
 
virtual int GetPass ()
 
virtual void End ()
 
virtual double CalcPreviewInputLength (double previewLength)
 
virtual void Preview (bool dryOnly)
 
virtual bool EnableApply (bool enable=true)
 
virtual bool EnablePreview (bool enable=true)
 
virtual void EnableDebug (bool enable=true)
 
bool TotalProgress (double frac)
 
bool TrackProgress (int whichTrack, double frac, const wxString &=wxEmptyString)
 
bool TrackGroupProgress (int whichGroup, double frac, const wxString &=wxEmptyString)
 
int GetNumWaveTracks ()
 
int GetNumWaveGroups ()
 
void GetSamples (const WaveTrack *track, sampleCount *start, sampleCount *len)
 
void SetLinearEffectFlag (bool linearEffectFlag)
 
void SetPreviewFullSelectionFlag (bool previewDurationFlag)
 
bool IsPreviewing ()
 
void IncludeNotSelectedPreviewTracks (bool includeNotSelected)
 
void CopyInputTracks ()
 
void CopyInputTracks (int trackType)
 
std::shared_ptr
< AddedAnalysisTrack
AddAnalysisTrack (const wxString &name=wxString())
 
ModifiedAnalysisTrack ModifyAnalysisTrack (const LabelTrack *pOrigTrack, const wxString &name=wxString())
 
void ReplaceProcessedTracks (const bool bGoodResult)
 
TrackAddToOutputTracks (std::unique_ptr< Track > &&t)
 
TrackListinputTracks () const
 
- Protected Attributes inherited from Effect
ProgressDialogmProgress
 
double mProjectRate
 
double mSampleRate
 
SelectedRegionmpSelectedRegion {}
 
TrackFactorymFactory
 
std::shared_ptr< TrackListmOutputTracks
 
double mT0
 
double mT1
 
double mF0
 
double mF1
 
wxArrayString mPresetNames
 
wxArrayString mPresetValues
 
int mPass
 
wxDialog * mUIDialog
 
wxWindow * mUIParent
 
int mUIResultID
 
sampleCount mSampleCnt
 
int mOutputTracksType
 

Detailed Description

An Effect that modifies volume in different frequency bands.

Performs filtering, using an FFT to do a FIR filter. It lets the user draw an arbitrary envelope (using the same envelope editing code that is used to edit the track's amplitude envelope).

Also allows the curve to be specified with a series of 'graphic EQ' sliders.

The filter is applied using overlap/add of Hanning windows.

Clone of the FFT Filter effect, no longer part of Audacity.

Definition at line 98 of file Equalization.h.

Member Enumeration Documentation

anonymous enum
private
Enumerator
loFreqI 

Definition at line 145 of file Equalization.h.

Constructor & Destructor Documentation

EffectEqualization::EffectEqualization ( )
EffectEqualization::~EffectEqualization ( )
virtual

Definition at line 282 of file Equalization.cpp.

283 {
284 }

Member Function Documentation

bool EffectEqualization::CalcFilter ( )
private

Definition at line 1200 of file Equalization.cpp.

References DB_TO_LINEAR(), InverseRealFFT(), IsLinear(), M_PI, mFilterFuncI, mFilterFuncR, mHiFreq, mLinEnvelope, mLoFreq, mLogEnvelope, mM, mWindowSize, and RealFFT().

Referenced by Init(), and EqualizationPanel::Recalc().

1201 {
1202  double loLog = log10(mLoFreq);
1203  double hiLog = log10(mHiFreq);
1204  double denom = hiLog - loLog;
1205 
1206  double delta = mHiFreq / ((double)(mWindowSize / 2.));
1207  double val0;
1208  double val1;
1209 
1210  if( IsLinear() )
1211  {
1212  val0 = mLinEnvelope->GetValue(0.0); //no scaling required - saved as dB
1213  val1 = mLinEnvelope->GetValue(1.0);
1214  }
1215  else
1216  {
1217  val0 = mLogEnvelope->GetValue(0.0); //no scaling required - saved as dB
1218  val1 = mLogEnvelope->GetValue(1.0);
1219  }
1220  mFilterFuncR[0] = val0;
1221  double freq = delta;
1222 
1223  for(size_t i = 1; i <= mWindowSize / 2; i++)
1224  {
1225  double when;
1226  if( IsLinear() )
1227  when = freq/mHiFreq;
1228  else
1229  when = (log10(freq) - loLog)/denom;
1230  if(when < 0.)
1231  {
1232  mFilterFuncR[i] = val0;
1233  }
1234  else if(when > 1.0)
1235  {
1236  mFilterFuncR[i] = val1;
1237  }
1238  else
1239  {
1240  if( IsLinear() )
1241  mFilterFuncR[i] = mLinEnvelope->GetValue(when);
1242  else
1243  mFilterFuncR[i] = mLogEnvelope->GetValue(when);
1244  }
1245  freq += delta;
1246  }
1247  mFilterFuncR[mWindowSize / 2] = val1;
1248 
1250 
1251  {
1252  size_t i = 1;
1253  for(; i < mWindowSize / 2; i++)
1254  {
1256  mFilterFuncR[mWindowSize - i] = mFilterFuncR[i]; //Fill entire array
1257  }
1258  mFilterFuncR[i] = DB_TO_LINEAR(mFilterFuncR[i]); //do last one
1259  }
1260 
1261  //transfer to time domain to do the padding and windowing
1262  Floats outr{ mWindowSize };
1263  Floats outi{ mWindowSize };
1264  InverseRealFFT(mWindowSize, mFilterFuncR.get(), NULL, outr.get()); // To time domain
1265 
1266  {
1267  size_t i = 0;
1268  for(; i <= (mM - 1) / 2; i++)
1269  { //Windowing - could give a choice, fixed for now - MJS
1270  // double mult=0.54-0.46*cos(2*M_PI*(i+(mM-1)/2.0)/(mM-1)); //Hamming
1271  //Blackman
1272  double mult =
1273  0.42 -
1274  0.5 * cos(2 * M_PI * (i + (mM - 1) / 2.0) / (mM - 1)) +
1275  .08 * cos(4 * M_PI * (i + (mM - 1) / 2.0) / (mM - 1));
1276  outr[i] *= mult;
1277  if(i != 0){
1278  outr[mWindowSize - i] *= mult;
1279  }
1280  }
1281  for(; i <= mWindowSize / 2; i++)
1282  { //Padding
1283  outr[i] = 0;
1284  outr[mWindowSize - i] = 0;
1285  }
1286  }
1287  Floats tempr{ mM };
1288  {
1289  size_t i = 0;
1290  for(; i < (mM - 1) / 2; i++)
1291  { //shift so that padding on right
1292  tempr[(mM - 1) / 2 + i] = outr[i];
1293  tempr[i] = outr[mWindowSize - (mM - 1) / 2 + i];
1294  }
1295  tempr[(mM - 1) / 2 + i] = outr[i];
1296  }
1297 
1298  for (size_t i = 0; i < mM; i++)
1299  { //and copy useful values back
1300  outr[i] = tempr[i];
1301  }
1302  for (size_t i = mM; i < mWindowSize; i++)
1303  { //rest is padding
1304  outr[i]=0.;
1305  }
1306 
1307  //Back to the frequency domain so we can use it
1308  RealFFT(mWindowSize, outr.get(), mFilterFuncR.get(), mFilterFuncI.get());
1309 
1310  return TRUE;
1311 }
void InverseRealFFT(size_t NumSamples, const float *RealIn, const float *ImagIn, float *RealOut)
Definition: FFT.cpp:269
void RealFFT(size_t NumSamples, const float *RealIn, float *RealOut, float *ImagOut)
Definition: FFT.cpp:231
std::unique_ptr< Envelope > mLogEnvelope
Definition: Equalization.h:233
#define M_PI
Definition: Distortion.cpp:28
std::unique_ptr< Envelope > mLinEnvelope
Definition: Equalization.h:233
const double MIN_Threshold_Linear DB_TO_LINEAR(MIN_Threshold_dB)
bool EffectEqualization::CloseUI ( )
override

Definition at line 577 of file Equalization.cpp.

References Effect::CloseUI(), mCurve, and mPanel.

578 {
579  mCurve = NULL;
580  mPanel = NULL;
581 
582  return Effect::CloseUI();
583 }
bool CloseUI() override
Definition: Effect.cpp:707
EqualizationPanel * mPanel
Definition: Equalization.h:256
void EffectEqualization::EnvelopeUpdated ( )
private

Definition at line 1827 of file Equalization.cpp.

References IsLinear(), mLinEnvelope, and mLogEnvelope.

Referenced by EnvLinToLog(), ErrMin(), Flatten(), OnInterp(), OnInvert(), EqualizationPanel::OnMouseEvent(), OnSlider(), and UpdateDraw().

1828 {
1829  if (IsLinear())
1830  {
1831  EnvelopeUpdated(mLinEnvelope.get(), true);
1832  }
1833  else
1834  {
1835  EnvelopeUpdated(mLogEnvelope.get(), false);
1836  }
1837 }
std::unique_ptr< Envelope > mLogEnvelope
Definition: Equalization.h:233
std::unique_ptr< Envelope > mLinEnvelope
Definition: Equalization.h:233
void EffectEqualization::EnvelopeUpdated ( Envelope env,
bool  lin 
)
private

Definition at line 1839 of file Equalization.cpp.

References Envelope::GetNumberOfPoints(), Envelope::GetPoints(), mCurves, mDirty, mHiFreq, and Select().

1840 {
1841  // Allocate and populate point arrays
1842  size_t numPoints = env->GetNumberOfPoints();
1843  Doubles when{ numPoints };
1844  Doubles value{ numPoints };
1845  env->GetPoints( when.get(), value.get(), numPoints );
1846 
1847  // Clear the unnamed curve
1848  int curve = mCurves.size() - 1;
1849  mCurves[ curve ].points.clear();
1850 
1851  if(lin)
1852  {
1853  // Copy and convert points
1854  for (size_t point = 0; point < numPoints; point++)
1855  {
1856  double freq = when[ point ] * mHiFreq;
1857  double db = value[ point ];
1858 
1859  // Add it to the curve
1860  mCurves[ curve ].points.push_back( EQPoint( freq, db ) );
1861  }
1862  }
1863  else
1864  {
1865  double loLog = log10( 20. );
1866  double hiLog = log10( mHiFreq );
1867  double denom = hiLog - loLog;
1868 
1869  // Copy and convert points
1870  for (size_t point = 0; point < numPoints; point++)
1871  {
1872  double freq = pow( 10., ( ( when[ point ] * denom ) + loLog ));
1873  double db = value[ point ];
1874 
1875  // Add it to the curve
1876  mCurves[ curve ].points.push_back( EQPoint( freq, db ) );
1877  }
1878  }
1879  // Remember that we've updated the unnamed curve
1880  mDirty = true;
1881 
1882  // set 'unnamed' as the selected curve
1883  Select( (int) mCurves.size() - 1 );
1884 }
size_t GetNumberOfPoints() const
Return number of points.
Definition: Envelope.cpp:980
void Select(int sel)
void GetPoints(double *bufferWhen, double *bufferValue, int bufferLen) const
Returns the sets of when and value pairs.
Definition: Envelope.cpp:985
EQCurveArray mCurves
Definition: Equalization.h:231
EQPoint is used with EQCurve and hence EffectEqualization.
Definition: Equalization.h:55
void EffectEqualization::EnvLinToLog ( void  )
private

Definition at line 2283 of file Equalization.cpp.

References EnvelopeUpdated(), mHiFreq, mLinEnvelope, and mLogEnvelope.

Referenced by OnInvert(), OnLinFreq(), and UpdateGraphic().

2284 {
2285  size_t numPoints = mLinEnvelope->GetNumberOfPoints();
2286  if( numPoints == 0 )
2287  {
2288  return;
2289  }
2290 
2291  Doubles when{ numPoints };
2292  Doubles value{ numPoints };
2293 
2294  mLogEnvelope->Flatten(0.);
2295  mLogEnvelope->SetTrackLen(1.0);
2296  mLinEnvelope->GetPoints( when.get(), value.get(), numPoints );
2297  mLogEnvelope->Reassign(0., value[0]);
2298  double loLog = log10(20.);
2299  double hiLog = log10(mHiFreq);
2300  double denom = hiLog - loLog;
2301  bool changed = false;
2302 
2303  for (size_t i = 0; i < numPoints; i++)
2304  {
2305  if( when[i]*mHiFreq >= 20 )
2306  {
2307  // Caution: on Linux, when when == 20, the log calulation rounds
2308  // to just under zero, which causes an assert error.
2309  double flog = (log10(when[i]*mHiFreq)-loLog)/denom;
2310  mLogEnvelope->InsertOrReplace(std::max(0.0, flog) , value[i]);
2311  }
2312  else
2313  { //get the first point as close as we can to the last point requested
2314  changed = true;
2315  double v = value[i];
2316  mLogEnvelope->InsertOrReplace(0., v);
2317  }
2318  }
2319  mLogEnvelope->Reassign(1., value[numPoints - 1]);
2320 
2321  if(changed)
2322  EnvelopeUpdated(mLogEnvelope.get(), false);
2323 }
std::unique_ptr< Envelope > mLogEnvelope
Definition: Equalization.h:233
std::unique_ptr< Envelope > mLinEnvelope
Definition: Equalization.h:233
void EffectEqualization::EnvLogToLin ( void  )
private

Definition at line 2259 of file Equalization.cpp.

References mHiFreq, mLinEnvelope, and mLogEnvelope.

Referenced by OnInvert(), OnLinFreq(), and UpdateDraw().

2260 {
2261  size_t numPoints = mLogEnvelope->GetNumberOfPoints();
2262  if( numPoints == 0 )
2263  {
2264  return;
2265  }
2266 
2267  Doubles when{ numPoints };
2268  Doubles value{ numPoints };
2269 
2270  mLinEnvelope->Flatten(0.);
2271  mLinEnvelope->SetTrackLen(1.0);
2272  mLogEnvelope->GetPoints( when.get(), value.get(), numPoints );
2273  mLinEnvelope->Reassign(0., value[0]);
2274  double loLog = log10(20.);
2275  double hiLog = log10(mHiFreq);
2276  double denom = hiLog - loLog;
2277 
2278  for (size_t i = 0; i < numPoints; i++)
2279  mLinEnvelope->InsertOrReplace(pow( 10., ((when[i] * denom) + loLog))/mHiFreq , value[i]);
2280  mLinEnvelope->Reassign(1., value[numPoints-1]);
2281 }
std::unique_ptr< Envelope > mLogEnvelope
Definition: Equalization.h:233
std::unique_ptr< Envelope > mLinEnvelope
Definition: Equalization.h:233
void EffectEqualization::ErrMin ( void  )
private

Definition at line 2325 of file Equalization.cpp.

References EnvelopeUpdated(), GraphicEQ(), mBandsInUse, mCurves, mEQVals, mLogEnvelope, mWhens, NUM_PTS, and Select().

Referenced by UpdateGraphic().

2326 {
2327  double vals[NUM_PTS];
2328  double error = 0.0;
2329  double oldError = 0.0;
2330  double mEQValsOld = 0.0;
2331  double correction = 1.6;
2332  bool flag;
2333  size_t j=0;
2334  Envelope testEnvelope{ *mLogEnvelope };
2335 
2336  for(size_t i = 0; i < NUM_PTS; i++)
2337  vals[i] = testEnvelope.GetValue(mWhens[i]);
2338 
2339  // Do error minimisation
2340  error = 0.;
2341  GraphicEQ(&testEnvelope);
2342  for(size_t i = 0; i < NUM_PTS; i++) //calc initial error
2343  {
2344  double err = vals[i] - testEnvelope.GetValue(mWhens[i]);
2345  error += err*err;
2346  }
2347  oldError = error;
2348  while( j < mBandsInUse*12 ) //loop over the sliders a number of times
2349  {
2350  auto i = j % mBandsInUse; //use this slider
2351  if( (j > 0) & (i == 0) ) // if we've come back to the first slider again...
2352  {
2353  if( correction > 0 )
2354  correction = -correction; //go down
2355  else
2356  correction = -correction/2.; //go up half as much
2357  }
2358  flag = true; // check if we've hit the slider limit
2359  do
2360  {
2361  oldError = error;
2362  mEQValsOld = mEQVals[i];
2363  mEQVals[i] += correction; //move fader value
2364  if( mEQVals[i] > 20. )
2365  {
2366  mEQVals[i] = 20.;
2367  flag = false;
2368  }
2369  if( mEQVals[i] < -20. )
2370  {
2371  mEQVals[i] = -20.;
2372  flag = false;
2373  }
2374  GraphicEQ(&testEnvelope); //calculate envelope
2375  error = 0.;
2376  for(size_t k = 0; k < NUM_PTS; k++) //calculate error
2377  {
2378  double err = vals[k] - testEnvelope.GetValue(mWhens[k]);
2379  error += err*err;
2380  }
2381  }
2382  while( (error < oldError) && flag );
2383  if( error > oldError )
2384  {
2385  mEQVals[i] = mEQValsOld; //last one didn't work
2386  error = oldError;
2387  }
2388  else
2389  oldError = error;
2390  if( error < .0025 * mBandsInUse)
2391  break; // close enuff
2392  j++; //try next slider
2393  }
2394  if( error > .0025 * mBandsInUse ) // not within 0.05dB on each slider, on average
2395  {
2396  Select( (int) mCurves.size() - 1 );
2397  EnvelopeUpdated(&testEnvelope, false);
2398  }
2399 }
void Select(int sel)
Draggable curve used in TrackPanel for varying amplification.
Definition: Envelope.h:77
std::unique_ptr< Envelope > mLogEnvelope
Definition: Equalization.h:233
double mWhens[NUM_PTS]
Definition: Equalization.h:216
void GraphicEQ(Envelope *env)
EQCurveArray mCurves
Definition: Equalization.h:231
#define NUM_PTS
Definition: Equalization.h:15
double mEQVals[NUMBER_OF_BANDS+1]
Definition: Equalization.h:229
void EffectEqualization::Filter ( size_t  len,
float *  buffer 
)
private

Definition at line 1313 of file Equalization.cpp.

References hFFT, InverseRealFFTf(), mFFTBuffer, mFilterFuncI, mFilterFuncR, RealFFTf(), and ReorderToTime().

Referenced by ProcessOne().

1314 {
1315  float re,im;
1316  // Apply FFT
1317  RealFFTf(buffer, hFFT.get());
1318  //FFT(len, false, inr, NULL, outr, outi);
1319 
1320  // Apply filter
1321  // DC component is purely real
1322  mFFTBuffer[0] = buffer[0] * mFilterFuncR[0];
1323  for(size_t i = 1; i < (len / 2); i++)
1324  {
1325  re=buffer[hFFT->BitReversed[i] ];
1326  im=buffer[hFFT->BitReversed[i]+1];
1327  mFFTBuffer[2*i ] = re*mFilterFuncR[i] - im*mFilterFuncI[i];
1328  mFFTBuffer[2*i+1] = re*mFilterFuncI[i] + im*mFilterFuncR[i];
1329  }
1330  // Fs/2 component is purely real
1331  mFFTBuffer[1] = buffer[1] * mFilterFuncR[len/2];
1332 
1333  // Inverse FFT and normalization
1334  InverseRealFFTf(mFFTBuffer.get(), hFFT.get());
1335  ReorderToTime(hFFT.get(), mFFTBuffer.get(), buffer);
1336 }
void ReorderToTime(const FFTParam *hFFT, const fft_type *buffer, fft_type *TimeOut)
Definition: RealFFTf.cpp:366
void InverseRealFFTf(fft_type *buffer, const FFTParam *h)
Definition: RealFFTf.cpp:269
void RealFFTf(fft_type *buffer, const FFTParam *h)
Definition: RealFFTf.cpp:167
void EffectEqualization::Flatten ( )
private

Definition at line 1897 of file Equalization.cpp.

References EnvelopeUpdated(), ForceRecalc(), kThirdOct, mBandsInUse, mDrawMode, mEQVals, mLinEnvelope, mLogEnvelope, mSliders, and mSlidersOld.

Referenced by OnClear().

1898 {
1899  mLogEnvelope->Flatten(0.);
1900  mLogEnvelope->SetTrackLen(1.0);
1901  mLinEnvelope->Flatten(0.);
1902  mLinEnvelope->SetTrackLen(1.0);
1903  ForceRecalc();
1904  if( !mDrawMode )
1905  {
1906  for( size_t i = 0; i < mBandsInUse; i++)
1907  {
1908  mSliders[i]->SetValue(0);
1909  mSlidersOld[i] = 0;
1910  mEQVals[i] = 0.;
1911 
1912  wxString tip;
1913  if( kThirdOct[i] < 1000.)
1914  tip.Printf( wxT("%dHz\n%.1fdB"), (int)kThirdOct[i], 0. );
1915  else
1916  tip.Printf( wxT("%gkHz\n%.1fdB"), kThirdOct[i]/1000., 0. );
1917  mSliders[i]->SetToolTip(tip);
1918  }
1919  }
1920  EnvelopeUpdated();
1921 }
std::unique_ptr< Envelope > mLogEnvelope
Definition: Equalization.h:233
wxSlider * mSliders[NUMBER_OF_BANDS]
Definition: Equalization.h:269
static const double kThirdOct[]
std::unique_ptr< Envelope > mLinEnvelope
Definition: Equalization.h:233
double mEQVals[NUMBER_OF_BANDS+1]
Definition: Equalization.h:229
int mSlidersOld[NUMBER_OF_BANDS]
Definition: Equalization.h:228
void EffectEqualization::ForceRecalc ( )
private

Definition at line 1816 of file Equalization.cpp.

References EqualizationPanel::ForceRecalc(), and mPanel.

Referenced by Flatten(), GraphicEQ(), OnInvert(), OnLinFreq(), OnSliderM(), setCurve(), TransferDataFromWindow(), and UpdateDraw().

1817 {
1818  if (mPanel)
1819  {
1820  mPanel->ForceRecalc();
1821  }
1822 }
EqualizationPanel * mPanel
Definition: Equalization.h:256
bool EffectEqualization::GetAutomationParameters ( EffectAutomationParameters &  parms)
override

Definition at line 312 of file Equalization.cpp.

References kInterpStrings, mCurveName, mInterp, mLin, and mM.

313 {
314  parms.Write(KEY_FilterLength, (unsigned long)mM);
315  parms.Write(KEY_CurveName, mCurveName);
316  parms.Write(KEY_InterpLin, mLin);
317  parms.WriteEnum(KEY_InterpMeth, mInterp, wxArrayString(kNumInterpolations, kInterpStrings));
318 
319  return true;
320 }
static const wxString kInterpStrings[kNumInterpolations]
bool EffectEqualization::GetDefaultFileName ( wxFileName &  fileName)
private

Definition at line 1548 of file Equalization.cpp.

References FileNames::DataDir(), and FileNames::ResourcesDir().

Referenced by LoadCurves().

1549 {
1550  // look in data dir first, in case the user has their own defaults (maybe downloaded ones)
1551  fileName = wxFileName( FileNames::DataDir(), wxT("EQDefaultCurves.xml") );
1552  if( !fileName.FileExists() )
1553  { // Default file not found in the data dir. Fall back to Resources dir.
1554  // See http://docs.wxwidgets.org/trunk/classwx_standard_paths.html#5514bf6288ee9f5a0acaf065762ad95d
1555  fileName = wxFileName( FileNames::ResourcesDir(), wxT("EQDefaultCurves.xml") );
1556  }
1557  if( !fileName.FileExists() )
1558  {
1559  // LLL: Is there really a need for an error message at all???
1560  //wxString errorMessage;
1561  //errorMessage.Printf(_("EQCurves.xml and EQDefaultCurves.xml were not found on your system.\nPlease press 'help' to visit the download page.\n\nSave the curves at %s"), FileNames::DataDir());
1562  //ShowErrorDialog(mUIParent, _("EQCurves.xml and EQDefaultCurves.xml missing"),
1563  // errorMessage, wxT("http://wiki.audacityteam.org/wiki/EQCurvesDownload"), false);
1564 
1565  // Have another go at finding EQCurves.xml in the data dir, in case 'help' helped
1566  fileName = wxFileName( FileNames::DataDir(), wxT("EQDefaultCurves.xml") );
1567  }
1568  return (fileName.FileExists());
1569 }
static wxString ResourcesDir()
Definition: FileNames.cpp:168
static wxString DataDir()
Audacity user data directory.
Definition: FileNames.cpp:130
wxString EffectEqualization::GetDescription ( )
override

Definition at line 293 of file Equalization.cpp.

References _().

294 {
295  return _("Adjusts the volume levels of particular frequencies");
296 }
_("Move Track &Down")+wxT("\t")+(GetActiveProject() -> GetCommandManager() ->GetKeyFromName(wxT("TrackMoveDown"))), OnMoveTrack) POPUP_MENU_ITEM(OnMoveTopID, _("Move Track to &Top")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveTop"))), OnMoveTrack) POPUP_MENU_ITEM(OnMoveBottomID, _("Move Track to &Bottom")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveBottom"))), OnMoveTrack) void TrackMenuTable::OnSetName(wxCommandEvent &)
wxString EffectEqualization::GetSymbol ( )
override

Definition at line 288 of file Equalization.cpp.

References EQUALIZATION_PLUGIN_SYMBOL.

289 {
291 }
#define EQUALIZATION_PLUGIN_SYMBOL
Definition: Equalization.h:45
EffectType EffectEqualization::GetType ( )
override

Definition at line 305 of file Equalization.cpp.

306 {
307  return EffectTypeProcess;
308 }
void EffectEqualization::GraphicEQ ( Envelope env)
private

Definition at line 2401 of file Equalization.cpp.

References Envelope::Flatten(), ForceRecalc(), Envelope::InsertOrReplace(), kBspline, kCosine, kCubic, M_PI, mBandsInUse, mEQVals, mInterp, mWhens, mWhenSliders, NUM_PTS, Envelope::Reassign(), Envelope::SetTrackLen(), spline(), and splint().

Referenced by ErrMin(), OnInterp(), OnInvert(), OnSlider(), and UpdateGraphic().

2402 {
2403  // JKC: 'value' is for height of curve.
2404  // The 0.0 initial value would only get used if NUM_PTS were 0.
2405  double value = 0.0;
2406  double dist, span, s;
2407 
2408  env->Flatten(0.);
2409  env->SetTrackLen(1.0);
2410 
2411  switch( mInterp )
2412  {
2413  case kBspline: // B-spline
2414  {
2415  int minF = 0;
2416  for(size_t i = 0; i < NUM_PTS; i++)
2417  {
2418  while( (mWhenSliders[minF] <= mWhens[i]) & (minF < (int)mBandsInUse) )
2419  minF++;
2420  minF--;
2421  if( minF < 0 ) //before first slider
2422  {
2423  dist = mWhens[i] - mWhenSliders[0];
2424  span = mWhenSliders[1] - mWhenSliders[0];
2425  s = dist/span;
2426  if( s < -1.5 )
2427  value = 0.;
2428  else if( s < -.5 )
2429  value = mEQVals[0]*(s + 1.5)*(s + 1.5)/2.;
2430  else
2431  value = mEQVals[0]*(.75 - s*s) + mEQVals[1]*(s + .5)*(s + .5)/2.;
2432  }
2433  else
2434  {
2435  if( mWhens[i] > mWhenSliders[mBandsInUse-1] ) //after last fader
2436  {
2437  dist = mWhens[i] - mWhenSliders[mBandsInUse-1];
2438  span = mWhenSliders[mBandsInUse-1] - mWhenSliders[mBandsInUse-2];
2439  s = dist/span;
2440  if( s > 1.5 )
2441  value = 0.;
2442  else if( s > .5 )
2443  value = mEQVals[mBandsInUse-1]*(s - 1.5)*(s - 1.5)/2.;
2444  else
2445  value = mEQVals[mBandsInUse-1]*(.75 - s*s) +
2446  mEQVals[mBandsInUse-2]*(s - .5)*(s - .5)/2.;
2447  }
2448  else //normal case
2449  {
2450  dist = mWhens[i] - mWhenSliders[minF];
2451  span = mWhenSliders[minF+1] - mWhenSliders[minF];
2452  s = dist/span;
2453  if(s < .5 )
2454  {
2455  value = mEQVals[minF]*(0.75 - s*s);
2456  if( minF+1 < (int)mBandsInUse )
2457  value += mEQVals[minF+1]*(s+.5)*(s+.5)/2.;
2458  if( minF-1 >= 0 )
2459  value += mEQVals[minF-1]*(s-.5)*(s-.5)/2.;
2460  }
2461  else
2462  {
2463  value = mEQVals[minF]*(s-1.5)*(s-1.5)/2.;
2464  if( minF+1 < (int)mBandsInUse )
2465  value += mEQVals[minF+1]*(.75-(1.-s)*(1.-s));
2466  if( minF+2 < (int)mBandsInUse )
2467  value += mEQVals[minF+2]*(s-.5)*(s-.5)/2.;
2468  }
2469  }
2470  }
2471  if(mWhens[i]<=0.)
2472  env->Reassign(0., value);
2473  env->InsertOrReplace( mWhens[i], value );
2474  }
2475  env->Reassign( 1., value );
2476  break;
2477  }
2478 
2479  case kCosine: // Cosine squared
2480  {
2481  int minF = 0;
2482  for(size_t i = 0; i < NUM_PTS; i++)
2483  {
2484  while( (mWhenSliders[minF] <= mWhens[i]) & (minF < (int)mBandsInUse) )
2485  minF++;
2486  minF--;
2487  if( minF < 0 ) //before first slider
2488  {
2489  dist = mWhenSliders[0] - mWhens[i];
2490  span = mWhenSliders[1] - mWhenSliders[0];
2491  if( dist < span )
2492  value = mEQVals[0]*(1. + cos(M_PI*dist/span))/2.;
2493  else
2494  value = 0.;
2495  }
2496  else
2497  {
2498  if( mWhens[i] > mWhenSliders[mBandsInUse-1] ) //after last fader
2499  {
2500  span = mWhenSliders[mBandsInUse-1] - mWhenSliders[mBandsInUse-2];
2501  dist = mWhens[i] - mWhenSliders[mBandsInUse-1];
2502  if( dist < span )
2503  value = mEQVals[mBandsInUse-1]*(1. + cos(M_PI*dist/span))/2.;
2504  else
2505  value = 0.;
2506  }
2507  else //normal case
2508  {
2509  span = mWhenSliders[minF+1] - mWhenSliders[minF];
2510  dist = mWhenSliders[minF+1] - mWhens[i];
2511  value = mEQVals[minF]*(1. + cos(M_PI*(span-dist)/span))/2. +
2512  mEQVals[minF+1]*(1. + cos(M_PI*dist/span))/2.;
2513  }
2514  }
2515  if(mWhens[i]<=0.)
2516  env->Reassign(0., value);
2517  env->InsertOrReplace( mWhens[i], value );
2518  }
2519  env->Reassign( 1., value );
2520  break;
2521  }
2522 
2523  case kCubic: // Cubic Spline
2524  {
2525  double y2[NUMBER_OF_BANDS+1];
2526  mEQVals[mBandsInUse] = mEQVals[mBandsInUse-1];
2527  spline(mWhenSliders, mEQVals, mBandsInUse+1, y2);
2528  for(double xf=0; xf<1.; xf+=1./NUM_PTS)
2529  {
2530  env->InsertOrReplace(xf, splint(mWhenSliders, mEQVals, mBandsInUse+1, y2, xf));
2531  }
2532  break;
2533  }
2534  }
2535 
2536  ForceRecalc();
2537 }
void Flatten(double value)
Definition: Envelope.cpp:137
int Reassign(double when, double value)
Move a point at when to value.
Definition: Envelope.cpp:960
double mWhenSliders[NUMBER_OF_BANDS+1]
Definition: Equalization.h:217
int InsertOrReplace(double when, double value)
Add a point at a particular absolute time coordinate.
Definition: Envelope.h:194
void spline(double x[], double y[], size_t n, double y2[])
void SetTrackLen(double trackLen, double sampleDur=0.0)
Definition: Envelope.cpp:1077
double splint(double x[], double y[], size_t n, double y2[], double xr)
double mWhens[NUM_PTS]
Definition: Equalization.h:216
#define M_PI
Definition: Distortion.cpp:28
#define NUMBER_OF_BANDS
Definition: Equalization.h:14
#define NUM_PTS
Definition: Equalization.h:15
double mEQVals[NUMBER_OF_BANDS+1]
Definition: Equalization.h:229
XMLTagHandler * EffectEqualization::HandleXMLChild ( const wxChar *  tag)
overrideprivatevirtual

Implements XMLTagHandler.

Definition at line 2027 of file Equalization.cpp.

2028 {
2029  if( !wxStrcmp( tag, wxT("equalizationeffect") ) )
2030  {
2031  return this;
2032  }
2033 
2034  if( !wxStrcmp( tag, wxT("curve") ) )
2035  {
2036  return this;
2037  }
2038 
2039  if( !wxStrcmp( tag, wxT("point") ) )
2040  {
2041  return this;
2042  }
2043 
2044  return NULL;
2045 }
bool EffectEqualization::HandleXMLTag ( const wxChar *  tag,
const wxChar **  attrs 
)
overrideprivatevirtual

Implements XMLTagHandler.

Definition at line 1926 of file Equalization.cpp.

References Internat::CompatibleToDouble(), XMLValueChecker::IsGoodString(), and mCurves.

1927 {
1928  // May want to add a version strings...
1929  if( !wxStrcmp( tag, wxT("equalizationeffect") ) )
1930  {
1931  return true;
1932  }
1933 
1934  // Located a NEW curve
1935  if( !wxStrcmp(tag, wxT("curve") ) )
1936  {
1937  // Process the attributes
1938  while( *attrs )
1939  {
1940  // Cache attr/value and bump to next
1941  const wxChar *attr = *attrs++;
1942  const wxChar *value = *attrs++;
1943 
1944  // Create a NEW curve and name it
1945  if( !wxStrcmp( attr, wxT("name") ) )
1946  {
1947  const wxString strValue = value;
1948  if (!XMLValueChecker::IsGoodString(strValue))
1949  return false;
1950  // check for a duplicate name and add (n) if there is one
1951  int n = 0;
1952  wxString strValueTemp = strValue;
1953  bool exists;
1954  do
1955  {
1956  exists = false;
1957  for(size_t i = 0; i < mCurves.size(); i++)
1958  {
1959  if(n>0)
1960  strValueTemp.Printf(wxT("%s (%d)"),strValue,n);
1961  if(mCurves[i].Name == strValueTemp)
1962  {
1963  exists = true;
1964  break;
1965  }
1966  }
1967  n++;
1968  }
1969  while(exists == true);
1970 
1971  mCurves.push_back( EQCurve( strValueTemp ) );
1972  }
1973  }
1974 
1975  // Tell caller it was processed
1976  return true;
1977  }
1978 
1979  // Located a NEW point
1980  if( !wxStrcmp( tag, wxT("point") ) )
1981  {
1982  // Set defaults in case attributes are missing
1983  double f = 0.0;
1984  double d = 0.0;
1985 
1986  // Process the attributes
1987  double dblValue;
1988  while( *attrs )
1989  { // Cache attr/value and bump to next
1990  const wxChar *attr = *attrs++;
1991  const wxChar *value = *attrs++;
1992 
1993  const wxString strValue = value;
1994 
1995  // Get the frequency
1996  if( !wxStrcmp( attr, wxT("f") ) )
1997  {
1998  if (!XMLValueChecker::IsGoodString(strValue) ||
1999  !Internat::CompatibleToDouble(strValue, &dblValue))
2000  return false;
2001  f = dblValue;
2002  }
2003  // Get the dB
2004  else if( !wxStrcmp( attr, wxT("d") ) )
2005  {
2006  if (!XMLValueChecker::IsGoodString(strValue) ||
2007  !Internat::CompatibleToDouble(strValue, &dblValue))
2008  return false;
2009  d = dblValue;
2010  }
2011  }
2012 
2013  // Create a NEW point
2014  mCurves[ mCurves.size() - 1 ].points.push_back( EQPoint( f, d ) );
2015 
2016  // Tell caller it was processed
2017  return true;
2018  }
2019 
2020  // Tell caller we didn't understand the tag
2021  return false;
2022 }
static bool IsGoodString(const wxString &str)
static bool CompatibleToDouble(const wxString &stringToConvert, double *result)
Convert a string to a number.
Definition: Internat.cpp:121
EQCurve is used with EffectEqualization.
Definition: Equalization.h:77
EQCurveArray mCurves
Definition: Equalization.h:231
EQPoint is used with EQCurve and hence EffectEqualization.
Definition: Equalization.h:55
bool EffectEqualization::Init ( )
overridevirtual

Reimplemented from Effect.

Definition at line 470 of file Equalization.cpp.

References _(), CalcFilter(), TrackListIterator::First(), GetActiveProject(), Track::GetKind(), WaveTrack::GetRate(), Track::GetSelected(), kThirdOct, loFreqI, mBandsInUse, mCurveName, mEnvelope, Effect::MessageBox(), mHiFreq, mLin, mLinEnvelope, mLoFreq, mLogEnvelope, TrackListIterator::Next(), setCurve(), and Track::Wave.

471 {
472  int selcount = 0;
473  double rate = 0.0;
474  TrackListIterator iter(GetActiveProject()->GetTracks());
475  Track *t = iter.First();
476  while (t) {
477  if (t->GetSelected() && t->GetKind() == Track::Wave) {
478  WaveTrack *track = (WaveTrack *)t;
479  if (selcount==0) {
480  rate = track->GetRate();
481  }
482  else {
483  if (track->GetRate() != rate) {
484  Effect::MessageBox(_("To apply Equalization, all selected tracks must have the same sample rate."));
485  return(false);
486  }
487  }
488  selcount++;
489  }
490  t = iter.Next();
491  }
492 
493  mHiFreq = rate / 2.0;
494  // Unlikely, but better than crashing.
495  if (mHiFreq <= loFreqI) {
496  Effect::MessageBox( _("Track sample rate is too low for this effect."),
497  wxOK | wxCENTRE,
498  _("Effect Unavailable"));
499  return(false);
500  }
501 
502  mLoFreq = loFreqI;
503 
504  mBandsInUse = 0;
505  while (kThirdOct[mBandsInUse] <= mHiFreq) {
506  mBandsInUse++;
508  break;
509  }
510 
511  mEnvelope = (mLin ? mLinEnvelope : mLogEnvelope).get();
512 
514 
515  CalcFilter();
516 
517  return(true);
518 }
int MessageBox(const wxString &message, long style=DefaultMessageBoxStyle, const wxString &titleStr=wxString{})
Definition: Effect.cpp:2665
bool GetSelected() const
Definition: Track.h:268
Envelope * mEnvelope
Definition: Equalization.h:234
virtual int GetKind() const
Definition: Track.h:322
A Track that contains audio waveform data.
Definition: WaveTrack.h:60
Fundamental data object of Audacity, placed in the TrackPanel. Classes derived form it include the Wa...
Definition: Track.h:94
std::unique_ptr< Envelope > mLogEnvelope
Definition: Equalization.h:233
An iterator for a TrackList.
Definition: Track.h:394
_("Move Track &Down")+wxT("\t")+(GetActiveProject() -> GetCommandManager() ->GetKeyFromName(wxT("TrackMoveDown"))), OnMoveTrack) POPUP_MENU_ITEM(OnMoveTopID, _("Move Track to &Top")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveTop"))), OnMoveTrack) POPUP_MENU_ITEM(OnMoveBottomID, _("Move Track to &Bottom")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveBottom"))), OnMoveTrack) void TrackMenuTable::OnSetName(wxCommandEvent &)
static const double kThirdOct[]
AUDACITY_DLL_API AudacityProject * GetActiveProject()
Definition: Project.cpp:300
#define NUMBER_OF_BANDS
Definition: Equalization.h:14
std::unique_ptr< Envelope > mLinEnvelope
Definition: Equalization.h:233
double GetRate() const
Definition: WaveTrack.cpp:424
bool EffectEqualization::IsLinear ( )
private

Definition at line 1889 of file Equalization.cpp.

References mDrawMode, and mLin.

Referenced by CalcFilter(), EnvelopeUpdated(), OnInvert(), OnLinFreq(), and EqualizationPanel::OnPaint().

1890 {
1891  return mDrawMode && mLin;
1892 }
void EffectEqualization::LayoutEQSliders ( )
private

Definition at line 2092 of file Equalization.cpp.

References kThirdOct, mFreqRuler, mGraphicPanel, mHiFreq, mLoFreq, mSliders, and NUMBER_OF_BANDS.

Referenced by OnSize(), TransferDataFromWindow(), and UpdateGraphic().

2093 {
2094  // layout the Graphic EQ sliders here
2095  wxRect rulerR = mFreqRuler->GetRect();
2096  int sliderW = mSliders[0]->GetSize().GetWidth();
2097  int sliderH = mGraphicPanel->GetRect().GetHeight();
2098 
2099  int start = rulerR.GetLeft() - (sliderW / 2);
2100  float range = rulerR.GetWidth();
2101 
2102  double loLog = log10(mLoFreq);
2103  double hiLog = log10(mHiFreq);
2104  double denom = hiLog - loLog;
2105 
2106  for (int i = 0; (i < NUMBER_OF_BANDS) && (kThirdOct[i] <= mHiFreq); ++i)
2107  {
2108  // centre of this slider, from start
2109  float posn = range * (log10(kThirdOct[i]) - loLog) / denom;
2110 
2111  mSliders[i]->SetSize(start + (posn + 0.5), 0, sliderW, sliderH);
2112  }
2113 
2114  mGraphicPanel->Refresh();
2115 }
RulerPanel * mFreqRuler
Definition: Equalization.h:220
wxSlider * mSliders[NUMBER_OF_BANDS]
Definition: Equalization.h:269
static const double kThirdOct[]
#define NUMBER_OF_BANDS
Definition: Equalization.h:14
wxPanel * mGraphicPanel
Definition: Equalization.h:257
void EffectEqualization::LoadCurves ( const wxString &  fileName = wxEmptyString,
bool  append = false 
)
private

Definition at line 1341 of file Equalization.cpp.

References _(), FileNames::DataDir(), EQCURVES_REVISION, EQCURVES_VERSION, GetDefaultFileName(), XMLFileReader::GetErrorStr(), gPrefs, mCurves, Effect::MessageBox(), XMLFileReader::Parse(), EQCurve::points, UPDATE_ALL, and UpdateDefaultCurves().

Referenced by EditCurvesDialog::OnDefaults(), EditCurvesDialog::OnImport(), EditCurvesDialog::OnOK(), and PopulateOrExchange().

1342 {
1343  // Construct normal curve filename
1344  //
1345  // LLL: Wouldn't you know that as of WX 2.6.2, there is a conflict
1346  // between wxStandardPaths and wxConfig under Linux. The latter
1347  // creates a normal file as "$HOME/.audacity", while the former
1348  // expects the ".audacity" portion to be a directory.
1349  // MJS: I don't know what the above means, or if I have broken it.
1350  wxFileName fn;
1351 
1352  if(fileName == wxT("")) {
1353  // Check if presets are up to date.
1354  wxString eqCurvesCurrentVersion = wxString::Format(wxT("%d.%d"), EQCURVES_VERSION, EQCURVES_REVISION);
1355  wxString eqCurvesInstalledVersion = wxT("");
1356  gPrefs->Read(wxT("/Effects/Equalization/PresetVersion"), &eqCurvesInstalledVersion, wxT(""));
1357 
1358  bool needUpdate = (eqCurvesCurrentVersion != eqCurvesInstalledVersion);
1359 
1360  // UpdateDefaultCurves allows us to import NEW factory presets only,
1361  // or update all factory preset curves.
1362  if (needUpdate)
1364  fn = wxFileName( FileNames::DataDir(), wxT("EQCurves.xml") );
1365  }
1366  else
1367  fn = fileName; // user is loading a specific set of curves
1368 
1369  // If requested file doesn't exist...
1370  if( !fn.FileExists() && !GetDefaultFileName(fn) ) {
1371  mCurves.clear();
1372  mCurves.push_back( _("unnamed") ); // we still need a default curve to use
1373  return;
1374  }
1375 
1376  EQCurve tempCustom(wxT("temp"));
1377  if( append == false ) // Start from scratch
1378  mCurves.clear();
1379  else // appending so copy and remove 'unnamed', to replace later
1380  {
1381  tempCustom.points = mCurves.back().points;
1382  mCurves.pop_back();
1383  }
1384 
1385  // Load the curves
1386  XMLFileReader reader;
1387  const wxString fullPath{ fn.GetFullPath() };
1388  if( !reader.Parse( this, fullPath ) )
1389  {
1390  wxString msg;
1391  /* i18n-hint: EQ stands for 'Equalization'.*/
1392  msg.Printf(_("Error Loading EQ Curves from file:\n%s\nError message says:\n%s"), fullPath, reader.GetErrorStr());
1393  // Inform user of load failure
1394  Effect::MessageBox( msg,
1395  wxOK | wxCENTRE,
1396  _("Error Loading EQ Curves"));
1397  mCurves.push_back( _("unnamed") ); // we always need a default curve to use
1398  return;
1399  }
1400 
1401  // Move "unnamed" to end, if it exists in current language.
1402  int numCurves = mCurves.size();
1403  int curve;
1404  EQCurve tempUnnamed(wxT("tempUnnamed"));
1405  for( curve = 0; curve < numCurves-1; curve++ )
1406  {
1407  if( mCurves[curve].Name == _("unnamed") )
1408  {
1409  tempUnnamed.points = mCurves[curve].points;
1410  mCurves.erase(mCurves.begin() + curve);
1411  mCurves.push_back( _("unnamed") ); // add 'unnamed' back at the end
1412  mCurves.back().points = tempUnnamed.points;
1413  }
1414  }
1415 
1416  if( mCurves.back().Name != _("unnamed") )
1417  mCurves.push_back( _("unnamed") ); // we always need a default curve to use
1418  if( append == true )
1419  {
1420  mCurves.back().points = tempCustom.points;
1421  }
1422 
1423  return;
1424 }
int MessageBox(const wxString &message, long style=DefaultMessageBoxStyle, const wxString &titleStr=wxString{})
Definition: Effect.cpp:2665
void UpdateDefaultCurves(bool updateAll=false)
bool Parse(XMLTagHandler *baseHandler, const wxString &fname)
wxFileConfig * gPrefs
Definition: Prefs.cpp:72
Reads a file and passes the results through an XMLTagHandler.
Definition: XMLFileReader.h:18
#define EQCURVES_REVISION
EQCurve is used with EffectEqualization.
Definition: Equalization.h:77
EQCurveArray mCurves
Definition: Equalization.h:231
_("Move Track &Down")+wxT("\t")+(GetActiveProject() -> GetCommandManager() ->GetKeyFromName(wxT("TrackMoveDown"))), OnMoveTrack) POPUP_MENU_ITEM(OnMoveTopID, _("Move Track to &Top")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveTop"))), OnMoveTrack) POPUP_MENU_ITEM(OnMoveBottomID, _("Move Track to &Bottom")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveBottom"))), OnMoveTrack) void TrackMenuTable::OnSetName(wxCommandEvent &)
#define EQCURVES_VERSION
static wxString DataDir()
Audacity user data directory.
Definition: FileNames.cpp:130
wxString GetErrorStr()
bool GetDefaultFileName(wxFileName &fileName)
#define UPDATE_ALL
bool EffectEqualization::LoadFactoryDefaults ( )
override

Definition at line 352 of file Equalization.cpp.

References Effect::LoadFactoryDefaults(), mdBMax, mdBMin, mDrawGrid, and mDrawMode.

353 {
354  mdBMin = DEF_dBMin;
355  mdBMax = DEF_dBMax;
356  mDrawMode = DEF_DrawMode;
357  mDrawGrid = DEF_DrawGrid;
358 
360 }
bool LoadFactoryDefaults() override
Definition: Effect.cpp:661
wxString EffectEqualization::ManualPage ( )
overridevirtual

Reimplemented from Effect.

Definition at line 298 of file Equalization.cpp.

299 {
300  return wxT("Equalization");
301 }
void EffectEqualization::OnClear ( wxCommandEvent &  event)
private

Definition at line 2699 of file Equalization.cpp.

References Flatten().

2700 {
2701  Flatten();
2702 }
void EffectEqualization::OnCurve ( wxCommandEvent &  event)
private

Definition at line 2675 of file Equalization.cpp.

References mCurve, mDrawMode, setCurve(), and UpdateGraphic().

2676 {
2677  // Select NEW curve
2678  wxASSERT( mCurve != NULL );
2679  setCurve( mCurve->GetCurrentSelection() );
2680  if( !mDrawMode )
2681  UpdateGraphic();
2682 }
void UpdateGraphic(void)
void EffectEqualization::OnDrawMode ( wxCommandEvent &  event)
private

Definition at line 2642 of file Equalization.cpp.

References mDrawMode, and UpdateDraw().

2643 {
2644  UpdateDraw();
2645 
2646  mDrawMode = true;
2647 }
void EffectEqualization::OnGraphicMode ( wxCommandEvent &  event)
private

Definition at line 2649 of file Equalization.cpp.

References mDrawMode, and UpdateGraphic().

2650 {
2651  UpdateGraphic();
2652 
2653  mDrawMode = false;
2654 }
void UpdateGraphic(void)
void EffectEqualization::OnGridOnOff ( wxCommandEvent &  event)
private

Definition at line 2772 of file Equalization.cpp.

References mDrawGrid, mGridOnOff, and mPanel.

2773 {
2774  mDrawGrid = mGridOnOff->IsChecked();
2775  mPanel->Refresh(false);
2776 }
wxCheckBox * mGridOnOff
Definition: Equalization.h:261
EqualizationPanel * mPanel
Definition: Equalization.h:256
void EffectEqualization::OnInterp ( wxCommandEvent &  event)
private

Definition at line 2632 of file Equalization.cpp.

References EnvelopeUpdated(), GraphicEQ(), mGraphic, mInterp, mInterpChoice, and mLogEnvelope.

2633 {
2634  if (mGraphic->GetValue())
2635  {
2636  GraphicEQ(mLogEnvelope.get());
2637  EnvelopeUpdated();
2638  }
2639  mInterp = mInterpChoice->GetSelection();
2640 }
wxRadioButton * mGraphic
Definition: Equalization.h:259
wxChoice * mInterpChoice
Definition: Equalization.h:262
std::unique_ptr< Envelope > mLogEnvelope
Definition: Equalization.h:233
void GraphicEQ(Envelope *env)
void EffectEqualization::OnInvert ( wxCommandEvent &  event)
private

Definition at line 2704 of file Equalization.cpp.

References EnvelopeUpdated(), EnvLinToLog(), EnvLogToLin(), ForceRecalc(), GraphicEQ(), IsLinear(), kThirdOct, mBandsInUse, mDrawMode, mEQVals, mLinEnvelope, mLogEnvelope, mSliders, and mSlidersOld.

2705 {
2706  if(!mDrawMode) // Graphic (Slider) mode. Invert the sliders.
2707  {
2708  for (size_t i = 0; i < mBandsInUse; i++)
2709  {
2710  mEQVals[i] = -mEQVals[i];
2711  int newPosn = (int)mEQVals[i];
2712  mSliders[i]->SetValue( newPosn );
2713  mSlidersOld[i] = newPosn;
2714 
2715  wxString tip;
2716  if( kThirdOct[i] < 1000.)
2717  tip.Printf( wxT("%dHz\n%.1fdB"), (int)kThirdOct[i], mEQVals[i] );
2718  else
2719  tip.Printf( wxT("%gkHz\n%.1fdB"), kThirdOct[i]/1000., mEQVals[i] );
2720  mSliders[i]->SetToolTip(tip);
2721  }
2722  GraphicEQ(mLogEnvelope.get());
2723  }
2724  else // Draw mode. Invert the points.
2725  {
2726  bool lin = IsLinear(); // refers to the 'log' or 'lin' of the frequency scale, not the amplitude
2727  size_t numPoints; // number of points in the curve/envelope
2728 
2729  // determine if log or lin curve is the current one
2730  // and find out how many points are in the curve
2731  if(lin) // lin freq scale and so envelope
2732  {
2733  numPoints = mLinEnvelope->GetNumberOfPoints();
2734  }
2735  else
2736  {
2737  numPoints = mLogEnvelope->GetNumberOfPoints();
2738  }
2739 
2740  if( numPoints == 0 )
2741  return;
2742 
2743  Doubles when{ numPoints };
2744  Doubles value{ numPoints };
2745 
2746  if(lin)
2747  mLinEnvelope->GetPoints( when.get(), value.get(), numPoints );
2748  else
2749  mLogEnvelope->GetPoints( when.get(), value.get(), numPoints );
2750 
2751  // invert the curve
2752  for (size_t i = 0; i < numPoints; i++)
2753  {
2754  if(lin)
2755  mLinEnvelope->Reassign(when[i] , -value[i]);
2756  else
2757  mLogEnvelope->Reassign(when[i] , -value[i]);
2758  }
2759 
2760  // copy it back to the other one (just in case)
2761  if(lin)
2762  EnvLinToLog();
2763  else
2764  EnvLogToLin();
2765  }
2766 
2767  // and update the display etc
2768  ForceRecalc();
2769  EnvelopeUpdated();
2770 }
std::unique_ptr< Envelope > mLogEnvelope
Definition: Equalization.h:233
wxSlider * mSliders[NUMBER_OF_BANDS]
Definition: Equalization.h:269
void GraphicEQ(Envelope *env)
static const double kThirdOct[]
std::unique_ptr< Envelope > mLinEnvelope
Definition: Equalization.h:233
double mEQVals[NUMBER_OF_BANDS+1]
Definition: Equalization.h:229
int mSlidersOld[NUMBER_OF_BANDS]
Definition: Equalization.h:228
void EffectEqualization::OnLinFreq ( wxCommandEvent &  event)
private

Definition at line 2778 of file Equalization.cpp.

References EnvLinToLog(), EnvLogToLin(), ForceRecalc(), IsLinear(), mEnvelope, mFreqRuler, mHiFreq, mLin, mLinEnvelope, mLinFreq, mLoFreq, mLogEnvelope, RulerPanel::ruler, Ruler::SetLog(), and Ruler::SetRange().

Referenced by TransferDataToWindow().

2779 {
2780  mLin = mLinFreq->IsChecked();
2781  if(IsLinear()) //going from log to lin freq scale
2782  {
2783  mFreqRuler->ruler.SetLog(false);
2785  EnvLogToLin();
2786  mEnvelope = mLinEnvelope.get();
2787  mLin = true;
2788  }
2789  else //going from lin to log freq scale
2790  {
2791  mFreqRuler->ruler.SetLog(true);
2793  EnvLinToLog();
2794  mEnvelope = mLogEnvelope.get();
2795  mLin = false;
2796  }
2797  mFreqRuler->Refresh(false);
2798  ForceRecalc();
2799 }
void SetLog(bool log)
Definition: Ruler.cpp:197
Envelope * mEnvelope
Definition: Equalization.h:234
RulerPanel * mFreqRuler
Definition: Equalization.h:220
std::unique_ptr< Envelope > mLogEnvelope
Definition: Equalization.h:233
void SetRange(double min, double max)
Definition: Ruler.cpp:234
std::unique_ptr< Envelope > mLinEnvelope
Definition: Equalization.h:233
wxCheckBox * mLinFreq
Definition: Equalization.h:260
Ruler ruler
Definition: Ruler.h:304
void EffectEqualization::OnManage ( wxCommandEvent &  event)
private

Definition at line 2687 of file Equalization.cpp.

References mCurve, Effect::mUIParent, and UpdateCurves().

2688 {
2689  EditCurvesDialog d(mUIParent, this, mCurve->GetSelection());
2690  d.ShowModal();
2691 
2692  // Reload the curve names
2693  UpdateCurves();
2694 
2695  // Allow control to resize
2696  mUIParent->Layout();
2697 }
wxWindow * mUIParent
Definition: Effect.h:475
void EffectEqualization::OnSize ( wxSizeEvent &  event)
private

Definition at line 2582 of file Equalization.cpp.

References LayoutEQSliders(), mDrawMode, and Effect::mUIParent.

2583 {
2584  mUIParent->Layout();
2585 
2586  if (!mDrawMode)
2587  {
2588  LayoutEQSliders();
2589  }
2590 
2591  event.Skip();
2592 }
wxWindow * mUIParent
Definition: Effect.h:475
void EffectEqualization::OnSlider ( wxCommandEvent &  event)
private

Definition at line 2594 of file Equalization.cpp.

References EnvelopeUpdated(), GraphicEQ(), kThirdOct, mBandsInUse, mEQVals, mLogEnvelope, mSliders, and mSlidersOld.

2595 {
2596  wxSlider *s = (wxSlider *)event.GetEventObject();
2597  for (size_t i = 0; i < mBandsInUse; i++)
2598  {
2599  if( s == mSliders[i])
2600  {
2601  int posn = mSliders[i]->GetValue();
2602  if( wxGetKeyState(WXK_SHIFT) )
2603  {
2604  if( posn > mSlidersOld[i] )
2605  mEQVals[i] += (float).1;
2606  else
2607  if( posn < mSlidersOld[i] )
2608  mEQVals[i] -= .1f;
2609  }
2610  else
2611  mEQVals[i] += (posn - mSlidersOld[i]);
2612  if( mEQVals[i] > 20. )
2613  mEQVals[i] = 20.;
2614  if( mEQVals[i] < -20. )
2615  mEQVals[i] = -20.;
2616  int newPosn = (int)mEQVals[i];
2617  mSliders[i]->SetValue( newPosn );
2618  mSlidersOld[i] = newPosn;
2619  wxString tip;
2620  if( kThirdOct[i] < 1000.)
2621  tip.Printf( wxT("%dHz\n%.1fdB"), (int)kThirdOct[i], mEQVals[i] );
2622  else
2623  tip.Printf( wxT("%gkHz\n%.1fdB"), kThirdOct[i]/1000., mEQVals[i] );
2624  s->SetToolTip(tip);
2625  break;
2626  }
2627  }
2628  GraphicEQ(mLogEnvelope.get());
2629  EnvelopeUpdated();
2630 }
std::unique_ptr< Envelope > mLogEnvelope
Definition: Equalization.h:233
wxSlider * mSliders[NUMBER_OF_BANDS]
Definition: Equalization.h:269
void GraphicEQ(Envelope *env)
static const double kThirdOct[]
double mEQVals[NUMBER_OF_BANDS+1]
Definition: Equalization.h:229
int mSlidersOld[NUMBER_OF_BANDS]
Definition: Equalization.h:228
void EffectEqualization::OnSliderDBMAX ( wxCommandEvent &  event)
private

Definition at line 2667 of file Equalization.cpp.

References TransferDataFromWindow().

2668 {
2670 }
bool TransferDataFromWindow() override
void EffectEqualization::OnSliderDBMIN ( wxCommandEvent &  event)
private

Definition at line 2662 of file Equalization.cpp.

References TransferDataFromWindow().

2663 {
2665 }
bool TransferDataFromWindow() override
void EffectEqualization::OnSliderM ( wxCommandEvent &  event)
private

Definition at line 2656 of file Equalization.cpp.

References ForceRecalc(), and TransferDataFromWindow().

2657 {
2659  ForceRecalc();
2660 }
bool TransferDataFromWindow() override
void EffectEqualization::PopulateOrExchange ( ShuttleGui S)
overridevirtual

Reimplemented from Effect.

Definition at line 585 of file Equalization.cpp.

References _(), ShuttleGuiBase::AddButton(), ShuttleGuiBase::AddCheckBox(), ShuttleGuiBase::AddChoice(), ShuttleGuiBase::AddPrompt(), ShuttleGuiBase::AddRadioButton(), ShuttleGuiBase::AddRadioButtonToGroup(), ShuttleGuiBase::AddSlider(), ShuttleGui::AddSpace(), ShuttleGuiBase::AddUnits(), ShuttleGuiBase::AddVariableText(), ShuttleGuiBase::AddWindow(), ShuttleGuiBase::EndHorizontalLay(), ShuttleGuiBase::EndMultiColumn(), ShuttleGuiBase::EndVerticalLay(), EqualizationPanel, TrackListCondIterator::First(), RulerPanel::Options::Flip(), GetActiveProject(), ShuttleGuiBase::GetParent(), WaveTrack::GetRate(), AudacityProject::GetRate(), ShuttleGuiBase::GetSizer(), ShuttleGui::Id(), Effect::inputTracks(), Ruler::IntFormat, kThirdOct, label, RulerPanel::Options::LabelEdges(), Ruler::LinearDBFormat, LoadCurves(), loFreqI, RulerPanel::Options::Log(), mCurve, mCurves, mdBMaxSlider, mdBMinSlider, mdBRuler, mDraw, mEQVals, mFreqRuler, mGraphic, mGraphicPanel, mGridOnOff, mHiFreq, mInterpChoice, mInterpolations, mLinFreq, mLoFreq, mM, mMSlider, mMText, mPanel, mSliders, mSlidersOld, Effect::mUIParent, name, NUMBER_OF_BANDS, ShuttleGui::Prop(), safenew, ShuttleGuiBase::SetBorder(), ShuttleGui::SetSizeHints(), ShuttleGuiBase::SetSizerProportion(), ShuttleGuiBase::SetStretchyCol(), ShuttleGuiBase::SetStretchyRow(), ShuttleGuiBase::SetStyle(), ShuttleGuiBase::StartHorizontalLay(), ShuttleGuiBase::StartMultiColumn(), ShuttleGuiBase::StartVerticalLay(), szr1, szrG, szrH, szrI, szrL, szrV, RulerPanel::Options::TickColour(), RulerPanel::Options::TicksAtExtremes(), and Track::Wave.

Referenced by PopulateUI().

586 {
587  wxWindow *const parent = S.GetParent();
588 
589  LoadCurves();
590 
592  WaveTrack *t = (WaveTrack *) iter.First();
593  mHiFreq = (t ? t->GetRate() : GetActiveProject()->GetRate()) / 2.0;
594  mLoFreq = loFreqI;
595 
596  S.SetBorder(0);
597 
598  S.SetSizerProportion(1);
599  S.StartMultiColumn(1, wxEXPAND);
600  {
601  S.SetStretchyCol(0);
602  S.SetStretchyRow(1);
603  szrV = S.GetSizer();
604 
605  // -------------------------------------------------------------------
606  // ROW 1: Top border
607  // -------------------------------------------------------------------
608  S.AddSpace(5);
609 
610  S.SetSizerProportion(1);
611  S.StartMultiColumn(3, wxEXPAND);
612  {
613  S.SetStretchyCol(1);
614  S.SetStretchyRow(0);
615  szr1 = S.GetSizer();
616 
617  // -------------------------------------------------------------------
618  // ROW 2: Equalization panel and sliders for vertical scale
619  // -------------------------------------------------------------------
620  S.StartVerticalLay();
621  {
623  parent, wxID_ANY, wxVERTICAL,
624  wxSize{ 100, 100 }, // Ruler can't handle small sizes
625  RulerPanel::Range{ 60.0, -120.0 },
627  _("dB"),
629  .LabelEdges(true)
630  .TicksAtExtremes(true)
631  .TickColour( { 0, 0, 0 } )
632  );
633 
634  S.Prop(1);
635  S.AddSpace(0, 1);
636  S.AddWindow(mdBRuler, wxEXPAND | wxALIGN_RIGHT);
637  S.AddSpace(0, 1);
638  }
639  S.EndVerticalLay();
640 
641  mPanel = safenew EqualizationPanel(parent, wxID_ANY, this);
642  S.Prop(1);
643  S.AddWindow(mPanel, wxEXPAND | wxALIGN_LEFT | wxALIGN_TOP);
644  S.SetSizeHints(wxDefaultCoord, wxDefaultCoord);
645 
646  S.SetBorder(5);
647  S.StartVerticalLay();
648  {
649  S.AddVariableText(_("+ dB"), false, wxCENTER);
650  S.SetStyle(wxSL_VERTICAL | wxSL_INVERSE);
651  mdBMaxSlider = S.Id(ID_dBMax).AddSlider( {}, 30, 60, 0);
652 #if wxUSE_ACCESSIBILITY
653  mdBMaxSlider->SetName(_("Max dB"));
654  mdBMaxSlider->SetAccessible(safenew SliderAx(mdBMaxSlider, _("%d dB")));
655 #endif
656 
657  S.SetStyle(wxSL_VERTICAL | wxSL_INVERSE);
658  mdBMinSlider = S.Id(ID_dBMin).AddSlider( {}, -30, -10, -120);
659  S.AddVariableText(_("- dB"), false, wxCENTER);
660 #if wxUSE_ACCESSIBILITY
661  mdBMinSlider->SetName(_("Min dB"));
662  mdBMinSlider->SetAccessible(safenew SliderAx(mdBMinSlider, _("%d dB")));
663 #endif
664  }
665  S.EndVerticalLay();
666  S.SetBorder(0);
667 
668  // -------------------------------------------------------------------
669  // ROW 3: Frequency ruler
670  // -------------------------------------------------------------------
671 
672  // Column 1 is empty
673  S.AddSpace(1, 1);
674 
676  parent, wxID_ANY, wxHORIZONTAL,
677  wxSize{ 100, 100 }, // Ruler can't handle small sizes
680  _("Hz"),
682  .Log(true)
683  .Flip(true)
684  .LabelEdges(true)
685  .TicksAtExtremes(true)
686  .TickColour( { 0, 0, 0 } )
687  );
688 
689 
690  S.Prop(1);
691  S.SetBorder(1);
692  S.AddWindow(mFreqRuler, wxEXPAND | wxALIGN_LEFT | wxALIGN_TOP | wxLEFT);
693  S.SetBorder(0);
694 
695  // Column 3 is empty
696  S.AddSpace(1, 1);
697  }
698  S.EndMultiColumn();
699 
700  // -------------------------------------------------------------------
701  // ROW 3: Graphic EQ - this gets laid out horizontally in onSize
702  // -------------------------------------------------------------------
703  S.StartHorizontalLay(wxEXPAND, 0);
704  {
705  szrG = S.GetSizer();
706 
707  // Panel used to host the sliders since they will be positioned manually.
708  mGraphicPanel = safenew wxPanelWrapper(parent, wxID_ANY, wxDefaultPosition, wxSize(-1, 150));
709  S.Prop(1).AddWindow(mGraphicPanel, wxEXPAND);
710 
711  for (int i = 0; (i < NUMBER_OF_BANDS) && (kThirdOct[i] <= mHiFreq); ++i)
712  {
713  mSliders[i] = safenew wxSlider(mGraphicPanel, ID_Slider + i, 0, -20, +20,
714  wxDefaultPosition, wxDefaultSize, wxSL_VERTICAL | wxSL_INVERSE);
715 
716  mSliders[i]->Bind(wxEVT_ERASE_BACKGROUND,
717  // ignore it
718  [](wxEvent&){});
719 #if wxUSE_ACCESSIBILITY
720  wxString name;
721  if( kThirdOct[i] < 1000.)
722  name.Printf(_("%d Hz"), (int)kThirdOct[i]);
723  else
724  name.Printf(_("%g kHz"), kThirdOct[i]/1000.);
725  mSliders[i]->SetName(name);
726  mSliders[i]->SetAccessible(safenew SliderAx(mSliders[i], _("%d dB")));
727 #endif
728  mSlidersOld[i] = 0;
729  mEQVals[i] = 0.;
730  }
731  }
732  S.EndHorizontalLay();
733 
734  S.StartMultiColumn(7, wxALIGN_CENTER_HORIZONTAL);
735  {
736  S.SetBorder(5);
737 
738  // -------------------------------------------------------------------
739  // ROWS 4:
740  // -------------------------------------------------------------------
741 
742  S.AddSpace(5, 5);
743 
744  S.StartHorizontalLay(wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
745  {
746  S.AddPrompt(_("&EQ Type:"));
747  }
748  S.EndHorizontalLay();
749 
750  S.StartHorizontalLay(wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 1);
751  {
752  S.StartHorizontalLay(wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 1);
753  {
754  mDraw = S.Id(ID_Draw).AddRadioButton(_("&Draw"));
755  mDraw->SetName(_("Draw Curves"));
756 
757  mGraphic = S.Id(ID_Graphic).AddRadioButtonToGroup(_("&Graphic"));
758  mGraphic->SetName(_("Graphic EQ"));
759  }
760  S.EndHorizontalLay();
761  }
762  S.EndHorizontalLay();
763 
764  S.StartHorizontalLay(wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 1);
765  {
766  szrH = S.GetSizer();
767 
768  S.StartHorizontalLay(wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 1);
769  {
770  szrI = S.GetSizer();
771 
772  mInterpChoice = S.Id(ID_Interp).AddChoice( {}, wxT(""), &mInterpolations);
773  mInterpChoice->SetName(_("Interpolation type"));
774  mInterpChoice->SetSelection(0);
775  }
776  S.EndHorizontalLay();
777 
778  S.StartHorizontalLay(wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 1);
779  {
780  szrL = S.GetSizer();
781 
782  mLinFreq = S.Id(ID_Linear).AddCheckBox(_("Li&near Frequency Scale"), wxT("false"));
783  mLinFreq->SetName(_("Linear Frequency Scale"));
784  }
785  S.EndHorizontalLay();
786  }
787  S.EndHorizontalLay();
788 
789  // -------------------------------------------------------------------
790  // Filter length grouping
791  // -------------------------------------------------------------------
792 
793  S.StartHorizontalLay(wxEXPAND, 1);
794  {
795  S.StartHorizontalLay(wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 0);
796  {
797  S.AddPrompt(_("Length of &Filter:"));
798  }
799  S.EndHorizontalLay();
800 
801  S.StartHorizontalLay(wxEXPAND, 1);
802  {
803  S.SetStyle(wxSL_HORIZONTAL);
804  mMSlider = S.Id(ID_Length).AddSlider( {}, (mM - 1) / 2, 4095, 10);
805  mMSlider->SetName(_("Length of Filter"));
806  }
807  S.EndHorizontalLay();
808 
809  S.StartHorizontalLay(wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 0);
810  {
811  wxString label;
812  label.Printf(wxT("%ld"), mM);
813  mMText = S.AddVariableText(label);
814  mMText->SetName(label); // fix for bug 577 (NVDA/Narrator screen readers do not read static text in dialogs)
815  }
816  S.EndHorizontalLay();
817  }
818  S.EndHorizontalLay();
819 
820  S.AddSpace(1, 1);
821 
822  S.AddSpace(5, 5);
823 
824  // -------------------------------------------------------------------
825  // ROW 5:
826  // -------------------------------------------------------------------
827 
828  S.AddSpace(5, 5);
829 
830  S.StartHorizontalLay(wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
831  {
832  S.AddPrompt(_("&Select Curve:"));
833  }
834  S.EndHorizontalLay();
835 
836  S.StartHorizontalLay(wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 1);
837  {
838  S.StartHorizontalLay(wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 1);
839  {
840  wxArrayString curves;
841  for (size_t i = 0, cnt = mCurves.size(); i < cnt; i++)
842  {
843  curves.Add(mCurves[ i ].Name);
844  }
845 
846  mCurve = S.Id(ID_Curve).AddChoice( {}, wxT(""), &curves);
847  mCurve->SetName(_("Select Curve"));
848  }
849  S.EndHorizontalLay();
850  }
851  S.EndHorizontalLay();
852  S.Id(ID_Manage).AddButton(_("S&ave/Manage Curves..."));
853 
854  S.StartHorizontalLay(wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 1);
855  {
856  S.Id(ID_Clear).AddButton(_("Fla&tten"));
857  S.Id(ID_Invert).AddButton(_("&Invert"));
858 
859  mGridOnOff = S.Id(ID_Grid).AddCheckBox(_("Show g&rid lines"), wxT("false"));
860  mGridOnOff->SetName(_("Show grid lines"));
861  }
862  S.EndHorizontalLay();
863 
864  S.AddSpace(5, 5);
865  }
866  S.EndMultiColumn();
867  }
868  S.EndMultiColumn();
869 
870 #ifdef EXPERIMENTAL_EQ_SSE_THREADED
871  if (mEffectEqualization48x)
872  {
873  // -------------------------------------------------------------------
874  // ROW 6: Processing routine selection
875  // -------------------------------------------------------------------
876 
877  // Column 1 is blank
878  S.AddSpace(1, 1);
879 
880  S.StartHorizontalLay();
881  {
882  S.AddUnits(_("&Processing: "));
883 
884  mMathProcessingType[0] = S.Id(ID_DefaultMath).
885  AddRadioButton(_("D&efault"));
886  mMathProcessingType[1] = S.Id(ID_SSE).
887  AddRadioButtonToGroup(_("&SSE"));
888  mMathProcessingType[2] = S.Id(ID_SSEThreaded).
889  AddRadioButtonToGroup(_("SSE &Threaded"));
890  mMathProcessingType[3] = S.Id(ID_AVX).
891  AddRadioButtonToGroup(_("A&VX"));
892  mMathProcessingType[4] = S.Id(ID_AVXThreaded).
893  AddRadioButtonToGroup(_("AV&X Threaded"));
894 
895  if (!EffectEqualization48x::GetMathCaps()->SSE)
896  {
897  mMathProcessingType[1]->Disable();
898  mMathProcessingType[2]->Disable();
899  }
900  if (true)
901  {
902  mMathProcessingType[3]->Disable();
903  mMathProcessingType[4]->Disable();
904  }
905  // update the control state
906  mMathProcessingType[0]->SetValue(true);
907  int mathPath=EffectEqualization48x::GetMathPath();
908  if (mathPath&MATH_FUNCTION_SSE)
909  {
910  mMathProcessingType[1]->SetValue(true);
911  if (mathPath&MATH_FUNCTION_THREADED)
912  mMathProcessingType[2]->SetValue(true);
913  }
914  if (false) //mathPath&MATH_FUNCTION_AVX) { not implemented
915  {
916  mMathProcessingType[3]->SetValue(true);
917  if (mathPath&MATH_FUNCTION_THREADED)
918  mMathProcessingType[4]->SetValue(true);
919  }
920  S.Id(ID_Bench).AddButton(_("&Bench"));
921  }
922  S.EndHorizontalLay();
923 
924  // Column 3 is blank
925  S.AddSpace(1, 1);
926  }
927 #endif
928 
929  mUIParent->SetAutoLayout(false);
930  mUIParent->Layout();
931 
932  // "show" settings for graphics mode before setting the size of the dialog
933  // as this needs more space than draw mode
934  szrV->Show(szrG,true); // eq sliders
935  szrH->Show(szrI,true); // interpolation choice
936  szrH->Show(szrL,false); // linear freq checkbox
937 
938  mUIParent->SetSizeHints(mUIParent->GetBestSize());
939 
940 // szrL->SetMinSize( szrI->GetSize() );
941 
942  return;
943 }
friend class EqualizationPanel
Definition: Equalization.h:278
wxRadioButton * mGraphic
Definition: Equalization.h:259
wxWindow * AddWindow(wxWindow *pWindow, int Flags=wxALIGN_CENTRE|wxALL)
Definition: ShuttleGui.cpp:257
wxChoice * mInterpChoice
Definition: Equalization.h:262
Options & LabelEdges(bool l)
Definition: Ruler.h:266
void EndMultiColumn()
wxString label
Definition: Tags.cpp:727
wxCheckBox * mGridOnOff
Definition: Equalization.h:261
RulerPanel class allows you to work with a Ruler like any other wxWindow.
Definition: Ruler.h:244
void SetSizerProportion(int iProp)
Definition: ShuttleGui.h:254
TrackList * inputTracks() const
Definition: Effect.h:461
#define safenew
Definition: Audacity.h:223
wxRadioButton * mDraw
Definition: Equalization.h:258
void EndHorizontalLay()
Definition: ShuttleGui.cpp:975
void AddUnits(const wxString &Prompt)
Left aligned text string.
Definition: ShuttleGui.cpp:229
void AddPrompt(const wxString &Prompt)
Right aligned text string.
Definition: ShuttleGui.cpp:215
void EndVerticalLay()
Definition: ShuttleGui.cpp:991
void SetSizeHints(int minX=-1, int minY=-1)
Options & Flip(bool f)
Definition: Ruler.h:263
RulerPanel * mFreqRuler
Definition: Equalization.h:220
wxCheckBox * AddCheckBox(const wxString &Prompt, const wxString &Selected)
Definition: ShuttleGui.cpp:267
wxWindow * GetParent()
Definition: ShuttleGui.h:259
void StartHorizontalLay(int PositionFlags=wxALIGN_CENTRE, int iProp=1)
Definition: ShuttleGui.cpp:966
void StartMultiColumn(int nCols, int PositionFlags=wxALIGN_LEFT)
Definition: ShuttleGui.cpp:998
wxChoice * AddChoice(const wxString &Prompt, const wxString &Selected, const wxArrayString *pChoices)
Definition: ShuttleGui.cpp:331
A Track that contains audio waveform data.
Definition: WaveTrack.h:60
ShuttleGui & Id(int id)
void SetStyle(int Style)
Definition: ShuttleGui.h:252
wxSlider * mdBMaxSlider
Definition: Equalization.h:268
Options & Log(bool l)
Definition: Ruler.h:260
Options & TicksAtExtremes(bool t)
Definition: Ruler.h:269
wxSlider * mSliders[NUMBER_OF_BANDS]
Definition: Equalization.h:269
wxArrayString mInterpolations
Definition: Equalization.h:222
wxSizer * GetSizer()
Definition: ShuttleGui.h:269
wxStaticText * mMText
Definition: Equalization.h:265
wxWindow * mUIParent
Definition: Effect.h:475
EQCurveArray mCurves
Definition: Equalization.h:231
_("Move Track &Down")+wxT("\t")+(GetActiveProject() -> GetCommandManager() ->GetKeyFromName(wxT("TrackMoveDown"))), OnMoveTrack) POPUP_MENU_ITEM(OnMoveTopID, _("Move Track to &Top")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveTop"))), OnMoveTrack) POPUP_MENU_ITEM(OnMoveBottomID, _("Move Track to &Bottom")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveBottom"))), OnMoveTrack) void TrackMenuTable::OnSetName(wxCommandEvent &)
Options & TickColour(const wxColour c)
Definition: Ruler.h:272
void LoadCurves(const wxString &fileName=wxEmptyString, bool append=false)
const wxChar * name
Definition: Distortion.cpp:94
wxSlider * mMSlider
Definition: Equalization.h:266
static const double kThirdOct[]
AUDACITY_DLL_API AudacityProject * GetActiveProject()
Definition: Project.cpp:300
#define NUMBER_OF_BANDS
Definition: Equalization.h:14
wxStaticText * AddVariableText(const wxString &Str, bool bCenter=false, int PositionFlags=0)
Definition: ShuttleGui.cpp:373
std::pair< double, double > Range
Definition: Ruler.h:248
RulerPanel * mdBRuler
Definition: Equalization.h:219
ShuttleGui & Prop(int iProp)
Definition: ShuttleGui.h:374
double mEQVals[NUMBER_OF_BANDS+1]
Definition: Equalization.h:229
wxRadioButton * AddRadioButtonToGroup(const wxString &Prompt)
Definition: ShuttleGui.cpp:443
wxPanel * mGraphicPanel
Definition: Equalization.h:257
wxCheckBox * mLinFreq
Definition: Equalization.h:260
double GetRate() const
Definition: Project.h:181
int mSlidersOld[NUMBER_OF_BANDS]
Definition: Equalization.h:228
wxSizerItem * AddSpace(int width, int height)
double GetRate() const
Definition: WaveTrack.cpp:424
void SetBorder(int Border)
Definition: ShuttleGui.h:251
EqualizationPanel * mPanel
Definition: Equalization.h:256
wxButton * AddButton(const wxString &Text, int PositionFlags=wxALIGN_CENTRE)
Definition: ShuttleGui.cpp:301
void SetStretchyCol(int i)
Used to modify an already placed FlexGridSizer to make a column stretchy.
Definition: ShuttleGui.cpp:192
wxRadioButton * AddRadioButton(const wxString &Prompt)
Definition: ShuttleGui.cpp:427
wxSlider * mdBMinSlider
Definition: Equalization.h:267
void SetStretchyRow(int i)
Used to modify an already placed FlexGridSizer to make a row stretchy.
Definition: ShuttleGui.cpp:202
wxSlider * AddSlider(const wxString &Prompt, int pos, int Max, int Min=0)
Definition: ShuttleGui.cpp:456
void StartVerticalLay(int iProp=1)
Definition: ShuttleGui.cpp:982
bool EffectEqualization::PopulateUI ( wxWindow *  parent)
override

Definition at line 564 of file Equalization.cpp.

References eIsCreating, Effect::GetCurrentSettingsGroup(), Effect::LoadUserPreset(), Effect::mUIParent, and PopulateOrExchange().

565 {
566  mUIParent = parent;
567  mUIParent->PushEventHandler(this);
568 
570 
573 
574  return true;
575 }
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI...
Definition: ShuttleGui.h:366
wxString GetCurrentSettingsGroup() override
Definition: Effect.cpp:824
bool LoadUserPreset(const wxString &name) override
Definition: Effect.cpp:609
void PopulateOrExchange(ShuttleGui &S) override
wxWindow * mUIParent
Definition: Effect.h:475
bool EffectEqualization::Process ( )
overridevirtual

Reimplemented from Effect.

Definition at line 520 of file Equalization.cpp.

References Effect::CopyInputTracks(), WaveTrack::GetStartTime(), Effect::mOutputTracks, Effect::mT0, Effect::mT1, ProcessOne(), Effect::ReplaceProcessedTracks(), and Track::Wave.

521 {
522 #ifdef EXPERIMENTAL_EQ_SSE_THREADED
523  if(mEffectEqualization48x) {
524  if(mBench) {
525  mBench=false;
526  return mEffectEqualization48x->Benchmark(this);
527  }
528  else
529  return mEffectEqualization48x->Process(this);
530  }
531 #endif
532  this->CopyInputTracks(); // Set up mOutputTracks.
533  bool bGoodResult = true;
534 
536  WaveTrack *track = (WaveTrack *) iter.First();
537  int count = 0;
538  while (track) {
539  double trackStart = track->GetStartTime();
540  double trackEnd = track->GetEndTime();
541  double t0 = mT0 < trackStart? trackStart: mT0;
542  double t1 = mT1 > trackEnd? trackEnd: mT1;
543 
544  if (t1 > t0) {
545  auto start = track->TimeToLongSamples(t0);
546  auto end = track->TimeToLongSamples(t1);
547  auto len = end - start;
548 
549  if (!ProcessOne(count, track, start, len))
550  {
551  bGoodResult = false;
552  break;
553  }
554  }
555 
556  track = (WaveTrack *) iter.Next();
557  count++;
558  }
559 
560  this->ReplaceProcessedTracks(bGoodResult);
561  return bGoodResult;
562 }
double mT1
Definition: Effect.h:464
void CopyInputTracks()
Definition: Effect.cpp:2039
void ReplaceProcessedTracks(const bool bGoodResult)
Definition: Effect.cpp:2170
bool ProcessOne(int count, WaveTrack *t, sampleCount start, sampleCount len)
A Track that contains audio waveform data.
Definition: WaveTrack.h:60
std::shared_ptr< TrackList > mOutputTracks
Definition: Effect.h:462
double mT0
Definition: Effect.h:463
double GetStartTime() const
Get the time at which the first clip in the track starts.
Definition: WaveTrack.cpp:1859
bool EffectEqualization::ProcessOne ( int  count,
WaveTrack t,
sampleCount  start,
sampleCount  len 
)
private

Definition at line 1051 of file Equalization.cpp.

References WaveTrack::Clear(), Filter(), WaveTrack::Get(), GetActiveProject(), WaveTrack::GetClips(), WaveTrack::GetMaxBlockSize(), WaveTrack::GetRate(), AudacityProject::GetTrackFactory(), WaveTrack::Join(), WaveTrack::LongSamplesToTime(), mM, TrackFactory::NewWaveTrack(), WaveTrack::Paste(), Effect::TrackProgress(), and windowSize.

Referenced by Process().

1053 {
1054  // create a NEW WaveTrack to hold all of the output, including 'tails' each end
1056  auto output = p->GetTrackFactory()->NewWaveTrack(floatSample, t->GetRate());
1057 
1058  wxASSERT(mM - 1 < windowSize);
1059  size_t L = windowSize - (mM - 1); //Process L samples at a go
1060  auto s = start;
1061  auto idealBlockLen = t->GetMaxBlockSize() * 4;
1062  if (idealBlockLen % L != 0)
1063  idealBlockLen += (L - (idealBlockLen % L));
1064 
1065  Floats buffer{ idealBlockLen };
1066 
1067  Floats window1{ windowSize };
1068  Floats window2{ windowSize };
1069  float *thisWindow = window1.get();
1070  float *lastWindow = window2.get();
1071 
1072  auto originalLen = len;
1073 
1074  for(size_t i = 0; i < windowSize; i++)
1075  lastWindow[i] = 0;
1076 
1077  TrackProgress(count, 0.);
1078  bool bLoopSuccess = true;
1079  size_t wcopy = 0;
1080  int offset = (mM - 1) / 2;
1081 
1082  while (len != 0)
1083  {
1084  auto block = limitSampleBufferSize( idealBlockLen, len );
1085 
1086  t->Get((samplePtr)buffer.get(), floatSample, s, block);
1087 
1088  for(size_t i = 0; i < block; i += L) //go through block in lumps of length L
1089  {
1090  wcopy = std::min <size_t> (L, block - i);
1091  for(size_t j = 0; j < wcopy; j++)
1092  thisWindow[j] = buffer[i+j]; //copy the L (or remaining) samples
1093  for(auto j = wcopy; j < windowSize; j++)
1094  thisWindow[j] = 0; //this includes the padding
1095 
1096  Filter(windowSize, thisWindow);
1097 
1098  // Overlap - Add
1099  for(size_t j = 0; (j < mM - 1) && (j < wcopy); j++)
1100  buffer[i+j] = thisWindow[j] + lastWindow[L + j];
1101  for(size_t j = mM - 1; j < wcopy; j++)
1102  buffer[i+j] = thisWindow[j];
1103 
1104  std::swap( thisWindow, lastWindow );
1105  } //next i, lump of this block
1106 
1107  output->Append((samplePtr)buffer.get(), floatSample, block);
1108  len -= block;
1109  s += block;
1110 
1111  if (TrackProgress(count, ( s - start ).as_double() /
1112  originalLen.as_double()))
1113  {
1114  bLoopSuccess = false;
1115  break;
1116  }
1117  }
1118 
1119  if(bLoopSuccess)
1120  {
1121  // mM-1 samples of 'tail' left in lastWindow, get them now
1122  if(wcopy < (mM - 1)) {
1123  // Still have some overlap left to process
1124  // (note that lastWindow and thisWindow have been exchanged at this point
1125  // so that 'thisWindow' is really the window prior to 'lastWindow')
1126  size_t j = 0;
1127  for(; j < mM - 1 - wcopy; j++)
1128  buffer[j] = lastWindow[wcopy + j] + thisWindow[L + wcopy + j];
1129  // And fill in the remainder after the overlap
1130  for( ; j < mM - 1; j++)
1131  buffer[j] = lastWindow[wcopy + j];
1132  } else {
1133  for(size_t j = 0; j < mM - 1; j++)
1134  buffer[j] = lastWindow[wcopy + j];
1135  }
1136  output->Append((samplePtr)buffer.get(), floatSample, mM - 1);
1137  output->Flush();
1138 
1139  // now move the appropriate bit of the output back to the track
1140  // (this could be enhanced in the future to use the tails)
1141  double offsetT0 = t->LongSamplesToTime(offset);
1142  double lenT = t->LongSamplesToTime(originalLen);
1143  // 'start' is the sample offset in 't', the passed in track
1144  // 'startT' is the equivalent time value
1145  // 'output' starts at zero
1146  double startT = t->LongSamplesToTime(start);
1147 
1148  //output has one waveclip for the total length, even though
1149  //t might have whitespace seperating multiple clips
1150  //we want to maintain the original clip structure, so
1151  //only paste the intersections of the NEW clip.
1152 
1153  //Find the bits of clips that need replacing
1154  std::vector<std::pair<double, double> > clipStartEndTimes;
1155  std::vector<std::pair<double, double> > clipRealStartEndTimes; //the above may be truncated due to a clip being partially selected
1156  for (const auto &clip : t->GetClips())
1157  {
1158  double clipStartT;
1159  double clipEndT;
1160 
1161  clipStartT = clip->GetStartTime();
1162  clipEndT = clip->GetEndTime();
1163  if( clipEndT <= startT )
1164  continue; // clip is not within selection
1165  if( clipStartT >= startT + lenT )
1166  continue; // clip is not within selection
1167 
1168  //save the actual clip start/end so that we can rejoin them after we paste.
1169  clipRealStartEndTimes.push_back(std::pair<double,double>(clipStartT,clipEndT));
1170 
1171  if( clipStartT < startT ) // does selection cover the whole clip?
1172  clipStartT = startT; // don't copy all the NEW clip
1173  if( clipEndT > startT + lenT ) // does selection cover the whole clip?
1174  clipEndT = startT + lenT; // don't copy all the NEW clip
1175 
1176  //save them
1177  clipStartEndTimes.push_back(std::pair<double,double>(clipStartT,clipEndT));
1178  }
1179  //now go thru and replace the old clips with NEW
1180  for(unsigned int i = 0; i < clipStartEndTimes.size(); i++)
1181  {
1182  //remove the old audio and get the NEW
1183  t->Clear(clipStartEndTimes[i].first,clipStartEndTimes[i].second);
1184  auto toClipOutput = output->Copy(clipStartEndTimes[i].first-startT+offsetT0,clipStartEndTimes[i].second-startT+offsetT0);
1185  //put the processed audio in
1186  t->Paste(clipStartEndTimes[i].first, toClipOutput.get());
1187  //if the clip was only partially selected, the Paste will have created a split line. Join is needed to take care of this
1188  //This is not true when the selection is fully contained within one clip (second half of conditional)
1189  if( (clipRealStartEndTimes[i].first != clipStartEndTimes[i].first ||
1190  clipRealStartEndTimes[i].second != clipStartEndTimes[i].second) &&
1191  !(clipRealStartEndTimes[i].first <= startT &&
1192  clipRealStartEndTimes[i].second >= startT+lenT) )
1193  t->Join(clipRealStartEndTimes[i].first,clipRealStartEndTimes[i].second);
1194  }
1195  }
1196 
1197  return bLoopSuccess;
1198 }
bool TrackProgress(int whichTrack, double frac, const wxString &=wxEmptyString)
Definition: Effect.cpp:1988
bool Get(samplePtr buffer, sampleFormat format, sampleCount start, size_t len, fillFormat fill=fillZero, bool mayThrow=true) const
Definition: WaveTrack.cpp:1977
void Clear(double t0, double t1) override
Definition: WaveTrack.cpp:699
AudacityProject provides the main window, with tools and tracks contained within it.
Definition: Project.h:158
void Join(double t0, double t1)
Definition: WaveTrack.cpp:1509
static const size_t windowSize
Definition: Equalization.h:141
WaveClipHolders & GetClips()
Definition: WaveTrack.h:364
void Filter(size_t len, float *buffer)
void Paste(double t0, const Track *src) override
Definition: WaveTrack.cpp:1197
size_t GetMaxBlockSize() const
Definition: WaveTrack.cpp:1631
std::unique_ptr< WaveTrack > NewWaveTrack(sampleFormat format=(sampleFormat) 0, double rate=0)
Definition: WaveTrack.cpp:78
AUDACITY_DLL_API AudacityProject * GetActiveProject()
Definition: Project.cpp:300
double GetRate() const
Definition: WaveTrack.cpp:424
double LongSamplesToTime(sampleCount pos) const
Convert correctly between an number of samples and an (absolute) time in seconds. ...
Definition: WaveTrack.cpp:1854
TrackFactory * GetTrackFactory()
Definition: Project.cpp:1403
void EffectEqualization::SaveCurves ( const wxString &  fileName = wxEmptyString)
private

Definition at line 1575 of file Equalization.cpp.

References _(), FileNames::DataDir(), GuardedCall(), and WriteXML().

Referenced by EditCurvesDialog::OnExport(), EditCurvesDialog::OnOK(), UpdateDefaultCurves(), and ValidateUI().

1576 {
1577  wxFileName fn;
1578  if( fileName == wxT(""))
1579  {
1580  // Construct default curve filename
1581  //
1582  // LLL: Wouldn't you know that as of WX 2.6.2, there is a conflict
1583  // between wxStandardPaths and wxConfig under Linux. The latter
1584  // creates a normal file as "$HOME/.audacity", while the former
1585  // expects the ".audacity" portion to be a directory.
1586  fn = wxFileName( FileNames::DataDir(), wxT("EQCurves.xml") );
1587 
1588  // If the directory doesn't exist...
1589  if( !fn.DirExists() )
1590  {
1591  // Attempt to create it
1592  if( !fn.Mkdir( fn.GetPath(), 511, wxPATH_MKDIR_FULL ) )
1593  {
1594  // MkDir() will emit message
1595  return;
1596  }
1597  }
1598  }
1599  else
1600  fn = fileName;
1601 
1602  GuardedCall( [&] {
1603  // Create/Open the file
1604  const wxString fullPath{ fn.GetFullPath() };
1605  XMLFileWriter eqFile{ fullPath, _("Error Saving Equalization Curves") };
1606 
1607  // Write the curves
1608  WriteXML( eqFile );
1609 
1610  eqFile.Commit();
1611  } );
1612 }
void WriteXML(XMLWriter &xmlFile) const
Wrapper to output XML data to files.
Definition: XMLWriter.h:74
R GuardedCall(const F1 &body, const F2 &handler=F2::Default(), const F3 &delayedHandler={})
_("Move Track &Down")+wxT("\t")+(GetActiveProject() -> GetCommandManager() ->GetKeyFromName(wxT("TrackMoveDown"))), OnMoveTrack) POPUP_MENU_ITEM(OnMoveTopID, _("Move Track to &Top")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveTop"))), OnMoveTrack) POPUP_MENU_ITEM(OnMoveBottomID, _("Move Track to &Bottom")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveBottom"))), OnMoveTrack) void TrackMenuTable::OnSetName(wxCommandEvent &)
static wxString DataDir()
Audacity user data directory.
Definition: FileNames.cpp:130
void EffectEqualization::Select ( int  sel)
private

Definition at line 1803 of file Equalization.cpp.

References mCurve, mCurveName, and mCurves.

Referenced by EnvelopeUpdated(), ErrMin(), setCurve(), and ValidateUI().

1804 {
1805  // Set current choice
1806  if (mCurve)
1807  {
1808  mCurve->SetSelection( curve );
1809  mCurveName = mCurves[ curve ].Name;
1810  }
1811 }
EQCurveArray mCurves
Definition: Equalization.h:231
bool EffectEqualization::SetAutomationParameters ( EffectAutomationParameters &  parms)
override

Definition at line 322 of file Equalization.cpp.

References kInterpStrings, kNumInterpolations, mCurveName, mEnvelope, mInterp, mInterpolations, mLin, mLinEnvelope, mLogEnvelope, mM, ReadAndVerifyBool, ReadAndVerifyEnum, ReadAndVerifyInt, and ReadAndVerifyString.

323 {
324  // Pretty sure the interpolation name shouldn't have been interpreted when
325  // specified in chains, but must keep it that way for compatibility.
326  wxArrayString interpolations(mInterpolations);
327  for (int i = 0; i < kNumInterpolations; i++)
328  {
329  interpolations.Add(kInterpStrings[i]);
330  }
331 
332  ReadAndVerifyInt(FilterLength);
333  ReadAndVerifyString(CurveName);
334  ReadAndVerifyBool(InterpLin);
335  ReadAndVerifyEnum(InterpMeth, interpolations);
336 
337  mM = FilterLength;
338  mCurveName = CurveName;
339  mLin = InterpLin;
340  mInterp = InterpMeth;
341 
342  if (InterpMeth >= kNumInterpolations)
343  {
344  InterpMeth -= kNumInterpolations;
345  }
346 
347  mEnvelope = (mLin ? mLinEnvelope : mLogEnvelope).get();
348 
349  return true;
350 }
#define ReadAndVerifyEnum(name, list)
Definition: Effect.h:785
Envelope * mEnvelope
Definition: Equalization.h:234
#define ReadAndVerifyInt(name)
Definition: Effect.h:790
static const wxString kInterpStrings[kNumInterpolations]
std::unique_ptr< Envelope > mLogEnvelope
Definition: Equalization.h:233
wxArrayString mInterpolations
Definition: Equalization.h:222
#define ReadAndVerifyString(name)
Definition: Effect.h:794
std::unique_ptr< Envelope > mLinEnvelope
Definition: Equalization.h:233
#define ReadAndVerifyBool(name)
Definition: Effect.h:793
void EffectEqualization::setCurve ( int  currentCurve)
private

Definition at line 1617 of file Equalization.cpp.

References Envelope::Flatten(), ForceRecalc(), Envelope::InsertOrReplace(), loFreqI, mCurves, mHiFreq, min(), mLin, mLinEnvelope, mLogEnvelope, Select(), and Envelope::SetTrackLen().

Referenced by EditCurvesDialog::OnOK().

1618 {
1619  // Set current choice
1620  wxASSERT( currentCurve < (int) mCurves.size() );
1621  Select(currentCurve);
1622 
1623  Envelope *env;
1624  int numPoints = (int) mCurves[currentCurve].points.size();
1625 
1626  if (mLin) { // linear freq mode
1627  env = mLinEnvelope.get();
1628  }
1629  else { // log freq mode
1630  env = mLogEnvelope.get();
1631  }
1632  env->Flatten(0.);
1633  env->SetTrackLen(1.0);
1634 
1635  // Handle special case of no points.
1636  if (numPoints == 0) {
1637  ForceRecalc();
1638  return;
1639  }
1640 
1641  double when, value;
1642 
1643  // Handle special case 1 point.
1644  if (numPoints == 1) {
1645  // only one point, so ensure it is in range then return.
1646  when = mCurves[currentCurve].points[0].Freq;
1647  if (mLin) {
1648  when = when / mHiFreq;
1649  }
1650  else { // log scale
1651  // We don't go below loFreqI (20 Hz) in log view.
1652  double loLog = log10((double)loFreqI);
1653  double hiLog = log10(mHiFreq);
1654  double denom = hiLog - loLog;
1655  when = (log10(std::max((double) loFreqI, when)) - loLog)/denom;
1656  }
1657  value = mCurves[currentCurve].points[0].dB;
1658  env->InsertOrReplace(std::min(1.0, std::max(0.0, when)), value);
1659  ForceRecalc();
1660  return;
1661  }
1662 
1663  // We have at least two points, so ensure they are in frequency order.
1664  std::sort(mCurves[currentCurve].points.begin(),
1665  mCurves[currentCurve].points.end());
1666 
1667  if (mCurves[currentCurve].points[0].Freq < 0) {
1668  // Corrupt or invalid curve, so bail.
1669  ForceRecalc();
1670  return;
1671  }
1672 
1673  if(mLin) { // linear Hz scale
1674  for(int pointCount = 0; pointCount < numPoints; pointCount++) {
1675  when = mCurves[currentCurve].points[pointCount].Freq / mHiFreq;
1676  value = mCurves[currentCurve].points[pointCount].dB;
1677  if(when <= 1) {
1678  env->InsertOrReplace(when, value);
1679  if (when == 1)
1680  break;
1681  }
1682  else {
1683  // There are more points at higher freqs,
1684  // so interpolate next one then stop.
1685  when = 1.0;
1686  double nextDB = mCurves[currentCurve].points[pointCount].dB;
1687  if (pointCount > 0) {
1688  double nextF = mCurves[currentCurve].points[pointCount].Freq;
1689  double lastF = mCurves[currentCurve].points[pointCount-1].Freq;
1690  double lastDB = mCurves[currentCurve].points[pointCount-1].dB;
1691  value = lastDB +
1692  ((nextDB - lastDB) *
1693  ((mHiFreq - lastF) / (nextF - lastF)));
1694  }
1695  else
1696  value = nextDB;
1697  env->InsertOrReplace(when, value);
1698  break;
1699  }
1700  }
1701  }
1702  else { // log Hz scale
1703  double loLog = log10((double) loFreqI);
1704  double hiLog = log10(mHiFreq);
1705  double denom = hiLog - loLog;
1706  int firstAbove20Hz;
1707 
1708  // log scale EQ starts at 20 Hz (threshold of hearing).
1709  // so find the first point (if any) above 20 Hz.
1710  for (firstAbove20Hz = 0; firstAbove20Hz < numPoints; firstAbove20Hz++) {
1711  if (mCurves[currentCurve].points[firstAbove20Hz].Freq > loFreqI)
1712  break;
1713  }
1714 
1715  if (firstAbove20Hz == numPoints) {
1716  // All points below 20 Hz, so just use final point.
1717  when = 0.0;
1718  value = mCurves[currentCurve].points[numPoints-1].dB;
1719  env->InsertOrReplace(when, value);
1720  ForceRecalc();
1721  return;
1722  }
1723 
1724  if (firstAbove20Hz > 0) {
1725  // At least one point is before 20 Hz and there are more
1726  // beyond 20 Hz, so interpolate the first
1727  double prevF = mCurves[currentCurve].points[firstAbove20Hz-1].Freq;
1728  prevF = log10(std::max(1.0, prevF)); // log zero is bad.
1729  double prevDB = mCurves[currentCurve].points[firstAbove20Hz-1].dB;
1730  double nextF = log10(mCurves[currentCurve].points[firstAbove20Hz].Freq);
1731  double nextDB = mCurves[currentCurve].points[firstAbove20Hz].dB;
1732  when = 0.0;
1733  value = nextDB - ((nextDB - prevDB) * ((nextF - loLog) / (nextF - prevF)));
1734  env->InsertOrReplace(when, value);
1735  }
1736 
1737  // Now get the rest.
1738  for(int pointCount = firstAbove20Hz; pointCount < numPoints; pointCount++)
1739  {
1740  double flog = log10(mCurves[currentCurve].points[pointCount].Freq);
1741  wxASSERT(mCurves[currentCurve].points[pointCount].Freq >= loFreqI);
1742 
1743  when = (flog - loLog)/denom;
1744  value = mCurves[currentCurve].points[pointCount].dB;
1745  if(when <= 1.0) {
1746  env->InsertOrReplace(when, value);
1747  }
1748  else {
1749  // This looks weird when adjusting curve in Draw mode if
1750  // there is a point off-screen.
1751 
1752  /*
1753  // we have a point beyond fs/2. Insert it so that env code can use it.
1754  // but just this one, we have no use for the rest
1755  env->SetTrackLen(when); // can't Insert if the envelope isn't long enough
1756  env->Insert(when, value);
1757  break;
1758  */
1759 
1760  // interpolate the final point instead
1761  when = 1.0;
1762  if (pointCount > 0) {
1763  double lastDB = mCurves[currentCurve].points[pointCount-1].dB;
1764  double logLastF =
1765  log10(mCurves[currentCurve].points[pointCount-1].Freq);
1766  value = lastDB +
1767  ((value - lastDB) *
1768  ((log10(mHiFreq) - logLastF) / (flog - logLastF)));
1769  }
1770  env->InsertOrReplace(when, value);
1771  break;
1772  }
1773  }
1774  }
1775  ForceRecalc();
1776 }
void Flatten(double value)
Definition: Envelope.cpp:137
void Select(int sel)
Draggable curve used in TrackPanel for varying amplification.
Definition: Envelope.h:77
int InsertOrReplace(double when, double value)
Add a point at a particular absolute time coordinate.
Definition: Envelope.h:194
void SetTrackLen(double trackLen, double sampleDur=0.0)
Definition: Envelope.cpp:1077
std::unique_ptr< Envelope > mLogEnvelope
Definition: Equalization.h:233
int min(int a, int b)
EQCurveArray mCurves
Definition: Equalization.h:231
std::unique_ptr< Envelope > mLinEnvelope
Definition: Equalization.h:233
void EffectEqualization::setCurve ( const wxString &  curveName)
private

Definition at line 1783 of file Equalization.cpp.

References _(), mCurves, Effect::MessageBox(), and setCurve().

1784 {
1785  unsigned i = 0;
1786  for( i = 0; i < mCurves.size(); i++ )
1787  if( curveName == mCurves[ i ].Name )
1788  break;
1789  if( i == mCurves.size())
1790  {
1791  Effect::MessageBox( _("Requested curve not found, using 'unnamed'"),
1792  wxOK|wxICON_ERROR,
1793  _("Curve not found") );
1794  setCurve((int) mCurves.size() - 1);
1795  }
1796  else
1797  setCurve( i );
1798 }
int MessageBox(const wxString &message, long style=DefaultMessageBoxStyle, const wxString &titleStr=wxString{})
Definition: Effect.cpp:2665
EQCurveArray mCurves
Definition: Equalization.h:231
_("Move Track &Down")+wxT("\t")+(GetActiveProject() -> GetCommandManager() ->GetKeyFromName(wxT("TrackMoveDown"))), OnMoveTrack) POPUP_MENU_ITEM(OnMoveTopID, _("Move Track to &Top")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveTop"))), OnMoveTrack) POPUP_MENU_ITEM(OnMoveBottomID, _("Move Track to &Bottom")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveBottom"))), OnMoveTrack) void TrackMenuTable::OnSetName(wxCommandEvent &)
void EffectEqualization::setCurve ( void  )
private

Definition at line 1778 of file Equalization.cpp.

References mCurves.

Referenced by Init(), OnCurve(), setCurve(), and UpdateCurves().

1779 {
1780  setCurve((int) mCurves.size() - 1);
1781 }
EQCurveArray mCurves
Definition: Equalization.h:231
void EffectEqualization::spline ( double  x[],
double  y[],
size_t  n,
double  y2[] 
)
private

Definition at line 2539 of file Equalization.cpp.

Referenced by GraphicEQ().

2540 {
2541  wxASSERT( n > 0 );
2542 
2543  double p, sig;
2544  Doubles u{ n };
2545 
2546  y2[0] = 0.; //
2547  u[0] = 0.; //'natural' boundary conditions
2548  for (size_t i = 1; i + 1 < n; i++)
2549  {
2550  sig = ( x[i] - x[i-1] ) / ( x[i+1] - x[i-1] );
2551  p = sig * y2[i-1] + 2.;
2552  y2[i] = (sig - 1.)/p;
2553  u[i] = ( y[i+1] - y[i] ) / ( x[i+1] - x[i] ) - ( y[i] - y[i-1] ) / ( x[i] - x[i-1] );
2554  u[i] = (6.*u[i]/( x[i+1] - x[i-1] ) - sig * u[i-1]) / p;
2555  }
2556  y2[n - 1] = 0.;
2557  for (size_t i = n - 1; i--;)
2558  y2[i] = y2[i]*y2[i+1] + u[i];
2559 }
double EffectEqualization::splint ( double  x[],
double  y[],
size_t  n,
double  y2[],
double  xr 
)
private

Definition at line 2561 of file Equalization.cpp.

Referenced by GraphicEQ().

2562 {
2563  wxASSERT( n > 1 );
2564 
2565  double a, b, h;
2566  static double xlast = 0.; // remember last x value requested
2567  static size_t k = 0; // and which interval we were in
2568 
2569  if( xr < xlast )
2570  k = 0; // gone back to start, (or somewhere to the left)
2571  xlast = xr;
2572  while( (x[k] <= xr) && (k + 1 < n) )
2573  k++;
2574  wxASSERT( k > 0 );
2575  k--;
2576  h = x[k+1] - x[k];
2577  a = ( x[k+1] - xr )/h;
2578  b = (xr - x[k])/h;
2579  return( a*y[k]+b*y[k+1]+((a*a*a-a)*y2[k]+(b*b*b-b)*y2[k+1])*h*h/6.);
2580 }
bool EffectEqualization::Startup ( )
overridevirtual

Reimplemented from Effect.

Definition at line 411 of file Equalization.cpp.

References Effect::GetCurrentSettingsGroup(), gPrefs, mCurveName, mdBMax, mdBMin, mDrawGrid, mDrawMode, mInterp, mLin, mM, Effect::SaveUserPreset(), and Effect::SetPrivateConfig().

412 {
413  wxString base = wxT("/Effects/Equalization/");
414 
415  // Migrate settings from 2.1.0 or before
416 
417  // Already migrated, so bail
418  if (gPrefs->Exists(base + wxT("Migrated")))
419  {
420  return true;
421  }
422 
423  // Load the old "current" settings
424  if (gPrefs->Exists(base))
425  {
426  // These get saved to the current preset
427  int filterLength;
428  gPrefs->Read(base + wxT("FilterLength"), &filterLength, 4001);
429  mM = std::max(0, filterLength);
430  if ((mM < 21) || (mM > 8191)) { // corrupted Prefs?
431  mM = 4001; //default
432  }
433  gPrefs->Read(base + wxT("CurveName"), &mCurveName, wxT("unnamed"));
434  gPrefs->Read(base + wxT("Lin"), &mLin, false);
435  gPrefs->Read(base + wxT("Interp"), &mInterp, 0);
436 
438 
439  // These persist across preset changes
440  double dBMin;
441  gPrefs->Read(base + wxT("dBMin"), &dBMin, -30.0);
442  if ((dBMin < -120) || (dBMin > -10)) { // corrupted Prefs?
443  dBMin = -30; //default
444  }
445  mdBMin = dBMin;
447 
448  double dBMax;
449  gPrefs->Read(base + wxT("dBMax"), &dBMax, 30.);
450  if ((dBMax < 0) || (dBMax > 60)) { // corrupted Prefs?
451  dBMax = 30; //default
452  }
453  mdBMax = dBMax;
455 
456  gPrefs->Read(base + wxT("DrawMode"), &mDrawMode, true);
458 
459  gPrefs->Read(base + wxT("DrawGrid"), &mDrawGrid, true);
461 
462  // Do not migrate again
463  gPrefs->Write(base + wxT("Migrated"), true);
464  gPrefs->Flush();
465  }
466 
467  return true;
468 }
bool SaveUserPreset(const wxString &name) override
Definition: Effect.cpp:625
wxString GetCurrentSettingsGroup() override
Definition: Effect.cpp:824
bool SetPrivateConfig(const wxString &group, const wxString &key, const wxString &value) override
Definition: Effect.cpp:945
wxFileConfig * gPrefs
Definition: Prefs.cpp:72
bool EffectEqualization::TransferDataFromWindow ( )
overridevirtual

Reimplemented from Effect.

Definition at line 997 of file Equalization.cpp.

References _(), ForceRecalc(), Ruler::GetMaxSize(), LayoutEQSliders(), mdBMax, mdBMaxSlider, mdBMin, mdBMinSlider, mdBRuler, mFreqRuler, mM, mMSlider, mMText, mPanel, RulerPanel::ruler, and Ruler::SetRange().

Referenced by OnSliderDBMAX(), OnSliderDBMIN(), OnSliderM(), and TransferDataToWindow().

998 {
999  wxString tip;
1000 
1001  bool rr = false;
1002  float dB = (float) mdBMinSlider->GetValue();
1003  if (dB != mdBMin) {
1004  rr = true;
1005  mdBMin = dB;
1006  tip.Printf(_("%d dB"), (int)mdBMin);
1007  mdBMinSlider->SetToolTip(tip);
1008  }
1009 
1010  dB = (float) mdBMaxSlider->GetValue();
1011  if (dB != mdBMax) {
1012  rr = true;
1013  mdBMax = dB;
1014  tip.Printf(_("%d dB"), (int)mdBMax);
1015  mdBMaxSlider->SetToolTip(tip);
1016  }
1017 
1018  // Refresh ruler if values have changed
1019  if (rr) {
1020  int w1, w2, h;
1021  mdBRuler->ruler.GetMaxSize(&w1, &h);
1022  mdBRuler->ruler.SetRange(mdBMax, mdBMin);
1023  mdBRuler->ruler.GetMaxSize(&w2, &h);
1024  if( w1 != w2 ) // Reduces flicker
1025  {
1026  mdBRuler->SetSize(wxSize(w2,h));
1027  LayoutEQSliders();
1028  mFreqRuler->Refresh(false);
1029  }
1030  mdBRuler->Refresh(false);
1031 
1032  mPanel->Refresh(false);
1033  }
1034 
1035  size_t m = 2 * mMSlider->GetValue() + 1; // odd numbers only
1036  if (m != mM) {
1037  mM = m;
1038  ForceRecalc();
1039 
1040  tip.Printf(wxT("%d"), mM);
1041  mMText->SetLabel(tip);
1042  mMText->SetName(mMText->GetLabel()); // fix for bug 577 (NVDA/Narrator screen readers do not read static text in dialogs)
1043  mMSlider->SetToolTip(tip);
1044  }
1045 
1046  return true;
1047 }
void GetMaxSize(wxCoord *width, wxCoord *height)
Definition: Ruler.cpp:1533
RulerPanel * mFreqRuler
Definition: Equalization.h:220
wxSlider * mdBMaxSlider
Definition: Equalization.h:268
wxStaticText * mMText
Definition: Equalization.h:265
_("Move Track &Down")+wxT("\t")+(GetActiveProject() -> GetCommandManager() ->GetKeyFromName(wxT("TrackMoveDown"))), OnMoveTrack) POPUP_MENU_ITEM(OnMoveTopID, _("Move Track to &Top")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveTop"))), OnMoveTrack) POPUP_MENU_ITEM(OnMoveBottomID, _("Move Track to &Bottom")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveBottom"))), OnMoveTrack) void TrackMenuTable::OnSetName(wxCommandEvent &)
void SetRange(double min, double max)
Definition: Ruler.cpp:234
wxSlider * mMSlider
Definition: Equalization.h:266
RulerPanel * mdBRuler
Definition: Equalization.h:219
EqualizationPanel * mPanel
Definition: Equalization.h:256
Ruler ruler
Definition: Ruler.h:304
wxSlider * mdBMinSlider
Definition: Equalization.h:267
bool EffectEqualization::TransferDataToWindow ( )
overridevirtual

Reimplemented from Effect.

Definition at line 948 of file Equalization.cpp.

References mdBMax, mdBMaxSlider, mdBMin, mdBMinSlider, mDraw, mDrawGrid, mDrawMode, mGraphic, mGridOnOff, mInterp, mInterpChoice, mLin, mLinFreq, mM, mMSlider, Effect::mUIParent, OnLinFreq(), szrG, szrH, szrI, szrL, szrV, TransferDataFromWindow(), UpdateCurves(), and UpdateGraphic().

949 {
950  // Set log or lin freq scale (affects interpolation as well)
951  mLinFreq->SetValue( mLin );
952  wxCommandEvent dummyEvent;
953  OnLinFreq(dummyEvent); // causes a CalcFilter
954 
955  mGridOnOff->SetValue( mDrawGrid ); // checks/unchecks the box on the interface
956 
957  mMSlider->SetValue((mM - 1) / 2);
958  mM = 0; // force refresh in TransferDataFromWindow()
959 
960  mdBMinSlider->SetValue((int)mdBMin);
961  mdBMin = 0; // force refresh in TransferDataFromWindow()
962 
963  mdBMaxSlider->SetValue((int)mdBMax);
964  mdBMax = 0; // force refresh in TransferDataFromWindow()
965 
966  // Reload the curve names
967  UpdateCurves();
968 
969  // Set graphic interpolation mode
970  mInterpChoice->SetSelection(mInterp);
971 
972  // Set Graphic (Fader) or Draw mode
973  if (mDrawMode)
974  {
975  mDraw->SetValue(true);
976  szrV->Show(szrG,false); // eq sliders
977  szrH->Show(szrI,false); // interpolation choice
978  szrH->Show(szrL,true); // linear freq checkbox
979  }
980  else
981  {
982  mGraphic->SetValue(true);
983  UpdateGraphic();
984  }
985 
987 
988  mUIParent->Layout();
989  wxGetTopLevelParent(mUIParent)->Layout();
990 
991  return true;
992 }
void UpdateGraphic(void)
bool TransferDataFromWindow() override
wxRadioButton * mGraphic
Definition: Equalization.h:259
wxChoice * mInterpChoice
Definition: Equalization.h:262
wxCheckBox * mGridOnOff
Definition: Equalization.h:261
wxRadioButton * mDraw
Definition: Equalization.h:258
void OnLinFreq(wxCommandEvent &event)
wxSlider * mdBMaxSlider
Definition: Equalization.h:268
wxWindow * mUIParent
Definition: Effect.h:475
wxSlider * mMSlider
Definition: Equalization.h:266
wxCheckBox * mLinFreq
Definition: Equalization.h:260
wxSlider * mdBMinSlider
Definition: Equalization.h:267
void EffectEqualization::UpdateCurves ( )
private

Definition at line 2117 of file Equalization.cpp.

References mCurve, mCurveName, mCurves, and setCurve().

Referenced by OnManage(), and TransferDataToWindow().

2118 {
2119  // Reload the curve names
2120  mCurve->Clear();
2121  for (size_t i = 0, cnt = mCurves.size(); i < cnt; i++)
2122  {
2123  mCurve->Append(mCurves[ i ].Name);
2124  }
2125  mCurve->SetStringSelection(mCurveName);
2126 
2127  // Allow the control to resize
2128  mCurve->SetSizeHints(-1, -1);
2129 
2130  // Set initial curve
2131  setCurve( mCurveName );
2132 }
EQCurveArray mCurves
Definition: Equalization.h:231
void EffectEqualization::UpdateDefaultCurves ( bool  updateAll = false)
private

Definition at line 1429 of file Equalization.cpp.

References _(), EQCURVES_REVISION, EQCURVES_VERSION, gPrefs, mCurves, EQCurve::Name, FileNames::ResourcesDir(), and SaveCurves().

Referenced by LoadCurves().

1430 {
1431  if (mCurves.size() == 0)
1432  return;
1433 
1434  /* i18n-hint: name of the 'unnamed' custom curve */
1435  wxString unnamed = _("unnamed");
1436 
1437  // Save the "unnamed" curve and remove it so we can add it back as the final curve.
1438  EQCurve userUnnamed(wxT("temp"));
1439  userUnnamed = mCurves.back();
1440  mCurves.pop_back();
1441 
1442  EQCurveArray userCurves = mCurves;
1443  mCurves.clear();
1444  // We only wamt to look for the shipped EQDefaultCurves.xml
1445  wxFileName fn = wxFileName(FileNames::ResourcesDir(), wxT("EQDefaultCurves.xml"));
1446  wxLogDebug(wxT("Attempting to load EQDefaultCurves.xml from %s"),fn.GetFullPath());
1447  XMLFileReader reader;
1448 
1449  if(!reader.Parse(this, fn.GetFullPath())) {
1450  wxLogError(wxT("EQDefaultCurves.xml could not be read."));
1451  return;
1452  }
1453  else {
1454  wxLogDebug(wxT("Loading EQDefaultCurves.xml successful."));
1455  }
1456 
1457  EQCurveArray defaultCurves = mCurves;
1458  mCurves.clear(); // clear now so that we can sort then add back.
1459 
1460  // Remove "unnamed" if it exists.
1461  if (defaultCurves.back().Name == unnamed) {
1462  defaultCurves.pop_back();
1463  }
1464  else {
1465  wxLogError(wxT("Error in EQDefaultCurves.xml"));
1466  }
1467 
1468  int numUserCurves = userCurves.size();
1469  int numDefaultCurves = defaultCurves.size();
1470  EQCurve tempCurve(wxT("test"));
1471 
1472  if (updateAll) {
1473  // Update all factory preset curves.
1474  // Sort and add factory defaults first;
1475  mCurves = defaultCurves;
1476  std::sort(mCurves.begin(), mCurves.end());
1477  // then add remaining user curves:
1478  for (int curveCount = 0; curveCount < numUserCurves; curveCount++) {
1479  bool isCustom = true;
1480  tempCurve = userCurves[curveCount];
1481  // is the name in the dfault set?
1482  for (int defCurveCount = 0; defCurveCount < numDefaultCurves; defCurveCount++) {
1483  if (tempCurve.Name == mCurves[defCurveCount].Name) {
1484  isCustom = false;
1485  break;
1486  }
1487  }
1488  // if tempCurve is not in the default set, add it to mCurves.
1489  if (isCustom) {
1490  mCurves.push_back(tempCurve);
1491  }
1492  }
1493  }
1494  else {
1495  // Import NEW factory defaults but retain all user modified curves.
1496  for (int defCurveCount = 0; defCurveCount < numDefaultCurves; defCurveCount++) {
1497  bool isUserCurve = false;
1498  // Add if the curve is in the user's set (preserve user's copy)
1499  for (int userCurveCount = 0; userCurveCount < numUserCurves; userCurveCount++) {
1500  if (userCurves[userCurveCount].Name == defaultCurves[defCurveCount].Name) {
1501  isUserCurve = true;
1502  mCurves.push_back(userCurves[userCurveCount]);
1503  break;
1504  }
1505  }
1506  if (!isUserCurve) {
1507  mCurves.push_back(defaultCurves[defCurveCount]);
1508  }
1509  }
1510  std::sort(mCurves.begin(), mCurves.end());
1511  // now add the rest of the user's curves.
1512  for (int userCurveCount = 0; userCurveCount < numUserCurves; userCurveCount++) {
1513  bool isDefaultCurve = false;
1514  tempCurve = userCurves[userCurveCount];
1515  for (int defCurveCount = 0; defCurveCount < numDefaultCurves; defCurveCount++) {
1516  if (tempCurve.Name == defaultCurves[defCurveCount].Name) {
1517  isDefaultCurve = true;
1518  break;
1519  }
1520  }
1521  if (!isDefaultCurve) {
1522  mCurves.push_back(tempCurve);
1523  }
1524  }
1525  }
1526  defaultCurves.clear();
1527  userCurves.clear();
1528 
1529  // Add back old "unnamed"
1530  if(userUnnamed.Name == unnamed) {
1531  mCurves.push_back( userUnnamed ); // we always need a default curve to use
1532  }
1533 
1534  SaveCurves();
1535 
1536  // Write current EqCurve version number
1537  // TODO: Probably better if we used pluginregistry.cfg
1538  wxString eqCurvesCurrentVersion = wxString::Format(wxT("%d.%d"), EQCURVES_VERSION, EQCURVES_REVISION);
1539  gPrefs->Write(wxT("/Effects/Equalization/PresetVersion"), eqCurvesCurrentVersion);
1540  gPrefs->Flush();
1541 
1542  return;
1543 }
void SaveCurves(const wxString &fileName=wxEmptyString)
wxFileConfig * gPrefs
Definition: Prefs.cpp:72
Reads a file and passes the results through an XMLTagHandler.
Definition: XMLFileReader.h:18
#define EQCURVES_REVISION
EQCurve is used with EffectEqualization.
Definition: Equalization.h:77
EQCurveArray mCurves
Definition: Equalization.h:231
_("Move Track &Down")+wxT("\t")+(GetActiveProject() -> GetCommandManager() ->GetKeyFromName(wxT("TrackMoveDown"))), OnMoveTrack) POPUP_MENU_ITEM(OnMoveTopID, _("Move Track to &Top")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveTop"))), OnMoveTrack) POPUP_MENU_ITEM(OnMoveBottomID, _("Move Track to &Bottom")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveBottom"))), OnMoveTrack) void TrackMenuTable::OnSetName(wxCommandEvent &)
static wxString ResourcesDir()
Definition: FileNames.cpp:168
#define EQCURVES_VERSION
std::vector< EQCurve > EQCurveArray
Definition: Equalization.h:92
void EffectEqualization::UpdateDraw ( )
private

Definition at line 2134 of file Equalization.cpp.

References EnvelopeUpdated(), EnvLogToLin(), ForceRecalc(), mEnvelope, mFreqRuler, mHiFreq, mLin, mLinEnvelope, mLogEnvelope, Effect::mUIParent, RulerPanel::ruler, Ruler::SetLog(), Ruler::SetRange(), szrG, szrH, szrI, szrL, and szrV.

Referenced by OnDrawMode().

2135 {
2136  size_t numPoints = mLogEnvelope->GetNumberOfPoints();
2137  Doubles when{ numPoints };
2138  Doubles value{ numPoints };
2139  double deltadB = 0.1;
2140  double dx, dy, dx1, dy1, err;
2141 
2142  mLogEnvelope->GetPoints( when.get(), value.get(), numPoints );
2143 
2144  // set 'unnamed' as the selected curve
2145  EnvelopeUpdated();
2146 
2147  bool flag = true;
2148  while (flag)
2149  {
2150  flag = false;
2151  int numDeleted = 0;
2152  mLogEnvelope->GetPoints( when.get(), value.get(), numPoints );
2153  for (size_t j = 0; j + 2 < numPoints; j++)
2154  {
2155  dx = when[j+2+numDeleted] - when[j+numDeleted];
2156  dy = value[j+2+numDeleted] - value[j+numDeleted];
2157  dx1 = when[j+numDeleted+1] - when[j+numDeleted];
2158  dy1 = dy * dx1 / dx;
2159  err = fabs(value[j+numDeleted+1] - (value[j+numDeleted] + dy1));
2160  if( err < deltadB )
2161  { // within < deltadB dB?
2162  mLogEnvelope->Delete(j+1);
2163  numPoints--;
2164  numDeleted++;
2165  flag = true;
2166  }
2167  }
2168  }
2169 
2170  if(mLin) // do not use IsLinear() here
2171  {
2172  EnvLogToLin();
2173  mEnvelope = mLinEnvelope.get();
2174  mFreqRuler->ruler.SetLog(false);
2176  }
2177 
2178  szrV->Show(szrG,false);
2179  szrH->Show(szrI,false);
2180  szrH->Show(szrL,true);
2181 
2182  mUIParent->Layout();
2183  wxGetTopLevelParent(mUIParent)->Layout();
2184  ForceRecalc(); // it may have changed slightly due to the deletion of points
2185 }
void SetLog(bool log)
Definition: Ruler.cpp:197
Envelope * mEnvelope
Definition: Equalization.h:234
RulerPanel * mFreqRuler
Definition: Equalization.h:220
std::unique_ptr< Envelope > mLogEnvelope
Definition: Equalization.h:233
wxWindow * mUIParent
Definition: Effect.h:475
void SetRange(double min, double max)
Definition: Ruler.cpp:234
std::unique_ptr< Envelope > mLinEnvelope
Definition: Equalization.h:233
Ruler ruler
Definition: Ruler.h:304
void EffectEqualization::UpdateGraphic ( void  )
private

Definition at line 2187 of file Equalization.cpp.

References EnvLinToLog(), ErrMin(), GraphicEQ(), kThirdOct, LayoutEQSliders(), lrint, mBandsInUse, mDrawMode, mEnvelope, mEQVals, mFreqRuler, mHiFreq, mLin, mLinEnvelope, mLoFreq, mLogEnvelope, mSliders, mSlidersOld, Effect::mUIParent, mWhenSliders, RulerPanel::ruler, Ruler::SetLog(), Ruler::SetRange(), szrG, szrH, szrI, szrL, and szrV.

Referenced by OnCurve(), OnGraphicMode(), and TransferDataToWindow().

2188 {
2189  double loLog = log10(mLoFreq);
2190  double hiLog = log10(mHiFreq);
2191  double denom = hiLog - loLog;
2192 
2193  if(mLin) //going from lin to log freq scale - do not use IsLinear() here
2194  { // add some extra points to the linear envelope for the graphic to follow
2195  double step = pow(2., 1./12.); // twelve steps per octave
2196  double when,value;
2197  for(double freq=10.; freq<mHiFreq; freq*=step)
2198  {
2199  when = freq/mHiFreq;
2200  value = mLinEnvelope->GetValue(when);
2201  mLinEnvelope->InsertOrReplace(when, value);
2202  }
2203 
2204  EnvLinToLog();
2205  mEnvelope = mLogEnvelope.get();
2206  mFreqRuler->ruler.SetLog(true);
2207  mFreqRuler->ruler.SetRange(mLoFreq, mHiFreq);
2208  }
2209 
2210  for (size_t i = 0; i < mBandsInUse; i++)
2211  {
2212  if( kThirdOct[i] == mLoFreq )
2213  mWhenSliders[i] = 0.;
2214  else
2215  mWhenSliders[i] = (log10(kThirdOct[i])-loLog)/denom;
2216  mEQVals[i] = mLogEnvelope->GetValue(mWhenSliders[i]); //set initial values of sliders
2217  if( mEQVals[i] > 20.)
2218  mEQVals[i] = 20.;
2219  if( mEQVals[i] < -20.)
2220  mEQVals[i] = -20.;
2221  }
2222  ErrMin(); //move sliders to minimise error
2223  for (size_t i = 0; i < mBandsInUse; i++)
2224  {
2225  mSliders[i]->SetValue(lrint(mEQVals[i])); //actually set slider positions
2226  mSlidersOld[i] = mSliders[i]->GetValue();
2227  wxString tip;
2228  if( kThirdOct[i] < 1000.)
2229  tip.Printf( wxT("%dHz\n%.1fdB"), (int)kThirdOct[i], mEQVals[i] );
2230  else
2231  tip.Printf( wxT("%gkHz\n%.1fdB"), kThirdOct[i]/1000., mEQVals[i] );
2232  mSliders[i]->SetToolTip(tip);
2233  }
2234 
2235  szrV->Show(szrG,true); // eq sliders
2236  szrH->Show(szrI,true); // interpolation choice
2237  szrH->Show(szrL,false); // linear freq checkbox
2238 
2239  mUIParent->Layout();
2240  wxGetTopLevelParent(mUIParent)->Layout();
2241 // mUIParent->Layout(); // Make all sizers get resized first
2242  LayoutEQSliders(); // Then layout sliders
2243  mUIParent->Layout();
2244  wxGetTopLevelParent(mUIParent)->Layout();
2245 // mUIParent->Layout(); // And layout again to resize dialog
2246 
2247 #if 0
2248  wxSize wsz = mUIParent->GetSize();
2249  wxSize ssz = szrV->GetSize();
2250  if (ssz.x > wsz.x || ssz.y > wsz.y)
2251  {
2252  mUIParent->Fit();
2253  }
2254 #endif
2255  GraphicEQ(mLogEnvelope.get());
2256  mDrawMode = false;
2257 }
void SetLog(bool log)
Definition: Ruler.cpp:197
double mWhenSliders[NUMBER_OF_BANDS+1]
Definition: Equalization.h:217
Envelope * mEnvelope
Definition: Equalization.h:234
RulerPanel * mFreqRuler
Definition: Equalization.h:220
#define lrint(dbl)
Definition: float_cast.h:136
std::unique_ptr< Envelope > mLogEnvelope
Definition: Equalization.h:233
wxSlider * mSliders[NUMBER_OF_BANDS]
Definition: Equalization.h:269
void GraphicEQ(Envelope *env)
wxWindow * mUIParent
Definition: Effect.h:475
void SetRange(double min, double max)
Definition: Ruler.cpp:234
static const double kThirdOct[]
std::unique_ptr< Envelope > mLinEnvelope
Definition: Equalization.h:233
double mEQVals[NUMBER_OF_BANDS+1]
Definition: Equalization.h:229
int mSlidersOld[NUMBER_OF_BANDS]
Definition: Equalization.h:228
Ruler ruler
Definition: Ruler.h:304
bool EffectEqualization::ValidateUI ( )
override

Definition at line 364 of file Equalization.cpp.

References _(), Effect::GetCurrentSettingsGroup(), mCurveName, mCurves, mdBMax, mdBMin, mDirty, mDisallowCustom, mDrawGrid, mDrawMode, Effect::MessageBox(), mLogEnvelope, SaveCurves(), Select(), and Effect::SetPrivateConfig().

365 {
366  // If editing a batch chain, we don't want to be using the unnamed curve so
367  // we offer to save it.
368 
369  if (mDisallowCustom && mCurveName.IsSameAs(wxT("unnamed")))
370  {
371  // PRL: This is unreachable. mDisallowCustom is always false.
372 
373  Effect::MessageBox(_("To use this EQ curve in a batch chain, please choose a new name for it.\nChoose the 'Save/Manage Curves...' button and rename the 'unnamed' curve, then use that one."),
374  wxOK | wxCENTRE,
375  _("EQ Curve needs a different name"));
376  return false;
377  }
378 
379  // Update unnamed curve (so it's there for next time)
380  //(done in a hurry, may not be the neatest -MJS)
381  if (mDirty && !mDrawMode)
382  {
383  size_t numPoints = mLogEnvelope->GetNumberOfPoints();
384  Doubles when{ numPoints };
385  Doubles value{ numPoints };
386  mLogEnvelope->GetPoints(when.get(), value.get(), numPoints);
387  for (size_t i = 0, j = 0; j + 2 < numPoints; i++, j++)
388  {
389  if ((value[i] < value[i + 1] + .05) && (value[i] > value[i + 1] - .05) &&
390  (value[i + 1] < value[i + 2] + .05) && (value[i + 1] > value[i + 2] - .05))
391  { // within < 0.05 dB?
392  mLogEnvelope->Delete(j + 1);
393  numPoints--;
394  j--;
395  }
396  }
397  Select((int) mCurves.size() - 1);
398  }
399  SaveCurves();
400 
405 
406  return true;
407 }
int MessageBox(const wxString &message, long style=DefaultMessageBoxStyle, const wxString &titleStr=wxString{})
Definition: Effect.cpp:2665
wxString GetCurrentSettingsGroup() override
Definition: Effect.cpp:824
void Select(int sel)
void SaveCurves(const wxString &fileName=wxEmptyString)
bool SetPrivateConfig(const wxString &group, const wxString &key, const wxString &value) override
Definition: Effect.cpp:945
std::unique_ptr< Envelope > mLogEnvelope
Definition: Equalization.h:233
EQCurveArray mCurves
Definition: Equalization.h:231
_("Move Track &Down")+wxT("\t")+(GetActiveProject() -> GetCommandManager() ->GetKeyFromName(wxT("TrackMoveDown"))), OnMoveTrack) POPUP_MENU_ITEM(OnMoveTopID, _("Move Track to &Top")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveTop"))), OnMoveTrack) POPUP_MENU_ITEM(OnMoveBottomID, _("Move Track to &Bottom")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveBottom"))), OnMoveTrack) void TrackMenuTable::OnSetName(wxCommandEvent &)
void EffectEqualization::WriteXML ( XMLWriter xmlFile) const
private

Definition at line 2050 of file Equalization.cpp.

Referenced by SaveCurves().

2052 {
2053  // Start our heirarchy
2054  xmlFile.StartTag( wxT( "equalizationeffect" ) );
2055 
2056  // Write all curves
2057  int numCurves = mCurves.size();
2058  int curve;
2059  for( curve = 0; curve < numCurves; curve++ )
2060  {
2061  // Start a NEW curve
2062  xmlFile.StartTag( wxT( "curve" ) );
2063  xmlFile.WriteAttr( wxT( "name" ), mCurves[ curve ].Name );
2064 
2065  // Write all points
2066  int numPoints = mCurves[ curve ].points.size();
2067  int point;
2068  for( point = 0; point < numPoints; point++ )
2069  {
2070  // Write NEW point
2071  xmlFile.StartTag( wxT( "point" ) );
2072  xmlFile.WriteAttr( wxT( "f" ), mCurves[ curve ].points[ point ].Freq, 12 );
2073  xmlFile.WriteAttr( wxT( "d" ), mCurves[ curve ].points[ point ].dB, 12 );
2074  xmlFile.EndTag( wxT( "point" ) );
2075  }
2076 
2077  // Terminate curve
2078  xmlFile.EndTag( wxT( "curve" ) );
2079  }
2080 
2081  // Terminate our heirarchy
2082  xmlFile.EndTag( wxT( "equalizationeffect" ) );
2083 }
virtual void StartTag(const wxString &name)
Definition: XMLWriter.cpp:78
virtual void WriteAttr(const wxString &name, const wxString &value)
Definition: XMLWriter.cpp:131
virtual void EndTag(const wxString &name)
Definition: XMLWriter.cpp:101
EQCurveArray mCurves
Definition: Equalization.h:231

Friends And Related Function Documentation

friend class EditCurvesDialog
friend

Definition at line 279 of file Equalization.h.

friend class EqualizationPanel
friend

Definition at line 278 of file Equalization.h.

Referenced by PopulateOrExchange().

Member Data Documentation

HFFT EffectEqualization::hFFT
private

Definition at line 205 of file Equalization.h.

Referenced by Filter().

size_t EffectEqualization::mBandsInUse
private

Definition at line 218 of file Equalization.h.

Referenced by ErrMin(), Flatten(), GraphicEQ(), Init(), OnInvert(), OnSlider(), and UpdateGraphic().

wxChoice* EffectEqualization::mCurve
private

Definition at line 263 of file Equalization.h.

Referenced by CloseUI(), OnCurve(), OnManage(), PopulateOrExchange(), Select(), and UpdateCurves().

wxString EffectEqualization::mCurveName
private
EQCurveArray EffectEqualization::mCurves
private
float EffectEqualization::mdBMax
private
wxSlider* EffectEqualization::mdBMaxSlider
private
float EffectEqualization::mdBMin
private
wxSlider* EffectEqualization::mdBMinSlider
private
RulerPanel* EffectEqualization::mdBRuler
private
bool EffectEqualization::mDirty
private

Definition at line 227 of file Equalization.h.

Referenced by EnvelopeUpdated(), and ValidateUI().

bool EffectEqualization::mDisallowCustom
private

Definition at line 223 of file Equalization.h.

Referenced by ValidateUI().

wxRadioButton* EffectEqualization::mDraw
private
bool EffectEqualization::mDrawGrid
private
bool EffectEqualization::mDrawMode
private
Envelope* EffectEqualization::mEnvelope
private
double EffectEqualization::mEQVals[NUMBER_OF_BANDS+1]
private
Floats EffectEqualization::mFFTBuffer
private

Definition at line 206 of file Equalization.h.

Referenced by Filter().

Floats EffectEqualization::mFilterFuncI
private
Floats EffectEqualization::mFilterFuncR
private
RulerPanel* EffectEqualization::mFreqRuler
private
wxRadioButton* EffectEqualization::mGraphic
private

Definition at line 259 of file Equalization.h.

Referenced by OnInterp(), PopulateOrExchange(), and TransferDataToWindow().

wxPanel* EffectEqualization::mGraphicPanel
private

Definition at line 257 of file Equalization.h.

Referenced by LayoutEQSliders(), and PopulateOrExchange().

wxCheckBox* EffectEqualization::mGridOnOff
private

Definition at line 261 of file Equalization.h.

Referenced by OnGridOnOff(), PopulateOrExchange(), and TransferDataToWindow().

double EffectEqualization::mHiFreq
private
int EffectEqualization::mInterp
private
wxChoice* EffectEqualization::mInterpChoice
private

Definition at line 262 of file Equalization.h.

Referenced by OnInterp(), PopulateOrExchange(), and TransferDataToWindow().

wxArrayString EffectEqualization::mInterpolations
private

Definition at line 222 of file Equalization.h.

Referenced by PopulateOrExchange(), and SetAutomationParameters().

wxSizerItem* EffectEqualization::mLeftSpacer
private

Definition at line 254 of file Equalization.h.

bool EffectEqualization::mLin
private
std::unique_ptr<Envelope> EffectEqualization::mLinEnvelope
private
wxCheckBox* EffectEqualization::mLinFreq
private

Definition at line 260 of file Equalization.h.

Referenced by OnLinFreq(), PopulateOrExchange(), and TransferDataToWindow().

double EffectEqualization::mLoFreq
private
std::unique_ptr<Envelope> EffectEqualization::mLogEnvelope
private
size_t EffectEqualization::mM
private
wxButton* EffectEqualization::mManage
private

Definition at line 264 of file Equalization.h.

wxSlider* EffectEqualization::mMSlider
private
wxStaticText* EffectEqualization::mMText
private

Definition at line 265 of file Equalization.h.

Referenced by PopulateOrExchange(), and TransferDataFromWindow().

EqualizationPanel* EffectEqualization::mPanel
private
wxSlider* EffectEqualization::mSliders[NUMBER_OF_BANDS]
private
int EffectEqualization::mSlidersOld[NUMBER_OF_BANDS]
private

Definition at line 228 of file Equalization.h.

Referenced by Flatten(), OnInvert(), OnSlider(), PopulateOrExchange(), and UpdateGraphic().

double EffectEqualization::mWhens[NUM_PTS]
private

Definition at line 216 of file Equalization.h.

Referenced by ErrMin(), and GraphicEQ().

double EffectEqualization::mWhenSliders[NUMBER_OF_BANDS+1]
private

Definition at line 217 of file Equalization.h.

Referenced by GraphicEQ(), and UpdateGraphic().

size_t EffectEqualization::mWindowSize
private
wxSizer* EffectEqualization::szr1
private

Definition at line 248 of file Equalization.h.

Referenced by PopulateOrExchange().

wxSizer* EffectEqualization::szr2
private

Definition at line 249 of file Equalization.h.

wxSizer* EffectEqualization::szr3
private

Definition at line 250 of file Equalization.h.

wxSizer* EffectEqualization::szr4
private

Definition at line 251 of file Equalization.h.

wxSizer* EffectEqualization::szr5
private

Definition at line 252 of file Equalization.h.

wxSizer* EffectEqualization::szrC
private

Definition at line 242 of file Equalization.h.

wxSizer* EffectEqualization::szrG
private
wxSizer* EffectEqualization::szrH
private
wxSizer* EffectEqualization::szrI
private
wxSizer* EffectEqualization::szrL
private
wxSizer* EffectEqualization::szrV
private
const size_t EffectEqualization::windowSize = 16384u
staticprivate

Definition at line 141 of file Equalization.h.

Referenced by ProcessOne().


The documentation for this class was generated from the following files: