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 temp = track->WideEmptyCopy();
422 auto pTempTrack = *temp->Any<WaveTrack>().begin();
423 pTempTrack->ConvertToSampleFormat(floatSample);
424 auto iter0 = pTempTrack->Channels().begin();
425
426 for (const auto pChannel : track->Channels()) {
427 constexpr auto windowSize = EqualizationFilter::windowSize;
428 const auto &M = mParameters.mM;
429
430 wxASSERT(M - 1 < windowSize);
431 size_t L = windowSize - (M - 1); //Process L samples at a go
432 auto s = start;
433 auto idealBlockLen = pChannel->GetMaxBlockSize() * 4;
434 if (idealBlockLen % L != 0)
435 idealBlockLen += (L - (idealBlockLen % L));
436 auto pNewChannel = *iter0++;
437 Task task{ M, idealBlockLen, *pNewChannel };
438 bGoodResult = ProcessOne(task, count, *pChannel, start, len);
439 if (!bGoodResult)
440 goto done;
441 }
442 pTempTrack->Flush();
443 // Remove trailing data from the temp track
444 pTempTrack->Clear(t1 - t0, pTempTrack->GetEndTime());
445 track->ClearAndPaste(t0, t1, *pTempTrack, true, true);
446 }
447
448 count++;
449 }
450 done:
451
452 if (bGoodResult)
453 outputs.Commit();
454
455 return bGoodResult;
456}
457
458std::unique_ptr<EffectEditor> EffectEqualization::PopulateOrExchange(
459 ShuttleGui & S, EffectInstance &instance, EffectSettingsAccess &access,
460 const EffectOutputs *pOutputs)
461{
462 mUIParent = S.GetParent();
463 return mUI.PopulateOrExchange(S, instance, access, pOutputs);
464}
465
466//
467// Populate the window with relevant variables
468//
470{
472}
473
474// EffectEqualization implementation
475
477 int count, const WaveChannel &t, sampleCount start, sampleCount len)
478{
479 constexpr auto windowSize = EqualizationFilter::windowSize;
480
481 const auto &M = mParameters.mM;
482
483 wxASSERT(M - 1 < windowSize);
484 size_t L = windowSize - (M - 1); //Process L samples at a go
485 auto s = start;
486
487 auto &buffer = task.buffer;
488 auto &window1 = task.window1;
489 auto &window2 = task.window2;
490 auto &thisWindow = task.thisWindow;
491 auto &lastWindow = task.lastWindow;
492
493 auto originalLen = len;
494
495 auto &output = task.output;
496
497 TrackProgress(count, 0.);
498 bool bLoopSuccess = true;
499 size_t wcopy = 0;
500
501 while (len != 0)
502 {
503 auto block = limitSampleBufferSize( task.idealBlockLen, len );
504
505 t.GetFloats(buffer.get(), s, block);
506
507 for(size_t i = 0; i < block; i += L) //go through block in lumps of length L
508 {
509 wcopy = std::min <size_t> (L, block - i);
510 for(size_t j = 0; j < wcopy; j++)
511 thisWindow[j] = buffer[i+j]; //copy the L (or remaining) samples
512 for(auto j = wcopy; j < windowSize; j++)
513 thisWindow[j] = 0; //this includes the padding
514
515 mParameters.Filter(windowSize, thisWindow);
516
517 // Overlap - Add
518 for(size_t j = 0; (j < M - 1) && (j < wcopy); j++)
519 buffer[i+j] = thisWindow[j] + lastWindow[L + j];
520 for(size_t j = M - 1; j < wcopy; j++)
521 buffer[i+j] = thisWindow[j];
522
523 std::swap( thisWindow, lastWindow );
524 } //next i, lump of this block
525
526 task.AccumulateSamples((samplePtr)buffer.get(), block);
527 len -= block;
528 s += block;
529
530 if (TrackProgress(count, ( s - start ).as_double() /
531 originalLen.as_double()))
532 {
533 bLoopSuccess = false;
534 break;
535 }
536 }
537
538 if (bLoopSuccess) {
539 // M-1 samples of 'tail' left in lastWindow, get them now
540 if(wcopy < (M - 1)) {
541 // Still have some overlap left to process
542 // (note that lastWindow and thisWindow have been exchanged at this point
543 // so that 'thisWindow' is really the window prior to 'lastWindow')
544 size_t j = 0;
545 for(; j < M - 1 - wcopy; j++)
546 buffer[j] = lastWindow[wcopy + j] + thisWindow[L + wcopy + j];
547 // And fill in the remainder after the overlap
548 for( ; j < M - 1; j++)
549 buffer[j] = lastWindow[wcopy + j];
550 } else {
551 for(size_t j = 0; j < M - 1; j++)
552 buffer[j] = lastWindow[wcopy + j];
553 }
554 task.AccumulateSamples((samplePtr)buffer.get(), M - 1);
555 }
556 return bLoopSuccess;
557}
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
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:69
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:116
void SetLinearEffectFlag(bool linearEffectFlag)
Definition: EffectBase.cpp:215
const TrackList * inputTracks() const
Definition: EffectBase.h:91
double mProjectRate
Definition: EffectBase.h:112
std::shared_ptr< TrackList > mTracks
Definition: EffectBase.h:109
double mT0
Definition: EffectBase.h:115
const AudacityProject * FindProject() const
Definition: EffectBase.cpp:225
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:630
SettingsVisitor that sets parameters to a value (from a string)
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:347
auto Selected() -> TrackIterRange< TrackType >
Definition: Track.h:1096
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:2656
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:154
A Track that contains audio waveform data.
Definition: WaveTrack.h:222
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
auto begin(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Definition: PackedArray.h:150
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:645
double GetRate(const Track &track)
Definition: TimeTrack.cpp:196
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