58 constexpr auto nInterpolations =
61 if (
params.mInterp >= nInterpolations)
62 params.mInterp -= nInterpolations;
75{
XO(
"Equalization") };
84{
wxT(
"Filter Curve"),
XO(
"Filter Curve EQ") };
89{
wxT(
"Graphic EQ"),
XO(
"Graphic EQ") };
94 : mParameters{ GetDefinition() }
116 const auto t = trackList
117 ? *trackList->Any<
const WaveTrack >().first
147 return XO(
"Adjusts the volume levels of particular frequencies");
154 return L
"Graphic_EQ";
156 return L
"Filter_Curve_EQ";
157 return L
"Equalization";
175 int numPoints = curves[ 0 ].points.size();
177 for( point = 0; point < numPoints; point++ )
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 );
198 curves[0].points.clear();
200 for (
int i = 0; i < 200; i++)
202 const wxString nameFreq = wxString::Format(
"f%i",i);
203 const wxString nameVal = wxString::Format(
"v%i",i);
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 );
210 curves[0].points.push_back(
EQPoint( f,d ));
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\"") },
296 S.SetForWriting( &eap );
327 rate = (*(trackRange.first++)) ->
GetRate();
330 for (
auto track : trackRange) {
331 if (track->GetRate() != rate) {
334 "To apply Equalization, all selected tracks must have the same sample rate.") );
347 if (hiFreq <= loFreqI) {
349 XO(
"Track sample rate is too low for this effect."),
351 XO(
"Effect Unavailable") );
369 bool bGoodResult =
true;
373 double trackStart = track->GetStartTime();
374 double trackEnd = track->GetEndTime();
375 double t0 =
mT0 < trackStart? trackStart:
mT0;
376 double t1 =
mT1 > trackEnd? trackEnd:
mT1;
379 auto start = track->TimeToLongSamples(t0);
380 auto end = track->TimeToLongSamples(t1);
381 auto len =
end - start;
416 : buffer{ idealBlockLen }
417 , output{ t.EmptyCopy() }
418 , leftTailRemaining{ (M - 1) / 2 }
420 memset(lastWindow, 0, windowSize *
sizeof(
float));
425 auto leftTail =
std::min(len, leftTailRemaining);
426 leftTailRemaining -= leftTail;
428 buffer += leftTail *
sizeof(float);
439 float *thisWindow{ window1.get() };
440 float *lastWindow{ window2.get() };
459 wxASSERT(M - 1 < windowSize);
460 size_t L = windowSize - (M - 1);
463 if (idealBlockLen % L != 0)
464 idealBlockLen += (L - (idealBlockLen % L));
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;
473 auto originalLen = len;
475 auto &output = task.output;
479 bool bLoopSuccess =
true;
488 for(
size_t i = 0; i < block; i += L)
490 wcopy = std::min <size_t> (L, block - i);
491 for(
size_t j = 0; j < wcopy; j++)
492 thisWindow[j] = buffer[i+j];
493 for(
auto j = wcopy; j < windowSize; j++)
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];
507 task.AccumulateSamples((
samplePtr)buffer.get(), block);
512 originalLen.as_double()))
514 bLoopSuccess =
false;
522 if(wcopy < (M - 1)) {
527 for(; j < M - 1 - wcopy; j++)
528 buffer[j] = lastWindow[wcopy + j] + thisWindow[L + wcopy + j];
530 for( ; j < M - 1; j++)
531 buffer[j] = lastWindow[wcopy + j];
533 for(
size_t j = 0; j < M - 1; j++)
534 buffer[j] = lastWindow[wcopy + j];
536 task.AccumulateSamples((
samplePtr)buffer.get(), M - 1);
EffectDistortionSettings params
std::optional< std::unique_ptr< EffectSettingsAccess::Message > > OptionalMessage
static const struct @23 FactoryPresets[]
const TranslatableString name
const int kEqOptionGraphic
std::vector< RegistryPath > RegistryPaths
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)
static Settings & settings()
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.
std::shared_ptr< TrackList > mOutputTracks
void SetLinearEffectFlag(bool linearEffectFlag)
const TrackList * inputTracks() const
void ReplaceProcessedTracks(const bool bGoodResult)
const AudacityProject * FindProject() const
static const ComponentInterfaceSymbol Symbol
static const ComponentInterfaceSymbol Symbol
An Effect that modifies volume in different frequency bands.
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
OptionalMessage LoadFactoryDefaults(EffectSettings &settings) const override
bool Process(EffectInstance &instance, EffectSettings &settings) override
wxWeakRef< wxWindow > mUIParent
EffectEqualization(int Options=kEqLegacy)
EqualizationFilter mParameters
EqualizationCurvesList mCurvesList
static const ComponentInterfaceSymbol Symbol
ComponentInterfaceSymbol GetSymbol() const override
bool ProcessOne(int count, WaveTrack *t, sampleCount start, sampleCount len)
OptionalMessage LoadFactoryDefaults(EffectSettings &settings) const override
bool VisitSettings(SettingsVisitor &visitor, EffectSettings &settings) override
void CopyInputTracks(bool allSyncLockSelected=false)
bool TrackProgress(int whichTrack, double frac, const TranslatableString &={}) const
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.
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.
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.
SettingsVisitor that sets parameters to a value (from a string)
static TrackList & Get(AudacityProject &project)
auto Selected() -> TrackIterRange< TrackType >
Holds a msgid for the translation catalog; may also bind format arguments.
wxString Translation() const
A Track that contains audio waveform data.
void ConvertToSampleFormat(sampleFormat format, const std::function< void(size_t)> &progressReport={})
size_t GetMaxBlockSize() const override
This returns a nonnegative number of samples meant to size a memory buffer.
Positions or offsets within audio files need a wide type.
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
CommandManager::Options Options
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)
double GetRate(const Track &track)
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.
void LoadDefaults(int options)
static constexpr EnumParameter InterpMeth
static constexpr EffectParameter FilterLength
static constexpr EffectParameter InterpLin
void AccumulateSamples(constSamplePtr buffer, size_t len)
std::shared_ptr< WaveTrack > output
EqualizationTask(size_t M, size_t idealBlockLen, WaveTrack &t)