Fwd: Re: [PD] Writing a MIDI file...or at least a qlist...to disc

Kyle Klipowicz kyleklip at gmail.com
Thu Oct 12 23:36:51 CEST 2006


Here's the patch by the way, it was sent off-list.

~Kyle

---------- Forwarded message ----------
From: Kyle Klipowicz <kyleklip at gmail.com>
Date: Oct 11, 2006 4:41 PM
Subject: Re: Re: [PD] Writing a MIDI file...or at least a qlist...to disc
To: Richard Bowers <richard.bowers at ntlworld.com>

Hi Richard~

This is not a silly question!  Sequencing is one of the biggest pains for
many Pd users.

I think this solution would be fine, since these things don't take up much
space as text.  Textfile also allows appending.  I would suggest using
inter-onset intervals (IOI's) to keep track of your notes.  For example, 100
65 96 could be 100 ms from the previous note at pitch 65 and velocity 96.
You could use velocity of 0 to release the specific pitches.

Anyway, here is an example, as well as the list-help file.  Be warned, I
don't have a midi device here at work, so it may not work properly!  But the
general principle should be OK.

~Kyle

On 10/11/06, Richard Bowers <richard.bowers at ntlworld.com> wrote:
>
>  Thanks for your help,  Kyle. I'm replying off list because I'm a beginner
> and my next questions will probably be silly to most members:
>
> Do you think list would be able to store between 10,000 -15,000 lines
> consisting of a timestamp, note number and velocity?
>
> If not, would it be possible to append a written file on-the-fly using
> more manageable amounts of data?
>
> Sorry for these annoying questions but I have trouble getting the right
> information from the help files (I couldn't even find the list examples you
> mentioned !! The 'list' help comes up with info on 'bang').
>
> Regards,
>
> Richard.
>
>  -----Original Message-----
> *From:* pd-list-bounces at iem.at [mailto: pd-list-bounces at iem.at] *On Behalf
> Of *Kyle Klipowicz
> *Sent:* 11 October 2006 20:55
> *To:* Richard Bowers
> *Cc:* PD list
> *Subject:* [Norton AntiSpam] Re: [PD] Writing a MIDI file...or at least a
> qlist...to disc
>
> You could use timer combined with list to record a sequence (see the
> sequencers in the list example docs) and then write the final message to
> disk using textfile.
>
> ~Kle
>
> On 10/11/06, Richard Bowers <richard.bowers at ntlworld.com> wrote:
> >
> >  I've done a quick search on the archive for help on this topic, but I
> > didn't find anything crystal clear.
> >
> > Basically, I'm running a PD patch on a Mac which is sending (internally,
> > not through hardware) MIDI note on/off pairs to another program (Arkaos). I
> > would like to be able to capture the MIDI stream within PD (or the numeric
> > values on which the MIDI notes are based) into a file for later retrieval.
> > So
> >
> > 1) is there a purpose-built object which will handle this? or
> >
> > 2) can a file be written to disc as a qlist? If so, could someone
> > describe how to write such a file?
> >
> > Any help will be greatly appreciated.
> >
> > Many thanks,
> >
> > --Richard.
> >
> > _______________________________________________
> > PD-list at iem.at mailing list
> > UNSUBSCRIBE and account-management ->
> > http://lists.puredata.info/listinfo/pd-list
> >
> >
> >
>
>
> --
>
> http://theradioproject.com
> http://perhapsidid.blogspot.com
>
> (((())))(()()((((((((()())))()(((((((())()()())())))
> (())))))(()))))))))))))(((((((((((()()))))))))((())))
> ))(((((((((((())))())))))))))))))))__________
> _____())))))(((((((((((((()))))))))))_______
> ((((((())))))))))))((((((((000)))oOOOOOO
>
>


-- 

http://theradioproject.com
http://perhapsidid.blogspot.com

(((())))(()()((((((((()())))()(((((((())()()())())))
(())))))(()))))))))))))(((((((((((()()))))))))((())))
))(((((((((((())))())))))))))))))))__________
_____())))))(((((((((((((()))))))))))_______
((((((())))))))))))((((((((000)))oOOOOOO



-- 

http://theradioproject.com
http://perhapsidid.blogspot.com

(((())))(()()((((((((()())))()(((((((())()()())())))
(())))))(()))))))))))))(((((((((((()()))))))))((())))
))(((((((((((())))())))))))))))))))__________
_____())))))(((((((((((((()))))))))))_______
((((((())))))))))))((((((((000)))oOOOOOO
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puredata.info/pipermail/pd-list/attachments/20061012/6136b34a/attachment.htm>
-------------- next part --------------
#N canvas 230 75 502 497 12;
#X obj 301 -61 cnv 15 130 210 empty empty empty 20 12 0 14 -200701
-66577 0;
#X obj 132 147 textfile;
#X obj 90 218 del;
#X msg 319 -38 rewind;
#X msg 319 -61 bang;
#X text 356 -62 start;
#X obj 187 181 print;
#X msg 319 -16 clear;
#X obj 167 232 unpack f f f;
#X obj 132 182 t b f;
#X text 22 238 delay onset time;
#X obj 212 281 noteout;
#X text 192 257 pitch;
#X text 245 257 velocity;
#X text 171 166 debug info;
#X text 339 5 read a file;
#X text 338 82 write one;
#X obj 320 30 openpanel;
#X msg 320 55 read \$1;
#X obj 320 8 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#X msg 320 127 write \$1;
#X obj 320 102 savepanel;
#X obj 320 83 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#X obj 43 -56 notein;
#X obj 43 56 pack f f f;
#X obj 43 15 timer;
#X obj 43 -23 t b b f;
#X msg 43 86 add \$1 \$2 \$3;
#X text 78 -39 find IOI and package data;
#X text 15 -77 Raw MIDI record and playback;
#X text 19 377 (c) 2006 Kyle Klipowicz GNU and all that jazz;
#X text 22 310 You could extend this by multiplying the delay time
to double \, halve \, etc. the sequence. If you want to edit your data
without resorting to a text editor \, try to study data structures
in Pd.;
#X connect 1 0 6 0;
#X connect 1 0 9 0;
#X connect 2 0 1 0;
#X connect 3 0 1 0;
#X connect 4 0 1 0;
#X connect 7 0 1 0;
#X connect 8 0 2 1;
#X connect 8 1 11 0;
#X connect 8 2 11 1;
#X connect 9 0 2 0;
#X connect 9 1 8 0;
#X connect 17 0 18 0;
#X connect 18 0 1 0;
#X connect 19 0 17 0;
#X connect 20 0 1 0;
#X connect 21 0 20 0;
#X connect 22 0 21 0;
#X connect 23 0 26 0;
#X connect 23 1 24 2;
#X connect 24 0 27 0;
#X connect 25 0 24 0;
#X connect 26 0 25 0;
#X connect 26 1 25 1;
#X connect 26 2 24 1;
#X connect 27 0 1 0;
-------------- next part --------------
#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";


More information about the Pd-list mailing list