Seemless (non pitch shifting) Variable Delay

kp*'s icon

I love delay. But I get bored when the delay time is the same for very long so I have been messing with various delay lines to see what I can do to make a nice variable delay. The way I was always taught to get around that was to use two delay lines and crossfade between them so you can see all three of those strategies in the patch below.

1. just a tapin/tapout pair. Audible clicks when the delay time changes. So you would need to change the delay time between sounding events or suffer the consequences.

2. tapin/tapout w/ line. This just shows how you can smooth the clicks by ramping with line~ but you still get pitch change like you would on an old school bucket brigade analog delay device or tape machine.

3. Here am trying the crossfading delay, using 2 tapouts and a pair of lines crossfading to have variable time delay w/o clicks or pitch change.

I imagine there are many ways to do this (i bet you could use matrix as well). I just wonder if the way I have it here works as intended or if it could be done in a better way. It seems a bit glitchy or perhaps that is just a function of using a rapid ramp time and metro and having the change sometimes occur at a time when the sound is still occurring? I just don't know. It simply doesn't sound as I wish i am trying to get a variable delay that does not change pitch and does so seamlessly. Is there some better strategy for this or is my strategy correct but just a less than perfect execution on the programming end of things.

cheers,

-kp--

kp*'s icon
Max Patch
Copy patch and select New From Clipboard in Max.

and here is the stripped down patch....

Christopher Dobrian's icon
Roman Thilenius's icon

you should use 3 and not only 2 parallel processes for best results.

search for "vdb" at the forums, there must be like 20 versions of such patchers, i dont
even remember who made the first one.

Maurizio Giri's icon

Just use delay~, it has a "ramp" message to change delay time without clicks.

Max Patch
Copy patch and select New From Clipboard in Max.

m

kp*'s icon

Thanks for the replies. I will fire up Max and investigate all three strategies outlined here. Thanks Chris for that link. That is most helpful. I need to look at it more closely but I already picked up one new (unrelated) trick from that patch. I hadn't seen the use of "#" as a way to pass an initial value from the front patcher before. Groovy.

I didn't know about vdb~ but searching shows that the vdb~ do jour is ej.vdb~ but I am not sure what "window size" means in this context (there is no FFT involved as far as I can see). I don't see any addition information or examples. Can anyone explain what this parameter is? and some values to start with? Emmanuel?

I am not sure how i missed delay~ Perhaps I was also under the impression that it was a delay~ that would produce the old school analog-esque pitch shift. Had no idea it does this right out of the box.

That's a lot to pour over. I might need more coffee.

-kp--

kp*'s icon

Looks like the ej.vdb~ helpfile originally linked to the vdb~ help patcher but is now missing. I am guessing that this explains things in more detail but the vdb~ object (abstraction?) is part of a larger package that was not open source. I don't much care about the vdb~ since ej.vdb~ is freely available but I am guessing the helpfile would be good to have. Anyone have the help patcher or just can give me some sense of what ej.vdb~ expects as a window size.

Chris's option works similarly to mine. Delay~ seems to work as well. I am surprised this ramp time thing just works and there is not doppler shift.

I am curious to know what ej.vdb~ is like.

The thing I don't like about my patch (and the Dobrian example) is that while there is no click and no pitchshift it does, if you reset the delay time while something is sounding, chop the sound short. I like this guitar pedal I have that is buffered that has a "trails" option that makes sure that each repeat is fully sounded no matter what, even if you turn the sucka off. I guess I am interested in something like that ... which maybe involves using (god help me) poly~ but perhaps ej.vdb~ does the trick. Delay~ so far is proving the best option if I can just figure out that window size. I am guessing that that controls how much of a buffer to use to store the so called "trails"? I am guessing just set this param to be a tad larger than the longest delay time you anticipate using?

this is fun.

fun
fun
fun
fun

Roman Thilenius's icon

windowing in the various vdb versions is not so much different from
windowing in an ftt ... you fade in an out between 2 (or 3) parallel processes.

so window size means frequency of interpolation. this is not too unimportant,
because you might hear that.

kp*'s icon

ah... so I was wrong in my guess.

So does this need to be a power of 2?

What's a good starting value for delay times around 500msec?

I guess if it is windowing too much it will create artifacts or aliasing? Too slow and the interp will be crude? So perhaps it needs to be a much smaller value than I guessed...

Emmanuel Jourdan's icon

the windowing is there to make a crossfade between 2 delay lines. Changing the position of the playhead in the delay line create either transposition or clicks, so if you make a fade out, change the delay (which cause the unwanted sound), and fade back in again you don't hear the problem. If you have 2 playheads, you just need to have the windowing in opposition so you can listen to a continuous sound. The original vdb~ from Benjamin Thigpen did that, the version in the ejies was a bit more efficient to do the windowing, and actually you can use directly M4L.vdelay~ which is another variation on the subject and comes with Max 5.1 or higher.

Roman Thilenius's icon

in practice, it will never ever be possible to have a perfect transition in such
a delay, because what would be a perfect result? holding the same sample
all the time during the delay time is changed? that resulted in silence.

your idea of using poly~is not wrong, it would be one solution.

using poly~ will make a it a bit easier to add functionality such as automatic
windowing, i.e. dont make fixed windows, but use another (muted) poly voice
to set new delay times, then wait for the next low treshold of the incoming audio
and switch voices then.
might be more effective than LFO-style windowing.

kp*'s icon

Thanks to both of you. I was totally unaware of M4L.vdelay~ which sits on my hard drive hiding.

So I am clearly my guess about the windowsize was totally wrong. I imagine the window size needs to be some fraction of your smallest delay time? I'll try fiddling with some values about but if my lowest delay time is 100ms and my largest is like 800ms then a window size of 50 should do as a starting value?

-kp-