HISE Logo Forum
    • Categories
    • Register
    • Login

    Using LUT on SNEX

    Scheduled Pinned Locked Moved Unsolved General Questions
    16 Posts 6 Posters 538 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.
    • orangeO
      orange
      last edited by orange

      I have a table like below.

      Can we use this table in the snex_shaper node for waveshaper purposes, with linear interpolation?

      Like Shape FX module do?

      {
      	0.000000000000,0.026395170504,0.112717516501,0.28967484953,0.325145529984,
      	0.431252112449,0.637287699521,0.743252764286,0.849147785350,0.954973246465
      
      }
      

      develop Branch / XCode 13.1
      macOS Monterey / M1 Max

      Dan KorneffD griffinboyG 2 Replies Last reply Reply Quote 0
      • Dan KorneffD
        Dan Korneff @orange
        last edited by

        @orange I'm not sure about the shaper node, but I'm using a waveshaper with lookup table in SNEX and C++ node.

        Dan Korneff - Producer / Mixer / Audio Nerd

        orangeO 1 Reply Last reply Reply Quote 1
        • orangeO
          orange @Dan Korneff
          last edited by

          @Dan-Korneff Lookup Table is what I'm aiming for. It doesn't have to be snex_shaper, snex is fine too.

          Is there a small example?

          develop Branch / XCode 13.1
          macOS Monterey / M1 Max

          ustkU 1 Reply Last reply Reply Quote 0
          • ustkU
            ustk @orange
            last edited by ustk

            @orange I used a document I found by chance in tools/snex_playground/all/IndexDoc.md
            I wonder why such a treasure isn't in the doc, @Christoph-Hart ?

            There's everything inside to create a LUT and interpolate

            Can't help pressing F5 in the forum...

            1 Reply Last reply Reply Quote 1
            • orangeO orange marked this topic as a question on
            • Dan KorneffD
              Dan Korneff
              last edited by

              I did something like this:

              #pragma once
              #include <JuceHeader.h>
              
              namespace project
              {
              using namespace juce;
              using namespace hise;
              using namespace scriptnode;
              
              // ==========================| The node class with all required callbacks |==========================
              
              template <int NV> struct LUT_Test: public data::base
              {
                  // Metadata Definitions ------------------------------------------------------------------------
                  SNEX_NODE(LUT_Test);
                  
                  struct MetadataClass
                  {
                      SN_NODE_ID("LUT_Test");
                  };
              
              
                      // Constants for the Lookup Table --------------------------------------------------------------
                          static constexpr int tableSize = 200;       // The size of the lookup table array
                          static constexpr float xMin = -1.0f;        // Minimum input value (start of the input range)
                          static constexpr float xMax = 1.0f;         // Maximum input value (end of the input range)
                          static constexpr float xRange = xMax - xMin;  // Total range of input values
                  
              
                      // Lookup Table Data ---------------------------------------------------------------------------
                  static constexpr float lookupTable[tableSize] = {
                      -0.356490f, -0.357427f, -0.358393f, -0.359388f, -0.360412f, -0.361464f, -0.362544f, -0.363653f, -0.364790f, -0.365954f, 
                      -0.367146f, -0.368366f, -0.369613f, -0.370887f, -0.372188f, -0.373515f, -0.374870f, -0.376251f, -0.377658f, -0.379091f, 
                      -0.380551f, -0.382031f, -0.383487f, -0.384854f, -0.386069f, -0.387067f, -0.387784f, -0.388167f, -0.388236f, -0.388037f, 
                      -0.387613f, -0.387010f, -0.386272f, -0.385446f, -0.384574f, -0.383703f, -0.382877f, -0.382142f, -0.381541f, -0.381120f, 
                      -0.380925f, -0.380999f, -0.381387f, -0.382135f, -0.383288f, -0.384889f, -0.386944f, -0.389391f, -0.392161f, -0.395186f, 
                      -0.398397f, -0.401724f, -0.405101f, -0.408457f, -0.411725f, -0.414835f, -0.417719f, -0.420308f, -0.422534f, -0.424328f, 
                      -0.425621f, -0.426345f, -0.426464f, -0.425989f, -0.424939f, -0.423329f, -0.421179f, -0.418503f, -0.415321f, -0.411648f, 
                      -0.407502f, -0.402900f, -0.397859f, -0.392396f, -0.386529f, -0.380274f, -0.373649f, -0.366634f, -0.359082f, -0.350815f, 
                      -0.341658f, -0.331433f, -0.319963f, -0.307071f, -0.292583f, -0.276464f, -0.258907f, -0.240127f, -0.220341f, -0.199765f, 
                      -0.178613f, -0.157102f, -0.135447f, -0.113863f, -0.092567f, -0.071774f, -0.051659f, -0.032214f, -0.013375f, 0.004921f, 
                      0.022736f, 0.040134f, 0.057177f, 0.073928f, 0.090451f, 0.106808f, 0.123062f, 0.139276f, 0.155513f, 0.171836f, 
                      0.188308f, 0.204992f, 0.221950f, 0.239246f, 0.256943f, 0.275078f, 0.293520f, 0.312062f, 0.330498f, 0.348620f, 
                      0.366224f, 0.383101f, 0.399047f, 0.413853f, 0.427315f, 0.439226f, 0.449378f, 0.457566f, 0.463622f, 0.467645f, 
                      0.469852f, 0.470458f, 0.469678f, 0.467729f, 0.464826f, 0.461186f, 0.457023f, 0.452555f, 0.447995f, 0.443562f, 
                      0.439469f, 0.435933f, 0.433164f, 0.431234f, 0.430080f, 0.429634f, 0.429825f, 0.430586f, 0.431847f, 0.433540f, 
                      0.435594f, 0.437942f, 0.440514f, 0.443241f, 0.446055f, 0.448886f, 0.451665f, 0.454324f, 0.456793f, 0.459003f, 
                      0.460886f, 0.462372f, 0.463417f, 0.464063f, 0.464372f, 0.464405f, 0.464224f, 0.463891f, 0.463468f, 0.463016f, 
                      0.462596f, 0.462272f, 0.462104f, 0.462155f, 0.462484f, 0.463117f, 0.464024f, 0.465173f, 0.466533f, 0.468071f, 
                      0.469755f, 0.471553f, 0.473432f, 0.475361f, 0.477308f, 0.479239f, 0.481124f, 0.482929f, 0.484623f, 0.486174f, 
                      0.487549f, 0.488716f, 0.489644f, 0.490299f, 0.490650f, 0.490665f, 0.490311f, 0.489556f, 0.488369f, 0.486716f
                  };
              
              
                  // set to true if you want this node to have a modulation dragger
                  static constexpr bool isModNode() { return false; };
                  static constexpr bool isPolyphonic() { return NV > 1; };
                  // set to true if your node produces a tail
                  static constexpr bool hasTail() { return false; };
                  // set to true if your doesn't generate sound from silence and can be suspended when the input signal is silent
                  static constexpr bool isSuspendedOnSilence() { return false; };
                  // Undefine this method if you want a dynamic channel count
                  static constexpr int getFixChannelAmount() { return 2; };
              
                  // Define the amount and types of external data slots you want to use
                  static constexpr int NumTables = 0;
                  static constexpr int NumSliderPacks = 0;
                  static constexpr int NumAudioFiles = 0;
                  static constexpr int NumFilters = 0;
                  static constexpr int NumDisplayBuffers = 0;
              
                  // Scriptnode Callbacks ------------------------------------------------------------------------
              
                  void prepare(PrepareSpecs specs)
                  {
                      // Prepare your node with specifications
                  }
              
                  void reset()
                  {
                      // Reset any node states
                  }
              
                  template <typename T> void process(T& data)
                  {
                      static constexpr int NumChannels = getFixChannelAmount();
                      auto& fixData = data.template as<ProcessData<NumChannels>>();
              
                      auto fd = fixData.toFrameData();
              
                      while (fd.next())
                      {
                          processFrame(fd.toSpan());
                      }
                  }
              
              template <typename T> void processFrame(T& data)
              {
                  for (int i = 0; i < data.size(); ++i)
                  {
                      float input = data[i];
              // If the input sample is below a small threshold, treat it as silence to save a little processing
                      if (Math.abs(input) < 1e-6)  // threshold value for silence
                      {
                          data[i] = 0.0f;
                          continue;
                      }
              
              // Normalize the input sample from its range [min, max] to [0, 1] so you can index the table
                      float normalizedX = (input - (-1.0f)) / (1.0f - (-1.0f));  
              
                      // Scale the normalized input to the lookup table index range
                      float scaledIndex = normalizedX * (tableSize - 1);
              
                      // Get the integer part of the index
                      int index = static_cast<int>(scaledIndex);
              
                      // Get fractional part for interpolation
                      float frac = scaledIndex - index;
              
                      // Interpolate between two points in the table
                      float y0 = lookupTable[index];
                      float y1 = lookupTable[index + 1];
                      float output = y0 + frac * (y1 - y0);  // Linear interpolation
              
                      //If the output is very small set it to zero to prevent denormal numbers
                      if (Math.abs(output) < 1e-10) output = 0.0f;
              
                      data[i] = output;  // Process with lookup table
                  }
              }
              
              
                  int handleModulation(double& value)
                  {
                      return 0;
                  }
              
                  void handleHiseEvent(HiseEvent& e)
                  {
                      // Add logic for handling events here
                  }
              
                  void setExternalData(const ExternalData& data, int index)
                  {
                      // Handle external data (if any)
                  }
              
                  // Parameter Functions -------------------------------------------------------------------------
              
                  template <int P> void setParameter(double v)
                  {
                      if (P == 0)
                      {
                          // Handle parameters
                      }
                  }
              
                  void createParameters(ParameterDataList& data)
                  {
                      // Create parameters for the node
                      {
                          parameter::data p("MyParameter", { 0.0, 1.0 });
                          registerCallback<0>(p);
                          p.setDefaultValue(0.5);
                          data.add(std::move(p));
                      }
                  }
              };
              }
              
              

              Dan Korneff - Producer / Mixer / Audio Nerd

              orangeO JulesVJ 2 Replies Last reply Reply Quote 1
              • orangeO
                orange @Dan Korneff
                last edited by

                @Dan-Korneff Thanks.

                Faust also has great interpolators.

                Link Preview Image
                interpolators - Faust Libraries

                favicon

                (faustlibraries.grame.fr)

                develop Branch / XCode 13.1
                macOS Monterey / M1 Max

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

                  @orange

                  If snex has access to juce, there are many excellent interpolators and there is a lookuptable class even I believe. I used it before with a good result.
                  I haven't tried accessing it in Snex though.

                  1 Reply Last reply Reply Quote 1
                  • JulesVJ
                    JulesV @Dan Korneff
                    last edited by

                    @Dan-Korneff I tried to assign the code that you shared above to snex, but I get tons of errors.

                    Sorry for the inconvenience, do you have a chance to share the snex code directly?

                    template <int NV> struct LUTSNEX
                    {
                    	SNEX_NODE(LUTSNEX);
                    	
                    	
                    	// Constants for the Lookup Table --------------------------------------------------------------
                         int tableSize = 200;       // The size of the lookup table array
                         float xMin = -1.0f;        // Minimum input value (start of the input range)
                         float xMax = 1.0f;         // Maximum input value (end of the input range)
                         float xRange = xMax - xMin;  // Total range of input values
                        
                    	
                    	 // Lookup Table Data ---------------------------------------------------------------------------
                    	 float lookupTable[tableSize] = {
                    	 -0.356490f, -0.357427f, -0.358393f, -0.359388f, -0.360412f, -0.361464f, -0.362544f, -0.363653f, -0.364790f, -0.365954f, 
                    	 -0.367146f, -0.368366f, -0.369613f, -0.370887f, -0.372188f, -0.373515f, -0.374870f, -0.376251f, -0.377658f, -0.379091f, 
                    	 -0.380551f, -0.382031f, -0.383487f, -0.384854f, -0.386069f, -0.387067f, -0.387784f, -0.388167f, -0.388236f, -0.388037f, 
                    	 -0.387613f, -0.387010f, -0.386272f, -0.385446f, -0.384574f, -0.383703f, -0.382877f, -0.382142f, -0.381541f, -0.381120f, 
                    	 -0.380925f, -0.380999f, -0.381387f, -0.382135f, -0.383288f, -0.384889f, -0.386944f, -0.389391f, -0.392161f, -0.395186f, 
                    	 -0.398397f, -0.401724f, -0.405101f, -0.408457f, -0.411725f, -0.414835f, -0.417719f, -0.420308f, -0.422534f, -0.424328f, 
                    	 -0.425621f, -0.426345f, -0.426464f, -0.425989f, -0.424939f, -0.423329f, -0.421179f, -0.418503f, -0.415321f, -0.411648f, 
                    	 -0.407502f, -0.402900f, -0.397859f, -0.392396f, -0.386529f, -0.380274f, -0.373649f, -0.366634f, -0.359082f, -0.350815f, 
                    	 -0.341658f, -0.331433f, -0.319963f, -0.307071f, -0.292583f, -0.276464f, -0.258907f, -0.240127f, -0.220341f, -0.199765f, 
                    	 -0.178613f, -0.157102f, -0.135447f, -0.113863f, -0.092567f, -0.071774f, -0.051659f, -0.032214f, -0.013375f, 0.004921f, 
                    	 0.022736f, 0.040134f, 0.057177f, 0.073928f, 0.090451f, 0.106808f, 0.123062f, 0.139276f, 0.155513f, 0.171836f, 
                    	 0.188308f, 0.204992f, 0.221950f, 0.239246f, 0.256943f, 0.275078f, 0.293520f, 0.312062f, 0.330498f, 0.348620f, 
                    	 0.366224f, 0.383101f, 0.399047f, 0.413853f, 0.427315f, 0.439226f, 0.449378f, 0.457566f, 0.463622f, 0.467645f, 
                    	 0.469852f, 0.470458f, 0.469678f, 0.467729f, 0.464826f, 0.461186f, 0.457023f, 0.452555f, 0.447995f, 0.443562f, 
                    	 0.439469f, 0.435933f, 0.433164f, 0.431234f, 0.430080f, 0.429634f, 0.429825f, 0.430586f, 0.431847f, 0.433540f, 
                    	 0.435594f, 0.437942f, 0.440514f, 0.443241f, 0.446055f, 0.448886f, 0.451665f, 0.454324f, 0.456793f, 0.459003f, 
                    	 0.460886f, 0.462372f, 0.463417f, 0.464063f, 0.464372f, 0.464405f, 0.464224f, 0.463891f, 0.463468f, 0.463016f, 
                    	 0.462596f, 0.462272f, 0.462104f, 0.462155f, 0.462484f, 0.463117f, 0.464024f, 0.465173f, 0.466533f, 0.468071f, 
                    	 0.469755f, 0.471553f, 0.473432f, 0.475361f, 0.477308f, 0.479239f, 0.481124f, 0.482929f, 0.484623f, 0.486174f, 
                    	 0.487549f, 0.488716f, 0.489644f, 0.490299f, 0.490650f, 0.490665f, 0.490311f, 0.489556f, 0.488369f, 0.486716f
                    	    };
                    	
                    
                    	
                    	    // Define the amount and types of external data slots you want to use
                    	    int NumTables = 0;
                    	    int NumSliderPacks = 0;
                    	    int NumAudioFiles = 0;
                    	    int NumFilters = 0;
                    	    int NumDisplayBuffers = 0;
                    	
                    	
                    	
                    	// Initialise the processing specs here
                    	void prepare(PrepareSpecs ps)
                    	{
                    		
                    	}
                    	
                    	// Reset the processing pipeline here
                    	void reset()
                    	{
                    		
                    	}
                    	
                    	// Process the signal here
                    	template <typename ProcessDataType> void process(ProcessDataType& data)
                    	{
                    		for (int i = 0; i < data.size(); ++i)
                    		    {
                    		        float input = data[i];
                    		// If the input sample is below a small threshold, treat it as silence to save a little processing
                    		        if (Math.abs(input) < 1e-6)  // threshold value for silence
                    		        {
                    		            data[i] = 0.0f;
                    		            continue;
                    		        }
                    		
                    		// Normalize the input sample from its range [min, max] to [0, 1] so you can index the table
                    		        float normalizedX = (input - (-1.0f)) / (1.0f - (-1.0f));  
                    		
                    		        // Scale the normalized input to the lookup table index range
                    		        float scaledIndex = normalizedX * (tableSize - 1);
                    		
                    		        // Get the integer part of the index
                    		        int index = static_cast<int>(scaledIndex);
                    		
                    		        // Get fractional part for interpolation
                    		        float frac = scaledIndex - index;
                    		
                    		        // Interpolate between two points in the table
                    		        float y0 = lookupTable[index];
                    		        float y1 = lookupTable[index + 1];
                    		        float output = y0 + frac * (y1 - y0);  // Linear interpolation
                    		
                    		        //If the output is very small set it to zero to prevent denormal numbers
                    		        if (Math.abs(output) < 1e-10) output = 0.0f;
                    		
                    		        data[i] = output;  // Process with lookup table
                    		    }
                    	}
                    	
                    	// Process the signal as frame here
                    	template <int C> void processFrame(span<float, C>& data)
                    	{
                    	}
                    	
                    	// Process the MIDI events here
                    	void handleHiseEvent(HiseEvent& e)
                    	{
                    		
                    	}
                    	
                    	// Use this function to setup the external data
                    	void setExternalData(const ExternalData& d, int index)
                    	{
                    		
                    	}
                    	
                    	// Set the parameters here
                    	template <int P> void setParameter(double v)
                    	{
                    		
                    	}
                    };
                    
                    
                    Dan KorneffD 1 Reply Last reply Reply Quote 0
                    • Dan KorneffD
                      Dan Korneff @JulesV
                      last edited by

                      @JulesV post the errors.

                      Dan Korneff - Producer / Mixer / Audio Nerd

                      JulesVJ 1 Reply Last reply Reply Quote 0
                      • JulesVJ
                        JulesV @Dan Korneff
                        last edited by

                        @Dan-Korneff said in Using LUT on SNEX:

                        @JulesV post the errors.

                        I posted the code that I tried above

                        Dan KorneffD ustkU 2 Replies Last reply Reply Quote 0
                        • Dan KorneffD
                          Dan Korneff @JulesV
                          last edited by

                          @JulesV but the code doesn't show me the errors you're getting.

                          Dan Korneff - Producer / Mixer / Audio Nerd

                          JulesVJ 1 Reply Last reply Reply Quote 1
                          • ustkU
                            ustk @JulesV
                            last edited by

                            @JulesV @Dan-Korneff The thing with SNEX is that the errors in the console show up in a lazy fashion... Everything gets on one line, and often line numbers aren't showing anything but the last line number of the scripting window.

                            I tend to compile at every new line I write so I know when and where I introduced a mistake

                            Can't help pressing F5 in the forum...

                            1 Reply Last reply Reply Quote 1
                            • JulesVJ
                              JulesV @Dan Korneff
                              last edited by JulesV

                              @Dan-Korneff said in Using LUT on SNEX:

                              @JulesV but the code doesn't show me the errors you're getting.

                              Have you copy pasted my code above?

                              First of all, for xRange I get can't assign static constant to a dynamic expression error.

                              This time when I move this variable to the void process function, I get the Expected initializer for non templated membererror for the lookupTable array.

                              @ustk I am new to snex, have you tried the code above?

                              ustkU 1 Reply Last reply Reply Quote 0
                              • ustkU
                                ustk @JulesV
                                last edited by

                                @JulesV said in Using LUT on SNEX:

                                First of all, for xRange I get can't assign static constant to a dynamic expression error.

                                Probably here:

                                float xRange = xMax - xMin;
                                

                                This shouldn't be the case as the dependent variables are not static const
                                I get this all the time too, forcing to initialise using literals... @Christoph-Hart ?

                                Can't help pressing F5 in the forum...

                                1 Reply Last reply Reply Quote 1
                                • FortuneF
                                  Fortune
                                  last edited by Fortune

                                  @Christoph-Hart Can we ask you for a proper working example snippet for the use of lut in snex, which is asked in this topic?

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

                                    Sorry for the late reply. I just realized that I'm using a 3rd party node for my LUT test.
                                    Here's the full project you guys can take a look:
                                    https://hub.korneffaudio.com/index.php/s/xPcEwQicPH63Fkd

                                    Dan Korneff - Producer / Mixer / Audio Nerd

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

                                    40

                                    Online

                                    1.7k

                                    Users

                                    11.8k

                                    Topics

                                    103.0k

                                    Posts