"rolling buffer" - is it even possible?

Wetterberg's icon

Hey, I think I must've asked this in the past, so I'll attempt to reframe the question a bit:

What is the state of the art in terms of capturing a "rolling" buffer? By rolling I mean a buffer that is continually being rewritten, like a delay line.

The solutions I've seen - used by Robert Henke and others - have often been two buffers, one being read, one being written, and then they'd switch every bar or whatever.

Is this still our best bet? I get why we obviously can't update a buffer all the time, but perhaps a more gracious way of switching often?

Andrew Pask's icon

Try using the stutter~ object with really large sizes

Cheers

-A

Wetterberg's icon

ah! so essentially stutter~ can be slotted in instead of buffer~?

Mike S's icon

I'd imagine this is pretty doable in gen?

Wetterberg's icon

peeking and poking, I presume, right? Gen~ doesn't do its own buffers, rather it accesses outside buffers, as I understand it?

the problem comes when reading from and writing to a buffer at the same time. Clicks and other mess abound.

Mike S's icon

If you were 1 sample behind when reading then you wouldn't get any clicks?

The reason (I think) you can't do this in MSP land is because even the smallest signal vector sizes will allow for discontinuities at the start/end points of the buffer when reading/writing, but I imagine in gen~ you could get rid of this? I don't know, could be wrong on all counts.

leafcutter's icon

sounds like you are describing tapin~ & tapout~

Wetterberg's icon

This is for a granular engine specifically, so normal tapin~ and out wouldn't work I'm afraid.

Ideally I'd be able to simply stop recording to the buffer, and keep using what's already captured.

I think some stutter~ experiments are in order.

Wetterberg's icon

Right - either way, it would suffer from the same problems, would it not?

brendan mccloskey's icon

I recall Rodrigo generating a fairly extensive discussion on a very similar topic a while back; can't seem to find it, maybe he'll chime in.

B

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

I used something like this in a patch. This is the recording part, and then there's a separate playback part that plays from random bits of the buffer too.

Rodrigo's icon

And here's the whole patch in context. It starts/stops recording based on onset detection, as well as picking a new random chunk of buffer to play from (also being triggered by onset detection).

autoaccomp.zip
zip
Wetterberg's icon

aw yeah, Rodrigo you're always on point, man. This is really close to what I was thinking. I can use this for sampling bits ala percussion, but it can also feed a granulator easily (we use a quadrophonic version of Brendans Granary patch) - this is so much fun.

also, yoink; I'm stealing your onset detection. It's quite good. And way OP with all those descriptors going on.

Rodrigo's icon

Heh, glad you dig it!

I'm really happy with the onset detection. I did a bunch of testing with that stuff a year or so ago and this worked, by far, the best. It's based on an envelope following patch by Peter M.

And the descriptors stuff is my generic 'analyze everything' stuff from all of my patches. In this patch it's massively overkill, but it's just using a couple odd descriptors to determine how long to record for each time there is an onset.

Rodrigo's icon

Oh, and here's a tidier version of the onset detection which I use as an abstraction.

onsetdetection.maxpat
Max Patch
Wetterberg's icon

thanks!

Peter McCulloch's icon
Max Patch
Copy patch and select New From Clipboard in Max.

Couldn't resist: here's a version that outputs clicks with a signal rate lockout.

Wetterberg's icon

ah, dope. Is there a way to implement the lockout thing for both on-/ and offs? Like, a gate instead of a trigger?

Rodrigo's icon

Like locking out all activity, or just one or the other? Can just stick the onebang code in before the toggle and it will keep the toggle from firing as fast. or can individually filter them (so only 'on's get filtered, but 'off's can happen whenever).

Anything's possible of course!

Peter McCulloch's icon

@wetterberg: (for signal rate) check out the dev branch of BEAP for Bp.oneshot. It does both triggers and gates.

Peter McCulloch's icon

And here's an abstraction version...

P.S. Cool stuff, Rodrigo!

PM.OneShot.maxpat
Max Patch
Wetterberg's icon

ah, dope. dope dope dope.

Nathan Wolek's icon

Wetterberg:
You might want to check out the nw.recordplus~ external that just finished updating for 64 bit Max. "Offers functionality similar to record~, but on/off changes are controlled by a signal and not executed until the next zero crossing in the audio signal. In addition, this object functions as though the loop and append options are always on."

It was something I originally cooked up for Hipno, but never got around to releasing separately. Now part of the package here: https://github.com/nwolek/LowkeyNW

Demo video is on my agenda for this week. Cheers.

-Nathan

Wetterberg's icon

Sweet, Nathan! I'm going to play around with recordplus tonight :)

zh's icon

Thanks Andrew for pointing out Stutter~, simple and elegant solution.

Roman Thilenius's icon

not to forget tapin tapout...

Roman Thilenius's icon

you are trying to compete with ruslan now?

Roman Thilenius's icon

you just said that you want to raise up a more modern form of existentialism based on the average UFO rotation velocity in C++ while determining the gamma factor of my karma, and now you ask how that compares to ruslan?

Roman Thilenius's icon

i´d still use tapin and tapout.

Roman Thilenius's icon

ruslan == multilayer metaphorism

rknLA's icon

Is the descriptorsrt~ object 32-bit only? I'm seeing these "no suitable image found" errors similar to what's described here

Rodrigo's icon

Yup, only 32bit at the moment, but I believe there is an update being worked on.

SmokeDoepferEveryday's icon

old thread but I can't seem to get the click out either Peter or Rodrigo's onset abstractions, any reason for this? a bang works but not a click if anyone could clarify?

onset-detection.maxpat
Max Patch

onset.maxpat
Max Patch

Rodrigo's icon

It's an issue with your gen~ abstraction. Here's a later version of the same idea (the core gen~ here is something PA Tremblay wrote):

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

Ernest's icon

HI, I've made 'rolling buffers' a couple of times in gen~, as one way to exchange voice data between poly instances. The buffer needs to be larger than the larger buffer size in the audio settings, or you get stuttering, but it can be read as little as one cycle after being written.

SmokeDoepferEveryday's icon

Many thanks Rodrigo!
Just curious, in the original gen code what did this mean? :D
max_k = 9007199254740800; // For all your John Cage-related onset detection

SmokeDoepferEveryday's icon

@Ernest if you have a rolling buffer poly instance example would love to see an example (if poss)