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 EffectClientInterface EffectUIClientInterface EffectHostInterface EffectDefinitionInterface ConfigClientInterface IdentInterface ParamsInterface

Public Member Functions

 EffectEqualization ()
 
virtual ~EffectEqualization ()
 
IdentInterfaceSymbol GetSymbol () override
 
wxString GetDescription () override
 
wxString ManualPage () override
 
EffectType GetType () override
 
bool DefineParams (ShuttleParams &S) override
 
bool GetAutomationParameters (CommandParameters &parms) override
 
bool SetAutomationParameters (CommandParameters &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
 
IdentInterfaceSymbol GetVendor () override
 
wxString GetVersion () override
 
IdentInterfaceSymbol GetFamilyId () 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 LoadUserPreset (const wxString &name) override
 
bool SaveUserPreset (const wxString &name) override
 
wxArrayString GetFactoryPresets () override
 
bool LoadFactoryPreset (int id) override
 
void SetHostUI (EffectUIHostInterface *host) override
 
bool IsGraphicalUI () override
 
bool HideUI () override
 
bool CanExportPresets () override
 
void ExportPresets () override
 
void ImportPresets () override
 
bool HasOptions () override
 
void ShowOptions () override
 
double GetDefaultDuration () override
 
double GetDuration () override
 
NumericFormatId GetDurationFormat () override
 
virtual NumericFormatId 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 EffectClientInterface
virtual ~EffectClientInterface ()
 
- Public Member Functions inherited from EffectDefinitionInterface
virtual ~EffectDefinitionInterface ()
 
- Public Member Functions inherited from IdentInterface
virtual ~IdentInterface ()
 
const wxString & GetTranslatedName ()
 
- Public Member Functions inherited from ParamsInterface
virtual ~ParamsInterface ()
 
virtual bool DefineParams (ShuttleParams &WXUNUSED(S))
 
- Public Member Functions inherited from EffectUIClientInterface
virtual ~EffectUIClientInterface ()
 
- Public Member Functions inherited from EffectHostInterface
virtual ~EffectHostInterface ()
 
- Public Member Functions inherited from ConfigClientInterface
virtual ~ConfigClientInterface ()
 
- 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
 
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 99 of file Equalization.h.

Member Enumeration Documentation

anonymous enum
private
Enumerator
loFreqI 

Definition at line 147 of file Equalization.h.

Constructor & Destructor Documentation

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

Definition at line 279 of file Equalization.cpp.

280 {
281 }

Member Function Documentation

bool EffectEqualization::CalcFilter ( )
private

Definition at line 1199 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().

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

Reimplemented from Effect.

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:682
EqualizationPanel * mPanel
Definition: Equalization.h:257
bool EffectEqualization::DefineParams ( ShuttleParams S)
override

Definition at line 308 of file Equalization.cpp.

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

308  {
309  S.SHUTTLE_PARAM( mM, FilterLength );
310  S.SHUTTLE_PARAM( mCurveName, CurveName);
311  S.SHUTTLE_PARAM( mLin, InterpLin);
312  S.SHUTTLE_ENUM_PARAM( mInterp, InterpMeth, kInterpStrings, nInterpolations );
313 
314  return true;
315 }
static const IdentInterfaceSymbol kInterpStrings[nInterpolations]
void EffectEqualization::EnvelopeUpdated ( )
private

Definition at line 1826 of file Equalization.cpp.

References IsLinear(), mLinEnvelope, and mLogEnvelope.

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

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

Definition at line 1838 of file Equalization.cpp.

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

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

Definition at line 2282 of file Equalization.cpp.

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

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

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

Definition at line 2258 of file Equalization.cpp.

References mHiFreq, mLinEnvelope, and mLogEnvelope.

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

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

Definition at line 2324 of file Equalization.cpp.

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

Referenced by UpdateGraphic().

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

Definition at line 1312 of file Equalization.cpp.

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

Referenced by ProcessOne().

1313 {
1314  float re,im;
1315  // Apply FFT
1316  RealFFTf(buffer, hFFT.get());
1317  //FFT(len, false, inr, NULL, outr, outi);
1318 
1319  // Apply filter
1320  // DC component is purely real
1321  mFFTBuffer[0] = buffer[0] * mFilterFuncR[0];
1322  for(size_t i = 1; i < (len / 2); i++)
1323  {
1324  re=buffer[hFFT->BitReversed[i] ];
1325  im=buffer[hFFT->BitReversed[i]+1];
1326  mFFTBuffer[2*i ] = re*mFilterFuncR[i] - im*mFilterFuncI[i];
1327  mFFTBuffer[2*i+1] = re*mFilterFuncI[i] + im*mFilterFuncR[i];
1328  }
1329  // Fs/2 component is purely real
1330  mFFTBuffer[1] = buffer[1] * mFilterFuncR[len/2];
1331 
1332  // Inverse FFT and normalization
1333  InverseRealFFTf(mFFTBuffer.get(), hFFT.get());
1334  ReorderToTime(hFFT.get(), mFFTBuffer.get(), buffer);
1335 }
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 1896 of file Equalization.cpp.

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

Referenced by OnClear().

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

Definition at line 1815 of file Equalization.cpp.

References EqualizationPanel::ForceRecalc(), and mPanel.

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

1816 {
1817  if (mPanel)
1818  {
1819  mPanel->ForceRecalc();
1820  }
1821 }
EqualizationPanel * mPanel
Definition: Equalization.h:257
bool EffectEqualization::GetAutomationParameters ( CommandParameters parms)
overridevirtual

Reimplemented from Effect.

Definition at line 317 of file Equalization.cpp.

References mCurveName, mInterp, mLin, mM, nInterpolations, and CommandParameters::WriteEnum().

318 {
319  parms.Write(KEY_FilterLength, (unsigned long)mM);
320  parms.Write(KEY_CurveName, mCurveName);
321  parms.Write(KEY_InterpLin, mLin);
322  parms.WriteEnum(KEY_InterpMeth, mInterp, kInterpStrings, nInterpolations);
323 
324  return true;
325 }
static const IdentInterfaceSymbol kInterpStrings[nInterpolations]
bool WriteEnum(const wxString &key, int value, const IdentInterfaceSymbol choices[], size_t nChoices)
bool EffectEqualization::GetDefaultFileName ( wxFileName &  fileName)
private

Definition at line 1547 of file Equalization.cpp.

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

Referenced by LoadCurves().

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

Reimplemented from Effect.

Definition at line 290 of file Equalization.cpp.

References _().

291 {
292  return _("Adjusts the volume levels of particular frequencies");
293 }
_("Move Track &Down")+wxT("\t")+(GetActiveProject() -> GetCommandManager() ->GetKeyFromName(wxT("TrackMoveDown")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveTopID, _("Move Track to &Top")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveTop")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveBottomID, _("Move Track to &Bottom")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveBottom")).Raw()), OnMoveTrack)#define SET_TRACK_NAME_PLUGIN_SYMBOLclass SetTrackNameCommand:public AudacityCommand
IdentInterfaceSymbol EffectEqualization::GetSymbol ( )
overridevirtual

Reimplemented from Effect.

Definition at line 285 of file Equalization.cpp.

References EQUALIZATION_PLUGIN_SYMBOL.

286 {
288 }
#define EQUALIZATION_PLUGIN_SYMBOL
Definition: Equalization.h:46
EffectType EffectEqualization::GetType ( )
overridevirtual

Reimplemented from Effect.

Definition at line 302 of file Equalization.cpp.

References EffectTypeProcess.

303 {
304  return EffectTypeProcess;
305 }
void EffectEqualization::GraphicEQ ( Envelope env)
private

Definition at line 2400 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().

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

Implements XMLTagHandler.

Definition at line 2026 of file Equalization.cpp.

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

Implements XMLTagHandler.

Definition at line 1925 of file Equalization.cpp.

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

1926 {
1927  // May want to add a version strings...
1928  if( !wxStrcmp( tag, wxT("equalizationeffect") ) )
1929  {
1930  return true;
1931  }
1932 
1933  // Located a NEW curve
1934  if( !wxStrcmp(tag, wxT("curve") ) )
1935  {
1936  // Process the attributes
1937  while( *attrs )
1938  {
1939  // Cache attr/value and bump to next
1940  const wxChar *attr = *attrs++;
1941  const wxChar *value = *attrs++;
1942 
1943  // Create a NEW curve and name it
1944  if( !wxStrcmp( attr, wxT("name") ) )
1945  {
1946  const wxString strValue = value;
1947  if (!XMLValueChecker::IsGoodString(strValue))
1948  return false;
1949  // check for a duplicate name and add (n) if there is one
1950  int n = 0;
1951  wxString strValueTemp = strValue;
1952  bool exists;
1953  do
1954  {
1955  exists = false;
1956  for(size_t i = 0; i < mCurves.size(); i++)
1957  {
1958  if(n>0)
1959  strValueTemp.Printf(wxT("%s (%d)"),strValue,n);
1960  if(mCurves[i].Name == strValueTemp)
1961  {
1962  exists = true;
1963  break;
1964  }
1965  }
1966  n++;
1967  }
1968  while(exists == true);
1969 
1970  mCurves.push_back( EQCurve( strValueTemp ) );
1971  }
1972  }
1973 
1974  // Tell caller it was processed
1975  return true;
1976  }
1977 
1978  // Located a NEW point
1979  if( !wxStrcmp( tag, wxT("point") ) )
1980  {
1981  // Set defaults in case attributes are missing
1982  double f = 0.0;
1983  double d = 0.0;
1984 
1985  // Process the attributes
1986  double dblValue;
1987  while( *attrs )
1988  { // Cache attr/value and bump to next
1989  const wxChar *attr = *attrs++;
1990  const wxChar *value = *attrs++;
1991 
1992  const wxString strValue = value;
1993 
1994  // Get the frequency
1995  if( !wxStrcmp( attr, wxT("f") ) )
1996  {
1997  if (!XMLValueChecker::IsGoodString(strValue) ||
1998  !Internat::CompatibleToDouble(strValue, &dblValue))
1999  return false;
2000  f = dblValue;
2001  }
2002  // Get the dB
2003  else if( !wxStrcmp( attr, wxT("d") ) )
2004  {
2005  if (!XMLValueChecker::IsGoodString(strValue) ||
2006  !Internat::CompatibleToDouble(strValue, &dblValue))
2007  return false;
2008  d = dblValue;
2009  }
2010  }
2011 
2012  // Create a NEW point
2013  mCurves[ mCurves.size() - 1 ].points.push_back( EQPoint( f, d ) );
2014 
2015  // Tell caller it was processed
2016  return true;
2017  }
2018 
2019  // Tell caller we didn't understand the tag
2020  return false;
2021 }
static bool IsGoodString(const wxString &str)
static bool CompatibleToDouble(const wxString &stringToConvert, double *result)
Convert a string to a number.
Definition: Internat.cpp:122
EQCurve is used with EffectEqualization.
Definition: Equalization.h:78
EQCurveArray mCurves
Definition: Equalization.h:232
EQPoint is used with EQCurve and hence EffectEqualization.
Definition: Equalization.h:56
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:2660
bool GetSelected() const
Definition: Track.h:275
Envelope * mEnvelope
Definition: Equalization.h:235
virtual int GetKind() const
Definition: Track.h:329
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:101
std::unique_ptr< Envelope > mLogEnvelope
Definition: Equalization.h:234
An iterator for a TrackList.
Definition: Track.h:401
_("Move Track &Down")+wxT("\t")+(GetActiveProject() -> GetCommandManager() ->GetKeyFromName(wxT("TrackMoveDown")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveTopID, _("Move Track to &Top")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveTop")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveBottomID, _("Move Track to &Bottom")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveBottom")).Raw()), OnMoveTrack)#define SET_TRACK_NAME_PLUGIN_SYMBOLclass SetTrackNameCommand:public AudacityCommand
static const double kThirdOct[]
AUDACITY_DLL_API AudacityProject * GetActiveProject()
Definition: Project.cpp:308
#define NUMBER_OF_BANDS
Definition: Equalization.h:14
std::unique_ptr< Envelope > mLinEnvelope
Definition: Equalization.h:234
double GetRate() const
Definition: WaveTrack.cpp:398
bool EffectEqualization::IsLinear ( )
private

Definition at line 1888 of file Equalization.cpp.

References mDrawMode, and mLin.

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

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

Definition at line 2091 of file Equalization.cpp.

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

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

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

Definition at line 1340 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().

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

Reimplemented from Effect.

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:636
wxString EffectEqualization::ManualPage ( )
overridevirtual

Reimplemented from Effect.

Definition at line 295 of file Equalization.cpp.

296 {
297  return wxT("Equalization");
298 }
void EffectEqualization::OnClear ( wxCommandEvent &  event)
private

Definition at line 2698 of file Equalization.cpp.

References Flatten().

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

Definition at line 2674 of file Equalization.cpp.

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

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

Definition at line 2641 of file Equalization.cpp.

References mDrawMode, and UpdateDraw().

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

Definition at line 2648 of file Equalization.cpp.

References mDrawMode, and UpdateGraphic().

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

Definition at line 2771 of file Equalization.cpp.

References mDrawGrid, mGridOnOff, and mPanel.

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

Definition at line 2631 of file Equalization.cpp.

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

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

Definition at line 2703 of file Equalization.cpp.

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

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

Definition at line 2777 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().

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

Definition at line 2686 of file Equalization.cpp.

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

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

Definition at line 2581 of file Equalization.cpp.

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

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

Definition at line 2593 of file Equalization.cpp.

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

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

Definition at line 2666 of file Equalization.cpp.

References TransferDataFromWindow().

2667 {
2669 }
bool TransferDataFromWindow() override
void EffectEqualization::OnSliderDBMIN ( wxCommandEvent &  event)
private

Definition at line 2661 of file Equalization.cpp.

References TransferDataFromWindow().

2662 {
2664 }
bool TransferDataFromWindow() override
void EffectEqualization::OnSliderM ( wxCommandEvent &  event)
private

Definition at line 2655 of file Equalization.cpp.

References ForceRecalc(), and TransferDataFromWindow().

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

Reimplemented from Effect.

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:409
wxString GetCurrentSettingsGroup() override
Definition: Effect.cpp:801
bool LoadUserPreset(const wxString &name) override
Definition: Effect.cpp:584
void PopulateOrExchange(ShuttleGui &S) override
wxWindow * mUIParent
Definition: Effect.h:472
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:461
void CopyInputTracks()
Definition: Effect.cpp:2036
void ReplaceProcessedTracks(const bool bGoodResult)
Definition: Effect.cpp:2162
bool ProcessOne(int count, WaveTrack *t, sampleCount start, sampleCount len)
double GetStartTime() const override
Get the time at which the first clip in the track starts.
Definition: WaveTrack.cpp:1853
A Track that contains audio waveform data.
Definition: WaveTrack.h:60
std::shared_ptr< TrackList > mOutputTracks
Definition: Effect.h:459
double mT0
Definition: Effect.h:460
bool EffectEqualization::ProcessOne ( int  count,
WaveTrack t,
sampleCount  start,
sampleCount  len 
)
private

Definition at line 1050 of file Equalization.cpp.

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

Referenced by Process().

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

Definition at line 1574 of file Equalization.cpp.

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

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

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

Definition at line 1802 of file Equalization.cpp.

References mCurve, mCurveName, and mCurves.

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

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

Reimplemented from Effect.

Definition at line 327 of file Equalization.cpp.

References mCurveName, mEnvelope, mInterp, mLin, mLinEnvelope, mLogEnvelope, mM, nInterpolations, ReadAndVerifyBool, ReadAndVerifyEnum, ReadAndVerifyInt, and ReadAndVerifyString.

328 {
329  // Pretty sure the interpolation name shouldn't have been interpreted when
330  // specified in chains, but must keep it that way for compatibility.
331 
332  ReadAndVerifyInt(FilterLength);
333  ReadAndVerifyString(CurveName);
334  ReadAndVerifyBool(InterpLin);
336 
337  mM = FilterLength;
338  mCurveName = CurveName;
339  mLin = InterpLin;
340  mInterp = InterpMeth;
341 
342  if (InterpMeth >= nInterpolations)
343  {
344  InterpMeth -= nInterpolations;
345  }
346 
347  mEnvelope = (mLin ? mLinEnvelope : mLogEnvelope).get();
348 
349  return true;
350 }
Envelope * mEnvelope
Definition: Equalization.h:235
#define ReadAndVerifyEnum(name, list, listSize)
Definition: Effect.h:786
#define ReadAndVerifyInt(name)
Definition: Effect.h:797
std::unique_ptr< Envelope > mLogEnvelope
Definition: Equalization.h:234
static const IdentInterfaceSymbol kInterpStrings[nInterpolations]
#define ReadAndVerifyString(name)
Definition: Effect.h:801
std::unique_ptr< Envelope > mLinEnvelope
Definition: Equalization.h:234
#define ReadAndVerifyBool(name)
Definition: Effect.h:800
void EffectEqualization::setCurve ( int  currentCurve)
private

Definition at line 1616 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().

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

Definition at line 1782 of file Equalization.cpp.

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

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

Definition at line 1777 of file Equalization.cpp.

References mCurves.

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

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

Definition at line 2538 of file Equalization.cpp.

Referenced by GraphicEQ().

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

Definition at line 2560 of file Equalization.cpp.

Referenced by GraphicEQ().

2561 {
2562  wxASSERT( n > 1 );
2563 
2564  double a, b, h;
2565  static double xlast = 0.; // remember last x value requested
2566  static size_t k = 0; // and which interval we were in
2567 
2568  if( xr < xlast )
2569  k = 0; // gone back to start, (or somewhere to the left)
2570  xlast = xr;
2571  while( (x[k] <= xr) && (k + 1 < n) )
2572  k++;
2573  wxASSERT( k > 0 );
2574  k--;
2575  h = x[k+1] - x[k];
2576  a = ( x[k+1] - xr )/h;
2577  b = (xr - x[k])/h;
2578  return( a*y[k]+b*y[k+1]+((a*a*a-a)*y2[k]+(b*b*b-b)*y2[k+1])*h*h/6.);
2579 }
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 }
AudacityPrefs * gPrefs
Definition: Prefs.cpp:73
bool SaveUserPreset(const wxString &name) override
Definition: Effect.cpp:600
wxString GetCurrentSettingsGroup() override
Definition: Effect.cpp:801
bool SetPrivateConfig(const wxString &group, const wxString &key, const wxString &value) override
Definition: Effect.cpp:922
bool EffectEqualization::TransferDataFromWindow ( )
overridevirtual

Reimplemented from Effect.

Definition at line 996 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().

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

Reimplemented from Effect.

Definition at line 947 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().

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

Definition at line 2116 of file Equalization.cpp.

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

Referenced by OnManage(), and TransferDataToWindow().

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

Definition at line 1428 of file Equalization.cpp.

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

Referenced by LoadCurves().

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

Definition at line 2133 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().

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

Definition at line 2186 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().

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

Reimplemented from Effect.

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 macro, 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 macro, 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:2660
wxString GetCurrentSettingsGroup() override
Definition: Effect.cpp:801
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:922
std::unique_ptr< Envelope > mLogEnvelope
Definition: Equalization.h:234
EQCurveArray mCurves
Definition: Equalization.h:232
_("Move Track &Down")+wxT("\t")+(GetActiveProject() -> GetCommandManager() ->GetKeyFromName(wxT("TrackMoveDown")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveTopID, _("Move Track to &Top")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveTop")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveBottomID, _("Move Track to &Bottom")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveBottom")).Raw()), OnMoveTrack)#define SET_TRACK_NAME_PLUGIN_SYMBOLclass SetTrackNameCommand:public AudacityCommand
void EffectEqualization::WriteXML ( XMLWriter xmlFile) const
private

Definition at line 2049 of file Equalization.cpp.

Referenced by SaveCurves().

2051 {
2052  // Start our heirarchy
2053  xmlFile.StartTag( wxT( "equalizationeffect" ) );
2054 
2055  // Write all curves
2056  int numCurves = mCurves.size();
2057  int curve;
2058  for( curve = 0; curve < numCurves; curve++ )
2059  {
2060  // Start a NEW curve
2061  xmlFile.StartTag( wxT( "curve" ) );
2062  xmlFile.WriteAttr( wxT( "name" ), mCurves[ curve ].Name );
2063 
2064  // Write all points
2065  int numPoints = mCurves[ curve ].points.size();
2066  int point;
2067  for( point = 0; point < numPoints; point++ )
2068  {
2069  // Write NEW point
2070  xmlFile.StartTag( wxT( "point" ) );
2071  xmlFile.WriteAttr( wxT( "f" ), mCurves[ curve ].points[ point ].Freq, 12 );
2072  xmlFile.WriteAttr( wxT( "d" ), mCurves[ curve ].points[ point ].dB, 12 );
2073  xmlFile.EndTag( wxT( "point" ) );
2074  }
2075 
2076  // Terminate curve
2077  xmlFile.EndTag( wxT( "curve" ) );
2078  }
2079 
2080  // Terminate our heirarchy
2081  xmlFile.EndTag( wxT( "equalizationeffect" ) );
2082 }
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:232

Friends And Related Function Documentation

friend class EditCurvesDialog
friend

Definition at line 280 of file Equalization.h.

friend class EqualizationPanel
friend

Definition at line 279 of file Equalization.h.

Referenced by PopulateOrExchange().

Member Data Documentation

HFFT EffectEqualization::hFFT
private

Definition at line 207 of file Equalization.h.

Referenced by Filter().

size_t EffectEqualization::mBandsInUse
private

Definition at line 220 of file Equalization.h.

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

wxChoice* EffectEqualization::mCurve
private

Definition at line 264 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 228 of file Equalization.h.

Referenced by EnvelopeUpdated(), and ValidateUI().

bool EffectEqualization::mDisallowCustom
private

Definition at line 224 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 208 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 260 of file Equalization.h.

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

wxPanel* EffectEqualization::mGraphicPanel
private

Definition at line 258 of file Equalization.h.

Referenced by LayoutEQSliders(), and PopulateOrExchange().

wxCheckBox* EffectEqualization::mGridOnOff
private

Definition at line 262 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 263 of file Equalization.h.

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

wxSizerItem* EffectEqualization::mLeftSpacer
private

Definition at line 255 of file Equalization.h.

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

Definition at line 261 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 265 of file Equalization.h.

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

Definition at line 266 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 229 of file Equalization.h.

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

double EffectEqualization::mWhens[NUM_PTS]
private

Definition at line 218 of file Equalization.h.

Referenced by ErrMin(), and GraphicEQ().

double EffectEqualization::mWhenSliders[NUMBER_OF_BANDS+1]
private

Definition at line 219 of file Equalization.h.

Referenced by GraphicEQ(), and UpdateGraphic().

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

Definition at line 249 of file Equalization.h.

Referenced by PopulateOrExchange().

wxSizer* EffectEqualization::szr2
private

Definition at line 250 of file Equalization.h.

wxSizer* EffectEqualization::szr3
private

Definition at line 251 of file Equalization.h.

wxSizer* EffectEqualization::szr4
private

Definition at line 252 of file Equalization.h.

wxSizer* EffectEqualization::szr5
private

Definition at line 253 of file Equalization.h.

wxSizer* EffectEqualization::szrC
private

Definition at line 243 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 143 of file Equalization.h.

Referenced by ProcessOne().


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