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.

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.