Forum

    • Register
    • Login
    • Search
    • Categories

    Delay sample node

    Feature Requests
    3
    15
    261
    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.
    • ustk
      ustk last edited by ustk

      @Christoph-Hart Is there a way to get a delay node in sample? A fix 1 sample and/or a variable one would help filter design

      1 Reply Last reply Reply Quote 0
      • ustk
        ustk last edited by ustk

        This post is deleted!
        1 Reply Last reply Reply Quote 0
        • Christoph Hart
          Christoph Hart last edited by Christoph Hart

          This is a more or less functional delay in SNEX:

          template <int NV> struct sample_delay
          {
              SNEX_NODE(sample_delay);
              
              //! Type declarations
              
              // the max size for the delay
              static const int MaxBufferSize = 128;
              // we assume stereo operation
              static const int NumChannels = 2;
              
              // a stereo frame (just two float numbers next to each other)
              using FrameData = span<float, NumChannels>;
              
              // a fixed size buffer type for MaxBufferSize frames
              using DelayBufferType = span<FrameData, MaxBufferSize>;
              
              // A index type that will wrap around its upper limit
              using IndexType = index::wrapped<MaxBufferSize>;
              
              //! Member variables
              DelayBufferType buffer;
              IndexType readBuffer;
              IndexType writeBuffer;
              
              // Reset the processing pipeline here
              void reset()
              {
                  // clear the buffer
                  for(auto& frame: buffer)
                      for(auto& s: frame)
                          s = 0.0f;
                          
                  // set the write buffer offset (= delay) to any value
                  writeBuffer = 50;
              }
              
              void processFrame(FrameData& d)
              {
                  // write the current frame to the buffer
                  buffer[++writeBuffer] = d;
                  
                  // read from the read position (behind the write position)
                  d = buffer[++readBuffer];
              }
              
              // A dummy method if you call it with 1 channel
              void processFrame(span<float, 1>& data) {}
              
              template <typename ProcessDataType> void process(ProcessDataType& data)
              {
                  // Create a FrameProcessor from the process data
                  auto fp = data.toFrameData();
                  
                  // iterate over the frames and call processFrame above
                  while(fp.next())
                      processFrame(fp.toSpan());
              }
              
              // Unused callbacks...
              
              void prepare(PrepareSpecs ps) {}
              void handleHiseEvent(HiseEvent& e) {}
              void setExternalData(const ExternalData& d, int index) {}
              template <int P> void setParameter(double v) {}
          };
          

          I'll leave it as excercise for the reader to make the delay time a parameter 🙂

          ustk 1 Reply Last reply Reply Quote 3
          • ustk
            ustk @Christoph Hart last edited by

            @Christoph-Hart Oh great I'll study this with attention!
            And what if I use a frame1_block with send/receive? It seems that the signal is then received a sample later right?

            1 Reply Last reply Reply Quote 0
            • Christoph Hart
              Christoph Hart last edited by

              If the receive node is before the send node, then yes, there will be a delay of a single sample.

              1 Reply Last reply Reply Quote 0
              • orange
                orange last edited by orange

                I can't get decimal value sample delay with Simple Gain Delay (with using getMilliSecondsForSamples) and Latency Compensation. For sample delay, only integer values are working.

                For example, there is no difference between 2.2 and 2.4 sample delay. Hise applies 2 samples on both of them. Am I missing something?

                develop Branch / XCode 13.1
                macOS Monterey / M1 Max

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

                  @orange delay can only be multiples of one sample. Any ms value is rounded to the nearest sample, so the opposite is only integer samples can be computed to decimal ms for a given samplerate.
                  Or in other words, a system cannot compute between samples since it is the lowest discrete value.
                  That been said, if you need more precision, then you should consider oversampling in scriptnode and set the delay in there. (But I am not sure in the end this will be delayed of the amount you set in the oversampled container when going back to the original samplerate world)

                  1 Reply Last reply Reply Quote 1
                  • Christoph Hart
                    Christoph Hart last edited by

                    @orange What you need is a interpolating delay line, then you can delay by non-integer sample values. There is a index type in SNEX which offers interpolation.

                    It's actually used in the PitchShifter example (which also needs a varying interpolating delay line for the Doppler effect):

                    https://github.com/christophhart/hise_tutorial/blob/77ed71405fd1d5a9cdfd9b827637bc666d3a35f4/PitchShifting/DspNetworks/CodeLibrary/snex_node/PitchShifter.h#L58

                    ustk 2 Replies Last reply Reply Quote 2
                    • orange
                      orange last edited by

                      I will check it out, thanks guys!

                      develop Branch / XCode 13.1
                      macOS Monterey / M1 Max

                      1 Reply Last reply Reply Quote 0
                      • ustk
                        ustk @Christoph Hart last edited by ustk

                        @Christoph-Hart So is your example a good start for designing filters? If I mix pre and post delay with coefficients...
                        Or is there a "node only" way for the novice?

                        1 Reply Last reply Reply Quote 0
                        • ustk
                          ustk @Christoph Hart last edited by ustk

                          @Christoph-Hart Hmm... I just copied/pasted your sample delay script above in a SNEX file and this is what I get:

                          Untitled.png

                          1 Reply Last reply Reply Quote 0
                          • Christoph Hart
                            Christoph Hart last edited by

                            I think you have to name the snex file exactly lile the class, so sample_delay.

                            However I think I need to think about a better way of quickly sharing examples, something like the HiseSnippet function for SNEX - currently all Snex code management is file based.

                            ustk 1 Reply Last reply Reply Quote 1
                            • ustk
                              ustk @Christoph Hart last edited by

                              @Christoph-Hart Thanks this seems to work...

                              • And what is the purpose of the clickable SNEX logo?

                              • At first, I thought it would call a code editor, but apparently, we can only edit the SNEX file externally right?

                              • So when we edit and save a SNEX file, does Hise automatically handle the update without restarting?

                              1 Reply Last reply Reply Quote 0
                              • Christoph Hart
                                Christoph Hart last edited by

                                If your in the workbench you can edit the snex node code when you press the snex button but I have no idea what it does in HISE lol.

                                ustk 1 Reply Last reply Reply Quote 1
                                • ustk
                                  ustk @Christoph Hart last edited by ustk

                                  @Christoph-Hart 🙂
                                  I think I might more often use SNEX from within Hise than the workbench at least for little things. Or maybe we can work in both at the same time, then each time you save in the workbench Hise takes the update into account...

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

                                  7
                                  Online

                                  983
                                  Users

                                  6.6k
                                  Topics

                                  60.8k
                                  Posts