How to reset delay ?


    Jun 22 2017 | 1:13 pm
    Hi at all I have a very stupid question: how can I "clear" the Delay's buffer?
    I've try to find out something from the documentation but with no sucess.
    The goal is to clear the delay line immediatly, without waiting his time.
    This is for a re-trigger porpouse.
    Thanks in advance!!!
    Enrico

    • Jun 22 2017 | 2:30 pm
      The only way to reset Delay is to reset the whole gen~ ...
      ...of course this is shitty...
      ...or to roll your own Delay in GenExpr using Data & Poke etc and create a for-loop to write 0's to the Data on a History reset only. This is how I do it.
      I have always wanted to be able to reset Delay, and also to be able to reset Historys from Max top-level even in the subpatch / function level in Gen.
      Please someone tell me if I am being an idiot. If not, can we all please feature-request this :)
    • Jun 22 2017 | 2:31 pm
      no matter if we´re talking pipe, delay, delay~ or tapout~: sending "0., 275." for the delay time should clear the buffer.
    • Jun 22 2017 | 2:34 pm
      Hi Roman. This is the GEN forum.
    • Jun 22 2017 | 2:35 pm
      damn :)
    • Jun 22 2017 | 3:21 pm
      @STKR :
      "or to roll your own Delay in GenExpr using Data & Poke etc and create a for-loop to write 0's to the Data on a History reset only" sound really intersting!
      Are you meaning to write a (circular) buffer and use it as delay line?
      Seems to be an expensive solution, for a so simple operation...
      Or maybe simply I can't figure out how to.
      Maybe can be usefull to use two delay line and switching between?
      Thank so much!!
      Enri
    • Jun 22 2017 | 6:16 pm
      never said it was a good idea :)
      something like this:
    • Jun 24 2017 | 1:07 am
      Writing your own circular buffer might not be *that* more expensive -- the delay operator itself uses an anonymous data object internally, and shares some of the same code generation with sample/poke et al. It has a few of its own optimizations but they might not make all that much difference. Delay is there as a convenience but sometimes you need something a little more flexible.
    • Jul 10 2017 | 5:57 pm
      I started to think about this problem, reaching the conclusion one needs some kind of sample counter which is set when the delay should be cleared and decrements to zero. Then when the counter value is more than one, the delay output is zero. I haven't quite figured out how to set the counter.
    • Jul 11 2017 | 5:54 pm
      Thanks at all guys! @STRK : I will study your code, its a bit complex for me, but a good source to learn @Wakefield : Really clear, as usual, thx! @ERNEST: thanks to think about this.
      Enrico
    • Nov 13 2019 | 12:26 pm
      Hi all,
      I'm reactivating this somehow old post since I'm facing the same problem, but, on top of that, I'd like to use the intersample interpolation feature of the delay operator, which is not easy to reimplement with the circular buffer method pointed out above.
      For curiosity I exported my gen patch in cpp, and noticed that a "reset" method seems indeed to be internally implemented (this can be seen in genlib_ops.h). As far as I can understand, it would then require to bind this function with a method "delay.reset()" in GenExpr.
      No chance that it can be implemented one of these days?
      Best
      Alexis
    • Feb 06 2021 | 3:21 pm
      Hello. @Alexis, I'm really interested in this topic since I use delay because of its fractional interpolation, for waveguides etc. Can you tell if you've managed to implement it in gen somehow?
    • Feb 06 2021 | 4:51 pm
      Hi Massimiliano,
      no, I couldn't manage it in a clean and instantaneous way. The only thing that I could make work well: basically write zeros in the delay line in a synchronous way (one zero for each sample). I was not able to find a clean and reliable way to set the whole delay line to zero at once with a loop. So what I did is close to what Ernest suggested: having a counter which is set to a maximum value (a little bit bigger than the size of the delay line) when a dedicated inlet receives an impulse (non-zero signal), and is decremented with 1 at each sample. As long as the counter is >=0, write zero to the input of the delay line. Otherwise write the proper input.
      Alexis
    • Feb 06 2021 | 6:12 pm
      " I'd like to use the intersample interpolation feature of the delay operator, which is not easy to reimplement with the circular buffer method pointed out above."
      If you implement a delay using [data] (or [buffer]), then you can use exactly the same @interp arguments to your [peek] or [sample] operators to read from the delay buffer. E.g. [data tape samplerate] for a 1 second delay memory, and [peek tape @interp linear] for linear interpolation of the delay buffer. Here's a basic delay with interpolation using [data]:
    • Feb 06 2021 | 6:24 pm
      BTW the reason for not having a "zero out the delay" operation in gen~ is because this could be quite an expensive operation and cause audio dropouts. One way of working around it is to mute the delay output (and feedback if you had it) for the period of the delay time.
    • Feb 06 2021 | 7:09 pm
      The phrase "...this could be quite an expensive operation and cause audio dropouts" is an example of Graham's praiseworthy inclination toward understatement, I think. :-)
    • Feb 06 2021 | 7:45 pm
      With feedback:
    • Feb 06 2021 | 10:24 pm
      Thank you so much guys for keeping the discussion up. Graham, this solution is just brilliant, I'm amazed. Thank you.
    • Feb 07 2021 | 12:41 am
      Seems pretty easy also to turn it into a reverse delay, awesome!
    • Feb 07 2021 | 10:08 am
      Update: here's the reverse version wrapped around the delay time boundaries. Basically, the counter always reads backward from (count-t) to ((count-t)-t), so every time it has read a portion equal to t it jumps to the new (count-t) value.
    • Feb 07 2021 | 10:58 pm
      Fun fact: I'm using the gen patcher as an abstraction, and I've loaded two instances of it within a larger gen patcher. It just doesn't work, and the reason seems that there's a conflict because of the object data, which isn't that local as other gen objects though, isn't it?
    • Feb 09 2021 | 2:53 pm
      I just did a very exhaustive test. As far as I can tell, a named [data] is global to the gen~ that contains it, regardless how deeply it is packed into subpatchers/abstractions/codeboxes/genexprs. This is behaviour that [data] inherits because it shares a lot of implementation details with [buffer]. The difference is that [buffer] is also global to Max (including over multiple gen~ objects), but [data] belongs only to one gen~ object.
      I *thought* I remembered a case where embedding in a codebox would produce more than one data storage, but I'm having a hard time reproducing it now.
    • Feb 09 2021 | 2:54 pm
      BTW it occurs to me: with regard to the original request, the solution posted above (muting the output for the duration of the delay time) would work just as well with a [delay] object. No idea why I didn't realize that earlier, sorry! Sometimes you miss the wood for the trees, eh?
      Here's that "fake clear by muting" solution applied to [delay]:
    • Jan 23 2022 | 4:03 am
      Hi Graham! The last patch you pasted seems to be the exact same as the previous one. I have not managed to make it work with delay~ yet...
    • Jan 23 2022 | 5:18 am
      I think you should look more closely at what's inside the gen~ object in both examples, Jérémi.