Shift Distortion Implementation


(Artie Fufkin) #1

I’m trying to emulate the shift distortion with a VST. I’m using the Robin Schmidt FuncShaper VST with an absolute value function and high pass filter(to get rid of DC offset). Getting close, but there’s just a little bit of extra grit with the shift distortion, even when I’m just about matching levels.

Can anybody shed some light or provide conjecture on the implementation? :slight_smile:


(taktik) #2

Yup, that’s basically it.

It’s:

with Drive [0 to 1] and Input [-1 to 1]
Output = pow(abs(Input), 1.0 - Drive * 0.9))
– followed by a auto-DC filter.

The Drive parameter modifies the shape.
The Tone parameter controls a shelf filter’s gain at 1200 Hz

See plot on wolframalpha how the drive parameter modifies the shape.


(ffx) #3

Thanks taktik! Any chance you would also share the exact “shape” soft-clipping algorithm?


(gentleclockdivider) #4

scroll down how I recreated the distortion in reaktor and with renoise built in modules
In renoise the shift distortion is just a filter + a rectitifier , the recitification can be achieved by inserting a distortion module after the filter (set to shift because this does the actual rectifiaction , absolute value )

The simple distortion is just an arctan , imho tanh sounds much better


(ffx) #5

No love for me, as usual :unicorn:


(gentleclockdivider) #6

like I said ,
The soft distortion is just a atan curve , but tanh sounds much better imho
Try this one in func shaper where x is input
x / (((abs.x)/1)+1)


(ffx) #7

@gentleclockdivider are you referring to me? I would like to know the exact algorithm of the softclipping mode of the distortion plugin, so I can accurately reproduce it in lua prototype for converting my songs.

Hm, using Reaktor for this would be fine, too. I wasn’t aware that you can go down to such an algorithmic base level in Reaktor.

I cannot see anything on your screenshot btw., way too small.

Once you name it “simple distortion”, once you name it “soft distortion”. So I assume you are referring to the first mode of the distortion plugin, which is a hardclipping or something?

Can you please elaborate…


(gentleclockdivider) #8

Sure you can go low level in reakor , it’s called reaktor core :slight_smile: , and it was first introduced way back in 2004 , so it’s almost 15 yeaars old
How do you think all the new zdf filters are made , exactly , in reaktor core!
But you can make distortions in reaktor with the even the basic primary math modules (screenshot shows core math modules ) , iow these are juST TRANSFER FUNCTIONS

You can maximize the screenshot , right click open in new tab

If you have soft distorion , which is the renoise default one , you’ll notice the output signal has some rounded corners , that would be an atan
Here I did the same in reakotr primary , the soft clip is just
First your input signal should be multiplied , that’s the input gain and defines the amount of distortion , the output of that signal is divided by the rectified input signal ( after being divided by Y and +Y)
Variable Y defines clipping amount
so
See screenshot
This would be the correct one
x/ ((absx)/y)+y

The new filter drive use a ‘tanh’ and inho sounds much better


(dblue) #9

MusicDSP.org is a great resource: http://www.musicdsp.org/en/latest/Effects/index.html

A lot of useful (and some not so useful!) DSP code snippets to learn from :slight_smile:

Search for “soft”, “saturation”, or “waveshaper”, and you’ll find a bunch of different examples that should do the trick.


(ffx) #10

Thanks! Is Reaktor also good performance wise? Does it support VST3 maybe even?

Still don’t get this one. I mean the distortion mode “Shape” in Renoise 3.1.1.

Your formula looks like this:
14

See how your graph starts to affect the waveform waaay too early, even always? The Renoise softclipper only affects transients, so the curving starts very late, and then is pretty steep, I would assume. It could even use something like:

if (abs(x)<0.8) do nothing
else do something

The point is I need the very exact, 100% accurate formula to exactly be able to recreate the same mixing result in another daw. Just like Sisyphus.

I guess it will more something like this:
55

Oh nice, in new design. I thought it was gone.


(ffx) #11

Any idea how I can check a value if it is undefined yet in macOS Grapher? I mean, how can I realize f’(x) in Grapher?

EDIT: Nice, found out there also is sign() in grapher:
57

But I need exact formula, please.


(ffx) #12

Psycle shaper:
50

Nice grapher quickmanual: http://y.barois.free.fr/grapher/Documentation_files/GCXENManual16042014A.pdf


(gentleclockdivider) #13

Why is a = 0.26 ?
Maybe play around a bit with that value 0.5 …1

Reaktor does not host vst’s , but it can run as a vst or standalone , performannce wise …it all depends but it will never be as efficieent as pure c++ code , but since distortion is just a mono voice , cpu will be verry verry low


(gentleclockdivider) #14

set a to 0.2 and input gain around +24db which equals a 100% drive in renoise dist.device ( make sure that under song options track headroom is set to 0db )
Results are the same


(ffx) #15

It is very kind of you that you want to sell me your algorithm. Yet my original question was a different :smile: I want the EXACT algorithm, not a cool distortion algorithm. At pre-gain = 0, that kind of result, the soft clipper, just exactly reacting as in Renoise.


(ffx) #16

@gentleclockdivider Does Reaktor 6 provide some kind of scripting, too, similar to formula device?


(gentleclockdivider) #17

Sadly enough , no
Reaktor is all about visually connecting modules ,
Here’s a reaktor implementation of the robin schmidt funcshaper preset 'freestyle curve ’


(ffx) #18

LOL seems like the concept has gone a bit too strict. Lot of elements for a simple math equation.


(gentleclockdivider) #19

noppes ; only the elements used in the equation , nothing more , nothing less
But yes , wiring modules together is indeed slower


(gentleclockdivider) #20

And this is the inside of a tanh module . :slight_smile:

Some modules are needed because they determine how the processing is done , since it is crucial that these happen on every sample tick ( and in sync )

You have to know that there are only about 34 low level core modules ,ranging from math operations , ,memory , scoped busses ,bitflow , logic etc…
These are the low(est) level building blocks , but there are hundred of macros ( made with these low level building blocks ) , and these are all you need actually
But yeah , max msp cod gen is probably what you are looking for