Old 07-21-2021, 01:52 PM   #1
gthibert
Human being with feelings
 
Join Date: Aug 2010
Posts: 10
Default JSFX flushing delay buffer

Hi,

I've made a slightly modified version of the Delay JSFX, and I'm trying to add a way to flush the buffer's delay. So far, I did this :

Code:
  x=0;
  loop(delaylen,
    x[0] = 0;
    x[1] = 0;
    x = x + 2;
  );
Which works sometimes, but I have problems other times. I don't know if my code is just wrong, but the problem (buffer is not completely emptied and there's glitches) occurs when the delay time is realy long and when multiple instances of the plugins are flushed at the same time.

Here's the complete code of the JSFX (mostly copied from the Delay JSFX):

Code:
desc: Delay Flush

slider1:300<0,100000,20>Delay (ms)
slider2:-120<-120,6,1>Feedback (dB)
slider3:0<-120,6,1>Mix In (dB)
slider4:0<-120,6,1>Output Wet (dB)
slider5:-120<-120,6,1>Output Dry (dB)
slider6:0<0,1,1{Off,On}>Resample On Length Change
slider7:0<1,0,1{Off,On}>Flush
slider8:multiplier_slider=1<0.1,10,0.05>Multiplier

in_pin:left input
in_pin:right input
out_pin:left output
out_pin:right output

@init
delaypos=0;

@slider
odelay=delaylen;
delaylen=slider1 * srate / 1000 * multiplier_slider;
//delaylen=min(slider1 * srate / 1000,500000);
odelay != delaylen ? (
  slider6 && odelay > delaylen ? (
      // resample down delay buffer, heh
      rspos=0; rspos2=0;
      drspos=odelay/delaylen;
      loop(delaylen,
         
         tpos = ((rspos)|0)*2;
         rspos2[0]=tpos[0];
         rspos2[1]=tpos[1];

         rspos2+=2;
         rspos+=drspos;
      );
      delaypos /= drspos;
      delaypos|=0;
      delaypos<0?delaypos=0;
  ) : (
    slider6 && odelay < delaylen ? (
        // resample up delay buffer, heh
        drspos=odelay/delaylen;
        rspos=odelay; 
        rspos2=delaylen*2;
        loop(delaylen,
           rspos-=drspos;
           rspos2-=2;
         
           tpos = ((rspos)|0)*2;
           rspos2[0]=tpos[0];
           rspos2[1]=tpos[1];

        );
        delaypos /= drspos;
        delaypos|=0;
        delaypos<0?delaypos=0;
    ) : (!slider6 && delaypos >= delaylen ? delaypos = 0);
  );
  freembuf(delaylen*2);
);


//flush buffer
slider7 == 1 ? (
  slider7 = 0;
  sliderchange(slider7);
  x=0;
  loop(delaylen,
    x[0] = 0;
    x[1] = 0;
    x = x + 2;
  );
);

wetmix = 2 ^(slider2/6);
drymix = 2 ^(slider3/6);
wetmix2 = 2 ^(slider4/6);
drymix2 = 2 ^(slider5/6);

@sample
dpint = delaypos*2;
os1=dpint[0];
os2=dpint[1];

dpint[0]=min(max(spl0*drymix + os1*wetmix,-4),4);
dpint[1]=min(max(spl1*drymix + os2*wetmix,-4),4);

(delaypos+=1) >= delaylen ? delaypos=0;

spl0=spl0*drymix2 + os1*wetmix2;
spl1=spl1*drymix2 + os2*wetmix2;
gthibert is offline   Reply With Quote
Old 07-21-2021, 05:27 PM   #2
gthibert
Human being with feelings
 
Join Date: Aug 2010
Posts: 10
Default Solution

So, I'm answering myself!

I've noticed the following in the JSFX doc :

Quote:
In the interest of avoiding common runtime hangs, the repeat count will be limited to approximately 1,000,000: if you need a loop with more iterations, you may wish to reconsider your design (or as a last resort, nest loops).
As my buffer was bigger than 1,000,000 on long delays, not all the values of the buffer were flushed with the loop.

I then discovered the memset() function.

Here's my solution (way more efficent) :

Code:
memset(0,0,delaylen*2);
gthibert is offline   Reply With Quote
Old 07-21-2021, 09:27 PM   #3
SaulT
Human being with feelings
 
Join Date: Oct 2013
Location: Seattle, WA
Posts: 876
Default

That's the ticket!

Something that I've experimented with is downsampling the delayed signal so that I can store longer signals. For example, if srate is 48 kHz then Nyquist is 24 kHz and half of that is 12 kHz so if I put a steep lowpass at 10 kHz or so then I could store every other sample, doubling my potential delay time.

If you're okay with an audibly lower fi sound then you could even go further and store every third or fourth sample, lowpassing at the appropriate places.

Restoring the signal would be just feeding it into a similar lowpass filter, adding in zeroes to fill in missing values. You would need to add a makeup gain.

Anyways, it's an idea I was messing around with, I think I implemented a very basic version of it in a concept plugin that's probably buried in a post somewhere. The idea there was that every repeat it would distort a little more, each echo eventually fading into noise.
SaulT is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 10:46 PM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.