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 "EffectOutputTracks.h"
39#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 =
326 TrackList::Get(*project).Selected<const WaveTrack>();
327 if (trackRange) {
328 rate = (*(trackRange.first++)) -> GetRate();
329 ++selcount;
330
331 for (auto track : trackRange) {
332 if (track->GetRate() != rate) {
334 XO(
335 "To apply Equalization, all selected tracks must have the same sample rate.") );
336 return(false);
337 }
338 ++selcount;
339 }
340 }
341 }
342 else
343 // Editing macro parameters, use this default
344 rate = 44100.0;
345
346 hiFreq = rate / 2.0;
347 // Unlikely, but better than crashing.
348 if (hiFreq <= loFreqI) {
350 XO("Track sample rate is too low for this effect."),
351 wxOK | wxCENTRE,
352 XO("Effect Unavailable") );
353 return(false);
354 }
355
356 loFreq = loFreqI;
357
358 mUI.Init();
359 mUI.setCurve(curveName);
360
362
363 return(true);
364}
365
367 Task(size_t M, size_t idealBlockLen, WaveChannel &channel)
370 , output{ channel }
371 , leftTailRemaining{ (M - 1) / 2 }
372 {
373 memset(lastWindow, 0, windowSize * sizeof(float));
374 }
375
377 {
378 auto leftTail = std::min(len, leftTailRemaining);
379 leftTailRemaining -= leftTail;
380 len -= leftTail;
381 buffer += leftTail * sizeof(float);
383 }
384
388
390 const size_t idealBlockLen;
391
392 // These pointers are swapped after each FFT window
393 float *thisWindow{ window1.get() };
394 float *lastWindow{ window2.get() };
395
396 // a new WaveChannel to hold all of the output,
397 // including 'tails' each end
399
401};
402
404{
405 EffectOutputTracks outputs { *mTracks, GetType(), { { mT0, mT1 } } };
407 bool bGoodResult = true;
408
409 int count = 0;
410 for (auto track : outputs.Get().Selected<WaveTrack>()) {
411 double trackStart = track->GetStartTime();
412 double trackEnd = track->GetEndTime();
413 double t0 = mT0 < trackStart? trackStart: mT0;
414 double t1 = mT1 > trackEnd? trackEnd: mT1;
415
416 if (t1 > t0) {
417 auto start = track->TimeToLongSamples(t0);
418 auto end = track->TimeToLongSamples(t1);
419 auto len = end - start;
420
421 auto pTempTrack = track->EmptyCopy();
422 pTempTrack->ConvertToSampleFormat(floatSample);
423 auto iter0 = pTempTrack->Channels().begin();
424
425 for (const auto pChannel : track->Channels()) {
426 constexpr auto windowSize = EqualizationFilter::windowSize;
427 const auto &M = mParameters.mM;
428
429 wxASSERT(M - 1 < windowSize);
430 size_t L = windowSize - (M - 1); //Process L samples at a go
431 auto s = start;
432 auto idealBlockLen = pChannel->GetMaxBlockSize() * 4;
433 if (idealBlockLen % L != 0)
434 idealBlockLen += (L - (idealBlockLen % L));
435 auto pNewChannel = *iter0++;
436 Task task{ M, idealBlockLen, *pNewChannel };
437 bGoodResult = ProcessOne(task, count, *pChannel, start, len);
438 if (!bGoodResult)
439 goto done;
440 }
441 pTempTrack->Flush();
442 // Remove trailing data from the temp track
443 pTempTrack->Clear(t1 - t0, pTempTrack->GetEndTime());
444 track->ClearAndPaste(t0, t1, *pTempTrack, true, true);
445 }
446
447 count++;
448 }
449 done:
450
451 if (bGoodResult)
452 outputs.Commit();
453
454 return bGoodResult;
455}
456
457std::unique_ptr<EffectEditor> EffectEqualization::PopulateOrExchange(
458 ShuttleGui & S, EffectInstance &instance, EffectSettingsAccess &access,
459 const EffectOutputs *pOutputs)
460{
461 mUIParent = S.GetParent();
462 return mUI.PopulateOrExchange(S, instance, access, pOutputs);
463}
464
465//
466// Populate the window with relevant variables
467//
469{
471}
472
473// EffectEqualization implementation
474
476 int count, const WaveChannel &t, sampleCount start, sampleCount len)
477{
478 constexpr auto windowSize = EqualizationFilter::windowSize;
479
480 const auto &M = mParameters.mM;
481
482 wxASSERT(M - 1 < windowSize);
483 size_t L = windowSize - (M - 1); //Process L samples at a go
484 auto s = start;
485
486 auto &buffer = task.buffer;
487 auto &window1 = task.window1;
488 auto &window2 = task.window2;
489 auto &thisWindow = task.thisWindow;
490 auto &lastWindow = task.lastWindow;
491
492 auto originalLen = len;
493
494 auto &output = task.output;
495
496 TrackProgress(count, 0.);
497 bool bLoopSuccess = true;
498 size_t wcopy = 0;
499
500 while (len != 0)
501 {
502 auto block = limitSampleBufferSize( task.idealBlockLen, len );
503
504 t.GetFloats(buffer.get(), s, block);
505
506 for(size_t i = 0; i < block; i += L) //go through block in lumps of length L
507 {
508 wcopy = std::min <size_t> (L, block - i);
509 for(size_t j = 0; j < wcopy; j++)
510 thisWindow[j] = buffer[i+j]; //copy the L (or remaining) samples
511 for(auto j = wcopy; j < windowSize; j++)
512 thisWindow[j] = 0; //this includes the padding
513
514 mParameters.Filter(windowSize, thisWindow);
515
516 // Overlap - Add
517 for(size_t j = 0; (j < M - 1) && (j < wcopy); j++)
518 buffer[i+j] = thisWindow[j] + lastWindow[L + j];
519 for(size_t j = M - 1; j < wcopy; j++)
520 buffer[i+j] = thisWindow[j];
521
522 std::swap( thisWindow, lastWindow );
523 } //next i, lump of this block
524
525 task.AccumulateSamples((samplePtr)buffer.get(), block);
526 len -= block;
527 s += block;
528
529 if (TrackProgress(count, ( s - start ).as_double() /
530 originalLen.as_double()))
531 {
532 bLoopSuccess = false;
533 break;
534 }
535 }
536
537 if (bLoopSuccess) {
538 // M-1 samples of 'tail' left in lastWindow, get them now
539 if(wcopy < (M - 1)) {
540 // Still have some overlap left to process
541 // (note that lastWindow and thisWindow have been exchanged at this point
542 // so that 'thisWindow' is really the window prior to 'lastWindow')
543 size_t j = 0;
544 for(; j < M - 1 - wcopy; j++)
545 buffer[j] = lastWindow[wcopy + j] + thisWindow[L + wcopy + j];
546 // And fill in the remainder after the overlap
547 for( ; j < M - 1; j++)
548 buffer[j] = lastWindow[wcopy + j];
549 } else {
550 for(size_t j = 0; j < M - 1; j++)
551 buffer[j] = lastWindow[wcopy + j];
552 }
553 task.AccumulateSamples((samplePtr)buffer.get(), M - 1);
554 }
555 return bLoopSuccess;
556}
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
static const struct @21 FactoryPresets[]
const bool bForBoth
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
size_t limitSampleBufferSize(size_t bufferSize, sampleCount limit)
Definition: SampleCount.cpp:22
char * samplePtr
Definition: SampleFormat.h:57
const char * constSamplePtr
Definition: SampleFormat.h:58
static TranslatableStrings names
Definition: TagsEditor.cpp:153
const auto project
#define S(N)
Definition: ToChars.cpp:64
static Settings & settings()
Definition: TrackInfo.cpp:47
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:114
void SetLinearEffectFlag(bool linearEffectFlag)
Definition: EffectBase.cpp:210
const TrackList * inputTracks() const
Definition: EffectBase.h:91
double mProjectRate
Definition: EffectBase.h:110
std::shared_ptr< TrackList > mTracks
Definition: EffectBase.h:107
double mT0
Definition: EffectBase.h:113
const AudacityProject * FindProject() const
Definition: EffectBase.cpp:220
static const ComponentInterfaceSymbol Symbol
Definition: Equalization.h:87
static const ComponentInterfaceSymbol Symbol
Definition: Equalization.h:95
An Effect that modifies volume in different frequency bands.
Definition: Equalization.h:23
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:79
OptionalMessage LoadFactoryDefaults(EffectSettings &settings) const override
bool ProcessOne(Task &task, int count, const WaveChannel &t, sampleCount start, sampleCount len)
bool Process(EffectInstance &instance, EffectSettings &settings) override
wxWeakRef< wxWindow > mUIParent
Definition: Equalization.h:75
EffectEqualization(int Options=kEqLegacy)
EqualizationFilter mParameters
Definition: Equalization.h:76
EqualizationCurvesList mCurvesList
Definition: Equalization.h:77
static const ComponentInterfaceSymbol Symbol
Definition: Equalization.h:28
ComponentInterfaceSymbol GetSymbol() const override
const int mOptions
Definition: Equalization.h:78
bool Init() override
OptionalMessage LoadFactoryDefaults(EffectSettings &settings) const override
Definition: Effect.cpp:165
bool VisitSettings(SettingsVisitor &visitor, EffectSettings &settings) override
Definition: Effect.cpp:102
bool TrackProgress(int whichTrack, double frac, const TranslatableString &={}) const
Definition: Effect.cpp:343
Performs effect computation.
Use this object to copy the input tracks to tentative outputTracks.
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)
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:640
SettingsVisitor that sets parameters to a value (from a string)
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:314
auto Selected() -> TrackIterRange< TrackType >
Definition: Track.h:967
Holds a msgid for the translation catalog; may also bind format arguments.
wxString Translation() const
bool Append(constSamplePtr buffer, sampleFormat format, size_t len)
Definition: WaveTrack.cpp:2216
bool GetFloats(float *buffer, sampleCount start, size_t len, fillFormat fill=FillFormat::fillZero, bool mayThrow=true, sampleCount *pNumWithinClips=nullptr) const
"narrow" overload fetches from the unique channel
Definition: WaveTrack.h:129
A Track that contains audio waveform data.
Definition: WaveTrack.h:203
Positions or offsets within audio files need a wide type.
Definition: SampleCount.h:19
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:628
double GetRate(const Track &track)
Definition: TimeTrack.cpp:182
const char * end(const char *str) noexcept
Definition: StringUtils.h:106
void AccumulateSamples(constSamplePtr buffer, size_t len)
static constexpr auto windowSize
Task(size_t M, size_t idealBlockLen, WaveChannel &channel)
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