HISE Logo Forum
    • Categories
    • Register
    • Login

    SNEX External data

    Scheduled Pinned Locked Moved Scripting
    11 Posts 3 Posters 468 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.
    • ?
      A Former User
      last edited by A Former User

      I'm working on the additive synth with Loris using SNEX

      Is there a way to programmatically and dynamically load audio files into a SNEX node via the external data? That way I can pass ratios/gains etc into the node and have everything all integrated nicely

      1566ee90-ef70-4630-8ff8-b2744e9fd49e-image.png

      Edit: ah just saw the Add External File Slot, is it related to this?

      1 Reply Last reply Reply Quote 0
      • d.healeyD
        d.healey
        last edited by d.healey

        Here's an example using the external audio file slot with script node. Might help you with SNEX.

        HiseSnippet 1250.3oc6W8zaaTDEeV6rI0lFAUhdeUN4HEhrgRAoJ.m3XSsnNwJNDUDBEMY2msG4YmY0tylDCBtvkdiy8FeD3J25W.NwWD9F.uYm0Y2E6DRrZpPHbjh76ey627l2+b+PoKDEICIVUNZZ.Prtu8foB03VioLAo6dDq21lE9LI0iIFcDDoH6NMfFEAdDKqxetVIqJqPR97Ge1tTNU3BYrHjikLW3YLelJia+leAiy6P8fiX94z9QM65JEsjbYLBnx10IAT2IzQv9TsZkrIVq11iojgCTTEDQrVYWo2zAikmKL5eLKhcJGzDMHCvCxvtij6oQrlKo0XF2q+rKdDgXY2OKLT1DFdW6dLO1k7yBGuSh.mLKxGOrJUDdkK.uF4gW8bvaAPxJGjVw.oGXOvMjEnxjnwyaY2UnfvgTLrmGJFcIk9AK6VRTCgZae5DnSHRboE0db85a4f+aymTsJF5iTNzXOlrCiCQNehSawHl.1liO+6bIezZYeojWKynHtTUOS+QfpkzOfCWrGUQODFBg.lVTaiKOjM1xYCCBc577FHUBBXCcpk4+s4fXjZrymhBqVQ6hFIHQKLmZec8uYymLLV3pXRgiTruTAGHpsY0uqZkpeeUm+tngCWnLcPJTx4P3BEqSTCuNCqIh8OEB2x4LJOFtTQ70qXJg8UmRjOi007lkSQonqfoNH.DWUdLI8gF+1W1UG404Qo7P8BfPESCAq8fyvhRSVUE68fnIJY.VVNWJGlrK8h4TUwJ.cYep.LFTHsSmZIhXpo4aK7Zqr3lBwGX2mobGuXLVZAXDiT2EXLsYx51sGNDbUY.bE6NO+toyQd2euqnk98SZIfTPXiWG8yCtw8ysJeWz+dk+00+9+qk9uPsTgov1F+WMcJL5SSoT1XrBfX+X+rQln0VkvqS5PYqWXmMAIHDBngvQx9b5zZQT8byCQfukyobo6jAruElerSfAW6p0nl6XpP.7nkY5zp23PUiq+k5PYrBWQrGUExt.uu38e.V16BsRQ2rXPJccMsNYY.H7RH9S7SpvFZZqTgMlIL27s8A04xvIIuQoemXsl4AIJIHexvKZP1gykmqWEgkl5hOLI75K4SCFKELWMKiFyP5N9xXzIov8ozninLtNWePbDN806.w.T4j1hVkOFBiRN30rquM9Gl6uuzCEY2g5hA1o8opw5hH2Ycb21MWe3bXsPxCdDyZaZhRHD80W8jkfKmaZtIIUSgkfkLmZ2ni0Rcobxw52aM3I5yzDuL3Sq55ZXcljGmDbJf3GZOjww0Di1NuJKKHI41GTigbkF4ovh4tBO3hYGXaLo0C67mXVZVPOlH8RYzoG8hBzj9zP7mKngdxp8ynvb8LSy5UkYdVO1AJHPW2Uf2D3bS.JOWcPbUrGtBHycJjasqa9SMucttJ9KW.O.abPl6z+Gb+W8p4u4X8VQ2+yu7k+57t+Ui9kG1T6db2QrcEV0eq89iZNm2ewueyt7M+Q+eK4xul8SYshUj4NFxc+a9518h4JlZbHP8ttauN2eWobhOMoa0xsX9ahdquI7gO0MTdhqYjjt57dIbvdEhjefeE6dZZmFjyRqn0MUI93Bam35pmz+d39eK1l2eIr4CVBadzRXyGtD173kvlOZIr4iuVaz6JuSrR5aFehL521zL1psfhaFjLIf7W75WoOL
        

        Libre Wave - Freedom respecting instruments and effects
        My Patreon - HISE tutorials
        YouTube Channel - Public HISE tutorials

        1 Reply Last reply Reply Quote 0
        • ?
          A Former User
          last edited by

          @d-healey Yeah that should work, i'll test it properly tomorrow, cheers!

          1 Reply Last reply Reply Quote 0
          • ?
            A Former User
            last edited by A Former User

            I'm getting a compilation error when exporting a SNEX node set to External Audio File slot:

            c:\users\desktop\hise\hi_dsp_library\node_api\nodes\processors.h(851): error C2338: T must be base class of data: :base (compiling source file ..\..\Source\Main.cpp) [D:\Documents\HISE\Loris Toolbox\DspNetworks\Binaries\Builds\Visual Studio2017\Loris Toolbox_DynamicLibrary.vcxproj]    
            

            Compilation works normally until I change the set the node to use the external file slot. Is there any obvious reason this might be happening? are they only able to use embedded data at compilation time?

            1 Reply Last reply Reply Quote 0
            • ?
              A Former User
              last edited by

              bump :) are snex nodes only able to use embedded data when compiled?

              1 Reply Last reply Reply Quote 0
              • ?
                A Former User
                last edited by

                @Christoph-Hart need your help with this when you get a moment, it's the last piece of the prototype puzzle

                Christoph HartC 1 Reply Last reply Reply Quote 0
                • Christoph HartC
                  Christoph Hart @A Former User
                  last edited by

                  @iamlamprey No, they should support dynamic external data - the granulator node was originally written in SNEX.

                  There are a few things you have to do though - I think you need to define a

                  static const int NumAudioFiles = 1;
                  

                  at the top of your SNEX class definition to let the C++ generator know to create a slot (otherwise it won't derive from data::base hence your compilation error.

                  ? 1 Reply Last reply Reply Quote 0
                  • ?
                    A Former User @Christoph Hart
                    last edited by

                    @Christoph-Hart Yeah I already have that defined, and able to load files and read them into SNEX. Still getting the error when I try compiling the node. I've made a new one, and done the old "comment everything out and slowly add pieces back in" trick, and the culprit is definitely the audio file slot, I'm probably referring the data incorrectly or something

                    Here's the full node, if it helps:

                    template <int NV> struct snexModalSynth
                    {
                    	/* NOTES
                    	200 sines was about 8% cpu on i7 8700K with Path of Exile open (lol) in a non-compiled SNEX node
                    	performance might be a little bit worse with Dyn instead of Span
                    	stereo would obviously be 2x 
                    	polyphony would be more as well...
                    
                    	when working with dyns, it must have some data referral
                    	be aware, when changing dyn values, it will also overwrite the relative span's data (dyns can have their memory addresses changed)
                    	*/
                    
                    	SNEX_NODE(snexModalSynth);
                    	
                    	double sr = 0.0;
                    	
                    	static const int NumAudioFiles = 1;
                    	
                    	const int numModes = 128;
                    
                    	dyn<float> ratios;
                    	span<double, 128> uptimes;
                    	span<double, 128> deltas;	
                    		
                    	float tick(int t)
                    	{
                    		return Math.sin(uptimes[t]);
                    	}
                    		
                    	// Initialise the processing specs here	
                    	
                    	void prepare(PrepareSpecs ps)
                    	{
                    		sr = ps.sampleRate;		
                    	}
                    	
                    	// Reset the processing pipeline here
                    	void reset()
                    	{
                    		for (int i = 0; i < uptimes.size(); i++)
                    		{
                    			uptimes[i] = 0.0;
                    		}				
                    	}
                    	
                    	
                    	
                    	// Process the signal as frame here
                    	template <int C> void processFrame(span<float, C>& data)
                    	{
                    		for (auto& s : data) // For each sample
                    		{
                    			float original = s;
                    
                    			for (int i=0; i < uptimes.size(); i++) // For each partial
                    			{
                    				s += tick(i);
                    				// need to add gains here...
                    				uptimes[i] += deltas[i];				
                    			}
                    
                    			// make sine waves not explode my ears
                    			s *= 0.006;
                    			s += original;
                    			
                    			// bring level back up 
                    			s *= 4;
                    		}
                    	}
                    	
                    	// Process the MIDI events here
                    	void handleHiseEvent(HiseEvent& e)
                    	{
                    		for (int i = 0; i < ratios.size(); i++)
                    		{
                    			const float scaledRatio = ratios[i] * 10.0;
                    			const double cyclesPerSecond = e.getFrequency() * scaledRatio;
                    			const double cyclesPerSample = cyclesPerSecond / sr;
                    			deltas[i] = 2.0 * 3.14159265359 * cyclesPerSample;
                    		}
                    	}
                    	
                    	// Use this function to setup the external data
                    	void setExternalData(const ExternalData& d, int index)
                    	{
                    		//refer this data to a dyn
                    		d.referBlockTo(ratios, 0);
                    	}
                    	
                    	template <int P> void setParameter(double v) {}	
                    	template <typename ProcessDataType> void process(ProcessDataType& data)  {}
                    	
                    };
                    
                    

                    Sidenote, is it possible to instantiate a Span using another variable as the size parameter? I've been doing it manually so far:

                    const int numModes = 128;
                    
                    
                    //both of these give errors
                    
                    span<double, numModes> deltas;	
                    span<double, int(numModes)> deltas;	
                    
                    
                    Christoph HartC 1 Reply Last reply Reply Quote 0
                    • Christoph HartC
                      Christoph Hart @A Former User
                      last edited by

                      You can use the static keyword to define a compile time constant (the const is just a hint to the compiler that you could cast away if you're into that kind of stuff).

                      Another option is to use a preprocessor definition:

                      static const int NumElements = 12;
                      #define NUM_ELEMENTS 12
                      
                      span<int, NumElements> x1;
                      span<int, NUM_ELEMENTS> x2
                      

                      I tried to compile the node and got this error:

                       static_assert failed due to requirement 'std::is_base_of<scriptnode::data::base, script_fx1_impl::test_node<1>>() || std::is_base_of<scriptnode::data::base, script_fx1_impl::test_node<1>>()' "T must be base class of data::base"
                      

                      So apparently I've implemented polymorphism in SNEX some time ago and forgot about it, so you need to derive your node from the data::base interface class in order to load external files:

                      template <int NV> struct snexModalSynth: public data::base 
                      

                      Apart from that it compiles.

                      ? 1 Reply Last reply Reply Quote 1
                      • ?
                        A Former User @Christoph Hart
                        last edited by

                        @Christoph-Hart awesome, i'll give it a spin on my end when i'm done rendering this unreal engine crap, cheers!

                        ? 1 Reply Last reply Reply Quote 0
                        • ?
                          A Former User @A Former User
                          last edited by

                          yep compiles successfully, thanks again :)

                          1 Reply Last reply Reply Quote 0
                          • O Orvillain referenced this topic on
                          • First post
                            Last post

                          5

                          Online

                          1.7k

                          Users

                          11.8k

                          Topics

                          102.3k

                          Posts