Warmer waveshapers

Geraint Luff
Signalsmith Audio Ltd.

Looking at a couple of ways to reduce the bright high-end you commonly get from waveshaping distortion, while preserving clarity.

This was originally a short tangent in my previous limiter post. I took it out because it was a distraction, but still wanted to share it because I think it's neat. 😄

Waveshaping distortion

Waveshaping is a method of distortion where a signal is passed through a waveshaping function, which maps each possible input value to an output value. Each value is mapped separately, so for an input signal x, we define the output y by:

y(t) = f(x(t))

This produces a warped version of the signal:

Let's have a listen to what that might sound like:

inputoutput
Some of the audio examples in this post have a slightly aggressive high-end. Reducing that is the point of the article, but we have to listen to it first, so maybe check your volume.

There are a wide variety of curves for the waveshaping function f, some of which have common names. Here are some examples:

This is a very rough summary. For a more comprehensive exploration of different types of waveshapers (and the types of harmonics/frequencies they can introduce), try this paper. It also explores some feedback/filtering structures which use waveshaping internally.

But really, you can use any curve you like, and I'd definitely recommend having some fun making up your own.

Harsh sounds

Waveshapers are great for creating bright harsh sounds, but (in my opinion) it's somewhat harder to get a more mellow distortion from them. Sometimes you want the crunch without the buzz.

Even the gentle soft-cornered waveshaping curves can sound bright when given a loud enough input, and complex chords and textures can end up filling the entire spectrum with fuzz.

So what can we do? Here are a couple of options:

Filtering the output (and input)

Harshness usually involves higher frequencies, so filtering the output with a high-shelf or lowpass EQ can reduce those high frequencies.

The downside is that you dull the whole sound. To compensate, you can use pre-filter the input (before the waveshaper) to boost the high-end input. If your pre-/post- filters are a matched pair (e.g. ±36dB shelves) then it won't colour parts of the sound which aren't affected by the waveshaper.

Let's compare a simple lowpass against the matched pre-/post-filters:

filtering
curve(none)outputpre/post
hard clip play play play
soft clip play play play
fuzzy play play play
wave-folding play play play
filter config:lowpass @ 1.8kHz±36dB high shelf @ 8kHz

You can hear that the filtered-output version sounds dull and muted. Using a pre-filter restores some clarity while keeping the distortion from being too bright. To help the comparison, here is our dry signal again:

Waveshaped gain

Another neat trick we can use for waveshaping is to re-phrase it as an input-dependent gain signal:

You need to find a gain function which matches the waveshaper you want - but that's straightforward:

g(v) = \frac{f(v)}{v}

From this perspective, our distortion is now a form of amplitude modulation (by a different waveshaped signal). We can filter this gain signal to make it smoother (and the amplitude-modulation less harsh):

Let's have a listen, and compare it to the matched pre/post pair:

filtering
curve(none)pre/postgain
hard clip play play play
soft clip play play play
fuzzy play play play
wave-folding play play play
filter config:±36dB high shelf @ 8kHzlowpass @ 1.8kHz

They sound pretty similar! Both approaches keep the high-end of the distortion down, without dulling the entire output.

Pre-filtering the gain path

Having a separate gain-path opens up some possibilities, because we don't have to worry about doing anything as a matched pair.

For example: for inputs with a strong low-end, the distortion can end up mostly determined by these low frequencies. If you don't like that, you could insert a high-pass before the gain-shaper:

gain filtering
curve(none)outputinput + output
hard clip play play play
soft clip play play play
fuzzy play play play
wave-folding play play play
filter config:lowpass @ 2.5kHzhighpass @ 150Hz before
lowpass @ 2.5kHz after
Does it sound good? Debatable. But it sounds interesting in a way which might be useful. I particularly like how it changes the "fuzzy" and "wave-folding" shapers.

... and more!

This filtered-gain approach is neat, but why stop at filtering? There's a whole range of other processors we could try using in that gain path.

For example, if your clipper is also chopping off the top of your dynamic range, you could preserve it by using a compressor/limiter at the start of the gain-path:

This can be combined with other techniques (including pre-/post-filtering), so there's a lot of room to experiment here.

Awkward waveshaping curves

This whole gain-filtering trick only works for curves which go through 0 with a fairly sensible gradient, which is true for many waveshaping curves - but not all.

This curve has a steep gradient near 0. This corresponds to large gain values: g(v) = f(v)/v.

These waveshaping curves aren't an issue when used directly, but can cause larger gain values than expected when using the approach described above.

I don't have a general-purpose solution to this. Sometimes these waveshapers can sometimes be rephrased in other creative ways (to allow control of their timbre), or you can use pre-/post-filtering approach instead.

Conclusion

I find that when I'm experimenting with different ways to degrade a sound, it's easy to create a bright splashy mess. This is harsh to listen to, and can be difficult to fit into a mix.

These two approaches (pre-/post-filtering, and a separate gain path) are simple tricks which can keep the harshness of a waveshaper in check, and help craft the specific kind of mess you want. 😛

I also just like when we can re-phrase an existing audio processing element, viewing it from a different perspective. It often presents new ways to understand the mechanisms and get creative with the sound.