#N canvas 53 107 633 496 12; #X obj 29 11 list; #X text 352 455 updated for Pd version 0.39; #X text 76 12 - building and using variable-length messages; #N canvas 92 130 654 658 about-lists 0; #X obj 50 625 print message; #X msg 50 438 list x.wav 44100; #X msg 50 596 read \$1 \$2; #X msg 50 467 set x.wav 44100; #X msg 67 567 set \, add2 read \, adddollar 1 \, adddollar 2; #X msg 50 497 x.wav 44100; #X obj 67 541 loadbang; #X text 155 544 reset message as it was; #X text 207 438 good; #X text 196 469 bad; #X text 46 25 Messages in Pd are simewhat artificially divided into two classes. First are data-holding messages (bang \, float \, symbol \, list) which are the primary way of communicating between objects. Second is "everything else" (you could call them out-of-band messages or metamessages) that describe changes in configuration \, read and write files \, quit Pd \, etc. These are provided so that complex objects don't need to have 100 separate inlets for every possible functionality. It's not clear whether this was a good design choice \, but it's entrenched. ; #X text 162 497 ugly; #X text 48 183 The distinction becomes visible \, and ugly \, when the leading item in a data-holding message is a symbol. In this case \, to disambiguate it from the other sort \, the printed form of the message has a selector \, "list" or "symbol" prepended to it. Underneath \, there is always a selector in fromt of data messages \, but it is implied if the first data item is a number.; #X msg 411 461 list 44100 x.wav; #X msg 424 486 44100 x.wav; #X obj 411 512 print number-first; #X text 405 433 these two are equivalent:; #X text 50 294 In the example below \, the top message sets \$1 to "x.wav" and \$2 to 44100 in the "read" message. The lower message box outputs the message "read x.wav 44100". The "set" message changes the content of the message box itself (click on the longer message box below to repair the damage.) The "ugly" message \, since it is neither "list" nor "set" \, gets interpreted in an arbitrary (and probably inappropriate!) way.; #X connect 1 0 2 0; #X connect 2 0 0 0; #X connect 3 0 2 0; #X connect 4 0 2 0; #X connect 5 0 2 0; #X connect 6 0 4 0; #X connect 13 0 15 0; #X connect 14 0 15 0; #X restore 42 311 pd about-lists; #X text 33 52 There are four list classes:; #X obj 22 82 list append; #X obj 22 107 list prepend; #X obj 22 157 list trim; #X obj 22 132 list split; #X text 140 81 - append the second list to the first; #X text 141 108 - prepend the second list to the first; #X text 141 133 - split a list in two; #X text 141 160 - trim the "list" selector off; #N canvas 186 284 602 409 trim 0; #X msg 159 239 1 2 3; #X msg 159 190 list cis boom bah; #X msg 160 265 bang; #X msg 159 163 walk the dog; #X obj 134 341 list trim; #X obj 134 363 print trim; #X msg 160 287 1 x y; #X msg 159 313 x 1 y; #X text 29 19 trim - convert list to message \, using first item as selector; #X msg 159 213 55; #X text 27 55 The "list trim" object inputs lists (or makes lists out of incoming non-list messages) and outputs a message whose selector is the first item of the list \, and whose arguments \, if any \, are the remainder of the list. If the list has no items \, or if its first item is numeric \, the selector is "list" (which might print out as list \, float \, or bang.); #X connect 0 0 4 0; #X connect 1 0 4 0; #X connect 2 0 4 0; #X connect 3 0 4 0; #X connect 4 0 5 0; #X connect 6 0 4 0; #X connect 7 0 4 0; #X connect 9 0 4 0; #X restore 506 160 pd trim; #X text 501 53 details:; #X text 499 36 click for; #N canvas 322 170 608 420 append 0; #X obj 17 324 list append 1 2; #X floatatom 17 154 5 0 0 0 - - -; #X msg 17 129 1 2 3; #X msg 17 82 list cis boom bah; #X msg 17 179 bang; #X msg 176 294 bang; #X obj 17 353 print append; #X msg 17 39 walk the dog; #X msg 176 244 list x y z; #X msg 175 218 go dog go; #X msg 174 268 4 5 6 and 7; #X text 138 37 non-list message converted to list; #X text 182 77 list starting with symbol; #X text 181 96 (needs explicit "list" selector); #X text 69 152 number is one-element list; #X text 72 129 numeric list; #X text 67 181 bang is zero-element list; #X text 270 215 same for right inlet...; #X text 286 267 (note: only the first item; #X text 289 286 need be a number to make this; #X text 289 304 a list.); #X text 170 325 <- creation args initialize the list to append; #X text 20 6 Append - append (concatenate) the second list to the first ; #X connect 0 0 6 0; #X connect 1 0 0 0; #X connect 2 0 0 0; #X connect 3 0 0 0; #X connect 4 0 0 0; #X connect 5 0 0 1; #X connect 7 0 0 0; #X connect 8 0 0 1; #X connect 9 0 0 1; #X connect 10 0 0 1; #X restore 506 84 pd append; #N canvas 391 326 667 561 split 0; #X msg 103 328 1 2 3; #X msg 79 231 list cis boom bah; #X msg 99 263 bang; #X obj 79 421 list split 2; #X floatatom 182 396 3 0 5 0 - - -; #X obj 79 469 print split1; #X obj 198 470 print split2; #X msg 79 204 walk the dog; #X msg 102 306 1 2; #X msg 100 285 1; #X msg 103 349 1 2 3 4; #X msg 103 372 1 2 so are you; #X obj 320 470 print split3; #X text 76 488 first n; #X text 195 489 rest of list; #X text 317 489 shorter than n; #X text 218 394 new split point; #X text 49 25 Split - cut a list into smaller ones; #X text 210 419 <-- creation arg inits split point; #X text 201 202 non-list message converted to list; #X text 245 231 list with three symbols; #X text 139 288 list with one number; #X text 177 310 ... etc; #X text 241 370 <- if the first item is a number \, it's a list.; #X text 142 262 list with no items; #X text 48 61 The "list split" object takes lists and outputs the first "n" items (left outlet) and the remaining ones (middle outlet). The two outputs appear in the usual right-to-left order. In case there are fewer than "n" items in the list \, it is output (in its entirety) from the third outlet instead. The creation argument or the inlet sets the split point.; #X connect 0 0 3 0; #X connect 1 0 3 0; #X connect 2 0 3 0; #X connect 3 0 5 0; #X connect 3 1 6 0; #X connect 3 2 12 0; #X connect 4 0 3 1; #X connect 7 0 3 0; #X connect 8 0 3 0; #X connect 9 0 3 0; #X connect 10 0 3 0; #X connect 11 0 3 0; #X restore 506 134 pd split; #N canvas 0 0 640 478 prepend 0; #X obj 17 324 list append 1 2; #X floatatom 17 154 5 0 0 0 - - -; #X msg 17 129 1 2 3; #X msg 17 82 list cis boom bah; #X msg 17 179 bang; #X msg 176 294 bang; #X obj 17 353 print append; #X msg 17 39 walk the dog; #X msg 176 244 list x y z; #X msg 175 218 go dog go; #X msg 174 268 4 5 6 and 7; #X text 138 37 non-list message converted to list; #X text 182 77 list starting with symbol; #X text 181 96 (needs explicit "list" selector); #X text 69 152 number is one-element list; #X text 72 129 numeric list; #X text 67 181 bang is zero-element list; #X text 270 215 same for right inlet...; #X text 286 267 (note: only the first item; #X text 289 286 need be a number to make this; #X text 289 304 a list.); #X text 20 6 Prepend - prepend the second list to the first; #X text 167 324 <- creation args initialize the list to prepend; #X connect 0 0 6 0; #X connect 1 0 0 0; #X connect 2 0 0 0; #X connect 3 0 0 0; #X connect 4 0 0 0; #X connect 5 0 0 1; #X connect 7 0 0 0; #X connect 8 0 0 1; #X connect 9 0 0 1; #X connect 10 0 0 1; #X restore 506 109 pd prepend; #X text 29 228 In general \, inlets that take lists (two each for append/prepend \, and one each for split and trim) will convert non-list messages (such as "set 5") to lists (such as "list set 5" automatically. Here's more about lists in Pd:; #X text 30 344 And here are some examples showing how to use these objects to compose and/or use variable length messages:; #N canvas 305 50 723 650 example1 0; #X obj 43 173 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 252 176 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X text 247 154 clear; #X text 40 153 send; #X msg 91 175 250; #X msg 123 175 500; #X msg 156 175 750; #X msg 189 175 1000; #X obj 43 258 list append; #X obj 208 220 t l; #X obj 91 214 list prepend; #X obj 43 426 t l l; #X obj 94 426 print start; #X obj 149 257 print stored; #X obj 43 451 list split 1; #X obj 43 575 del; #X obj 43 607 print bang; #X obj 75 542 list append; #X msg 55 403 0 250 250 500; #X text 118 150 -- add --; #X text 57 20 example 1: simple rhythmic sequencer; #X text 49 53 The top part of this patch demonstrates building up a message from a variable number of elements provided sequentially. The "list prepend" object stores the list and \, each time a number arrives \, prepends the previous list to it.; #X text 416 237 "list prepend" to its own inlet.; #X text 253 220 "trigger list" is needed only to connect outlet of ; #X text 274 258 printout shows the growing message.; #X text 67 279 "list append" stores the growing message which is output by the "send" button above. "list prepend" would have been equivalent. ; #X text 185 403 <-- test message; #X text 59 354 The bottom part of the patch takes numbers off the beginning of the list \, one by one \, to use as delays.; #X text 210 426 printout shows the sequence as it starts.; #X text 189 543 The rest of the list is stored for next time.; #X obj 161 505 print done; #X text 170 450 Split off the first item. If there is none \, nothing comes out the first or second outlet \, but instead we get a "bang" from the third one.; #X text 84 575 After delay \, output a bang and recall the rest of the list.; #X connect 0 0 8 0; #X connect 1 0 10 1; #X connect 4 0 10 0; #X connect 5 0 10 0; #X connect 6 0 10 0; #X connect 7 0 10 0; #X connect 8 0 11 0; #X connect 9 0 10 1; #X connect 10 0 9 0; #X connect 10 0 8 1; #X connect 10 0 13 0; #X connect 11 0 14 0; #X connect 11 1 12 0; #X connect 14 0 15 0; #X connect 14 1 17 1; #X connect 14 2 30 0; #X connect 15 0 16 0; #X connect 15 0 17 0; #X connect 17 0 14 0; #X connect 18 0 11 0; #X restore 221 397 pd example1; #X text 64 396 simple sequencer; #N canvas 126 39 568 569 example2 0; #X obj 66 263 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 292 266 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X text 287 244 clear; #X text 63 243 send; #X obj 66 342 list append; #X obj 213 317 t l; #X obj 94 303 list prepend; #X obj 66 410 t l l; #X obj 121 410 print start; #X obj 171 340 print stored; #X obj 66 486 del; #X obj 105 486 list append; #X msg 94 264 250 57; #X msg 154 264 500 52; #X msg 215 264 750 55; #X obj 66 461 unpack; #X obj 66 435 list split 2; #X text 80 38 example 2: sequencer with pitch; #X text 147 242 -- add --; #X obj 185 438 print done; #X obj 115 517 print pitch; #X text 13 69 This example is a slight modification of example 1 showing how to build up lists with more than one item per iteration. We regard pairs of numbers as specifying a delay time and a pitch. Unlike the previous example \, the delay here is interpreted as teh delay until the next event \, not the delay since the previous one. This is done by taking the "pitch" output before the delay object (previously the "output" was taken from the delay object's output.); #X connect 0 0 4 0; #X connect 1 0 6 1; #X connect 4 0 7 0; #X connect 5 0 6 1; #X connect 6 0 5 0; #X connect 6 0 4 1; #X connect 6 0 9 0; #X connect 7 0 16 0; #X connect 7 1 8 0; #X connect 10 0 11 0; #X connect 11 0 16 0; #X connect 12 0 6 0; #X connect 13 0 6 0; #X connect 14 0 6 0; #X connect 15 0 10 0; #X connect 15 1 20 0; #X connect 16 0 15 0; #X connect 16 1 11 1; #X connect 16 2 19 0; #X restore 221 423 pd example2; #X text 55 425 another sequencer; #X text 113 452 serializer; #N canvas 116 31 673 426 example3 0; #X obj 19 287 list split 1; #X obj 19 378 print; #X obj 19 204 until; #X obj 19 242 list append; #X obj 45 171 t b l; #X obj 149 287 bang; #X msg 45 148 1 2 3 4 a b c; #X text 34 21 example 3: serializing a message without delays; #X text 17 55 The "until" object can be used as shown to iterate through all the items of a list.; #X text 178 147 <- click to test; #X text 101 171 First store list \, then start the loop; #X text 118 199 "until" bangs its output until told to stop by a "bang" to its right inlet.; #X text 137 241 Store the remaining list.; #X text 194 286 third outlet of "split" tells us to stop.; #X text 67 318 Second outlet of "split" becomes the new list for "list append" above.; #X text 75 377 First outlet is the output.; #X connect 0 0 1 0; #X connect 0 1 3 1; #X connect 0 2 5 0; #X connect 2 0 3 0; #X connect 3 0 0 0; #X connect 4 0 2 0; #X connect 4 1 3 1; #X connect 5 0 2 1; #X connect 6 0 4 0; #X restore 220 450 pd example3; #X obj 22 194 list; #X text 70 195 - short for "list append";