22

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?

Mike 'Pomax' Kamermans's user avatar
Mike 'Pomax' Kamermans
54.3k17 gold badges134 silver badges182 bronze badges
askedMar 10, 2014 at 22:38
PinkElephantsOnParade's user avatar

2 Answers2

48

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/

Mike 'Pomax' Kamermans's user avatar
Mike 'Pomax' Kamermans
54.3k17 gold badges134 silver badges182 bronze badges
answeredMar 10, 2014 at 23:19
Kevin Ennis's user avatar
Sign up to request clarification or add additional context in comments.

7 Comments

Love the transfergraph tool! You might want to visualize what a sine wave going through that transfer function looks like, too.
You're a god. Literally EXACTLY what I'm looking for. All I'm wondering now - where can I get more of these distortion curve equations? I'd like to experiment with some different ones!
They're definitely tough to find. Most really good-sounding effect algorithms are proprietary. Companies like Amplitube, Line6, etc invest a lot of time and money into this stuff, and they need to keep a competitive advantage — so it's hard to find great info. Granted, the really high-end stuff is using techniques that are a lot more complex than a simple waveshaper... but still. Best I could recommend is just running some searches for stuff like "guitar amp waveshaper" and see what comes up. That's what I did. But there's just not a lot out there.
If you choose an angle on 1 radian (instead of 20 degrees), and usePI 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.
Cool. Thanks @Grumdrig. By the way, another thing that might be helpful for people – for guitar distortion, assuming you're trying to emulate the sound of an amp, adding aConvolverNode 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.
|
12

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;}
answeredSep 24, 2018 at 4:11
tonethar's user avatar

Comments

Your Answer

Sign up orlog in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

By clicking “Post Your Answer”, you agree to ourterms of service and acknowledge you have read ourprivacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.