Old 09-22-2020, 05:50 AM   #1
brandflake11
Human being with feelings
 
Join Date: Dec 2018
Posts: 6
Default Turning Delay into 1in-8out Delay

Hello all,

I am currently learning Reaper's Jsfx programming by taking plugins and making them multichannel. I am really interested in taking the Delay plugin that comes stock with Reaper and turning it into a 1in-8out plugin. I have gotten very far, but for some reason, I can only get delays by working on delay lines 1 and 2.

I assume this is because I don't fully understand the programming involved in the main delay function. What I have done is taken the main programming that implements the delay, and duplicated it 8 times, including the variables used.

So, here is the block of programming that allows the delay to occur in the stock plugin:

Code:
odelay=delaylen;
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);
);
wetmix = 2 ^(slider2/6);
drymix = 2 ^(slider3/6);
wetmix2 = 2 ^(slider4/6);
drymix2 = 2 ^(slider5/6);
And here is what I have done with it 8 times to make it an 8 out delay, one duplication per delay line. This is the fourth delay line:

Code:
// Delay Line 4
odelay4 != delaylen4 ? (
  slider20 && odelay4 > delaylen4 ? (
      // resample down delay buffer, heh
      rspos4=0; rspos42=0;
      drspos4=odelay4/delaylen4;
      loop(delaylen4,
         
         tpos4 = ((rspos4)|0)*2;
         rspos42[0]=tpos4[0];
         rspos42[1]=tpos4[1];

         rspos42+=2;
         rspos4+=drspos4;
      );
      delaypos4 /= drspos4;
      delaypos4|=0;
      delaypos4<0?delaypos4=0;
  ) : (
    slider20 && odelay4 < delaylen4 ? (
        // resample up delay buffer, heh
        drspos4=odelay4/delaylen4;
        rspos4=odelay4; 
        rspos42=delaylen4*2;
        loop(delaylen4,
           rspos4-=drspos4;
           rspos42-=2;
         
           tpos4 = ((rspos4)|0)*2;
           rspos42[0]=tpos4[0];
           rspos42[1]=tpos4[1];

        );
        delaypos4 /= drspos4;
        delaypos4|=0;
        delaypos4<0?delaypos4=0;
    ) : (!slider20 && delaypos4 >= delaylen4 ? delaypos4 = 0);
p  );
  freembuf(delaylen4*2);
);
wetmix4 = 2 ^(slider8/6);
drymix4 = 2 ^(slider17/6);
wetmix42 = 2 ^(slider18/6);
drymix42 = 2 ^(slider19/6);
Here are my sliders:
Code:
slider1:0<0,4000,20>1st Delay (ms)
slider2:-120<-120,6,1>1st Feedback (dB)
slider3:0<0,4000,20>2nd Delay (ms)
slider4:-120<-120,6,1>2nd Feedback (dB)
slider5:0<0,4000,20>3rd Delay (ms)
slider6:-120<-120,6,1>3rd Feedback (dB)
slider7:0<0,4000,20>4th Delay (ms)
slider8:-120<-120,6,1>4th Feedback (dB)
slider9:0<0,4000,20>5th Delay (ms)
slider10:-120<-120,6,1>5th Feedback (dB)
slider11:0<0,4000,20>6th Delay (ms)
slider12:-120<-120,6,1>6th Feedback (dB)
slider13:0<0,4000,20>7th Delay (ms)
slider14:-120<-120,6,1>7th Feedback (dB)
slider15:0<0,4000,20>8th Delay (ms)
slider16:-120<-120,6,1>8th Feedback (dB)
slider17:0<-120,6,1>Mix In (dB)
slider18:-6<-120,6,1>Output Wet (dB)
slider19:0<-120,6,1>Output Dry (dB)
slider20:0<0,1,1{Off,On}>Resample On Length Change
And, here is what I have at the end, which I am figuring is where the signals come together:

Code:
@sample
dpint1 = delaypos1*2;
dpint2 = delaypos2*2;
dpint3 = delaypos3*2;
dpint4 = delaypos4*2;
dpint5 = delaypos5*2;
dpint6 = delaypos6*2;
dpint7 = delaypos7*2;
dpint8 = delaypos8*2;
os1=dpint1[0];
os2=dpint2[0];
os3=dpint3[0];
os4=dpint4[0];
os5=dpint5[0];
os6=dpint6[0];
os7=dpint7[0];
os8=dpint8[0];

dpint1[0]=min(max(spl0*drymix1 + os1*wetmix1,-4),4);
dpint2[0]=min(max(spl0*drymix2 + os2*wetmix2,-4),4);
dpint3[0]=min(max(spl0*drymix3 + os3*wetmix3,-4),4);
dpint4[0]=min(max(spl0*drymix4 + os4*wetmix4,-4),4);
dpint5[0]=min(max(spl0*drymix5 + os5*wetmix5,-4),4);
dpint6[0]=min(max(spl0*drymix6 + os6*wetmix6,-4),4);
dpint7[0]=min(max(spl0*drymix7 + os7*wetmix7,-4),4);
dpint8[0]=min(max(spl0*drymix8 + os8*wetmix8,-4),4);

(delaypos1+=1) >= delaylen1 ? delaypos1=0;
(delaypos2+=1) >= delaylen2 ? delaypos2=0;
(delaypos3+=1) >= delaylen3 ? delaypos3=0;
(delaypos4+=1) >= delaylen4 ? delaypos4=0;
(delaypos5+=1) >= delaylen5 ? delaypos5=0;
(delaypos6+=1) >= delaylen6 ? delaypos6=0;
(delaypos7+=1) >= delaylen7 ? delaypos7=0;
(delaypos8+=1) >= delaylen8 ? delaypos8=0;

spl0=spl0*drymix1 + os1*wetmix12; // Summing dry and wet mixes together
spl1=spl0*drymix2 + os2*wetmix22; // Summing dry and wet mixes together
spl2=spl0*drymix3 + os3*wetmix32; // Summing dry and wet mixes together
spl3=spl0*drymix4 + os4*wetmix42; // Summing dry and wet mixes together
spl4=spl0*drymix5 + os5*wetmix52; // Summing dry and wet mixes together
spl5=spl0*drymix6 + os6*wetmix62; // Summing dry and wet mixes together
spl6=spl0*drymix7 + os7*wetmix72; // Summing dry and wet mixes together
spl7=spl0*drymix8 + os8*wetmix82; // Summing dry and wet mixes together
Does anyone know why I would only be getting the delay working on delay lines 1 and 2? I have narrowed it down to the variables os[n], as os1 and os2 are receiving values, but the rest of the os[3-7] are not. I have looked at the other variables involved, like wetmix[n]2 and drymix[n], but they seem to be receiving values fine. I am pretty stumped with this!

Thank you for any help you can offer!
brandflake11 is offline   Reply With Quote
Old 09-23-2020, 06:34 PM   #2
ashcat_lt
Human being with feelings
 
Join Date: Dec 2012
Posts: 7,295
Default

The buffer for this delay is interleaved. Basically the left input is position 0 and the right is 1, then the next samples worth is 2 and 3 and so on. That’s kind of what’s happening with the lines like “dpint1 = delaypos1*2” but you want 8, so at least one of the things you need to do is change those to *8. I’m not in a great place to go much further than that, but hopefully it’ll point you in a positive direction.
ashcat_lt is offline   Reply With Quote
Old 09-24-2020, 06:11 AM   #3
brandflake11
Human being with feelings
 
Join Date: Dec 2018
Posts: 6
Default

Thanks for your response! I appreciate it greatly! I'll try to implement this and see if I get any difference in output.

EDIT: No difference after making these adjustments. I think the part that I need to understand more is the dpint[x] variables and delaypos. Does anyone have an idea of what these variables are doing?

Last edited by brandflake11; 09-24-2020 at 06:54 AM.
brandflake11 is offline   Reply With Quote
Old 09-24-2020, 08:35 AM   #4
ashcat_lt
Human being with feelings
 
Join Date: Dec 2012
Posts: 7,295
Default

K so first of all I don’t really understand how the “resample on length change” thing works, so I’m not even gonna touch it. If you want it to do that, it’ll need to be reworked eventually, but...

The original is 2 in 2 out with linked delay time. L and R are delayed by the same amount which is the only reason the whole interleaved buffer thing even works. It’s basically just one delay line that’s twice as long as it needs to be so that you can store (and retrieve) both samples next to each other. But you want 1 in 8 out with independent delay times. You want eight separate delay lines that don’t necessarily match. You can do that interleaved, but it’s kind of weird, and I think it would be much more clear if you actually just had separate buffers for each.

So delayposN keeps track of the sort of relative position of where you are in the individual delay line. dpintN is the absolute position in the one memory buffer array that we get in JS....

...and there I kind of come up short on trying to explain it, and I’m sorry. Like I understand it, but i just don’t know how to put into words what the problem is especially since your code snippets don’t all show the whole thing and I’m not really looking at the original...

...but the solution is that dpintN needs to be unique. dpint1 cannot equal dpint2 which cannot equal dpint8. They all have to be different at all times. They need to start different. Like @init. I think in the original dpint1 starts at 0 with dpint2 at 1, and then they both increment by 2 each time so they jump over each other...

So anyway. What you’d ought to do is block out a chunk of the array for each of your delay lines that is long enough to accommodate the longest delay you can set via the slider so that they are not interleaved and can’t overlap. That means like in @init set something like buffer1=0, buffer2=maxdelaylength, buffer3=maxdelaylength*2, etc... Then you don’t need any of that *2 stuff that I said you should change to *8. Then you can either have dpintN = bufferN + delayposN or just remove that whole section and have rest of it reference bufferN[delayposN] which really should just work.

Then go back and finger out how to do the resample thing...

I hope some of this helps, and I’m very sorry if it doesn’t.
ashcat_lt is offline   Reply With Quote
Old 09-24-2020, 10:41 AM   #5
brandflake11
Human being with feelings
 
Join Date: Dec 2018
Posts: 6
Default

Thank you for your help. I have just realized that I have been needlessly working on this though. The plugin delay lines 3-8 were actually working, they were just being output to speakers 3-8 (speakers I don't currently have), and so I couldn't hear them. I routed the outputs to 1 and 2 and they all are working fine. I can't believe I did this...

I have one more question: The input pin is automatically spl0, right? So, should the output be something like this to have a mono output be affected by each delay line?:
Code:
spl0=spl0*drymix1 + os1*wetmix12; // Summing dry and wet mixes together
spl1=spl0*drymix2 + os2*wetmix22; // Summing dry and wet mixes together
spl2=spl0*drymix3 + os3*wetmix32; // Summing dry and wet mixes together
spl3=spl0*drymix4 + os4*wetmix42; // Summing dry and wet mixes together
spl4=spl0*drymix5 + os5*wetmix52; // Summing dry and wet mixes together
spl5=spl0*drymix6 + os6*wetmix62; // Summing dry and wet mixes together
spl6=spl0*drymix7 + os7*wetmix72; // Summing dry and wet mixes together
spl7=spl0*drymix8 + os8*wetmix82; // Summing dry and wet mixes together
brandflake11 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 02:34 AM.


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