circular buffers and wrap-around reading

Feb 22, 2006 at 3:44pm

circular buffers and wrap-around reading

Hi,

I’m working with the buffer~ and wave~ objects to try to create a
circular/continuous buffer. i.e., I have a moving ‘window’ of sound that
can be any length and can read from it at any point. I’m most of the way
there, but there is one issue that doesn’t make the window smooth. As
I’m reading individual samples from the buffer (no need for looping), I
am using line~ to drive wave~. However, unlike phasor~ which will wrap
around from the end of the buffer to the beginning, line~ doesn’t appear
to do that. For example, if I have a 5000 ms. buffer, and I specify that
line~ go from 4000 to 1000, it is going to go backwards and give me a 3
sec. reverse sample as opposed to wrapping around to give me a 2 sec.
forward-played sample. Is there any way to get line~ to wrap around or
to always move forward through a buffer? Many thanks.

Best,

Peter

#24556
Feb 22, 2006 at 6:26pm

pong~ is what you want for wrapping audio signals into a given range.
It has two modes: pong and asteroids, (behaves like the ball in the
old Atari games) but it prefers to refer to them as mode 0 and mode 1.

However, your problem would be better solved by the abstraction at the
bottom. All it will do is sort the two values. (if you’re always
going from the minimum to the maximum time, you’ll always be reading
forward.

Peter McCulloch

Also, for people craving control-rate pong action, here’s PM.Pong:

max v2;
#N vpatcher 57 44 832 342;
#P origin 9 -62;
#P inlet 491 113 15 0;
#P window setfont “Sans Serif” 9.;
#P window linecount 1;
#P newex 508 113 128 196617 loadmess $3;
#N vpatcher 20 74 620 474;
#P window setfont “Sans Serif” 9.;
#P window linecount 1;
#P comment 235 151 128 196617 peter.mculloch@gmail.com;
#P comment 199 68 215 196617 Sorts two numbers , so that outlet 1 <
outlet 2;
#P window setfont “Arial Black” 18.;
#P comment 199 32 167 791478290 PM.MinMax;
#N comlet maximum;
#P outlet 111 147 15 0;
#N comlet minimum;
#P outlet 39 148 15 0;
#P window setfont “Sans Serif” 9.;
#P comment 91 39 24 196617 V2;
#N comlet Max;
#P inlet 94 57 15 0;
#N comlet Min;
#P inlet 39 57 15 0;
#P newex 39 87 65 196617 bondo 2 5;
#P newex 111 125 65 196617 maximum 0.;
#P newex 39 125 62 196617 minimum 0.;
#P comment 37 39 24 196617 V1;
#P connect 4 0 3 0;
#P connect 3 0 1 0;
#P connect 1 0 7 0;
#P connect 3 1 1 1;
#P connect 5 0 3 1;
#P connect 3 0 2 0;
#P connect 2 0 8 0;
#P connect 3 1 2 1;
#P pop;
#P newobj 259 147 242 196617 p MinMax;
#P inlet 259 113 15 0;
#P outlet 27 235 15 0;
#N vpatcher 20 74 601 258;
#P outlet 32 133 15 0;
#P inlet 32 49 15 0;
#P inlet 406 47 15 0;
#P inlet 219 47 15 0;
#P window setfont “Sans Serif” 9.;
#P hidden newex 428 47 113 196617 loadmess scalarmode 1;
#P newex 32 81 385 196617 vexpr
(((((($f1-$f2)/($f3-$f2))-int(($f1-$f2)/($f3-$f2))))*($f3-
$f2)+$f2)*(($f1-$f2)>=0))+(((((($f1-$f2)/($f3-$f2))-int(($f1 -$f2)/($f3-
$f2))))*($f3-$f2)+$f3)*(($f1-$f2)<0));
#P hidden fasten 1 0 0 0 433 76 37 76;
#P connect 4 0 0 0;
#P connect 0 0 5 0;
#P connect 2 0 0 1;
#P connect 3 0 0 2;
#P pop;
#P newobj 52 191 475 196617 p Wrap;
#P newex 136 54 27 196617 % 2;
#P newex 136 31 65 196617 loadmess $1;
#P newex 113 86 27 196617 + 1;
#N vpatcher 20 74 620 474;
#P outlet 32 191 15 0;
#P inlet 32 49 15 0;
#P inlet 406 47 15 0;
#P inlet 219 47 15 0;
#P window setfont “Sans Serif” 9.;
#P hidden newex 466 46 113 196617 loadmess scalarmode 1;
#P newex 32 169 75 196617 vexpr $f1+$f2;
#P newex 97 118 383 196617 vexpr
[(((abs(int(($f2-$f1)/($f3-$f2)))<0.)+(abs(int(($f2-$f1)/($f3-
$f2)))%2)%2)==1)]*[(-1.*abs(($f1-$f2)-(int(($f1-$f2)/($f3-$f 2)))*($f3-
$f2)))+$f3];
#P newex 32 81 385 196617 vexpr
[(((abs(int(($f2-$f1)/($f3-$f2)))<0.)+(abs(int(($f2-$f1)/($f3-
$f2)))%2)%2)==0)*(abs(($f1-$f2)-(int(($f1-$f2)/($f3-$f2)))*( $f3-
$f2))+$f2)];
#P hidden fasten 3 0 0 0 471 76 37 76;
#P connect 6 0 0 0;
#P hidden fasten 3 0 2 0 471 163 37 163;
#P connect 0 0 2 0;
#P connect 2 0 7 0;
#P hidden fasten 3 0 1 0 471 113 102 113;
#P connect 6 0 1 0;
#P connect 1 0 2 1;
#P connect 4 0 0 1;
#P connect 4 0 1 1;
#P connect 5 0 0 2;
#P connect 5 0 1 2;
#P pop;
#P newobj 27 171 475 196617 p Fold;
#P newex 27 117 35 196617 gate 2;
#P inlet 113 31 15 0;
#P inlet 52 31 15 0;
#P newex 276 113 128 196617 loadmess $2;
#P fasten 5 0 3 0 118 109 32 109;
#P connect 3 0 4 0;
#P connect 8 0 9 0;
#P connect 4 0 9 0;
#P connect 1 0 3 1;
#P connect 3 1 8 0;
#P fasten 7 0 5 0 141 78 118 78;
#P connect 2 0 5 0;
#P connect 6 0 7 0;
#P connect 0 0 11 0;
#P connect 10 0 11 0;
#P connect 11 0 4 1;
#P connect 11 0 8 1;
#P connect 12 0 11 1;
#P connect 13 0 11 1;
#P connect 11 1 4 2;
#P connect 11 1 8 2;
#P pop;

Sorting abstraction:

max v2;
#N vpatcher 10 59 610 459;
#P inlet 127 42 15 0;
#P inlet 61 42 15 0;
#P outlet 87 142 15 0;
#P outlet 61 141 15 0;
#P window setfont “Sans Serif” 9.;
#P window linecount 1;
#P newex 61 66 76 196617 bondo 2;
#P newex 87 115 65 196617 maximum 0.;
#P newex 61 94 62 196617 minimum 0.;
#P connect 5 0 2 0;
#P connect 2 0 0 0;
#P connect 0 0 3 0;
#P connect 2 0 1 0;
#P connect 1 0 4 0;
#P connect 2 1 0 1;
#P connect 6 0 2 1;
#P connect 2 1 1 1;
#P pop;

#71236
Feb 22, 2006 at 6:42pm

I would recommend an abstraction: mono_line~

You need to know the direction (monotonacity) and the maximum /
minimum clip values. You could use pong~ as described before, and if
the destination is in the wrong direction, add the difference to the
maximum value (negate all of this for monotonically decreasing line).
You’ll in effect be unwrapping the values and then using pong~ to clip
your line for you.

_Mark

#71237
Feb 22, 2006 at 8:09pm

great! thanks, i’ll check those all out. i assume you can read forward,
backward, and at different speeds? so pong~ in ‘asteroids mode’ should
theoretically give me a smooth two second sample if, in a 5000 ms
buffer, i read forward from 4000ms to 1000ms (and sound is continuous
through the wrap-around)? thanks again!

best,

peter

#71238
Feb 22, 2006 at 8:44pm

Not exactly. Pong~ has no sense of direction. It only operates on a
signal if it is outside the specified boundaries. However, if you did
pong~ 1 0 5000 and tried to read from 4000 to 6000 with line~, you
would do 4000->5000 then 0-1000. (it would wrap) If you feed line~
5000 to 3000, you would still get that. (so it would play backwards in
that circumstance)

You might think about it as an starting offset + width problem rather
than a start and end problem. (the good news is that the math is easy,
and makes transposition trivial to implement)

Peter

#71239
Feb 22, 2006 at 9:25pm

On around Feb 22, 2006, at 19:26, Peter McCulloch said something like:
> pong~ is what you want for wrapping audio signals into a given range.
> It has two modes: pong and asteroids,

Yet another tool for wrapping audio signals: lp.scampf, which offers
three modes: clip, wrap, and reflect, as well as linear and nonlinear,
symmetrical and asymmetrical mapping of input to output values.

If I can find some time I’ll see if I can whip up a demo patch, but
this may not happen all too soon…

> but it prefers to refer to them as mode 0 and mode 1.

lp.scampf prefers to refer to its modes as clip, wrap, and reflect
rather than “pong”. I’ve spent too much time among the Brits to want to
pong.

————– http://www.bek.no/~pcastine/Litter/ ————–
Peter Castine | ^
| Litter Power & Litter Bundle for Jitter
pcastine@gmx.net |
pcastine@bek.no | iCE: Sequencing, Recording, and Interface Building
4-15@kagi.com | for Max/MSP
| Extremely cool
| http://www.dspaudio.com
| http://www.dspaudio.com/software/software.html

#71240
Feb 25, 2006 at 4:43pm

> On around Feb 22, 2006, at 19:26, Peter McCulloch said something like:
> > pong~ is what you want for wrapping audio signals into a given range.
> > It has two modes: pong and asteroids,

> Yet another tool for wrapping audio signals: lp.scampf, which offers
> three modes: clip, wrap, and reflect, as well as linear and nonlinear,
> symmetrical and asymmetrical mapping of input to output values.
>
> If I can find some time I’ll see if I can whip up a demo patch, but
> this may not happen all too soon…

Hello,
I’m interested in the circular buffer/wrapping concept as well and was wondering if there was an example patch out there. I’m not certain what to do with the pm.pong abstract. Is there a help/demo patch of what exactly that abstract does?
Thanks,
Doug Michael

#71241
Feb 26, 2006 at 3:05am

This should hopefully clarify things.

thanks,

Peter McCulloch

> Hello,
> I’m interested in the circular buffer/wrapping concept as well and was
> wondering if there was an example patch out there. I’m not certain
> what to do with the pm.pong abstract. Is there a help/demo patch of
> what exactly that abstract does?
> Thanks,
> Doug Michael
>

max v2;
#N vpatcher 10 59 527 548;
#P window setfont “Sans Serif” 9.;
#P window linecount 1;
#P comment 339 449 134 196617 peter.mcculloch@gmail.com;
#P comment 203 160 53 196617 high value;
#P comment 180 139 53 196617 low value;
#P comment 370 158 53 196617 high value;
#P newex 79 39 48 196617 loadbang;
#P comment 54 413 30 196617 – 10;
#P flonum 331 157 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P flonum 305 137 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P flonum 253 211 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P user multiSlider 253 239 160 181 -10. 10. 1 3961 15 1 0 2 0 0 0;
#M frgb 0 0 0;
#M brgb 255 255 255;
#M rgb2 127 127 127;
#M rgb3 0 0 0;
#M rgb4 37 52 91;
#M rgb5 74 105 182;
#M rgb6 112 158 18;
#M rgb7 149 211 110;
#M rgb8 187 9 201;
#M rgb9 224 62 37;
#M rgb10 7 114 128;
#P newex 253 179 89 196617 Pm.Pong 1 -1. 4.;
#P flonum 157 157 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P flonum 131 137 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P message 79 64 74 196617 0 , 100 10000;
#P newex 79 90 53 196617 line 0. 20;
#P flonum 79 211 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P user multiSlider 79 239 160 181 -10. 10. 1 3961 15 1 0 2 0 0 0;
#M frgb 0 0 0;
#M brgb 255 255 255;
#M rgb2 127 127 127;
#M rgb3 0 0 0;
#M rgb4 37 52 91;
#M rgb5 74 105 182;
#M rgb6 112 158 18;
#M rgb7 149 211 110;
#M rgb8 187 9 201;
#M rgb9 224 62 37;
#M rgb10 7 114 128;
#P flonum 79 115 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P newex 79 179 89 196617 Pm.Pong 0 -1. 4.;
#P comment 54 239 20 196617 10;
#P comment 347 137 53 196617 low value;
#P window linecount 2;
#P comment 191 54 222 196617 PM.Pong wraps numbers into a specified
range. Works like pong~ , but on control rate stuff.;
#P connect 17 0 8 0;
#P connect 7 1 8 0;
#P connect 8 0 7 0;
#P connect 7 0 4 0;
#P connect 4 0 3 0;
#P connect 3 0 6 0;
#P connect 6 0 5 0;
#P connect 9 0 3 2;
#P connect 10 0 3 3;
#P fasten 4 0 11 0 84 134 258 134;
#P connect 11 0 13 0;
#P connect 13 0 12 0;
#P connect 14 0 11 2;
#P connect 15 0 11 3;
#P pop;

#71242

You must be logged in to reply to this topic.