More Types of Saturation
-
@Zazzi Scriptnode. Try some of the Math operators. Also peruse Faust's library, they have tons of waveshaper algorithms.
-
@Zazzi
Use scriptnode, see the 'Snex Shaper' node.
When you create a new file inside the node, and then expand the node, you will be able to edit the code, and you will find a function which has a statement that says:
'Return input'To create your own waveshaper distortion, you simply need to return something other than input.
By doing this, you are manipulating the digital signal, which causes it to distort.
Here are a couple of algorithms that you can tweak and experiment with:return ( 1.7finput + -0.5fMath.pow(input,2.0f) + -0.2fMath.pow(input,3.0f) - 0.75f(Math.pow(input,2.0f) - 1.9f*Math.pow(input,3.0f) + Math.pow(input,4.0f)));
return 0.6f + (input-0.6f) / Math.pow(1.0f+((input-0.6f)/(1.0f-0.6f)) , 2.0f);
If you want simple digital distortion, I recommend searching for waveshaper algorithms such as these, and experiment with different ways of implementing them.
Things get fun when you have multiple waveshapers mixed (wet/dry) one after the other, with different lowpass filters inbetween the waveshapers.
I recommend watching a youtube video named 'fifty shades of distortion' for some inspiration.Edit:
If you are wanting to emulate an Analog style saturation, things get much more complex. You have to start using some really advanced maths. I am currently working on a tube circuit model, which I'll release here when it's done. Using that, you could recreate the circuit of different tube amps and get an accurate distortion out.
These typically sound better than waveshapers becuase they react very dynamically to different volume levels, which sounds very lively. -
@griffinboy Thanks fo help, i was trying but i don't understand why it doesn't work:
-
@Zazzi
Interesting, I assume it works fine when you set it to 'return input' ?
I shall take a look to see if it has the same issue on my system.Edit:
There was a copy paste mistake in my math, here is the working version:return ( 1.7f * input + -0.5f * Math.pow(input,2.0f) + -0.2f * Math.pow(input,3.0f) - 0.75f * ( Math.pow(input,2.0f) - 1.9f * Math.pow(input,3.0f) + Math.pow(input,4.0f) ) );
Be sure to stick a 'gain' node before the saturator.
The other algorithm I gave is broken in this context though, don't use it.
-
This post is deleted! -
(edit) version 2.5
If you want a spicer distortion sound (nonlinear stuff)
then paste this into your snex node and read the instructions in the code.// Important: replace the two instances of 'NAME' below, with the name of your snex node FILE template <int NumVoices> struct NAME { SNEX_NODE(NAME); float a = 0.6f; float out = 0.0f; float saturate(float input) { if(input < a) { out = input; } else if(input > a) { // This is the distortion formula there is an alternate one below which you can swap out. // Experiment with different values in the equations. out = a + (input-a) / Math.pow(1.0f+((input-a)/(1.0f-a)) , 2.0f); // algorithm 2: use the two lines of code below, and comment out the line above this // a = 0.0f; // out = ( 1.58f*input + -0.16f*Math.pow(input,2.0f) + -0.42f*Math.pow(input,3.0f) - 0.2f*(Math.pow(input,2.0f) - 2.0f*Math.pow(input,3.0f) + Math.pow(input,4.0f))); } else if(input > 1.0f) { out = (a + 1.0f) / 2.0f; } return out; } float getSample(float input) { if(input>0.0f) { saturate(input); } else { input = input * -1.0f; saturate(input); out = out * -1.0f; } return out; } // These functions are the glue code that call the function above template <typename T> void process(T& data) { for(auto ch: data) { for(auto& s: data.toChannelData(ch)) { s = getSample(s); } } } template <typename T> void processFrame(T& data) { for(auto& s: data) s = getSample(s); } void reset() { } void prepare(PrepareSpecs ps) { } void setExternalData(const ExternalData& d, int index) { } template <int P> void setParameter(double v) { if(P==0) { } } };
-
@griffinboy Thank you very much, do you have a social where i can contact you for a work?
-
@Zazzi
Feel free to reach out on discord:
Discord: https://discord.com/invite/2QK5H7GxI am a novice programmer, but I am very ambitious with my audio projects, and so I often deal with very technical aspects.
If you need help with anything let me know and I can point you in the right direction, I love to help. -
@griffinboy I sent you the friend request :)
-
I made this sketch in Faust to allow us to test different types of saturation
import("stdfaust.lib"); // Parameters drive = hslider("Drive", 1, 1, 10, 0.1); saturationType = nentry("Saturation Type", 0, 0, 4, 1); dryWet = hslider("Dry/Wet", 1, 0, 1, 0.01); outGain = hslider("Output Gain", 1, 0, 2, 0.1); // Saturation Functions saturate(x) = (saturationType == 0) * aa.tanh1(x) + (saturationType == 1) * aa.arctan(x) + (saturationType == 2) * aa.hardclip(x) + (saturationType == 3) * aa.cubic1(x) + (saturationType == 4) * aa.hyperbolic(x); // Main Process process = _ <: (_, (*(drive) : saturate)) : dry_wet(dryWet) : *(outGain) with { dry_wet(mix, dry, wet) = (1-mix)*dry + mix*wet; };
-
@griffinboy Can't wait to see what you make, this sounds amazing!