aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Peach <mrpeach@users.sourceforge.net>2011-02-12 21:55:25 +0000
committerMartin Peach <mrpeach@users.sourceforge.net>2011-02-12 21:55:25 +0000
commit5169fa7f15cfc8df742cdfa6572f2288e8111de4 (patch)
tree09fcd4c18476fce1fc2dfed81a6c6eaf2b5f9839
parentfa47f6ea2ee29607de4d97a79d24b83f0b8c25f9 (diff)
Changed rightmost outlet into a status outlet for track tempo and meta info. Updated help patch.
svn path=/trunk/externals/mrpeach/; revision=14914
-rw-r--r--midifile/midifile-help.pd598
-rw-r--r--midifile/midifile.c168
2 files changed, 469 insertions, 297 deletions
diff --git a/midifile/midifile-help.pd b/midifile/midifile-help.pd
index a208b82..aca1f57 100644
--- a/midifile/midifile-help.pd
+++ b/midifile/midifile-help.pd
@@ -1,272 +1,326 @@
-#N canvas 375 332 399 237 12;
-#N canvas 189 27 888 819 midifile_write 0;
-#X obj 324 -2 bng 45 250 50 0 empty empty choose 5 23 0 8 -62784 -260818
--258699;
-#X obj 67 51 tgl 45 0 empty empty record 2 23 0 8 -258699 -241291 -24198
-0 1;
-#X floatatom 553 772 15 0 0 0 tick - -;
-#X obj 67 151 metro 2;
-#X floatatom 113 109 15 0 0 0 - - -;
-#X msg 113 83 2.005;
-#X msg 506 590 verbose \$1;
-#X text 494 545 verbosity defaults to 1;
-#X obj 324 54 savepanel;
-#X msg 409 493 240 1 2 3 4 247;
-#X text 523 492 a sysex message;
-#X obj 553 742 float;
-#X floatatom 506 564 5 0 0 0 - - -;
-#X msg 324 408 write \$1 \$2 \$3;
-#X msg 326 201 29;
-#X msg 364 201 30;
-#X msg 210 201 0;
-#X floatatom 405 275 5 0 0 0 ticks_per_frame - -;
-#X text 80 301 (ticks per quarter note if frames per second is zero)
-;
-#X msg 288 201 25;
-#X msg 248 201 24;
-#X text 79 322 25 20 will give accurate timing with metro ticks at
-2ms;
-#X obj 324 375 pack s 25 20;
-#X obj 559 663 midifile;
-#X text 7 199 time code frames per second:;
-#X text 484 432 default is 90 ticks per quarter note;
-#X msg 349 433 write filename.mid;
-#X msg 374 458 write filename.mid 77;
-#X text 534 458 77 ticks per quarter note;
-#X msg 442 526 flush;
-#X obj 629 96 cnv 15 200 20 empty empty empty 20 12 0 14 -257985 -66577
-0;
-#X floatatom 515 95 5 0 0 0 note - -;
-#X floatatom 515 125 5 0 0 0 velocity - -;
-#X obj 559 283 pack 144 0 0;
-#X obj 578 129 sel 0;
-#X obj 559 156 t b f;
-#X obj 559 257 f;
-#X text 160 658 Martin Peach \, 2010;
-#X text 553 565 set to 3 to debug input;
-#X obj 559 75 notein;
-#X obj 119 -2 cnv 15 200 20 empty empty empty 20 12 0 14 -257985 -66577
-0;
-#X text 121 -3 1: open a file for writing:;
-#X obj 116 50 cnv 15 200 20 empty empty empty 20 12 0 14 -257985 -66577
-0;
-#X text 118 49 2: start recording;
-#X obj 139 526 cnv 15 300 20 empty empty empty 20 12 0 14 -257985 -66577
-0;
-#X text 157 524 4: stop recording and save the file:;
-#X floatatom 513 180 5 0 0 0 channel - -;
-#X obj 610 237 +;
-#X msg 578 185 127;
-#X msg 610 157 143;
-#X floatatom 709 313 5 0 0 0 value - -;
-#X floatatom 709 344 5 0 0 0 controller - -;
-#X floatatom 707 393 5 0 0 0 channel - -;
-#X obj 755 293 ctlin;
-#X obj 755 447 pack 176 0 0;
-#X obj 755 479 print ctl>;
-#X obj 580 324 print note>;
-#X obj 755 329 t b f;
-#X obj 755 393 f;
-#X obj 810 336 + 175;
-#X text 646 93 3: input MIDI as lists;
-#X connect 0 0 8 0;
-#X connect 1 0 3 0;
-#X connect 3 0 23 0;
-#X connect 4 0 3 1;
-#X connect 5 0 4 0;
-#X connect 6 0 23 0;
-#X connect 8 0 22 0;
-#X connect 9 0 23 0;
-#X connect 11 0 2 0;
-#X connect 12 0 6 0;
-#X connect 13 0 23 0;
-#X connect 14 0 22 1;
-#X connect 15 0 22 1;
-#X connect 16 0 22 1;
-#X connect 17 0 22 2;
-#X connect 19 0 22 1;
-#X connect 20 0 22 1;
-#X connect 22 0 13 0;
-#X connect 23 1 11 1;
-#X connect 23 2 11 0;
-#X connect 26 0 23 0;
-#X connect 27 0 23 0;
-#X connect 29 0 23 0;
-#X connect 33 0 23 0;
-#X connect 33 0 56 0;
-#X connect 34 0 48 0;
-#X connect 34 1 49 0;
-#X connect 35 0 36 0;
-#X connect 35 1 33 1;
-#X connect 36 0 33 0;
-#X connect 39 0 31 0;
-#X connect 39 0 35 0;
-#X connect 39 1 32 0;
-#X connect 39 1 34 0;
-#X connect 39 1 33 2;
-#X connect 39 2 46 0;
-#X connect 39 2 47 1;
-#X connect 47 0 36 1;
-#X connect 48 0 47 0;
-#X connect 49 0 47 0;
-#X connect 53 0 50 0;
-#X connect 53 0 57 0;
-#X connect 53 1 51 0;
-#X connect 53 1 54 1;
-#X connect 53 2 52 0;
-#X connect 53 2 59 0;
-#X connect 54 0 55 0;
-#X connect 54 0 23 0;
-#X connect 57 0 58 0;
-#X connect 57 1 54 2;
-#X connect 58 0 54 0;
-#X connect 59 0 58 1;
-#X restore 76 116 pd midifile_write;
-#N canvas 214 27 1028 899 midifile_read 0;
-#X obj 203 523 bng 15 250 50 0 empty empty step 18 7 0 12 -4160 -257985
--1;
-#X obj -148 60 openpanel;
-#X obj -148 7 bng 45 250 50 0 empty empty choose 3 23 0 12 -62784 -260818
--258699;
-#X obj -35 142 tgl 45 0 empty empty play -45 23 0 12 -24198 -1 -258699
-0 1;
-#X msg 236 474 rewind;
-#X text 86 473 go to start of file;
-#X floatatom 373 593 15 0 0 0 current_tick - -;
-#X obj 80 297 hradio 15 1 0 16 empty empty track_number 0 -6 0 12 -62784
--241291 -1 2;
-#X msg 80 318 dump \$1;
-#X msg 199 437 68050;
-#X msg 24 262 track \$1;
-#X obj 24 222 hradio 15 1 0 16 empty empty track_number 0 -6 0 12 -62784
--241291 -1 3;
-#X obj -35 203 metro 2;
-#X text 29 540 creation arguments: midi_file_name;
-#X text 28 519 output only this track;
-#X text 143 317 parse this track to main window;
-#X msg 260 498 0;
-#X text 87 437 goto tick 68050;
-#X floatatom 109 699 5 0 0 0 note - -;
-#X floatatom 176 699 5 0 0 1 velocity - -;
-#X floatatom 752 618 15 0 0 0 last_tick - -;
-#X msg 156 394 verbose \$1;
-#X text -21 395 verbosity defaults to 1;
-#X text -97 2 1: choose a MIDI file to play;
-#X text 18 136 2: start playing it;
-#X obj 613 558 print ****;
-#X obj 280 138 spigot;
-#X obj 319 104 tgl 25 0 empty empty loop -45 12 0 12 -4160 -257985
--258113 0 1;
-#X msg -148 90 read \$1;
-#X floatatom 156 370 5 0 0 0 - - -;
-#X obj 156 351 hradio 15 1 0 4 empty empty verbosity 0 -6 0 12 -62784
--241291 -1 0;
-#X obj 24 239 - 1;
-#X text 689 673 note off events;
-#X obj 280 538 midifile wowo.mid;
-#X obj 536 254 ctlout 123;
-#X msg 536 224 123;
-#X obj 280 638 route 144 145 146 147 148 149 150 151 152 153 154 155
-156 157 158 159;
-#X text 648 374 Martin Peach \, 2010;
-#X obj 109 674 unpack 0 0;
-#X obj 456 690 route 128 129 130 131 132 133 134 135 136 137 138 139
-140 141 142 143;
-#X msg -121 117 read I_Wanna_Be_Sedated.mid;
-#X obj 536 196 bng 15 250 50 0 empty empty all_notes_off 17 7 0 10
--258113 -257985 -1;
-#X obj 720 558 t b b;
-#X floatatom -21 259 5 0 0 0 - - -;
-#X obj 558 558 bng 15 250 50 0 empty empty end 17 7 0 10 -258113 -257985
--1;
-#X text 406 554 bangs at end of file:;
-#X obj -118 674 print note_on;
-#X obj -119 726 print note_off;
-#X obj 280 442 f;
-#X floatatom 298 416 9 0 0 0 loop_start_tick - -;
-#X obj 720 511 sel 1;
-#X floatatom 458 468 9 0 0 0 loop_end_tick - -;
-#X text 59 239 -1 = play all tracks;
-#X obj 752 596 f;
-#X obj 405 491 == 1e+09;
-#X text 28 572 MIDI messages are output as lists;
-#X text 116 637 select note on events:;
-#X obj 280 814 noteout 1;
-#X obj 351 814 noteout 2;
-#X obj 423 814 noteout 3;
-#X obj 494 814 noteout 4;
-#X text -73 744 select note on events:;
-#X obj 93 745 route 176 177 178 179 180 181 182 183 184 185 186 187
-188 189 190 191 192;
-#X floatatom 93 812 5 0 0 0 controller - -;
-#X floatatom 160 812 5 0 0 1 value - -;
-#X obj 93 787 unpack 0 0;
-#X obj -119 781 print controller;
-#X obj -21 859 ctlout 1;
-#X obj -27 833 f;
-#X obj -27 807 t b f;
-#X connect 0 0 33 0;
-#X connect 1 0 28 0;
-#X connect 2 0 1 0;
-#X connect 3 0 12 0;
-#X connect 4 0 33 0;
-#X connect 7 0 8 0;
-#X connect 8 0 33 0;
-#X connect 9 0 33 0;
-#X connect 10 0 33 0;
-#X connect 11 0 31 0;
-#X connect 12 0 33 0;
-#X connect 16 0 33 0;
-#X connect 21 0 33 0;
-#X connect 26 0 48 0;
-#X connect 27 0 26 1;
-#X connect 28 0 33 0;
-#X connect 29 0 21 0;
-#X connect 30 0 29 0;
-#X connect 31 0 10 0;
-#X connect 31 0 43 0;
-#X connect 33 0 36 0;
-#X connect 33 0 62 0;
-#X connect 33 1 6 0;
-#X connect 33 1 53 1;
-#X connect 33 1 54 0;
-#X connect 33 2 25 0;
-#X connect 33 2 42 0;
-#X connect 33 2 44 0;
-#X connect 35 0 34 0;
-#X connect 36 0 38 0;
-#X connect 36 0 46 0;
-#X connect 36 0 57 0;
-#X connect 36 1 58 0;
-#X connect 36 2 59 0;
-#X connect 36 3 60 0;
-#X connect 36 16 39 0;
-#X connect 38 0 18 0;
-#X connect 38 1 19 0;
-#X connect 39 0 47 0;
-#X connect 39 0 57 0;
-#X connect 39 1 58 0;
-#X connect 39 2 59 0;
-#X connect 39 3 60 0;
-#X connect 40 0 33 0;
-#X connect 41 0 35 0;
-#X connect 42 0 26 0;
-#X connect 42 1 53 0;
-#X connect 48 0 33 0;
-#X connect 49 0 48 1;
-#X connect 50 0 42 0;
-#X connect 51 0 54 1;
-#X connect 53 0 20 0;
-#X connect 54 0 50 0;
-#X connect 62 0 65 0;
-#X connect 62 0 66 0;
-#X connect 65 0 63 0;
-#X connect 65 0 69 0;
-#X connect 65 1 64 0;
-#X connect 65 1 68 1;
-#X connect 68 0 67 0;
-#X connect 69 0 68 0;
-#X connect 69 1 67 1;
-#X restore 76 83 pd midifile_read;
-#X text 15 10 midifile reads and writes MIDI files.;
-#X text 152 170 2010/12/11 Martin Peach;
+#N canvas 375 332 399 237 12;
+#N canvas 189 27 888 819 midifile_write 0;
+#X obj 324 -2 bng 45 250 50 0 empty empty choose 5 23 0 8 -62784 -260818
+-258699;
+#X obj 67 51 tgl 45 0 empty empty record 2 23 0 8 -258699 -241291 -24198
+0 1;
+#X floatatom 553 772 15 0 0 0 tick - -;
+#X obj 67 151 metro 2;
+#X floatatom 113 109 15 0 0 0 - - -;
+#X msg 113 83 2.005;
+#X msg 506 590 verbose \$1;
+#X text 494 545 verbosity defaults to 1;
+#X obj 324 54 savepanel;
+#X msg 409 493 240 1 2 3 4 247;
+#X text 523 492 a sysex message;
+#X obj 553 742 float;
+#X floatatom 506 564 5 0 0 0 - - -;
+#X msg 324 408 write \$1 \$2 \$3;
+#X msg 326 201 29;
+#X msg 364 201 30;
+#X msg 210 201 0;
+#X floatatom 405 275 5 0 0 0 ticks_per_frame - -;
+#X text 80 301 (ticks per quarter note if frames per second is zero)
+;
+#X msg 288 201 25;
+#X msg 248 201 24;
+#X text 79 322 25 20 will give accurate timing with metro ticks at
+2ms;
+#X obj 324 375 pack s 25 20;
+#X obj 559 663 midifile;
+#X text 7 199 time code frames per second:;
+#X text 484 432 default is 90 ticks per quarter note;
+#X msg 349 433 write filename.mid;
+#X msg 374 458 write filename.mid 77;
+#X text 534 458 77 ticks per quarter note;
+#X msg 442 526 flush;
+#X obj 629 96 cnv 15 200 20 empty empty empty 20 12 0 14 -257985 -66577
+0;
+#X floatatom 515 95 5 0 0 0 note - -;
+#X floatatom 515 125 5 0 0 0 velocity - -;
+#X obj 559 283 pack 144 0 0;
+#X obj 578 129 sel 0;
+#X obj 559 156 t b f;
+#X obj 559 257 f;
+#X text 160 658 Martin Peach \, 2010;
+#X text 553 565 set to 3 to debug input;
+#X obj 559 75 notein;
+#X obj 119 -2 cnv 15 200 20 empty empty empty 20 12 0 14 -257985 -66577
+0;
+#X text 121 -3 1: open a file for writing:;
+#X obj 116 50 cnv 15 200 20 empty empty empty 20 12 0 14 -257985 -66577
+0;
+#X text 118 49 2: start recording;
+#X obj 139 526 cnv 15 300 20 empty empty empty 20 12 0 14 -257985 -66577
+0;
+#X text 157 524 4: stop recording and save the file:;
+#X floatatom 513 180 5 0 0 0 channel - -;
+#X obj 610 237 +;
+#X msg 578 185 127;
+#X msg 610 157 143;
+#X floatatom 709 313 5 0 0 0 value - -;
+#X floatatom 709 344 5 0 0 0 controller - -;
+#X floatatom 707 393 5 0 0 0 channel - -;
+#X obj 755 293 ctlin;
+#X obj 755 447 pack 176 0 0;
+#X obj 755 479 print ctl>;
+#X obj 580 324 print note>;
+#X obj 755 329 t b f;
+#X obj 755 393 f;
+#X obj 810 336 + 175;
+#X text 646 93 3: input MIDI as lists;
+#X connect 0 0 8 0;
+#X connect 1 0 3 0;
+#X connect 3 0 23 0;
+#X connect 4 0 3 1;
+#X connect 5 0 4 0;
+#X connect 6 0 23 0;
+#X connect 8 0 22 0;
+#X connect 9 0 23 0;
+#X connect 11 0 2 0;
+#X connect 12 0 6 0;
+#X connect 13 0 23 0;
+#X connect 14 0 22 1;
+#X connect 15 0 22 1;
+#X connect 16 0 22 1;
+#X connect 17 0 22 2;
+#X connect 19 0 22 1;
+#X connect 20 0 22 1;
+#X connect 22 0 13 0;
+#X connect 23 1 11 1;
+#X connect 23 2 11 0;
+#X connect 26 0 23 0;
+#X connect 27 0 23 0;
+#X connect 29 0 23 0;
+#X connect 33 0 23 0;
+#X connect 33 0 56 0;
+#X connect 34 0 48 0;
+#X connect 34 1 49 0;
+#X connect 35 0 36 0;
+#X connect 35 1 33 1;
+#X connect 36 0 33 0;
+#X connect 39 0 31 0;
+#X connect 39 0 35 0;
+#X connect 39 1 32 0;
+#X connect 39 1 34 0;
+#X connect 39 1 33 2;
+#X connect 39 2 46 0;
+#X connect 39 2 47 1;
+#X connect 47 0 36 1;
+#X connect 48 0 47 0;
+#X connect 49 0 47 0;
+#X connect 53 0 50 0;
+#X connect 53 0 57 0;
+#X connect 53 1 51 0;
+#X connect 53 1 54 1;
+#X connect 53 2 52 0;
+#X connect 53 2 59 0;
+#X connect 54 0 55 0;
+#X connect 54 0 23 0;
+#X connect 57 0 58 0;
+#X connect 57 1 54 2;
+#X connect 58 0 54 0;
+#X connect 59 0 58 1;
+#X restore 76 116 pd midifile_write;
+#N canvas 214 27 1028 899 midifile_read 0;
+#X obj 198 518 bng 15 250 50 0 empty empty step 18 7 0 12 -4160 -257985
+-1;
+#X obj -148 60 openpanel;
+#X obj -148 7 bng 45 250 50 0 empty empty choose 3 23 0 12 -62784 -260818
+-258699;
+#X obj -40 146 tgl 45 0 empty empty play -45 23 0 12 -24198 -1 -258699
+0 1;
+#X msg 231 469 rewind;
+#X text 81 468 go to start of file;
+#X floatatom 340 560 15 0 0 0 current_tick - -;
+#X obj 75 292 hradio 15 1 0 16 empty empty track_number 0 -6 0 12 -62784
+-241291 -1 0;
+#X msg 75 313 dump \$1;
+#X msg 194 432 68050;
+#X msg 19 257 track \$1;
+#X obj 19 217 hradio 15 1 0 16 empty empty track_number 0 -6 0 12 -62784
+-241291 -1 0;
+#X obj -40 198 metro 2;
+#X text 24 535 creation arguments: midi_file_name;
+#X text 23 514 output only this track;
+#X text 138 312 parse this track to main window;
+#X msg 255 493 0;
+#X text 82 432 goto tick 68050;
+#X floatatom 104 701 5 0 0 0 note - -;
+#X floatatom 171 701 5 0 0 1 velocity - -;
+#X floatatom 315 615 15 0 0 0 last_tick - -;
+#X msg 151 389 verbose \$1;
+#X text -26 390 verbosity defaults to 1;
+#X text -97 2 1: choose a MIDI file to play;
+#X text 13 140 2: start playing it;
+#X obj 275 415 spigot;
+#X obj 314 381 tgl 25 0 empty empty loop -45 12 0 12 -4160 -257985
+-258113 0 1;
+#X msg -148 90 read \$1;
+#X floatatom 151 365 5 0 0 0 - - -;
+#X obj 151 346 hradio 15 1 0 4 empty empty verbosity 0 -6 0 12 -62784
+-241291 -1 0;
+#X obj 19 234 - 1;
+#X text 684 668 note off events;
+#X obj 275 533 midifile wowo.mid;
+#X obj -95 496 ctlout 123;
+#X msg -95 466 123;
+#X obj 275 640 route 144 145 146 147 148 149 150 151 152 153 154 155
+156 157 158 159;
+#X obj 104 676 unpack 0 0;
+#X obj 451 692 route 128 129 130 131 132 133 134 135 136 137 138 139
+140 141 142 143;
+#X msg -121 117 read I_Wanna_Be_Sedated.mid;
+#X obj -95 438 bng 15 250 50 0 empty empty all_notes_off 17 7 0 10
+-258113 -257985 -1;
+#X obj 453 573 t b b;
+#X floatatom -26 254 5 0 0 0 - - -;
+#X obj 499 588 bng 15 250 50 0 empty empty end 17 7 0 10 -258113 -257985
+-1;
+#X text 407 532 bangs at end of file:;
+#X obj -123 676 print note_on;
+#X obj -124 728 print note_off;
+#X floatatom 456 422 9 0 0 0 loop_start_tick - -;
+#X text 54 234 -1 = play all tracks;
+#X obj 315 593 f;
+#X text -18 562 MIDI messages are output as lists;
+#X text 111 639 select note on events:;
+#X obj 275 816 noteout 1;
+#X obj 346 816 noteout 2;
+#X obj 418 816 noteout 3;
+#X obj 489 816 noteout 4;
+#X text -78 746 select note on events:;
+#X obj 88 747 route 176 177 178 179 180 181 182 183 184 185 186 187
+188 189 190 191 192;
+#X floatatom 88 814 5 0 0 0 controller - -;
+#X floatatom 155 814 5 0 0 1 value - -;
+#X obj 88 789 unpack 0 0;
+#X obj -124 783 print controller;
+#X obj -26 861 ctlout 1;
+#X obj -32 835 f;
+#X obj -32 809 t b f;
+#X obj 499 553 route bang format tracks ticks_per_quarternote;
+#X obj 275 441 f 0;
+#X text 601 830 Martin Peach \, 2011;
+#X floatatom 578 585 3 0 0 1 format - -;
+#X floatatom 658 585 5 0 0 1 tracks - -;
+#X floatatom 738 585 5 0 0 1 ticks_per_quarternote - -;
+#X floatatom 263 55 5 0 0 1 tracks - -;
+#X symbolatom 427 105 40 0 0 0 - - -;
+#X obj 427 79 prepend set;
+#X obj 418 139 unpack 0 0;
+#X floatatom 485 192 15 0 0 0 last_tick - -;
+#X floatatom 418 165 5 0 0 1 track - -;
+#X floatatom 340 105 5 0 0 1 track - -;
+#X obj 340 79 unpack 0 s;
+#X obj 496 231 unpack 0 0 0 0;
+#X floatatom 496 299 3 0 0 1 / - -;
+#X floatatom 527 299 3 0 0 1 - - -;
+#X floatatom 559 268 5 0 0 1 clocks_per_click - -;
+#X floatatom 591 299 5 0 0 1 32nds_per_quarternote - -;
+#X floatatom 714 406 15 0 0 0 microsec_per_quarternote - -;
+#X obj 574 427 /;
+#X floatatom 715 447 15 0 0 0 microsec_per_tick - -;
+#X obj 574 468 / 1000;
+#X floatatom 574 499 15 0 0 0 millisec_per_tick - -;
+#X obj 740 105 print other_meta;
+#X obj 263 18 route seq_num name end time_sig microsec_per_quarternote
+;
+#X obj 652 76 route key_sig;
+#X obj 652 133 unpack 0 0 s;
+#X symbolatom 733 238 10 0 0 0 key - -;
+#X obj 733 212 prepend set;
+#X floatatom 652 162 5 0 0 1 +sharps/-flats - -;
+#X obj 692 191 tgl 15 0 empty empty minor 17 7 0 10 -262144 -1 -1 0
+1;
+#X connect 0 0 32 0;
+#X connect 1 0 27 0;
+#X connect 2 0 1 0;
+#X connect 3 0 12 0;
+#X connect 4 0 32 0;
+#X connect 7 0 8 0;
+#X connect 8 0 32 0;
+#X connect 9 0 32 0;
+#X connect 10 0 32 0;
+#X connect 11 0 30 0;
+#X connect 12 0 32 0;
+#X connect 16 0 32 0;
+#X connect 21 0 32 0;
+#X connect 25 0 65 0;
+#X connect 26 0 25 1;
+#X connect 27 0 32 0;
+#X connect 28 0 21 0;
+#X connect 29 0 28 0;
+#X connect 30 0 10 0;
+#X connect 30 0 41 0;
+#X connect 32 0 35 0;
+#X connect 32 0 56 0;
+#X connect 32 1 6 0;
+#X connect 32 1 48 1;
+#X connect 32 2 64 0;
+#X connect 34 0 33 0;
+#X connect 35 0 36 0;
+#X connect 35 0 44 0;
+#X connect 35 0 51 0;
+#X connect 35 1 52 0;
+#X connect 35 2 53 0;
+#X connect 35 3 54 0;
+#X connect 35 16 37 0;
+#X connect 36 0 18 0;
+#X connect 36 1 19 0;
+#X connect 37 0 45 0;
+#X connect 37 0 51 0;
+#X connect 37 1 52 0;
+#X connect 37 2 53 0;
+#X connect 37 3 54 0;
+#X connect 38 0 32 0;
+#X connect 39 0 34 0;
+#X connect 40 0 25 0;
+#X connect 40 1 48 0;
+#X connect 46 0 65 1;
+#X connect 48 0 20 0;
+#X connect 56 0 59 0;
+#X connect 56 0 60 0;
+#X connect 59 0 57 0;
+#X connect 59 0 63 0;
+#X connect 59 1 58 0;
+#X connect 59 1 62 1;
+#X connect 62 0 61 0;
+#X connect 63 0 62 0;
+#X connect 63 1 61 1;
+#X connect 64 0 42 0;
+#X connect 64 0 40 0;
+#X connect 64 1 67 0;
+#X connect 64 2 68 0;
+#X connect 64 3 69 0;
+#X connect 64 3 84 1;
+#X connect 64 4 89 0;
+#X connect 65 0 32 0;
+#X connect 72 0 71 0;
+#X connect 73 0 75 0;
+#X connect 73 1 74 0;
+#X connect 77 0 76 0;
+#X connect 77 1 72 0;
+#X connect 78 0 79 0;
+#X connect 78 1 80 0;
+#X connect 78 2 81 0;
+#X connect 78 3 82 0;
+#X connect 84 0 85 0;
+#X connect 84 0 86 0;
+#X connect 86 0 87 0;
+#X connect 89 0 70 0;
+#X connect 89 1 77 0;
+#X connect 89 2 73 0;
+#X connect 89 3 78 0;
+#X connect 89 4 83 0;
+#X connect 89 4 84 0;
+#X connect 89 5 90 0;
+#X connect 90 0 91 0;
+#X connect 90 1 88 0;
+#X connect 91 0 94 0;
+#X connect 91 1 95 0;
+#X connect 91 2 93 0;
+#X connect 93 0 92 0;
+#X restore 76 83 pd midifile_read;
+#X text 15 10 midifile reads and writes MIDI files.;
+#X text 152 170 2010/12/11 Martin Peach;
diff --git a/midifile/midifile.c b/midifile/midifile.c
index c0adebb..de87d1a 100644
--- a/midifile/midifile.c
+++ b/midifile/midifile.c
@@ -62,7 +62,7 @@ typedef struct t_midifile
size_t total_time; /* current time for this MIDI file in delta_time units */
t_atom midi_data[3]; /* one MIDI packet as a list */
t_outlet *midi_list_outlet;
- t_outlet *bang_outlet;
+ t_outlet *status_outlet;
t_outlet *total_time_outlet;
FILE *fP;
FILE *tmpFP;
@@ -109,6 +109,7 @@ static void *midifile_new(t_symbol *s, int argc, t_atom *argv);
static void midifile_verbosity(t_midifile *x, t_floatarg verbosity);
static void midifile_single_track(t_midifile *x, t_floatarg track);
static void midifile_dump(t_midifile *x, t_floatarg track);
+static t_symbol *midifile_key_name(int sf, int mi);
void midifile_setup(void);
void midifile_setup(void)
@@ -175,8 +176,8 @@ static void *midifile_new(t_symbol *s, int argc, t_atom *argv)
}
x->midi_list_outlet = outlet_new(&x->x_obj, &s_list);
x->total_time_outlet = outlet_new(&x->x_obj, &s_float); /* current total_time */
- x->bang_outlet = outlet_new(&x->x_obj, &s_bang); /* bang at end of file */
- post("midifile 2008 Martin Peach");
+ x->status_outlet = outlet_new(&x->x_obj, &s_anything);/* last outlet for everything else */
+ post("midifile 20110212 by Martin Peach");
return (void *)x;
}
@@ -266,7 +267,7 @@ static void midifile_flush(t_midifile *x)
if(x->state != mfWriting) return; /* only if we're writing */
- outlet_bang(x->bang_outlet); /* bang so tick count can be saved externally */
+ outlet_bang(x->status_outlet); /* bang so tick count can be saved externally */
midifile_write_end_of_track(x, end_time);
written = midifile_write_header(x);
/* now copy the MIDI data from tmpFP to fP */
@@ -413,7 +414,7 @@ static void midifile_bang(t_midifile *x)
{ /* set ended flag, only bang once */
if (x->verbosity > 1)
post ("ended = %d x->header_chunk.chunk_ntrks = %d", ended, x->header_chunk.chunk_ntrks);
- outlet_bang(x->bang_outlet);
+ outlet_bang(x->status_outlet);
++x->ended;
}
/* fall through into mfWriting */
@@ -560,7 +561,7 @@ static void midifile_float(t_midifile *x, t_float ticks)
{
if (x->verbosity)
post ("midifile: ended = %d x->header_chunk.chunk_ntrks = %d", ended, x->header_chunk.chunk_ntrks);
- outlet_bang(x->bang_outlet);
+ outlet_bang(x->status_outlet);
}
break;
case mfWriting: /* add ticks to current time */
@@ -590,6 +591,7 @@ static int midifile_read_header_chunk(t_midifile *x)
char buf[4];
size_t n;
int div, smpte, ticks;
+ t_atom output_atom;
if (x->fP == NULL)
{
@@ -649,6 +651,8 @@ static int midifile_read_header_chunk(t_midifile *x)
sP = "Unknown format";
}
if (x->verbosity) post("midifile: Header chunk format: %d (%s)", x->header_chunk.chunk_format, sP);
+ SETFLOAT(&output_atom, x->header_chunk.chunk_format);
+ outlet_anything( x->status_outlet, gensym("format"), 1, &output_atom);
n = fread(cP, 1L, 2L, x->fP);
x->offset += n;
@@ -659,6 +663,8 @@ static int midifile_read_header_chunk(t_midifile *x)
}
x->header_chunk.chunk_ntrks = midifile_get_multibyte_2(cP);
if (x->verbosity) post("midifile: Header chunk ntrks: %d", x->header_chunk.chunk_ntrks);
+ SETFLOAT(&output_atom, x->header_chunk.chunk_ntrks);
+ outlet_anything( x->status_outlet, gensym("tracks"), 1, &output_atom);
if (x->header_chunk.chunk_ntrks > MAX_TRACKS)
{
error ("midifile: Header chunk ntrks (%d) exceeds midifile MAX_TRACKS, set to %d",
@@ -680,8 +686,18 @@ static int midifile_read_header_chunk(t_midifile *x)
ticks = div & 0x0FF;
if (x->verbosity)
post("midifile: Header chunk division: 0x%X: %d frames per second, %d ticks per frame", div, smpte, ticks);
+ SETFLOAT(&output_atom, smpte);
+ outlet_anything( x->status_outlet, gensym("frames_per_sec"), 1, &output_atom);
+ SETFLOAT(&output_atom, ticks);
+ outlet_anything( x->status_outlet, gensym("ticks_per_frame"), 1, &output_atom);
+ }
+ else
+ {
+ if (x->verbosity)
+ post("midifile: Header chunk division: 0x%X: %d ticks per quarter note", div, div);
+ SETFLOAT(&output_atom, div);
+ outlet_anything( x->status_outlet, gensym("ticks_per_quarternote"), 1, &output_atom);
}
- else if (x->verbosity) post("midifile: Header chunk division: 0x%X: %d ticks per quarter note", div, div);
return 1;
}
@@ -1162,8 +1178,11 @@ static void midifile_get_next_track_chunk_data(t_midifile *x, int mfindex)
size_t delta_time, time_sig, len, i;
unsigned char status, c, d, nn, dd, cc, bb, mi, mcp, n;
char sf;
+ char fps, hour, min, sec, frame, subframe;
+
unsigned short sn;
unsigned char tt[3];
+ t_atom output_atom[6];
cP = x->track_chunk[mfindex].track_data + x->track_chunk[mfindex].track_index;
last_cP = x->track_chunk[mfindex].track_data + x->track_chunk[mfindex].chunk_length;
@@ -1220,13 +1239,24 @@ static void midifile_get_next_track_chunk_data(t_midifile *x, int mfindex)
x->midi_data[0].a_w.w_float = status;
outlet_list(x->midi_list_outlet, &s_list, 1, x->midi_data);
break;
- case 0xFF:
+ case 0xFF: /* meta event */
c = *cP++;
cP = midifile_read_var_len(cP, &len);/* meta length */
if (x->verbosity) post("midifile: Track %d Meta: %02X length %lu", mfindex, c, len);
switch (c)
{
- case 0x58:
+ case 0x59: /* key signature */
+ sf = *(signed char *)cP++;
+ mi = *cP++;
+ if (x->verbosity)
+ post ("midifile: Key Signature: %d %s, %s",
+ sf, (sf<0)?"flats":"sharps", (mi)?"minor":"major");
+ SETFLOAT(&output_atom[0], sf);
+ SETFLOAT(&output_atom[1], mi);
+ SETSYMBOL(&output_atom[2], midifile_key_name(sf, mi));
+ outlet_anything( x->status_outlet, gensym("key_sig"), 3, output_atom);
+ break;
+ case 0x58: /* time signature */
nn = *cP++;
dd = *cP++;
dd = 1<<(dd);
@@ -1235,87 +1265,150 @@ static void midifile_get_next_track_chunk_data(t_midifile *x, int mfindex)
if (x->verbosity)
post ("midifile: Time Signature: %d/%d %d clocks per tick, %d 32nd notes per quarternote",
nn, dd, cc, bb);
+ SETFLOAT(&output_atom[0], nn);
+ SETFLOAT(&output_atom[1], dd);
+ SETFLOAT(&output_atom[2], cc);
+ SETFLOAT(&output_atom[3], bb);
+ outlet_anything( x->status_outlet, gensym("time_sig"), 4, output_atom);
break;
- case 0x59:
- sf = *(signed char *)cP++;
- mi = *cP++;
- if (x->verbosity)
- post ("midifile: Key Signature: %d %s, %s",
- sf, (sf<0)?"flats":"sharps", (mi)?"minor":"major");
+ case 0x54: /* smpte offset */
+ hour = *cP++; /* hour is mixed with fps as 0ffhhhhhh */
+ switch (hour>>6)
+ {
+ case 0:
+ fps = 24;
+ break;
+ case 1:
+ fps = 25;
+ break;
+ case 2:
+ fps = 29;/* 30 fps dropframe */
+ break;
+ case 3:
+ fps = 30;
+ default:
+ fps = 0; /* error */
+ }
+ hour = hour & 0x3F;
+ min = *cP++;
+ sec = *cP++;
+ frame = *cP++;
+ subframe = *cP++;
+ if (x->verbosity) post ("midifile: %lu SMPTE offset: %d:%d:%d:%d:%d, %d fps", hour, min, sec, frame, subframe, fps);
+ SETFLOAT(&output_atom[0], hour);
+ SETFLOAT(&output_atom[1], min);
+ SETFLOAT(&output_atom[2], sec);
+ SETFLOAT(&output_atom[3], frame);
+ SETFLOAT(&output_atom[4], subframe);
+ SETFLOAT(&output_atom[5], fps);
+ outlet_anything( x->status_outlet, gensym("smpte"), 6, output_atom);
break;
- case 0x51:
+ case 0x51: /* set tempo */
tt[0] = *cP++;
tt[1] = *cP++;
tt[2] = *cP++;
time_sig = midifile_get_multibyte_3(tt);
if (x->verbosity) post ("midifile: %lu microseconds per MIDI quarter-note", time_sig);
+ SETFLOAT(&output_atom[0], time_sig);
+ outlet_anything( x->status_outlet, gensym("microsec_per_quarternote"), 1, output_atom);
break;
- case 0x2F:
+ case 0x2F: /* end of track */
if (x->verbosity) post ("midifile: End of Track %d", mfindex);
delta_time = NO_MORE_ELEMENTS;
+ SETFLOAT(&output_atom[0], mfindex);
+ SETFLOAT(&output_atom[1], x->total_time);
+ outlet_anything( x->status_outlet, gensym("end"), 2, output_atom);
cP += len;
break;
case 0x21:
tt[0] = *cP++;
if (x->verbosity) post ("midifile: MIDI port or cable number (unofficial): %d", tt[0]);
break;
- case 0x20:
+ case 0x20: /* MIDI channel prefix */
mcp = *cP++;
if (x->verbosity) post ("midifile: MIDI Channel Prefix: %d", mcp);
+ SETFLOAT(&output_atom[0], mfindex);
+ SETFLOAT(&output_atom[1], mcp);
+ outlet_anything( x->status_outlet, gensym("channel"), 2, output_atom);
break;
- case 0x06:
+ case 0x07: /* cue point */
+ str = cP;
+ c = cP[len];
+ cP[len] = '\0'; /* null terminate temporarily */
+ if (x->verbosity) post ("midifile: Cue Point: %s", str);
+ SETSYMBOL(&output_atom[0], gensym(str));
+ outlet_anything( x->status_outlet, gensym("cue"), 1, output_atom);
+ cP[len] = c;
+ cP += len;
+ break;
+ case 0x06: /* marker */
str = cP;
c = cP[len];
cP[len] = '\0'; /* null terminate temporarily */
if (x->verbosity) post ("midifile: Marker: %s", str);
+ SETSYMBOL(&output_atom[0], gensym(str));
+ outlet_anything( x->status_outlet, gensym("marker"), 1, output_atom);
cP[len] = c;
cP += len;
break;
- case 0x05:
+ case 0x05: /* lyrics */
str = cP;
c = cP[len];
cP[len] = '\0'; /* null terminate temporarily */
if (x->verbosity) post ("midifile: Lyric: %s", str);
+ SETSYMBOL(&output_atom[0], gensym(str));
+ outlet_anything( x->status_outlet, gensym("lyrics"), 1, output_atom);
cP[len] = c;
cP += len;
break;
- case 0x04:
+ case 0x04: /* instrument name */
str = cP;
c = cP[len];
cP[len] = '\0'; /* null terminate temporarily */
if (x->verbosity) post ("midifile: Instrument Name: %s", str);
+ SETSYMBOL(&output_atom[0], gensym(str));
+ outlet_anything( x->status_outlet, gensym("instr_name"), 1, output_atom);
cP[len] = c;
cP += len;
break;
- case 0x03:
+ case 0x03: /* sequence/track name */
str = cP;
c = cP[len];
cP[len] = '\0'; /* null terminate temporarily */
if (x->verbosity) post ("midifile: Sequence/Track Name: %s", str);
+ SETFLOAT(&output_atom[0], mfindex);
+ SETSYMBOL(&output_atom[1], gensym(str));
+ outlet_anything( x->status_outlet, gensym("name"), 2, output_atom);
cP[len] = c;
cP += len;
break;
- case 0x02:
+ case 0x02:/* copyright notice */
str = cP;
c = cP[len];
cP[len] = '\0'; /* null terminate temporarily */
if (x->verbosity) post ("midifile: Copyright Notice: %s", str);
+ SETSYMBOL(&output_atom[0], gensym(str));
+ outlet_anything( x->status_outlet, gensym("copyright"), 1, output_atom);
cP[len] = c;
cP += len;
break;
- case 0x01:
+ case 0x01: /* text event */
str = cP;
c = cP[len];
cP[len] = '\0'; /* null terminate temporarily */
if (x->verbosity) post ("midifile: Text Event: %s", str);
+ SETSYMBOL(&output_atom[0], gensym(str));
+ outlet_anything( x->status_outlet, gensym("text"), 1, output_atom);
cP[len] = c;
cP += len;
break;
- case 0x00:
+ case 0x00: /* sequence number */
tt[0] = *cP++;
tt[1] = *cP++;
sn = midifile_get_multibyte_2(tt);
if (x->verbosity) post ("midifile: Sequence Number %d", sn);
+ SETFLOAT(&output_atom[0], sn);
+ outlet_anything( x->status_outlet, gensym("seq_num"), 1, output_atom);
break;
default:
if (x->verbosity) post ("midifile: Unknown: %02X", c);
@@ -1463,4 +1556,29 @@ static void midifile_skip_next_track_chunk_data(t_midifile *x, int mfindex)
else x->track_chunk[mfindex].total_time += delta_time;
}
+static t_symbol *midifile_key_name(int sf, int mi)
+{
+ /* set a symbole to the key name baseed on */
+ /* sf= number of sharps if positive, else flats
+ /* mi = 0=major 1= minor */
+ char *maj_key[15]={"B", "Gb", "Db", "Ab", "Eb", "Bb", "F", "C", "G", "D", "A", "E", "B", "F#", "Db"};
+ char *min_key[15]={"G#", "Eb", "Bb", "F", "C", "G", "D", "A", "E", "B", "F#", "C#", "G#", "D#", "Bb"};
+ char buf[8] = {"no_key."};
+ int i;
+
+ if ((sf >= -7)&&(sf <= 7))
+ {
+ if (mi == 1)
+ {
+ i = sprintf(buf, "%s", min_key[sf+7]);
+ sprintf(buf+i, "%s", "Minor");
+ }
+ else if (mi == 0)
+ {
+ i = sprintf(buf, "%s", maj_key[sf+7]);
+ sprintf(buf+i, "%s", "Major");
+ }
+ }
+ return gensym(buf);
+}
/* fin midifile.c */