working with WebAudio API and trying to get distortion going! Issue is, I'm not sure how to get into the "curve" param of WaveShaper.
Simply put, 'oscidis' is a WaveShaper node created earlier in the program. Oscidisv is a value I have set to 0 statically, for now.:
const wsCurve = new Float32Array();
if (oscidisv >= -1 && oscidisv < 1) {
const k = (2 * oscidisv) / (1 - oscidisv);
for (let i = 0; i < 16; i += 1) {
// LINEAR INTERPOLATION:
// x = (c - a) * (z - y) / (b - a) + y
// given
// a = 0, b = 2048, z = 1, y = -1, c = i
const x = ((i - 0) * (1 - -1)) / (16 - 0) + -1;
wsCurve[i] = ((1 + k) * x) / (1 + k * Math.abs(x));
}
}
oscidis.curve.value = wsCurve;
The issue - I'm not hearing any difference in sound regardless of what I put here )-=. I don't notice any real distortion even with the distortion at max (1). Do you guys know anything about a more noticeable distortion waveshaping function? Or if I'm doing this right at all in the WebAudio API?
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/
I took some of the suggestions above and re-factored the function. I also cut down the number of samples in the typed array from 44K to 256, it makes the browser happier :-()
let distortionFilter = audioCtx.createWaveShaper();
distortionFilter.curve = makeDistortionCurve();
function makeDistortionCurve(amount=20) {
let n_samples = 256, curve = new Float32Array(n_samples);
for (let i = 0 ; i < n_samples; ++i ) {
let x = i * 2 / n_samples - 1;
curve[i] = (Math.PI + amount) * x / (Math.PI + amount * Math.abs(x));
}
return curve;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With