Variable-hardness clipping function

notes
k >= 1 is the "clipping hardness". 1 gives a smooth clipping, and a high value gives
hardclipping.

Don't set k too high, because the formula use the pow() function, which use exp() and
would overflow easily. 100 seems to be a reasonable value for "hardclipping"
code
1
f (x) = sign (x) * pow (atan (pow (abs (x), k)), (1 / k));

Comments

// Use this function instead of atan and see performance increase drastically :)

inline double fastatan( double x )
{
    return (x / (1.0 + 0.28 * (x * x)));
}
The greater k becomes the lesser is the change in the form of f(x, k). I recommend using
f2(x, k2) = sign(x) * pow(atan(pow(abs(x), 1 / k2)), k2) ,  k2 in [0.01, 1]
where k2 is the "clipping softness" (k2 = 0.01 means "hardclipping", k2 = 1 means
"softclipping"). This gives better control over the clipping effect.
Don't know if i understood ok , but, how can i clip at diferent levels than -1.0/1.0 using this
func? tried several ways but none seems to work
The most straightforward way to adjust the level (x) at which the signal is clipped would be to
multiply the signal by 1/x before the clipping function then multiply it again by x afterwards.
Atan is a nice softclipping function, but you can do without pow().

x: input value
a: clipping factor (0 = none, infinity = hard)
ainv: 1/a

y = ainv * atan( x * a );
Even better, you can normalize the output using:

shape = 1..infinity

precalc:
  inv_atan_shape=1.0/atan(shape);
process:
  output = inv_atan_shape * atan(input*shape);

This gives a very soft transition from no distortion to hard clipping.
Scoofy,

What do you mean with 'shape'?
Is it a new parameter?
sign (x) * pow (atan (pow (abs (x), k)), (1 / k));

OUCH! That's a lot of pow, atan and floating point division - probably kill most CPU's :) My
experience has been that any sigmoid function will create decent distortion if oversampled and
eq'ed properly. You can adjust the "hardness" of the clipping by simply changing a couple
coefficients, or by increasing/decreasing the input gain: like so:

y = A * tanh(B * x)

Cascading a couple/few of these will give you bone-crushing, Megadeth/Slayer style grind while
rolling back the gain gives a Fender Twin sound.

Two cascaded half-wave soft clippers gives duty-cycle modulation and a transfer curve similar to
the 3/2 power curve of tubes. I came up w/ a model based on that solution after reading reading
this: http://www.trueaudio.com/at_eetjlm.htm (orig. link at www.simulanalog.org)
If anyone is interested, I have a working amp modeler and various c/c++ classes that model
distortion circuits by numerical solutions to non-linear ODE's like those described by
Yeh, Smith, Macak, Pakarinen, et al. in their PhD disertations and DAFX papers. Although
static waveshapers/filters can give decent approximations & cool sounds, they lack the dynamic
properties of the actual circuits and have poor harmonics. I also have whitepapers on my
implementations for those that think math is cool. Drop me a line for more info.