If we want it to work much more gracefully, we could take a page from some pedal delays which compress the signal on the way into the buffer and then expands it on the way back out.
This will still end up getting pretty loud - heading toward square waves with RMS (!!!) levels equal to whatever ceiling we’ve set. If we want that distortion to sound better, we call our favorite waveshaping function at this point instead. Then it’ll just get more distorted as you play. The easiest way to stop it getting quite so loud is to just choose a limit and do that min(max()) thing before we write to the buffer. We can just do like ReaDelay and tell folks “yeah it does that”, or we could try to handle it ourselves. We have to decide how much we care about that. This will also escalate quickly toward infinity. Worst case scenario, you play the exact same thing over and over in time with the delay. That’s cool.īut it’s also going to mix in whatever you play next, and whatever you play after that, and the whole thing is going to keep getting louder and louder. Turn off the speakers and walk away and come back days later and it’s still playing whatever i last did. It gets stupid loud.Īt 0db feedback, if we play something that is shorter than the delay time, it will repeat exactly the same literally forever. Just as the real noise floor is down past -300db, the real clipping ceiling is over 300db louder than your DAC can pass or any fixed point file can reproduce. Positive feedback here could end up getting REALLY LOUD. You’ve got it topping out at 0db in order to stop it from self-oscillating with escalating velocity. Now this is going even further down the road.īut then I look at the other end of that slider. Like one of those volume controls with the power switch built in. What I like to do is pick a lower usable limit and then have the slider go 1 step further than that and call that OFF. One might ask why anyone would add enough gain to hear this and I would answer “guitar amp”. We do, however, have a bunch of ways that we might amplify and smash this signal after it comes back out. You can usually get away with it in analog because -90db is going to bury it in the noise floor, but here we don’t have that safety net.
In the floating point engine, this kind of assumption is dangerous. I suppose it’s a little more advanced point than the very basics that you were addressing here, but at this point I think it’s safe to get into it. I meant to mention this originally too, but caught up in other parts of it. 90 decibels of attenuation is basically silence for all intents and purposes, so that's a good minimum. Audio people should know decibels, it's one of the basic units of measure. Similarly, I'm picking decibels for feedback. We expect weird things when simple digital delays are modulated, and I understand that this example wasn’t meant to address that, but just pointing it out for those who might have higher expectations.
We basically leave a bunch of buffer slots full of stuff, it never actually plays out so we kind of jump back to even further back then we already were, and then if we switch back to a longer time we’ll end up hearing stuff that maybe happened quite a while ago. Consider what happens when we have a long time and then shorten it. Basically, it’s gonna glitch hard and strange when you adjust the delay time. The other thing I wanted to mention is more about the fundamental nature of this very simple type of delay. ) Then in you just send it the input and remove all references to old0 and old1.
Using functions makes your code a lot simpler to write, easier to read, and much more scalable. I could have written the plugin without the functions, but it's such a valuable and important part of JS that I really needed to make sure that I illustrated it. If I was to see the pos variable just hanging out but not delay0.pos and delay1.pos, then I'll know I forgot to put it in the instance(). A common mistake I make when I'm writing is I'll forget to put a function's variable inside the instance() command. You can check to make sure they look right. Remember that Reaper lists all of the current variables in the "development environment" window. You can take this technique with the circular buffers and make reverb functions, or you could put a filter on the delayed output, all kinds of things. Now, there are a lot of places you could go with this. Hopefully this is clear enough.Īnd, umm, that's basically it. Old1 = spl1 This part of the code is executed every sample, right? So each sample we are putting the current sample and some of the previous output into our buffer, then make sure we save the current output for use next sample. Spl1 += lay(spl1 + old1 * feedbackGain) * wetGain Code: += lay(spl0 + old0 * feedbackGain) * wetGain