Question

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?

Was it helpful?

Solution

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/

OTHER TIPS

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;
} 
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top