O2DPSoftClip

x2 oversampled SoftClip with Differentiated Polynomial Anti aliasing.
Author: Smashed Transistors
License: BSD
Github: tiar/dist/O2DPSoftClip.axo

Inlets

frac32buffer.bipolar in1

frac32buffer.bipolar in0

Outlets

frac32buffer.bipolar out1

frac32buffer.bipolar out0

Parameters

frac32.u.map InGain

frac32.u.map OutGain

Declaration
float x0, x1, I0, I1, out, inGain, outGain, outGain_2;
int32_t old_in;
int32_t outMax, outMin;
Init
x0 = x1 = I0 = I1 = out = 0;
old_in = 0;
Control Rate
inGain = param_InGain * (1.0f / (1 << 25)) * (1.0f / (1 << 27));
outGain_2 = (float)param_OutGain;
outGain = 2.0f * param_OutGain;
outMax = (int32_t)(outGain);
outMin = -outMax;
Audio Rate
// precedent value of input
x1 = x0;
// current input value (float)
x0 = inlet_in1 * inGain;
// precedent value of Integral
I1 = I0;
// calc of current Integral
I0 = fabs(x0);
if (I0 < 1) {
  float x2 = x0 * x0;
  I0 = x2 * (0.75f - 0.125f * x2);
} else {
  I0 -= 0.375f;
}
// if the precendent and current input are different enough
// we use the differenciation trick (ie mean on the x1 x0 interval
if ((inlet_in1 & 0xFFFFF000) != (old_in & 0xFFFFF000)) {
  outlet_out1 = (int32_t)(outGain * (I0 - I1) / (x0 - x1));
} else {
  // if the precedent and current values are close, no antialiasing
  // is necessary and we avoid a division by a small x0-x1:
  // we simply calculate the value of the saturation
  outlet_out1 =
      x0 >= 1
          ? outMax
          : x0 <= -1 ? outMin : (int32_t)(outGain_2 * (x0 * (3.0f - x0 * x0)));
}
old_in = inlet_in1;

// precedent value of input
x1 = x0;
// current input value (float)
x0 = inlet_in0 * inGain;
// precedent value of Integral
I1 = I0;
// calc of current Integral
I0 = fabs(x0);
if (I0 < 1) {
  float x2 = x0 * x0;
  I0 = x2 * (0.75f - 0.125f * x2);
} else {
  I0 -= 0.375f;
}
// if the precendent and current input are different enough
// we use the differenciation trick (ie mean on the x1 x0 interval
if ((inlet_in0 & 0xFFFFF000) != (old_in & 0xFFFFF000)) {
  outlet_out0 = (int32_t)(outGain * (I0 - I1) / (x0 - x1));
} else {
  // if the precedent and current values are close, no antialiasing
  // is necessary and we avoid a division by a small x0-x1:
  // we simply calculate the value of the saturation
  outlet_out0 =
      x0 >= 1
          ? outMax
          : x0 <= -1 ? outMin : (int32_t)(outGain_2 * (x0 * (3.0f - x0 * x0)));
}
old_in = inlet_in0;

Privacy

© 2024 Zrna Research