HISE Logo Forum
    • Categories
    • Register
    • Login

    Distortion Whiz required...

    Scheduled Pinned Locked Moved General Questions
    15 Posts 4 Posters 969 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.
    • DanHD
      DanH
      last edited by

      I've created a distortion emulation which is pretty close to what I'm emulating. However the distortion I am emulating manages to really boost the first harmonic of the source material, leaving my emulation sounding a little weak by comparison.

      If anyone has any experience in this field please let me know :)

      DHPlugins / DC Breaks | Artist / Producer / DJ / Developer
      https://dhplugins.com/ | https://dcbreaks.com/
      London, UK

      griffinboyG Dan KorneffD 2 Replies Last reply Reply Quote 0
      • griffinboyG
        griffinboy @DanH
        last edited by griffinboy

        @DanH

        I have a waveshaping algorithm that boosts the first harmonic significantly.
        I am personally not a fan of this sound, it gets very messy at high gains, unless implement the nonlinearities that an analog amplifier would have.

        I don't have a picture of just the first harmonic, but here is that shaper, combined with other shapers to which get the full spectrum filled.

        0d300519-87cf-44ac-b507-b74bf154d0ee-image.png

        I'd have to know what profile you're aiming for to understand what we are talking about

        1 Reply Last reply Reply Quote 0
        • Dan KorneffD
          Dan Korneff @DanH
          last edited by

          @DanH how are you emulating? Waveshaper? Transfer Function?

          Dan Korneff - Producer / Mixer / Audio Nerd

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

            @Dan-Korneff
            Yes that's a good question.
            Are you using waveshapers, or something like Wave Domain filters?

            DanHD 1 Reply Last reply Reply Quote 0
            • DanHD
              DanH @griffinboy
              last edited by

              @griffinboy I'm using the Shape FX waveshaper, so not much ability to change it as any slight variance to the curve I have significantly changes the sound. I was thinking about adding an SNEX Shaper node to the chain simply to boost the fundamental.

              DHPlugins / DC Breaks | Artist / Producer / DJ / Developer
              https://dhplugins.com/ | https://dcbreaks.com/
              London, UK

              griffinboyG 2 Replies Last reply Reply Quote 0
              • griffinboyG
                griffinboy @DanH
                last edited by griffinboy

                @DanH
                Yes use a snex node.
                I don't recommend using the shapeFX, it's not precice for designing this type of effect, not to mention that you want to use scriptnode anyway, because more goes into distortion than just wave shapers.
                You have filters, multiple shapers with different gain stages, and logic to change the curve depending on the input gain.

                Edit* you say you want to use the node to 'simply' boost the fundamental, but to choose specific harmonics to boost, you'll have to use either trial and error, or Chebyshev polynomials.
                Look into Chebyshev polynomial waveshaping.

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

                  @DanH

                  I might have solved this if you are still looking for a solution.
                  The first harmonic is the sine wave, the second is generated by my algorithm.

                  This algorithm only boosts the first harmonic, no matter how high the gain is.

                  16afa3e1-3e5d-40d1-bf52-3d5367cf8e32-image.png

                  Let me know if you want the algorithm, if this is what you meant when you made the post.

                  Edit: if you were in fact referring to the fundamental needing boosting, rather than the first harmonic needing boosting, then that's even easier and I can solve that for you in a simple step.

                  DanHD 1 Reply Last reply Reply Quote 0
                  • DanHD
                    DanH @griffinboy
                    last edited by

                    @griffinboy ah amazing! Yes mainly the fundamental - but a small boost to the first harmonic is also really useful!

                    DHPlugins / DC Breaks | Artist / Producer / DJ / Developer
                    https://dhplugins.com/ | https://dcbreaks.com/
                    London, UK

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

                      @DanH

                      To make the fundamental louder, you simply need to mix the original signal with the saturated signal, that way you can control how loud the original fundamental is, compared to the generated saturation harmonics.
                      Having less distortion mixed in, means that the fundamental, by comparison, is louder.

                      Now, for the first harmonic, here is the snex code.
                      You will need to create a snex shaper node, create a new file inside the snex node and call it firstorder, then paste in the code at the bottom of this post.

                      694d901a-a34a-44eb-875e-6e5ba6cf9087-image.png

                      You will also want to place this filter afterwards, it gets rid of subsonic frequencies.
                      Create a wet / dry matrix (there is a template node for this) and a simple gain. Gain staging will allow you to control the loudness of the harmonic.

                      Code:

                      template <int NV> struct firstorder
                      {
                          SNEX_NODE(firstorder);
                          
                          // USE VERY HIGH INPUT AND OUTPUT GAIN (390 input gain)
                              // Generates first order harmonic only
                          
                          // Front end variables
                              float drive = 2.0f;    // Controls saturation
                              float mix = 0.5f;      // Dry/Wet Mix
                              float bias = 0.6f;     // Dynamic bias (if we need it)
                              float tone = 0.7f;     // Tone control for filtering (if we need it)
                              
                              float outGain = 0.7f; // (Control the volume of the whole signal after processing)
                              float preGain = 390.0f; // (an pre-gain for gain staging)
                          
                                  // Operating point and tube model parameters
                                  float E = 250.0f; // Anode voltage in Volts
                                  float Rp = 100000.0f; // Plate resistance in Ohms
                                  float Rk = 1000.0f; // Cathode resistance in Ohms
                                  float Ck = 10e-6f; // Cathode capacitance in Farads
                              
                                  // Quadric surface model coefficients
                                  float kp = 1.014e-5f;  // Coefficient for Vpk
                                  float kp2 = 5.498e-8f; // Coefficient for Vpk squared
                                  float kpg = 1.076e-5f; // Cross-product coefficient for Vgk * Vpk
                              
                                  // Internal state variables
                                  float Vk0 = 0.0f;  // Initial cathode voltage
                                  float Vp0 = 0.0f;  // Initial plate voltage
                          
                              float getSample(float input)
                              {
                                   // Apply pre-gain to the input
                                  float Vgk = input * preGain;
                          
                                  // Compute plate-to-cathode voltage
                                  float Vpk = E - Vgk;
                          
                                  // Compute the current through the plate using the quadric surface model
                                  float ip = kp2 * Vpk * Vpk + kpg * Vgk * Vpk + kp * Vpk;
                          
                                  // Apply the output gain
                                  float output = ip * outGain;
                          
                                  return output;
                              }
                          
                              // Process each sample of the data
                              template <typename T> void process(T& data)
                              {
                                  for (auto ch : data)
                                  {
                                      for (auto& s : data.toChannelData(ch))
                                      {
                                          s = getSample(s);
                                      }
                                  }
                              }
                          
                              // Process each sample for a single frame of data
                              template <typename T> void processFrame(T& data)
                              {
                                  for (auto& s : data)
                                      s = getSample(s);
                              }
                          
                              void reset()
                              {
                           
                              }
                          
                              // Set up Stereo processing 
                              static const int NUM_CHANNELS = 2;
                              // Get the project sampleRate
                              double sr = 0.0;
                              void prepare(PrepareSpecs ps)
                              {
                                  sr = ps.sampleRate;
                              }
                              
                              
                              void recomputeConstants()
                               {
                                   // Calculate constants based on initial conditions
                                   float k1 = kpg / (2.0f * kp2) + Rp / Rk + 1.0f;
                                   float k2 = k1 * (kp / kp2 + 2.0f * E) * kp2;
                                   float k3 = Rk * k2 + 1.0f;
                                   
                                   Vk0 = (k3 - Math.sqrt(k3 * k3 - 1.0f)) / (2.0f * Rk * k1 * k1 *kp2);
                                   
                                   Vp0 = E - Rp / Rk * Vk0;
                               }
                              
                              
                              void prepareToPlay(double sampleRate)
                                 {
                                     recomputeConstants();
                                 }
                                 
                                
                          
                          
                              void setExternalData(const ExternalData& d, int index)
                              {
                                  // Optional: External data setting
                              }
                          
                      
                          
                      
                      
                      
                          
                          // Process the MIDI events here
                          void handleHiseEvent(HiseEvent& e)
                          {
                              
                          }
                          
                          
                          
                          // Set the parameters here
                          template <int P> void setParameter(double v)
                          {
                              
                          }
                      };
                      
                      
                      DanHD 1 Reply Last reply Reply Quote 1
                      • DanHD
                        DanH @griffinboy
                        last edited by

                        @griffinboy Thank you! Will give this a try asap :)

                        DHPlugins / DC Breaks | Artist / Producer / DJ / Developer
                        https://dhplugins.com/ | https://dcbreaks.com/
                        London, UK

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

                          @DanH
                          If there are any problems let me know.
                          Copying and pasting snex can be a little weird sometimes... Surprise errors and such

                          Edit*
                          Realised that this code might produce a silent output.
                          If you do want it fixed, I can do that for you just let me know.
                          I tried to simplify it a bit but I think removing the controls impacted the functionality

                          DanHD 1 Reply Last reply Reply Quote 0
                          • DanHD
                            DanH @griffinboy
                            last edited by DanH

                            @griffinboy just got round to testing and it works well for boosting 2nd / 4th / 6th etc harmonics - all the even ones (My understanding is that the fundamental and the first harmonic are the same frequency). Sounds quite good in tandem with a distortion module and also good for adding a harmonic to sub bass :) So a big thanks for putting this together!

                            Were there meant to be some controls in the SNEX Shaper? Because nothing appears when the code is compiled...

                            I'm not sure I get your method of increasing the level of the fundamental. I need the mix to be at full anyway (unless I've misunderstood your suggestion). The picture below is a 50hz tone run through the distortion I'm trying to emulate and my own emulation layered on top. The key difference which I'm trying to emulate right now is the obvious increased level of the original distortion at 50hz (or the fundamental of any signal running through it).

                            DIZ.png

                            DHPlugins / DC Breaks | Artist / Producer / DJ / Developer
                            https://dhplugins.com/ | https://dcbreaks.com/
                            London, UK

                            Matt_SFM 1 Reply Last reply Reply Quote 0
                            • Matt_SFM
                              Matt_SF @DanH
                              last edited by Matt_SF

                              @DanH said in Distortion Whiz required...:

                              Were there meant to be some controls in the SNEX Shaper? Because nothing appears when the code is compiled...

                              Click on the 3 dots on the top-left corner of the SNEX node, select "Add Parameter" and give it a name.

                              Here you can then specify which variable you want to change using the knob :

                                  // Set the parameters here
                              	template <int P> void setParameter(double v)
                                  	{
                                  		if(P == 0)
                                  		{	
                                  			drive= (float)v;
                                  		}
                                  		if(P == 1)
                                  		{	
                                  			mix= (float)v;
                                  		}
                                  		if(P == 2)
                                  		{	
                                  			bias= (float)v;
                                  		}
                                              // etc...
                                  	}
                              

                              Develop branch
                              Win10 & VS17 / Ventura & Xcode 14. 3

                              DanHD 1 Reply Last reply Reply Quote 0
                              • DanHD
                                DanH @Matt_SF
                                last edited by

                                @Matt_SF thanks!

                                DHPlugins / DC Breaks | Artist / Producer / DJ / Developer
                                https://dhplugins.com/ | https://dcbreaks.com/
                                London, UK

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

                                  @DanH

                                  If I'm honest, those controls were removed because the algorithm was acting up. I wrote this one when I had much less understanding of distortion. It was meant to be a chebyshev waveshaper but it went wrong!

                                  In the following months I've been developing a much more accurate method for designing distortions. I shall be sharing it when it is ready.

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

                                  23

                                  Online

                                  1.7k

                                  Users

                                  11.9k

                                  Topics

                                  103.7k

                                  Posts