Here's one I've used that's based on a few different functions I've found in white papers and things like that:
const DEG = Math.PI / 180;
function makeDistortionCurve(k = 50) {
const n_samples = 44100;
const curve = new Float32Array(n_samples);
curve.forEach((_, i) => {
const x = (i * 2) / n_samples - 1;
curve[i] = ((3 + k) * x * 20 * DEG) / (Math.PI + k * Math.abs(x));
});
return curve;
}
I'd be lying if I told you I knew where the 3 + k
or 20
come from — but it works.
The value of amount
can basically be any positive number, but I've found that 0 - 100 is a pretty good range depending on how much distortion you need.
If you have any interest in seeing what these functions look like, I built a little tool to help me visualize them here: http://kevincennis.github.io/transfergraph/