Variable-hardness clipping function

References : Posted by Laurent de Soras
Linked file : laurent.gif
(this linked file is included below)
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 :
f (x) = sign (x) * pow (atan (pow (abs (x), k)), (1 / k));

Comments
from : antiprosynthesis[AT]hotmail[DOT]com
comment : Use this function instead of atan and see performance increase drastically :) inline double fastatan( double x ) { return (x / (1.0 + 0.28 * (x * x))); }

from : spam[AT]musicdsp[DOT]org
comment : 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.

from : notinformed[AT]nomail[DOT]org
comment : 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

from : xeeton[AT]gmail[DOT]com
comment : 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.

from : cschueler[at]gmx[dot]de
comment : 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 );

from : scoofy[AT]inf[DOT]elte[DOT]hu
comment : 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.

from : travelan[AT]gmail[DOT]com
comment : Scoofy, What do you mean with 'shape'? Is it a new parameter?

from : superhotmuffin[AT]hotmail[DOT]com
comment : 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)

from : superhotmuffin[AT]hotmail[DOT]com
comment : 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.


Linked files