Soft/Hard clipping live guitar input with waveshaper

Taemin

Member
First of all, this is my first time using waveshaper. So basically I am trying to make a digital distortion/overdrive pedal using teensy4.0 and audio shield. I've read the description of waveshaper multiple times, did a ton of research, tried messing around with the example codes, posted a few questions, but I just can't understand how it works and how I should use it. Can someone explain some basics to me? Also an example code for a working clipping effect would be helpful.

You pass a transfer function to the class as an array of floats, it applies that function to every sample with interpolation.
The length of the array needs to be one more than a power of two, so 3, 5, 9, 17, 33, etc.

For instance passing the array {-1.0, 0.0, +1.0} would be the identity transform since the first and last points are
the mapping of -1.0 and +1.0 samples (samples are conceptually in the range +/-1.0 in the audio lib.)

Another example: passing {0.0, 0.0, 1.0} would give a rectification mapping as negative samples all map to 0.0

....which I think means you have to provide a 'graph' for a plausible transfer function that (soft) clips.

The array you need will have a plateau at or near -1 at the start and at or near 1 near the end with a steeper than 45 linear segment and possibly some softening around the knees between the linear segments.

Minimally five points might work (i.e. {-1.0,-1.0,0,1.0,1.0} ) but it's likely you'll need something smoother and perhaps not so flat in the plateau regions.

Don't expect a 'tube' sound from something very simple.

It's the interpolation that will start to get expensive if you have a ton of points defining your transfer function.

I've been meaning to try this out for literally years but I've never even started. Good luck and hope to see your results.

It's the interpolation that will start to get expensive if you have a ton of points defining your transfer function.

The interpolation costs the same whether its 2 or 8193 or whatever points. You might want thousands of points for a particular smoothly
changing curve in fact. I looked at the code.

I tried lots of different arrays after seeing your reply, and I at one point I got something that actually sounded sort of like a tube amp with overdrive pedals. But that was pretty much based on luck. I'm having a hard time understanding the whole "map to" part. So I drew a simple sine graph, divided it into 8 parts, and cut off the top and bottom part. I wrote down the estimated y values and used that as the array. It looks like this: float waveshape[9] = {-0.7, -0.7, -0.4, 0, 0.4, 0.7, 0.7, 0.7};

But now that I think about it, I don't think this is how it works. Can you help me out?

This thread reminded me I was going to implement a non-real-time audio plotter. I've done it now, see https://forum.pjrc.com/threads/69900-Non-realtime-audio-debugging for my post, which you may find helpful to experiment with waveshaping. I even put a 5-point waveshaper in the demo...

As noted by MarkT, your array needs to have 2^N+1 entries (your 9-element one actually only initialises 8 of them, so it may sound a bit odd!). This divides the input into 2^N "slots" which are linearly mapped to output values. Say your array is 9 elements, {-1.0,-0.9,-0.7,-0.4,0.0,0.42,0.75,0.95,1.0}: input values from -1.0 to -0.75 fall in the first slot, and will map to values between -1.0 and -0.9; from -0.75 to -0.50 are second slot, and map to -0.9 to -0.7 ... and so on. Note I've deliberately made the array asymmetrical, because that's valid (and may even sound nice).

Thanks. That helped a lot.

float ODShape[9] = {-1.0, -0.9, -0.7, -0.4, 0.0, 0.42, 0.75, 0.95, 1.0};
float DSShape[9] = {-0.9, -1.0, -0.9, -0.5, 0.0, 0.53, 0.95, 1.0, 0.94};
float FZShape[9] = {-1.0, -1.0, -1.0, -0.5, 0.0, 0.5, 1.0, 1.0, 1.0};

This was the closest I could get to the actual pedal sounds. I am pretty satisfied with it but if you have any suggestions that would be great.
I also modified your oscilloscope code to see if my code was actually working. That was also really helpful too.