Constantly updated buffer~

bobcrusoe's icon

How do I create a constantly updated buffer~? I want one to always contain the last ten seconds of sound out of an adc~. That is, I want it to be constantly be deleting anything that gets older than 10 seconds, and constantly adding anything new. Any ideas?

Rodrigo's icon

A delay instead?

Christopher Dobrian's icon

tapin~ is already implemented as a ring buffer. That is, it always contains the most recently received milliseconds of signal.

You can use count~ and poke~ and index~ to continually write to and read from a buffer~.

t's icon

if i understand the question correctly, bobcrusoe wants to constantly write in only first sample of a buffer and "move the buffer". so that when the first sample has been written, it moves to the position of second sample and so on. i don't know how this can be implemented using count~ and poke~? and i also don't have any idea how to do that. i know how to do that with jit.matrix but is not sample accurate. although it might be if using columns that are the same size as signal vector.

if that is what you want bobcrusoe i can try and implement a Jitter solution for you, but i am also interested in a buffer version.

bobcrusoe's icon

Yes that is what I would like to do. I have tried using tapin~, and although it constantly holds the most recently received milliseconds of a signal, if I am not mistaken there are many important ways in which it does not act at all like a buffer~. Christopher Dobrian, could you be a bit more clear about how you can use count~ and poke~ and index~ to continually write to and read from a buffer~?

Timo Rozendal's icon
Christopher Dobrian's icon

One generally doesn't "move the buffer" by moving every sample in memory, because that would be laborious; one uses a pointer to the "current time" (the most recently stored sample), which moves as you write into the buffer. Writing over-and-over into the same buffer keeps that buffer filled with the most recent signal. The idea is explained pretty well on Wikipedia's page about "Circular buffer".

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

Here's a very simplified example of what I meant about using count~ and poke~ to record continually into a buffer~.

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

*Of course, record~ can do the same thing, but you'd still probably want a count~ to keep track of where the current sample is.

t's icon

So basically the reading position (index~ value) should be always one sample behind the writing position (count~ value) if you want to hear the input with only one sample delay? And one also needs to constantly track the writing position in order to know where the 0 or starting position for reading is?

Thanks for the help so far! I always thought that this is the "dodgy" way of doing it:)

Roman Thilenius's icon

i would be interested what you are missing when using tapin~.

t's icon

quote: "i would be interested what you are missing when using tapin~."

If you want to use the resulting buffer as a source for MSP driven granular sampler for instance, using tapin~ would present a problem i guess. I hope I'm wrong...

Also as far as I know, the content of tapin~ can't be visualized?

Christopher Dobrian's icon

@t You can read from anywhere in the buffer~ that you want, with any buffer~-reading object that you want. But there will almost always be a discontinuity between the newest recorded sample and the oldest recorded sample, so you probably don't want to read over that point (which could happen if you're reading in reverse, for example, or at a different rate than the original recording).

Roman Thilenius's icon

okay, vizualizing - i wasnt thinking about that.
but in a constantly updated buffer a regular buffer window also wont really be of much help?

and about using index~ play~ or groove~ ... it is true that you can not name a tapping buffer,
but therefore you can play directly from it ... connect a tapout~ and voila .. you have 10 "plays"
ready to go ... seems perfect for granular stuff ...

what else?

bobcrusoe's icon

The circular buffer is exactly what I want. Thanks so much christopher dobrian.

t's icon

quote: "but in a constantly updated buffer a regular buffer window also wont really be of much help?"

If using waveform~ object to display and edit the buffer or set loop points it makes sense. There is even an example of circular buffer in the waveform~ help file.

Using tapout~ to trigger grains is not sample accurate so it might be a good choice for asynchronous granular synthesis but not for synchronous IMO. And I was referring to later one when I mentioned MSP driven granular sampler.

Roman Thilenius's icon

oh ja, thats true, waveform wont work at all with tapin.

about the sample accuracy, well, the trouble begins when you need to run stuff in parallel.

but i think you could use envelopes and windows stored in buffers (instead of using line~)
in order to play from a tapping buffer ... you wont be able to modulate that as flexible as with
points in a "line~" ... but sampleaccurate is it. :)

compared to groove~ (wich does not take signals in max v4) tapout~ seems almost
easy to program to play in different directions and with different speeds from a tapping
buffer.