25 {
XO(
"Hard Clipping") }, {
XO(
"Soft Clipping") },
26 {
XO(
"Soft Overdrive") }, {
XO(
"Medium Overdrive") },
27 {
XO(
"Hard Overdrive") }, {
XO(
"Cubic Curve (odd harmonics)") },
28 {
XO(
"Even Harmonics") }, {
XO(
"Expand and Compress") },
29 {
XO(
"Leveller") }, {
XO(
"Rectifier Distortion") },
30 {
XO(
"Hard Limiter 1413") }
43#define skipsamples 1000
56 {
XO(
"Hard clip -12dB, 80% make-up gain"), { 0, 0, -12.0, -70.0, 0.0, 80.0, 0 } },
58 {
XO(
"Soft clip -12dB, 80% make-up gain"), { 1, 0, -12.0, -70.0, 50.0, 80.0, 0 } },
59 {
XO(
"Fuzz Box"), { 1, 0, -30.0, -70.0, 80.0, 80.0, 0 } },
60 {
XO(
"Walkie-talkie"), { 1, 0, -50.0, -70.0, 60.0, 80.0, 0 } },
61 {
XO(
"Blues drive sustain"), { 2, 0, -6.0, -70.0, 30.0, 80.0, 0 } },
62 {
XO(
"Light Crunch Overdrive"), { 3, 0, -6.0, -70.0, 20.0, 80.0, 0 } },
63 {
XO(
"Heavy Overdrive"), { 4, 0, -6.0, -70.0, 90.0, 80.0, 0 } },
64 {
XO(
"3rd Harmonic (Perfect Fifth)"), { 5, 0, -6.0, -70.0, 100.0, 60.0, 0 } },
65 {
XO(
"Valve Overdrive"), { 6, 1, -6.0, -70.0, 30.0, 40.0, 0 } },
66 {
XO(
"2nd Harmonic (Octave)"), { 6, 1, -6.0, -70.0, 50.0, 0.0, 0 } },
67 {
XO(
"Gated Expansion Distortion"), { 7, 0, -6.0, -70.0, 30.0, 80.0, 0 } },
68 {
XO(
"Leveller, Light, -70dB noise floor"), { 8, 0, -6.0, -70.0, 0.0, 50.0, 1 } },
69 {
XO(
"Leveller, Moderate, -70dB noise floor"), { 8, 0, -6.0, -70.0, 0.0, 50.0, 2 } },
70 {
XO(
"Leveller, Heavy, -70dB noise floor"), { 8, 0, -6.0, -70.0, 0.0, 50.0, 3 } },
71 {
XO(
"Leveller, Heavier, -70dB noise floor"), { 8, 0, -6.0, -70.0, 0.0, 50.0, 4 } },
72 {
XO(
"Leveller, Heaviest, -70dB noise floor"), { 8, 0, -6.0, -70.0, 0.0, 50.0, 5 } },
73 {
XO(
"Half-wave Rectifier"), { 9, 0, -6.0, -70.0, 50.0, 50.0, 0 } },
74 {
XO(
"Full-wave Rectifier"), { 9, 0, -6.0, -70.0, 100.0, 50.0, 0 } },
75 {
XO(
"Full-wave Rectifier (DC blocked)"), { 9, 1, -6.0, -70.0, 100.0, 50.0, 0 } },
76 {
XO(
"Percussion Limiter"), {10, 0, -12.0, -70.0, 100.0, 30.0, 0 } },
84 return std::make_shared<Instance>(*
this);
107 return XO(
"Waveshaping distortion effect");
112 return L
"Distortion";
146 float*
const* outBlock,
size_t blockLen)
148 return InstanceProcess(
settings, mMaster, inBlock, outBlock, blockLen);
165 mSlaves.push_back(slave);
179 float*
const* outbuf,
size_t numSamples)
181 if (group >= mSlaves.size())
183 return InstanceProcess(
settings, mSlaves[group], inbuf, outbuf, numSamples);
247 const float*
const* inBlock,
float*
const* outBlock,
size_t blockLen)
251 const float* ibuf = inBlock[0];
252 float* obuf = outBlock[0];
262 double p1 = ms.mParam1 / 100.0;
263 double p2 = ms.mParam2 / 100.0;
271 for (
decltype(blockLen) i = 0; i < blockLen; i++)
278 switch (ms.mTableChoiceIndx)
283 WaveShaper(ibuf[i], ms) * ((1 - p2) + (data.
mMakeupGain * p2));
288 WaveShaper(ibuf[i], ms) * ((1 - p2) + (data.
mMakeupGain * p2));
291 obuf[i] = WaveShaper(ibuf[i], ms) * p2;
294 obuf[i] = WaveShaper(ibuf[i], ms) * p2;
297 obuf[i] = WaveShaper(ibuf[i], ms) * p2;
300 obuf[i] = WaveShaper(ibuf[i], ms) * p2;
303 obuf[i] = WaveShaper(ibuf[i], ms);
306 obuf[i] = WaveShaper(ibuf[i], ms) * p2;
309 obuf[i] = WaveShaper(ibuf[i], ms);
312 obuf[i] = WaveShaper(ibuf[i], ms);
316 obuf[i] = (WaveShaper(ibuf[i], ms) * (p1 - p2)) + (ibuf[i] * p2);
319 obuf[i] = WaveShaper(ibuf[i], ms);
323 obuf[i] = DCFilter(data, obuf[i]);
345 ExponentialTable(ms);
348 LogarithmicTable(ms);
354 EvenHarmonicTable(ms);
366 HardLimiter(state, ms);
380 double lowThresh = 1 - threshold;
381 double highThresh = 1 + threshold;
385 if (n < (
STEPS * lowThresh))
386 mTable[n] = -threshold;
387 else if (n > (
STEPS * highThresh))
388 mTable[n] = threshold;
390 mTable[n] = n / (double)
STEPS - 1;
401 double threshold = 1 + thresholdLinear;
402 double amount = std::pow(2.0, 7.0 * ms.
mParam1 / 100.0);
403 double peak = LogCurve(thresholdLinear, 1.0, amount);
410 if (n < (
STEPS * threshold))
411 mTable[n] = n / (float)
STEPS - 1;
413 mTable[n] = LogCurve(thresholdLinear, n / (
double)
STEPS - 1, amount);
419 double threshold,
float value,
double ratio)
421 return threshold + ((std::exp(ratio * (threshold - value)) - 1) / -ratio);
432 double linVal = n / (float)
STEPS;
433 double scale = -1.0 / (1.0 - amount);
434 double curve = std::exp((linVal - 1) * std::log(amount));
435 mTable[n] = scale * (curve - 1);
444 double stepsize = 1.0 /
STEPS;
459 mTable[n] = std::log(1 + (amount * linVal)) / std::log(1 + amount);
468 int iter = std::floor(ms.
mParam1 / 20.0);
469 double fractionalpart = (ms.
mParam1 / 20.0) - iter;
470 double stepsize = 1.0 /
STEPS;
476 for (
int i = 0; i < iter; i++)
478 mTable[n] = std::sin(mTable[n] *
M_PI_2);
481 ((std::sin(mTable[n] *
M_PI_2) - mTable[n]) * fractionalpart);
492 gain = 1.0 / Cubic(ms,
std::min(amount, 1.0));
494 double stepsize = amount /
STEPS;
501 mTable[i] = (i / (double)
STEPS) - 1.0;
508 mTable[i] = gain * Cubic(ms, x);
509 for (
int j = 0; j < ms.
mRepeats; j++)
511 mTable[i] = gain * Cubic(ms, mTable[i] * amount);
524 return x - (std::pow(x, 3.0) / 3.0);
530 double amount = ms.
mParam1 / -100.0;
532 double C = std::max(0.001, ms.
mParam2) / 10.0;
534 double step = 1.0 /
STEPS;
539 mTable[i] = ((1 + amount) * xval) -
540 (xval * (amount / std::tanh(
C)) * std::tanh(
C * xval));
547 int iter = std::floor(ms.
mParam1 / 20.0);
548 double fractionalpart = (ms.
mParam1 / 20.0) - iter;
549 double stepsize = 1.0 /
STEPS;
555 for (
int i = 0; i < iter; i++)
557 mTable[n] = (1.0 + std::sin((mTable[n] *
M_PI) -
M_PI_2)) / 2.0;
560 (((1.0 + std::sin((mTable[n] *
M_PI) -
M_PI_2)) / 2.0) - mTable[n]) *
571 double fractionalPass = ms.
mParam1 / 100.0;
573 const int numPoints = 6;
574 const double gainFactors[numPoints] = { 0.80, 1.00, 1.20, 1.20, 1.00, 0.80 };
575 double gainLimits[numPoints] = { 0.0001, 0.0, 0.1, 0.3, 0.5, 1.0 };
576 double addOnValues[numPoints];
578 gainLimits[1] = noiseFloor;
593 addOnValues[0] = 0.0;
594 for (
int i = 0; i < numPoints - 1; i++)
598 (gainLimits[i] * (gainFactors[i] - gainFactors[1 + i]));
608 mTable[n] = ((double)(n -
STEPS) / (double)
STEPS);
609 for (
int j = 0; j < numPasses; j++)
612 int index = numPoints - 1;
613 for (
int i = index; i >= 0 && mTable[n] < gainLimits[i]; i--)
618 mTable[n] = (mTable[n] * gainFactors[index]) + addOnValues[index];
622 if (fractionalPass > 0.001)
624 int index = numPoints - 1;
625 for (
int i = index; i >= 0 && mTable[n] < gainLimits[i]; i--)
629 mTable[n] += fractionalPass * ((mTable[n] * (gainFactors[index] - 1)) +
638 double amount = (ms.
mParam1 / 50.0) - 1;
639 double stepsize = 1.0 /
STEPS;
643 for (
int n = 0; n <=
STEPS; n++)
645 mTable[index] = n * stepsize;
651 for (
int n = 1; n <=
STEPS; n++)
653 mTable[index] = n * stepsize * amount;
673 for (
int n = 0; n <
STEPS; n++)
675 mTable[n] = -mTable[count];
694 sample *= 1 + amount;
701 index = std::max<int>(std::min<int>(index, 2 *
STEPS - 1), 0);
702 xOffset = ((1 + sample) *
STEPS) - index;
703 xOffset = std::min<double>(std::max<double>(xOffset, 0.0), 1.0);
706 out = mTable[index] + (mTable[index + 1] - mTable[index]) * xOffset;
715 const unsigned int queueLength = std::floor(data.
samplerate / 20.0);
static const struct @103 FactoryPresets[]
EffectDistortionSettings params
const TranslatableString name
std::optional< std::unique_ptr< EffectSettingsAccess::Message > > OptionalMessage
std::vector< RegistryPath > RegistryPaths
static Settings & settings()
Generates EffectParameterMethods overrides from variadic template arguments.
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
A WaveShaper distortion effect.
static constexpr EffectParameter DCBlock
static const EnumValueSymbol kTableTypeStrings[nTableTypes]
std::shared_ptr< EffectInstance > MakeInstance() const override
Make an object maintaining short-term state of an Effect.
OptionalMessage DoLoadFactoryPreset(int id, EffectSettings &settings)
static constexpr EffectParameter NoiseFloor
virtual ~DistortionBase()
RealtimeSince RealtimeSupport() const override
Since which version of Audacity has the effect supported realtime?
static constexpr EffectParameter Threshold_dB
static const ComponentInterfaceSymbol Symbol
TranslatableString GetDescription() const override
static constexpr EnumParameter TableTypeIndx
OptionalMessage LoadFactoryPreset(int id, EffectSettings &settings) const override
RegistryPaths GetFactoryPresets() const override
Report names of factory presets.
static constexpr EffectParameter Repeats
static constexpr EffectParameter Param1
EffectType GetType() const override
Type determines how it behaves.
ManualPageID ManualPage() const override
Name of a page in the Audacity alpha manual, default is empty.
static constexpr EffectParameter Param2
const EffectParameterMethods & Parameters() const override
ComponentInterfaceSymbol GetSymbol() const override
void SetLinearEffectFlag(bool linearEffectFlag)
RealtimeSince
In which versions of Audacity was an effect realtime capable?
std::queue< float > queuesamples
Hold values to send to effect output meters.
Interface for manipulations of an Effect's settings.
static EffectDistortionSettings & GetSettings(EffectSettings &settings)
Assume settings originated from MakeSettings() and copies thereof.
Holds a msgid for the translation catalog; may also bind format arguments.
wxString Translation() const
constexpr auto sampleRate
__finl float_x4 __vecc sqrt(const float_x4 &a)
void Rectifier(const EffectDistortionSettings &)
size_t InstanceProcess(EffectSettings &settings, EffectDistortionState &data, const float *const *inBlock, float *const *outBlock, size_t blockLen)
bool RealtimeAddProcessor(EffectSettings &settings, EffectOutputs *pOutputs, unsigned numChannels, float sampleRate) override
void SineTable(const EffectDistortionSettings &)
void EvenHarmonicTable(const EffectDistortionSettings &)
unsigned GetAudioOutCount() const override
How many output buffers to allocate at once.
void LogarithmicTable(const EffectDistortionSettings &)
size_t ProcessBlock(EffectSettings &settings, const float *const *inBlock, float *const *outBlock, size_t blockLen) override
Called for destructive effect computation.
void InstanceInit(EffectDistortionState &data, EffectSettings &settings, float sampleRate)
size_t RealtimeProcess(size_t group, EffectSettings &settings, const float *const *inbuf, float *const *outbuf, size_t numSamples) override
void MakeTable(EffectDistortionState &state, const EffectDistortionSettings &ms)
float LogCurve(double threshold, float value, double ratio)
bool RealtimeInitialize(EffectSettings &settings, double) override
float DCFilter(EffectDistortionState &data, float sample)
float WaveShaper(float sample, EffectDistortionSettings &ms)
unsigned GetAudioInCount() const override
How many input buffers to allocate at once.
void HardLimiter(EffectDistortionState &state, const EffectDistortionSettings &)
bool RealtimeFinalize(EffectSettings &settings) noexcept override
void HalfSinTable(const EffectDistortionSettings &)
void ExponentialTable(const EffectDistortionSettings &)
void Leveller(const EffectDistortionSettings &)
void CubicTable(const EffectDistortionSettings &)
void SoftClip(EffectDistortionState &, const EffectDistortionSettings &)
double Cubic(const EffectDistortionSettings &, double x)
bool ProcessInitialize(EffectSettings &settings, double sampleRate, ChannelNames chanMap) override
void HardClip(EffectDistortionState &, const EffectDistortionSettings &)
Externalized state of a plug-in.