waveshaping - parabolic curve function

justin's icon

trying to write a patch which distorts audio with a parabolic waveshaping function. for the moment, i am not interested in using wavetables in a buffer. i would rather do it as demonstrated in the patch below. my problem is adjusting the curve factor of the waveform...

any tips or helpful URL appreciated?

BTW, my maths aint too hot but am willing to learn!

thanks

justin

Max Patch
Copy patch and select New From Clipboard in Max.

redhexagonal's icon

use overdrive~?

Max Patch
Copy patch and select New From Clipboard in Max.

justin's icon

i have not been too impressed with overdrive cos it cliks and pops if u change the drive factor quickly with the mouse. that's why i like to keep things in signal domain... (maybe c74 can fix this!)

also i'm curious about the maths behind tweaking the transients of a waveform...

langsound's icon

i find scaling the audio signal going into overdrive~
gets me all my waveshaping fun with out clicks and pops.
so like:

insig~ line~
/
[*~ 32.]

overdrive~
outsig~

then again one might be able to plug a line~ object into the drive
factor input of overdrive~. that might also eliminate the clicks and
pops of changing audio parameters at control rates...

> i have not been too impressed with overdrive cos it cliks and pops
> if u change the drive factor quickly with the mouse. that's why i
> like to keep things in signal domain... (maybe c74 can fix this!)

jonathan lee marcus's icon

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Jul 27, 2006, at 10:24 AM, justin wrote:

> i have not been too impressed with overdrive cos it cliks and pops
> if u change the drive factor quickly with the mouse. that's why i
> like to keep things in signal domain... (maybe c74 can fix this!)

take a look at [sig~] to convert your floats to signal control and
[slide~] to smooth out changes.

feed this into [overdrive~]'s second inlet.

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (Darwin)

iD8DBQFEyNJpRvcxtaNGgooRAj9qAJ9KO02lEcvHlsNRbEcI9GXCnZM+lQCfd1Am
OStX/J3BZNk/42C765aIOLE=
=vv8W
-----END PGP SIGNATURE-----

justin's icon

didnt think overdrive could take sig to control drive factor, thought this was only float... i will try it out a bit later, busy at mo!

any clues as to maths behind it would still be appreciated?

cheers, j

volker böhm's icon

> any clues as to maths behind it would still be appreciated?

hm, just took a quick look at your patch and i guess you confused the
inlets of the pow~ object. left is exponent right is base.
try swapping and see if it gets you closer to where you want to go.
there are a lot of different approaches towards creating waveshaping
functions.
i don't know which one overdrive~ uses, but it looks kind of similar
to an arctan-distortion.

Max Patch
Copy patch and select New From Clipboard in Max.

also check the archives, i think jhno once proposed some techniques.
gruess,
vb

justin's icon

cheers vb!

i managed to get it to work with pow thanks to swapping inputs.
i knew i was along the right lines...

i also looked at ur patch which seems much cleaner. for a start you dont have to split positive and negative signals, which means less objects... however i managed to find jhno's thread on reaktor saturation module, and discovered you can go even simpler!

*~ (drive factor) > tanh~ = saturation / distortion

(IMO) this also seems to produce a warmer tone with less fuzz in the hi end than my pow~ attempts, which is harsher on the transients. not sure how it compares to ur patch, altho my guess is they are probably quite similar...

thanks again!

j

Trond Lossius's icon

Here's another approach using sinus. Looking at the patch it might look
ridiculous, but it sounds really good and warm. I believe this is the
distortion jhno ended up using for the overdrive in radiaL.

Me and Tim discussed these issues a lot a while ago, and ended with Tim
implementing both this and the tanh approach in the overdrive external
used in Jamoma: jmod.saturation~. Note that using tanh or sinus in the
signal loop like this is computationally expensive. Lookup tables are
much cheaper. jmod.saturation use lookup and linear interpolation AFAIR.

I should add that for some funny reason the mach-o version of
jmod.saturation~ don't like to load on Max 4.5.7 or lower. In Max 4.6 it
works fine.

Best,
Trond

Max Patch
Copy patch and select New From Clipboard in Max.

justin wrote:
> cheers vb!
>
> i managed to get it to work with pow thanks to swapping inputs.
> i knew i was along the right lines...
>
> i also looked at ur patch which seems much cleaner. for a start you dont have to split positive and negative signals, which means less objects... however i managed to find jhno's thread on reaktor saturation module, and discovered you can go even simpler!
>
> *~ (drive factor) > tanh~ = saturation / distortion
>
> (IMO) this also seems to produce a warmer tone with less fuzz in the hi end than my pow~ attempts, which is harsher on the transients. not sure how it compares to ur patch, altho my guess is they are probably quite similar...
>

justin's icon

only problem i have with table lookup is that changing the curve in real-time becomes problematic, especially as far as pluggo is concerned.

i tried to use defer to de-prioritize the uzi>function>peek~ part of the patch. but it still goes mental - gui in ableton live goes real slo and automation is a no go... maybe i'm doing something wrong? not quite sure where the defer bit should go in the patch!

your sine patch is quite different to the tanh, seems to be more subtle. can u still overdrive it as much as tanh? looks like ur kinda folding a sine wave twice over itself... but doesnt seem to have the grunt of tanh if u see wot i mean!

j

Trond Lossius's icon

I can understand that, but it depends on what kind of changes you want
to be able to do. If you look at the example I posted, I'm effectively
changing the curve. This because input is scaled before being wave
shaped, and then rescaled afterwards according to the maximum output
value possible for a signal in the range [-1,1]. So if the overdrive
value is close to 0 almost no distortion is added, as only a small
almost linear section of the sinus curve around origo is used. As it is
increased to 100% the distortion gets more and more pronounced. But all
the way maximum amplitude of the output stays consistent.

If you want to be able to move between radically different kinds of
curves (and not just use a larger or smaller part of it), you could also
contemplate using a jitter matrix. If you have for instance a jit.matrix
1 float32 512 2, and use jit.peek~ @interp 1 you could load one curve
into row 0 and another into row 1. By moving back and forth between row
0 and 1 you will move between the curves. Of course this is more
expensive than using a single lookup table as you are interpolating in
2D instead of 1D.

You would be able to expand this further either by adding more rows so
that you have more curves to choose between, or by dynamically changing
the cell values of one or the other row so that you substitute an old
curve for a new one.

You could also check out 2Dwave~.

Best,
Trond

justin wrote:
> only problem i have with table lookup is that changing the curve in real-time becomes problematic, especially as far as pluggo is concerned.
>
> i tried to use defer to de-prioritize the uzi>function>peek~ part of the patch. but it still goes mental - gui in ableton live goes real slo and automation is a no go... maybe i'm doing something wrong? not quite sure where the defer bit should go in the patch!
>
> your sine patch is quite different to the tanh, seems to be more subtle. can u still overdrive it as much as tanh? looks like ur kinda folding a sine wave twice over itself... but doesnt seem to have the grunt of tanh if u see wot i mean!
>

justin's icon

actually i quite like ur sin distort patch to get a bit more warmth... works a treat if u put it before tanh!

thanks for all suggestions!

j

Roman Thilenius's icon

> your sine patch is quite different to the tanh, seems to be more subtle. can u still overdrive it as much as tanh? looks like ur kinda folding a sine wave twice over itself... but doesnt seem to have the grunt of tanh if u see wot i mean!
>
> j

hmm hmm i would call the effect you can reach
with mult with [tanh~] a "saturation effect" - and
i find it still quite a subtile effect. :)

i get good results in that direction by using two
[tanh~] based DSPs in series.

if your signal input is not music, but only sinewaves
of a known frequency, then it can be worth looking
into [kink~] instead

redhexagonal's icon

that arctan distortion uses half the CPU of overdrive~.
very nice

mzed's icon

simpler!
>
> *~ (drive factor) > tanh~ = saturation / distortion
>
>

adding a +~ between *~ and tanh~ is also nice, because it creates asymetrical distortion.

cheers,

mzed

Roman Thilenius's icon

save this as

[110.saturn~]

Max Patch
Copy patch and select New From Clipboard in Max.

[110.saturn~.help]

Max Patch
Copy patch and select New From Clipboard in Max.

-110

redhexagonal's icon

i've been using something like this for waveshaping in an FM synth.

Max Patch
Copy patch and select New From Clipboard in Max.