HISE Logo Forum
    • Categories
    • Register
    • Login

    More Types of Saturation

    Scheduled Pinned Locked Moved General Questions
    12 Posts 5 Posters 799 Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • HISEnbergH
      HISEnberg @Zazzi
      last edited by

      @Zazzi Scriptnode. Try some of the Math operators. Also peruse Faust's library, they have tons of waveshaper algorithms.

      1 Reply Last reply Reply Quote 1
      • griffinboyG
        griffinboy @Zazzi
        last edited by griffinboy

        @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.

        Z L 2 Replies Last reply Reply Quote 3
        • Z
          Zazzi @griffinboy
          last edited by

          @griffinboy Thanks fo help, i was trying but i don't understand why it doesn't work:Screenshot 2024-06-28 alle 00.29.34.png

          griffinboyG 3 Replies Last reply Reply Quote 0
          • griffinboyG
            griffinboy @Zazzi
            last edited by griffinboy

            @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.

            1 Reply Last reply Reply Quote 0
            • griffinboyG
              griffinboy @Zazzi
              last edited by griffinboy

              This post is deleted!
              1 Reply Last reply Reply Quote 0
              • griffinboyG
                griffinboy @Zazzi
                last edited by griffinboy

                @Zazzi

                (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)
                				{
                		
                				}
                	}
                };
                
                Z 1 Reply Last reply Reply Quote 1
                • Z
                  Zazzi @griffinboy
                  last edited by

                  @griffinboy Thank you very much, do you have a social where i can contact you for a work?

                  griffinboyG 1 Reply Last reply Reply Quote 0
                  • griffinboyG
                    griffinboy @Zazzi
                    last edited by griffinboy

                    @Zazzi
                    Feel free to reach out on discord:
                    Discord: https://discord.com/invite/2QK5H7Gx

                    I 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.

                    Z 1 Reply Last reply Reply Quote 0
                    • Z
                      Zazzi @griffinboy
                      last edited by

                      @griffinboy I sent you the friend request :)

                      1 Reply Last reply Reply Quote 0
                      • M
                        Mighty23
                        last edited by

                        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;
                        };
                        

                        Free Party, Free Tekno & Free Software too

                        1 Reply Last reply Reply Quote 2
                        • L
                          LozPetts @griffinboy
                          last edited by

                          @griffinboy Can't wait to see what you make, this sounds amazing!

                          1 Reply Last reply Reply Quote 1
                          • First post
                            Last post

                          26

                          Online

                          1.7k

                          Users

                          11.8k

                          Topics

                          102.7k

                          Posts