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?
2 Answers2
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 the3 + k or20 come from — but it works.
The value ofamount 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/
7 Comments
PI instead of the magic number 3, then the function goes through (-1,-1) and (1,1), and the function simplifies to(PI + k) * x / (PI + k * abs(x)). The angle is really just an output scaling factor (which might as well be 1), and the PI is really just an input scaling factor, so that demystifies the function some.ConvolverNode with an impulse response from a speaker cabinet helps a lot. If you google around a bit, it's not too hard to find some. Otherwise, you get something like the sound of plugging the guitar into a distortion pedal and going straight to the console, which usually kind of sucks. The convolver will give the effect that you're actually moving some air around.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;}Comments
Explore related questions
See similar questions with these tags.



