circular buffer - click between the last and first sample

thomas's icon

Hi everyone,

I'm recording into a buffer inside gen~ and reading the content via the counter and peek operators. When I adjust the playback speed, I'm getting a click between the last and the first sample of the buffer, even when I switch back to the playback speed of 1.
Can someone tell me why? Thanks a lot!

circular_buffer.maxpat
Max Patch


Pedro Santos's icon

Does this help?
I'm using the normalized counter (0-1) to generate a quick fade in at the beginning of the buffer and a quick fade out at the end so you don't hear the click.

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

thomas's icon

Dear Pedro, thank you very much for your reply.
Yes I know the concept with the fades. My idea was to realize a circular buffer with the poke/peek operators in gen~.

But apparently no interpolation is calculated between the last and the first sample within the peek/sample etc. operators.

What surprises me is the following observation:
If I first read the buffer sample by sample (playback speed 1, no interpolation needed), I get a continuous signal - as expected.
If I change the playback speed and go back to 1, I don't get a continuous signal anymore, although I read the buffer sample by sample again. This seems strange to me. I can solve it again by reinstantinate the peek object...

RaToX's icon

this is strange and happens to me too. We'd like some from C74 or some expert to confirm that...

Iain Duncan's icon

I am guessing here, but something that is used in some other audio systems (i.e., csound) is adding an extra point (the "guard point") to buffers, where that point is a copy of the first point to make it possible for interpolation algorithms to run without having to have them check the buffer length. (so a buffer of 1024 samples is actually 1025 samples). Maaaaybeeee... this is it? :-)

thomas's icon

Hi Iain,

Thanks for your reply.

I think I found a solution. It looks like Max does it differently. Use poke and peek with the attribute '@boundmode wrap' and overshoot the read/write index by one sample. That does the interpolation.

circular_buffer.maxpat
Max Patch

Graham Wakefield's icon

Yes, all the @interp modes in gen~ will respect the @boundmode concepts properly.