Audacity 3.2.0
Equalization.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 Equalization.cpp
6
7 Mitch Golden
8 Vaughan Johnson (Preview)
9 Martyn Shaw (FIR filters, response curve, graphic EQ)
10
11*******************************************************************//****************************************************************//*******************************************************************/
35#include "Equalization.h"
36#include "EqualizationUI.h"
37#include "EffectEditor.h"
38#include "LoadEffects.h"
40#include "ShuttleGui.h"
41
42#include "WaveClip.h"
43#include "WaveTrack.h"
44
46{
49 // CurveName,
51 // Pretty sure the interpolation name shouldn't have been interpreted when
52 // specified in chains, but must keep it that way for compatibility.
54 > parameters {
56 EqualizationParameters &params, bool updating
57 ){
58 constexpr auto nInterpolations =
60 if (updating) {
61 if (params.mInterp >= nInterpolations)
62 params.mInterp -= nInterpolations;
63 }
64 return true;
65 }
66 };
67 return parameters;
68}
69
71// EffectEqualization
72//----------------------------------------------------------------------------
73
75{ XO("Equalization") };
76
77#ifdef LEGACY_EQ
79#endif
80
81// "Filter Curve EQ" in the user-facing string, but preserve the old
82// internal string
84{ wxT("Filter Curve"), XO("Filter Curve EQ") };
85
87
89{ wxT("Graphic EQ"), XO("Graphic EQ") };
90
92
94 : mParameters{ GetDefinition() }
95 , mOptions{ Options }
96{
97 auto &hiFreq = mParameters.mHiFreq;
98 auto &curves = mCurvesList.mCurves;
99
100 Parameters().Reset(*this);
101
103
104 // Load the EQ curves
105 EQCurveReader{ curves, GetName(), mOptions }.LoadCurves();
106
107 // Note: initial curve is set in TransferDataToWindow
108
109 //double loLog = log10(mLoFreq);
110 //double stepLog = (log10(hiFreq) - loLog)/((double)NUM_PTS-1.);
111
112 // We expect these Hi and Lo frequencies to be overridden by Init().
113 // Don't use inputTracks(). See bug 2321.
114#if 0
115 auto trackList = inputTracks();
116 const auto t = trackList
117 ? *trackList->Any< const WaveTrack >().first
118 : nullptr
119 ;
120 hiFreq =
121 (t
122 ? t->GetRate()
123 : mProjectRate)
124 / 2.0;
125#endif
126 hiFreq = mProjectRate / 2.0;
127}
128
129
131{
132}
133
134// ComponentInterface implementation
135
137{
140 if( mOptions == kEqOptionCurve )
143}
144
146{
147 return XO("Adjusts the volume levels of particular frequencies");
148}
149
151{
152 // Bug 2509: Must use _ and not space in names.
154 return L"Graphic_EQ";
155 if( mOptions == kEqOptionCurve )
156 return L"Filter_Curve_EQ";
157 return L"Equalization";
158}
159
160// EffectDefinitionInterface implementation
161
163{
164 return EffectTypeProcess;
165}
166
168 ConstSettingsVisitor &visitor, const EffectSettings &settings) const
169{
170 const auto &curves = mCurvesList.mCurves;
172
173 // Curve point parameters -- how many isn't known statically
174 if( dynamic_cast<ShuttleGetAutomation*>(&visitor)) {
175 int numPoints = curves[ 0 ].points.size();
176 int point;
177 for( point = 0; point < numPoints; point++ )
178 {
179 const wxString nameFreq = wxString::Format("f%i",point);
180 const wxString nameVal = wxString::Format("v%i",point);
181 visitor.Define( curves[ 0 ].points[ point ].Freq, nameFreq,
182 0.0, 0.0, 0.0, 0.0 );
183 visitor.Define( curves[ 0 ].points[ point ].dB, nameVal,
184 0.0, 0.0, 0.0, 0.0 );
185 }
186 }
187 return true;
188}
189
192{
193 auto &curves = mCurvesList.mCurves;
195
196 // Curve point parameters -- how many isn't known statically
197 {
198 curves[0].points.clear();
199
200 for (int i = 0; i < 200; i++)
201 {
202 const wxString nameFreq = wxString::Format("f%i",i);
203 const wxString nameVal = wxString::Format("v%i",i);
204 double f = -1000.0;
205 double d = 0.0;
206 visitor.Define( f, nameFreq, 0.0, -10000.0, 1000000.0, 0.0 );
207 visitor.Define( d, nameVal, 0.0, -10000.0, 10000.0, 0.0 );
208 if( f <= 0.0 )
209 break;
210 curves[0].points.push_back( EQPoint( f,d ));
211 }
212 mUI.setCurve( 0 );
213 }
214 return true;
215}
216
219{
220 // To do: externalize state so const_cast isn't needed
221 if (!const_cast<EffectEqualization&>(*this).DoLoadFactoryDefaults(settings))
222 return {};
223 return { nullptr };
224}
225
228{
231}
232
233// Constants determining who the prests are for.
234const bool kCURVE = false;
235const bool kBOTH = true;
236
237static const struct
238{
239 const bool bForBoth; // more extended set is used for Filter EQ
240 // See Bug 2254 for rationale.
242 const wxChar *values;
243}
245{
246 { kCURVE, XO("100Hz Rumble"), wxT("f0=\"20.0\" v0=\"-80.0\" f1=\"49.237316986327\" v1=\"-33.107692718506\" f2=\"54.196034330446\" v2=\"-29.553844451904\" f3=\"88.033573501041\" v3=\"-6.923076629639\" f4=\"95.871851182279\" v4=\"-4.523078918457\" f5=\"108.957037410504\" v5=\"-1.938461303711\" f6=\"123.828171198057\" v6=\"-0.73846244812\" f7=\"149.228077614658\" v7=\"-0.092308044434\"") },
247 { kCURVE, XO("AM Radio"), wxT("f0=\"20.0\" v0=\"-63.67\" f1=\"31.0\" v1=\"-33.219\" f2=\"50.0\" v2=\"-3.01\" f3=\"63.0\" v3=\"-0.106\" f4=\"100.0\" v4=\"0.0\" f5=\"2500.0\" v5=\"0.0\" f6=\"4000.0\" v6=\"-0.614\" f7=\"5000.0\" v7=\"-8.059\" f8=\"8000.0\" v8=\"-39.981\" f9=\"20000.0\" v9=\"-103.651\" f10=\"48000.0\" v10=\"-164.485\"") },
248 { kBOTH, XO("Bass Boost"), wxT("f0=\"100.0\" v0=\"9.0\" f1=\"500.0\" v1=\"0.0\"") },
249 { kBOTH, XO("Bass Cut"), wxT("f0=\"150.0\" v0=\"-50.0\" f1=\"300.0\" v1=\"0.0\"") },
250 { kCURVE, XO("Low rolloff for speech"), wxT("f0=\"50.0\" v0=\"-120.0\" f1=\"60.0\" v1=\"-50.0\" f2=\"65.0\" v2=\"-24.0\" f3=\"70.0\" v3=\"-12.0\" f4=\"80.0\" v4=\"-4.0\" f5=\"90.0\" v5=\"-1.0\" f6=\"100.0\" v6=\"0.0\"") },
251 { kBOTH, XO("RIAA"), wxT("f0=\"20.0\" v0=\"19.274\" f1=\"25.0\" v1=\"18.954\" f2=\"31.0\" v2=\"18.516\" f3=\"40.0\" v3=\"17.792\" f4=\"50.0\" v4=\"16.946\" f5=\"63.0\" v5=\"15.852\" f6=\"80.0\" v6=\"14.506\" f7=\"100.0\" v7=\"13.088\" f8=\"125.0\" v8=\"11.563\" f9=\"160.0\" v9=\"9.809\" f10=\"200.0\" v10=\"8.219\" f11=\"250.0\" v11=\"6.677\" f12=\"315.0\" v12=\"5.179\" f13=\"400.0\" v13=\"3.784\" f14=\"500.0\" v14=\"2.648\" f15=\"630.0\" v15=\"1.642\" f16=\"800.0\" v16=\"0.751\" f17=\"1000.0\" v17=\"0.0\" f18=\"1250.0\" v18=\"-0.744\" f19=\"1600.0\" v19=\"-1.643\" f20=\"2000.0\" v20=\"-2.589\" f21=\"2500.0\" v21=\"-3.7\" f22=\"3150.0\" v22=\"-5.038\" f23=\"4000.0\" v23=\"-6.605\" f24=\"5000.0\" v24=\"-8.21\" f25=\"6300.0\" v25=\"-9.98\" f26=\"8000.0\" v26=\"-11.894\" f27=\"10000.0\" v27=\"-13.734\" f28=\"12500.0\" v28=\"-15.609\" f29=\"16000.0\" v29=\"-17.708\" f30=\"20000.0\" v30=\"-19.62\" f31=\"25000.0\" v31=\"-21.542\" f32=\"48000.0\" v32=\"-27.187\"") },
252 { kCURVE, XO("Telephone"), wxT("f0=\"20.0\" v0=\"-94.087\" f1=\"200.0\" v1=\"-14.254\" f2=\"250.0\" v2=\"-7.243\" f3=\"315.0\" v3=\"-2.245\" f4=\"400.0\" v4=\"-0.414\" f5=\"500.0\" v5=\"0.0\" f6=\"2500.0\" v6=\"0.0\" f7=\"3150.0\" v7=\"-0.874\" f8=\"4000.0\" v8=\"-3.992\" f9=\"5000.0\" v9=\"-9.993\" f10=\"48000.0\" v10=\"-88.117\"") },
253 { kBOTH, XO("Treble Boost"), wxT("f0=\"4000.0\" v0=\"0.0\" f1=\"5000.0\" v1=\"9.0\"") },
254 { kBOTH, XO("Treble Cut"), wxT("f0=\"6000.0\" v0=\"0.0\" f1=\"10000.0\" v1=\"-110.0\"") },
255 { kCURVE, XO("Walkie-talkie"), wxT("f0=\"100.0\" v0=\"-120.0\" f1=\"101.0\" v1=\"0.0\" f2=\"2000.0\" v2=\"0.0\" f3=\"2001.0\" v3=\"-120.0\"") },
257
258
259
260
262{
264
265 for (size_t i = 0; i < WXSIZEOF(FactoryPresets); i++)
266 {
267 if ((mOptions == kEqOptionGraphic) && (FactoryPresets[i].bForBoth == false))
268 continue;
269 names.push_back(FactoryPresets[i].name.Translation());
270 }
271
272 return names;
273}
274
277{
278 int index = -1;
279 for (size_t i = 0; i < WXSIZEOF(FactoryPresets); i++)
280 {
281 if ((mOptions == kEqOptionGraphic) && (FactoryPresets[i].bForBoth == false))
282 continue;
283 if (id-- == 0) {
284 index = i;
285 break;
286 }
287 }
288 if (index < 0)
289 return {};
290
291 // mParams =
292 wxString params = FactoryPresets[index].values;
293
296 S.SetForWriting( &eap );
297 // To do: externalize state so const_cast isn't needed
298 if (!const_cast<EffectEqualization*>(this)->VisitSettings(S, settings))
299 return {};
300 return { nullptr };
301}
302
304 const EffectPlugin &, EffectSettings &settings) const
305{
306 // Stateful effect still cheats const_cast!
307 return const_cast<EffectEqualization&>(*this).mUI.ValidateUI(settings);
308}
309
310// Effect implementation
311
313{
314 constexpr auto loFreqI = EqualizationFilter::loFreqI;
315
316 const auto &lin = mParameters.mLin;
317 const auto &curveName = mParameters.mCurveName;
318 auto &loFreq = mParameters.mLoFreq;
319 auto &hiFreq = mParameters.mHiFreq;
320
321 int selcount = 0;
322 double rate = 0.0;
323
324 if (const auto project = FindProject()) {
325 auto trackRange = TrackList::Get(*project).Selected<const WaveTrack>();
326 if (trackRange) {
327 rate = (*(trackRange.first++)) -> GetRate();
328 ++selcount;
329
330 for (auto track : trackRange) {
331 if (track->GetRate() != rate) {
333 XO(
334 "To apply Equalization, all selected tracks must have the same sample rate.") );
335 return(false);
336 }
337 ++selcount;
338 }
339 }
340 }
341 else
342 // Editing macro parameters, use this default
343 rate = 44100.0;
344
345 hiFreq = rate / 2.0;
346 // Unlikely, but better than crashing.
347 if (hiFreq <= loFreqI) {
349 XO("Track sample rate is too low for this effect."),
350 wxOK | wxCENTRE,
351 XO("Effect Unavailable") );
352 return(false);
353 }
354
355 loFreq = loFreqI;
356
357 mUI.Init();
358 mUI.setCurve(curveName);
359
361
362 return(true);
363}
364
366{
367 this->CopyInputTracks(); // Set up mOutputTracks.
369 bool bGoodResult = true;
370
371 int count = 0;
372 for( auto track : mOutputTracks->Selected< WaveTrack >() ) {
373 double trackStart = track->GetStartTime();
374 double trackEnd = track->GetEndTime();
375 double t0 = mT0 < trackStart? trackStart: mT0;
376 double t1 = mT1 > trackEnd? trackEnd: mT1;
377
378 if (t1 > t0) {
379 auto start = track->TimeToLongSamples(t0);
380 auto end = track->TimeToLongSamples(t1);
381 auto len = end - start;
382
383 if (!ProcessOne(count, track, start, len))
384 {
385 bGoodResult = false;
386 break;
387 }
388 }
389
390 count++;
391 }
392
393 this->ReplaceProcessedTracks(bGoodResult);
394 return bGoodResult;
395}
396
397std::unique_ptr<EffectEditor> EffectEqualization::PopulateOrExchange(
398 ShuttleGui & S, EffectInstance &instance, EffectSettingsAccess &access,
399 const EffectOutputs *pOutputs)
400{
401 mUIParent = S.GetParent();
402 return mUI.PopulateOrExchange(S, instance, access, pOutputs);
403}
404
405//
406// Populate the window with relevant variables
407//
409{
411}
412
413namespace {
415 EqualizationTask( size_t M, size_t idealBlockLen, WaveTrack &t )
416 : buffer{ idealBlockLen }
417 , output{ t.EmptyCopy() }
418 , leftTailRemaining{ (M - 1) / 2 }
419 {
420 memset(lastWindow, 0, windowSize * sizeof(float));
421 }
422
423 void AccumulateSamples(constSamplePtr buffer, size_t len)
424 {
425 auto leftTail = std::min(len, leftTailRemaining);
426 leftTailRemaining -= leftTail;
427 len -= leftTail;
428 buffer += leftTail * sizeof(float);
429 output->Append(buffer, floatSample, len);
430 }
431
432 static constexpr auto windowSize = EqualizationFilter::windowSize;
433 Floats window1{ windowSize };
434 Floats window2{ windowSize };
435
437
438 // These pointers are swapped after each FFT window
439 float *thisWindow{ window1.get() };
440 float *lastWindow{ window2.get() };
441
442 // create a NEW WaveTrack to hold all of the output,
443 // including 'tails' each end
444 std::shared_ptr<WaveTrack> output;
445
447};
448}
449
450// EffectEqualization implementation
451
453 sampleCount start, sampleCount len)
454{
455 constexpr auto windowSize = EqualizationFilter::windowSize;
456
457 const auto &M = mParameters.mM;
458
459 wxASSERT(M - 1 < windowSize);
460 size_t L = windowSize - (M - 1); //Process L samples at a go
461 auto s = start;
462 auto idealBlockLen = t->GetMaxBlockSize() * 4;
463 if (idealBlockLen % L != 0)
464 idealBlockLen += (L - (idealBlockLen % L));
465
466 EqualizationTask task{ M, idealBlockLen, *t };
467 auto &buffer = task.buffer;
468 auto &window1 = task.window1;
469 auto &window2 = task.window2;
470 auto &thisWindow = task.thisWindow;
471 auto &lastWindow = task.lastWindow;
472
473 auto originalLen = len;
474
475 auto &output = task.output;
477
478 TrackProgress(count, 0.);
479 bool bLoopSuccess = true;
480 size_t wcopy = 0;
481
482 while (len != 0)
483 {
484 auto block = limitSampleBufferSize( idealBlockLen, len );
485
486 t->GetFloats(buffer.get(), s, block);
487
488 for(size_t i = 0; i < block; i += L) //go through block in lumps of length L
489 {
490 wcopy = std::min <size_t> (L, block - i);
491 for(size_t j = 0; j < wcopy; j++)
492 thisWindow[j] = buffer[i+j]; //copy the L (or remaining) samples
493 for(auto j = wcopy; j < windowSize; j++)
494 thisWindow[j] = 0; //this includes the padding
495
496 mParameters.Filter(windowSize, thisWindow);
497
498 // Overlap - Add
499 for(size_t j = 0; (j < M - 1) && (j < wcopy); j++)
500 buffer[i+j] = thisWindow[j] + lastWindow[L + j];
501 for(size_t j = M - 1; j < wcopy; j++)
502 buffer[i+j] = thisWindow[j];
503
504 std::swap( thisWindow, lastWindow );
505 } //next i, lump of this block
506
507 task.AccumulateSamples((samplePtr)buffer.get(), block);
508 len -= block;
509 s += block;
510
511 if (TrackProgress(count, ( s - start ).as_double() /
512 originalLen.as_double()))
513 {
514 bLoopSuccess = false;
515 break;
516 }
517 }
518
519 if(bLoopSuccess)
520 {
521 // M-1 samples of 'tail' left in lastWindow, get them now
522 if(wcopy < (M - 1)) {
523 // Still have some overlap left to process
524 // (note that lastWindow and thisWindow have been exchanged at this point
525 // so that 'thisWindow' is really the window prior to 'lastWindow')
526 size_t j = 0;
527 for(; j < M - 1 - wcopy; j++)
528 buffer[j] = lastWindow[wcopy + j] + thisWindow[L + wcopy + j];
529 // And fill in the remainder after the overlap
530 for( ; j < M - 1; j++)
531 buffer[j] = lastWindow[wcopy + j];
532 } else {
533 for(size_t j = 0; j < M - 1; j++)
534 buffer[j] = lastWindow[wcopy + j];
535 }
536 task.AccumulateSamples((samplePtr)buffer.get(), M - 1);
537 output->Flush();
538 }
539
540 if (bLoopSuccess)
541 PasteOverPreservingClips(*t, start, originalLen, *output);
542
543 return bLoopSuccess;
544}
wxT("CloseDown"))
int min(int a, int b)
EffectDistortionSettings params
Definition: Distortion.cpp:77
EffectType
@ EffectTypeProcess
std::optional< std::unique_ptr< EffectSettingsAccess::Message > > OptionalMessage
const bool kBOTH
const bool bForBoth
static const struct @23 FactoryPresets[]
const wxChar * values
const TranslatableString name
const bool kCURVE
const int kEqOptionCurve
const int kEqOptionGraphic
XO("Cut/Copy/Paste")
std::vector< RegistryPath > RegistryPaths
Definition: Identifier.h:219
void PasteOverPreservingClips(WaveTrack &oldTrack, sampleCount start, sampleCount len, WaveTrack &newContents)
Substitute new contents into existing track, preserving clip boundaries.
size_t limitSampleBufferSize(size_t bufferSize, sampleCount limit)
Definition: SampleCount.cpp:22
char * samplePtr
Definition: SampleFormat.h:55
const char * constSamplePtr
Definition: SampleFormat.h:56
static TranslatableStrings names
Definition: TagsEditor.cpp:152
#define S(N)
Definition: ToChars.cpp:64
static Settings & settings()
Definition: TrackInfo.cpp:83
Generates EffectParameterMethods overrides from variadic template arguments.
CommandParameters, derived from wxFileConfig, is essentially doing the same things as the SettingsVis...
TranslatableString GetName() const
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
Deserializer of curves from XML files.
One point in a curve.
double mT1
Definition: EffectBase.h:119
std::shared_ptr< TrackList > mOutputTracks
Definition: EffectBase.h:97
void SetLinearEffectFlag(bool linearEffectFlag)
Definition: EffectBase.cpp:211
const TrackList * inputTracks() const
Definition: EffectBase.h:94
double mProjectRate
Definition: EffectBase.h:115
double mT0
Definition: EffectBase.h:118
void ReplaceProcessedTracks(const bool bGoodResult)
Definition: EffectBase.cpp:224
const AudacityProject * FindProject() const
Definition: EffectBase.cpp:303
static const ComponentInterfaceSymbol Symbol
Definition: Equalization.h:84
static const ComponentInterfaceSymbol Symbol
Definition: Equalization.h:92
An Effect that modifies volume in different frequency bands.
Definition: Equalization.h:21
RegistryPaths GetFactoryPresets() const override
Report names of factory presets.
OptionalMessage DoLoadFactoryDefaults(EffectSettings &settings)
const EffectParameterMethods & Parameters() const override
virtual ~EffectEqualization()
std::unique_ptr< EffectEditor > PopulateOrExchange(ShuttleGui &S, EffectInstance &instance, EffectSettingsAccess &access, const EffectOutputs *pOutputs) override
Add controls to effect panel; always succeeds.
OptionalMessage LoadFactoryPreset(int id, EffectSettings &settings) const override
EffectType GetType() const override
Type determines how it behaves.
bool TransferDataToWindow(const EffectSettings &settings) override
bool VisitSettings(SettingsVisitor &visitor, EffectSettings &settings) override
ManualPageID ManualPage() const override
Name of a page in the Audacity alpha manual, default is empty.
bool ValidateUI(const EffectPlugin &plugin, EffectSettings &) const override
TranslatableString GetDescription() const override
EqualizationUI mUI
Definition: Equalization.h:76
OptionalMessage LoadFactoryDefaults(EffectSettings &settings) const override
bool Process(EffectInstance &instance, EffectSettings &settings) override
wxWeakRef< wxWindow > mUIParent
Definition: Equalization.h:72
EffectEqualization(int Options=kEqLegacy)
EqualizationFilter mParameters
Definition: Equalization.h:73
EqualizationCurvesList mCurvesList
Definition: Equalization.h:74
static const ComponentInterfaceSymbol Symbol
Definition: Equalization.h:26
ComponentInterfaceSymbol GetSymbol() const override
const int mOptions
Definition: Equalization.h:75
bool Init() override
bool ProcessOne(int count, WaveTrack *t, sampleCount start, sampleCount len)
OptionalMessage LoadFactoryDefaults(EffectSettings &settings) const override
Definition: Effect.cpp:173
bool VisitSettings(SettingsVisitor &visitor, EffectSettings &settings) override
Definition: Effect.cpp:110
void CopyInputTracks(bool allSyncLockSelected=false)
Definition: Effect.cpp:400
bool TrackProgress(int whichTrack, double frac, const TranslatableString &={}) const
Definition: Effect.cpp:350
Performs effect computation.
Hold values to send to effect output meters.
Interface for manipulations of an Effect's settings.
virtual void Reset(Effect &effect) const =0
Factory of instances of an effect.
Definition: EffectPlugin.h:36
static int DoMessageBox(const EffectPlugin &plugin, const TranslatableString &message, long style=DefaultMessageBoxStyle, const TranslatableString &titleStr={})
void setCurve(int currentCurve)
bool ValidateUI(EffectSettings &settings)
std::unique_ptr< EffectEditor > PopulateOrExchange(ShuttleGui &S, EffectInstance &instance, EffectSettingsAccess &access, const EffectOutputs *pOutputs)
bool TransferDataToWindow(const EffectSettings &settings)
bool GetFloats(float *buffer, sampleCount start, size_t len, fillFormat fill=fillZero, bool mayThrow=true, sampleCount *pNumWithinClips=nullptr) const
Retrieve samples from a track in floating-point format, regardless of the storage format.
Definition: SampleTrack.h:83
Visitor of effect or command parameters. This is a base class with lots of virtual functions that do ...
virtual void Define(Arg< bool > var, const wxChar *key, bool vdefault, bool vmin=false, bool vmax=false, bool vscl=false)
SettingsVisitor that gets parameter values into a string.
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:625
SettingsVisitor that sets parameters to a value (from a string)
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:360
auto Selected() -> TrackIterRange< TrackType >
Definition: Track.h:1319
Holds a msgid for the translation catalog; may also bind format arguments.
wxString Translation() const
A Track that contains audio waveform data.
Definition: WaveTrack.h:51
void ConvertToSampleFormat(sampleFormat format, const std::function< void(size_t)> &progressReport={})
Definition: WaveTrack.cpp:501
size_t GetMaxBlockSize() const override
This returns a nonnegative number of samples meant to size a memory buffer.
Definition: WaveTrack.cpp:1647
Positions or offsets within audio files need a wide type.
Definition: SampleCount.h:19
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Definition: PackedArray.h:159
BuiltinCommandsModule::Registration< CompareAudioCommand > reg
BuiltinEffectsModule::Registration< EffectEqualizationCurve > reg2
BuiltinEffectsModule::Registration< EffectEqualizationGraphic > reg3
void swap(std::unique_ptr< Alg_seq > &a, std::unique_ptr< Alg_seq > &b)
Definition: NoteTrack.cpp:752
double GetRate(const Track &track)
Definition: TimeTrack.cpp:179
Externalized state of a plug-in.
static constexpr int loFreqI
static constexpr size_t windowSize
void Filter(size_t len, float *buffer) const
Parameters of the Equalization effects that persist in configuration files.
static constexpr EnumParameter InterpMeth
static constexpr EffectParameter FilterLength
static constexpr EffectParameter InterpLin
void AccumulateSamples(constSamplePtr buffer, size_t len)
EqualizationTask(size_t M, size_t idealBlockLen, WaveTrack &t)