Waveshaping/Overdrive/Harmonics Cookbook for the N00b?

DSP, Plugin and Host development discussion.
RELATED
PRODUCTS

Post

Robin from www.rs-met.com wrote:...and that's what i would consider as the essence of dynamic distortion: producing more or less distortion depending on whether or not a transient is present. by simulating tube circuits, you would get that implicitely as a kind of side effect. personally, i would probably try to do it directly by splitting off the transient and distorting it separately.
This thread intersts me very much! Could you think of a way of splitting off the transients and distorting them seperately using basic audio processing "modules" like might be found in the MDA open source collection of plug-ins? Something like, say, splitting the signal to two instances of MDA Combo, one set for symmetrical clipping and the other asymmetrical (using the bias control) and then using a limiter that has it's threshold set to catch transients on the asymmetrical clipping branch to emphasise the added harmonics during the transients...or, uh, something like that?

I have some ideas that deal more with speaker cab/power amp interaction that relate to this subject, but I want to see if I can get the results I seek using open source building blocks (first in a modular host, then in Synthedit for a prototype) before I get down to the nitty gritty of coding. I tend to look at all audio processing in a modular effects unit way, being a guitar player who has always had a lot of stomp boxes and rack effects around.

I'm not trying to hijack this thread, but I was hoping that looking at it from a modular point of view might help the OP and others. Feel free to ignore me if I'm just rambling! :)

Post

Pieces_of_Fate wrote: Could you think of a way of splitting off the transients and distorting them seperately using basic audio processing "modules"
i think, the spl manual describes pretty well how this can be done. i think, the only missing bit is that you need to multiply you input signal with the envelope-difference to obtain your actual transient signal (and likewise for the steady part - although i wonder whether the steady part could better be obtained by just subtracting the transient from the original).

disclaimer: it's ages ago that i looked into this stuff, so take everthing i say with a grain of salt and experiment yourself
My website: rs-met.com, My presences on: YouTube, GitHub, Facebook

Post

Pieces_of_Fate wrote:Could you think of a way of splitting off the transients and distorting them seperately using basic audio processing "modules" like might be found in the MDA open source collection of plug-ins?
Yep. Two functions, one of which processes everything (or everything except transients), and one which only processes transients. Better yet, a composite function that does all of the above, but separates out transients first. Use different distortions on each. Stir to combine.
Last edited by Jafo on Mon Mar 29, 2010 7:13 pm, edited 1 time in total.
Wait... loot _then_ burn? D'oh!

Post

fwiw, here's a quick overview of what I've been using. I've been implementing a dynamic dc offset by taking a user-adjustable percentage of the absolute value of the previous sample's input, and adding it to the current input, then running that through various waveshaping functions.

x - x^3
x^3 - x
tanh(x)
x / (x + 1)
(-2 / (1 + exp(x)) + 1)
atan(x)
sign(x)*( (2*|x|) - x^2) )
and a few with differing functions for positive and negative phases

In general, these blow. Either farty, or fizzy -- which could be fixed with some sort of normalization and anti-aliasing, but none of them have the kind of dynamic tonal response I want. See here for another thread on this.
Wait... loot _then_ burn? D'oh!

Post

I made a quick little plug to showcase a few differing waveshaping models, all of which use a simple form of dynamic dc offset, controlled by the "Tweak" parameter. In the interests of fair comparison, I didn't add any filtering, even though most of these need some on the bottom end, or any anti-aliasing. I called this plug JAFO ("Just Another Fscking Overdrive"), and it can be found here. The trig functions seem to give the best results, but need low Tweak. I welcome critiques, but keep in mind that I'm a total n00b as a programmer. :(
Wait... loot _then_ burn? D'oh!

Post

Not sure if anybody is following this thread at all, but I might as well bring it to some sort of conclusion. I've found some very nice things, and I hope somebody will get some use out of them.

The best results happen with a dynamic dc offset. Not only does this add some asymmetry and thus even-order harmonics, but more importantly, it adds a certain life to the response. I'm taking a fraction of the previous sample's absolute value, using a decay and a comparison, but an envelope follower might work better.

The best functions are multi-part and polynomial. It helps if these are asymmetrical, too; you could even write completely different functions for positive and negative phases, but clipping each differently will do the trick nicely. If you're careful with how you write them, you don't need to worry about exceeding the +/- 1.0 bounds. You could also run them through atan(x), which soft-clips at pi/2. Don't bother to convert to radians or whatnot; just use atan(x) -- in fact, atan((in+offset)*gain) is a nice algorithm all on its own, but it does tend to get a rather furry kind of distortion.

Pakarinen's equation very effectively models a preamp tube; I think it's based on a 12AX7. Doidic's equation is equally effective for power tubes. Add in some EQ between the two, and a cab sim, and you've got a very nice amp sim. (Alas, my knowledge of C++ is younger than the new year, and I'm non-technical, so I'm using separate plugs for EQ and cab sims.) You can find these in various places on the Web if you Google for "A Review of Digital Techniques for Modeling Vacuum-Tube Guitar Amplifiers"; here is the most current version.

If you want a quick harmonic fix, just write a polynomial equation and substitute it in the processReplacing code for AGain in the VST SDK:

*out1 = ((0.2*x1*x1*x1)+(0.18*x1*x1)+(0.25*x1))*fPostGain;
*out2 = ((0.2*x2*x2*x2)+(0.18*x2*x2)+(0.25*x2))*fPostGain;

where x1 and x2 are *in1 and *in2 modified by dc offset. Yes, the 3rd harmonic is stronger than the second; when the offset raises, the second strengthens, and too much second easily becomes dull and unwieldy. Most of the classic amps we all know and love, have weak or nonexistent second-harmonic production due to push-pull topologies. Encase the polynomial in an atan() and it's even better.

One last caveat -- you'll need to high-pass at about 50Hz with any of these. Maybe one day I'll understand EQ equations. lol
Wait... loot _then_ burn? D'oh!

Post

great post,

I can't get biasing sound good, I have tried some methods, but none sounds good
The best results happen with a dynamic dc offset. Not only does this add some asymmetry and thus even-order harmonics, but more importantly, it adds a certain life to the response. I'm taking a fraction of the previous sample's absolute value, using a decay and a comparison, but an envelope follower might work better.
"decay and a comparison", how? (sorry I'm a noob)

Post

You know, no matter what I do, I always end up with the same ole distortion :( Haven't tried the above yet, but will... The prob I see with most ampsims is the horrible farty type sound they have at low gain...

~Rob.

Post

pylorca wrote:great post,

I can't get biasing sound good, I have tried some methods, but none sounds good
Good starting point would be negative feedback which generally tends to have a stabilizing effect on things.

Code: Select all

   out = shape( in - k * out )
The 'k' here would typically be a positive constant of less than 1 for stability, though if the derivative of the shaper is more than 1 at any point (ie the gain is more than unity somewhere around the transfer curve) then reciprocal of the maximum derivative gives you the upper bound on stable feedback.

Next thing you might want to do is lowpass the feedback, giving you something like:

Code: Select all

   out = shape( in - k * lp(out) )
A simple one-pole is probably what you want to at least start with. Experiment with cutoff, but somewhere between 10Hz and 100Hz is probably a good first guess.

At this point your bias will try to reduce the DC component caused by the non-linearity (assuming the shaper obeys shape(0)=0 and is increasing), which is pretty cool, but if the input spikes into one side (at least for symmetric non-linearity anyway) the bias will try to push it harder into the saturation and you'll lose gain. That's kinda cool I guess, but you could also try to bias it for minimum saturation... which is fairly simple modification:

Code: Select all

   linear_out = in - k * lp(linear_out - out)
   out = shape(linear_out)
Again, you might need to adjust if shaper has gain such that the difference can go negative, but the idea is to figure out how much the signal got clipped, then lowpass that and feed it back negatively to slowly push the input towards the other direction (ie towards linear region, assuming there is one).

You can do tons of other similar fairly simple things for various effects but that's what comes to mind right now.

As for actually doing amp-simulation, you'd probably want to figure out what sort of feedback there are in the various amplifier stages.

Post

Now the thing about stages, it seems if you put the same shaper just in series, you get the same result.... Should they be different(adding different harmonics)? I see that a lot, like I'll put a distortion in front of an ampsim, and it just doesn't give that Extra sound(kinda high fizzy sound,fuzzy).. It just kinda is like adding more gain, but the same gain.. nothing different..

~Rob.

Post

Jafo wrote:re: the SimulAnalog "Clipping" model. Yes, the transient is where the magic happens (I think it was Bootsy who wrote that, but my bookmarks and quotes file are on my home rig), but the effect in question -- harmonics but not volume increasing -- is also a function of the transfer curve, innit? "Saturation" means the device can't push any more electrons through it, after all.

Also, I'm finding that either some sort of asymmetric clipping, or the production of individual harmonics, is giving me much better results than a simple overall waveshaping.
Try not to base your ideas around the amplitude of the signal, but more the tone. Use any amplitude statistics you have to to get the sound you're after. The asymmetric clipping will produce even-order harmonics as well as odd-order, whereas symmetric clipping can only produce odd-order (with unbiased, symmetric input). This is where the bias comes into play in many models. I'm not a tube or transformer expert, but from what I have gathered, transformers create hysterisis inside them which can give even-order harmonics, while tubes just saturate. I think the catch is that tubes HAVE to be biased to operate, and that's where the even-order addition comes from. Because this bias is present, to get the proper output, the bias must be removed. That is where the dynamics come from, because during filtering this bias, the filter will ring and bump. If you use that concept in a daisy chain two or three times, you get a multi stage amp, and each stage adds more 'punch', because the next stage will isolate the gimmick from the last stage and fold into it. The most punch comes from silence before the signal.

Post

I added a bias in the defunct Float Crush v2 plugin (which was never released), and it had a hi pass filter on the output stage which would audibly thump near the f3 when the signal fell off. The way it worked internally was to mix a DC bias with the input, and filter the output after all the processing had been done. I am sure in more complex amp models the filters are in a different location of the 'circuit', and for different reasons. Doing biases is tricky and involves lots of technique and mojo to do well.

Post

Been trying forever to get something as stable sounding as this:



But, I'm sure this is in some weird filtering scheme that can get this... Surely sticking one impulse at the end wont do it..

But, its fuzzy, but.. hmm its not haha.. hard to explain...

~Rob.

Post

mystran wrote:
Good starting point would be negative feedback which generally tends to have a stabilizing effect on things.
....
Wow Thanks!

PS: Sorry for the delay.

Post Reply

Return to “DSP and Plugin Development”