aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKatja <katjav@users.sourceforge.net>2011-11-11 16:00:56 +0000
committerKatja <katjav@users.sourceforge.net>2011-11-11 16:00:56 +0000
commit844f29f5b8b7229e8983b4a2dfc9a21ed8931811 (patch)
tree89221ad33c9e8d951d1340a86048f2562f13dc71
add libdir 'testtools' with test abstractions to externalssvn2git-root
- abstraction 'unit-test-frame~.pd' - abstraction 'unit-test-frame.pd' - example patches svn path=/trunk/externals/testtools/; revision=15724
-rw-r--r--unit-test-frame-example.pd25
-rw-r--r--unit-test-frame-example.wavbin0 -> 2092 bytes
-rw-r--r--unit-test-frame.pd568
-rw-r--r--unit-test-frame~-example.pd30
-rw-r--r--unit-test-frame~-example.wavbin0 -> 2092 bytes
-rw-r--r--unit-test-frame~.pd460
6 files changed, 1083 insertions, 0 deletions
diff --git a/unit-test-frame-example.pd b/unit-test-frame-example.pd
new file mode 100644
index 0000000..ae658c1
--- /dev/null
+++ b/unit-test-frame-example.pd
@@ -0,0 +1,25 @@
+#N canvas 336 28 746 629 10;
+#X obj 53 300 unit-test-frame;
+#X obj 26 104 cnv 15 150 150 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X text 34 143 1 - reference name;
+#X text 34 162 2 - test delay in ms;
+#X text 33 123 test arguments (list):;
+#X obj 53 197 loadbang;
+#X obj 359 106 cnv 15 150 150 empty empty empty 20 12 0 14 -233017
+-66577 0;
+#X obj 374 200 sqrt;
+#X obj 374 156 / 512;
+#X msg 53 226 unit-test-frame-example 0;
+#X text 495 278 more info behind the question mark;
+#X text 358 18 Optionally use index 0 - 511 to get a series of outputs
+from the object or system under test.;
+#X text 416 155 normalization;
+#X text 394 112 system under test;
+#X text 358 52 Normalizing the object output is recommendable \, as
+it makes stddev more meaningful.;
+#X connect 0 2 8 0;
+#X connect 5 0 9 0;
+#X connect 7 0 0 1;
+#X connect 8 0 7 0;
+#X connect 9 0 0 0;
diff --git a/unit-test-frame-example.wav b/unit-test-frame-example.wav
new file mode 100644
index 0000000..1e79eee
--- /dev/null
+++ b/unit-test-frame-example.wav
Binary files differ
diff --git a/unit-test-frame.pd b/unit-test-frame.pd
new file mode 100644
index 0000000..9cd29ba
--- /dev/null
+++ b/unit-test-frame.pd
@@ -0,0 +1,568 @@
+#N canvas 435 37 710 662 10;
+#X obj 620 302 bng 50 250 50 0 empty empty list 5 25 0 14 -203904 -262144
+-1;
+#X obj 315 301 bng 50 250 50 0 empty empty list 5 25 0 14 -203904 -262144
+-1;
+#X obj 100 300 bng 50 250 50 0 empty empty list 5 25 0 14 -203904 -262144
+-1;
+#X obj 621 239 bng 50 250 50 0 empty empty ? 15 25 0 30 -260097 -262144
+-1;
+#X obj 474 302 hsl 130 50 0 127 0 0 \$0-dummysend \$0-stddev-label
+STDDEV-ZERO 4 35 0 10 -203904 -203904 -1 0 1;
+#X floatatom 477 309 18 0 0 0 - #0-stddev -;
+#X obj 256 301 bng 50 250 50 0 empty empty test 5 25 0 14 -260097 -262144
+-1;
+#X obj 40 300 bng 50 250 50 0 empty empty write 4 25 0 14 -260097 -262144
+-1;
+#X obj 43 239 hsl 195 50 0 112 0 0 \$0-dummysend \$0-dummyreceive empty
+-2 -8 0 10 -203904 -203904 -203904 0 1;
+#X symbolatom 45 247 25 0 0 0 - #0-refname #0-dummysend;
+#X text 44 267 reference;
+#N canvas 607 182 376 522 std.deviation 0;
+#X obj 80 127 until;
+#X obj 95 155 + 1;
+#X obj 80 180 f;
+#X obj 80 99 t f b;
+#X msg 122 163 0;
+#X obj 107 310 +;
+#X floatatom 107 337 8 0 0 0 - - -;
+#X obj 92 361 f;
+#X text 153 163 clear sums;
+#X obj 52 234 == 511;
+#X obj 52 258 sel 1;
+#X obj 80 203 t f f;
+#X obj 107 261 t f f;
+#X obj 107 286 *;
+#X obj 92 386 / 512;
+#X obj 92 410 sqrt;
+#X obj 92 439 outlet;
+#X text 137 441 stddev;
+#X obj 186 439 s \$0-stddev;
+#X obj 107 233 tabread \$0-difference;
+#X obj 191 58 + 1;
+#X obj 80 75 f 512;
+#X floatatom 202 10 5 0 0 0 - - -;
+#X obj 263 -16 r \$0-test-delay;
+#X obj 263 30 + 10;
+#X floatatom 272 8 5 0 0 0 - - -;
+#X obj 80 47 delay 10;
+#X obj 191 -16 r \$0-index;
+#X obj 80 -16 r \$0-test-prepare;
+#X connect 0 0 2 0;
+#X connect 1 0 2 1;
+#X connect 2 0 1 0;
+#X connect 2 0 11 0;
+#X connect 3 0 0 0;
+#X connect 3 1 4 0;
+#X connect 4 0 2 1;
+#X connect 4 0 5 1;
+#X connect 5 0 6 0;
+#X connect 6 0 5 1;
+#X connect 6 0 7 1;
+#X connect 7 0 14 0;
+#X connect 9 0 10 0;
+#X connect 10 0 7 0;
+#X connect 11 0 9 0;
+#X connect 11 1 19 0;
+#X connect 12 0 13 0;
+#X connect 12 1 13 1;
+#X connect 13 0 5 0;
+#X connect 14 0 15 0;
+#X connect 15 0 16 0;
+#X connect 15 0 18 0;
+#X connect 19 0 12 0;
+#X connect 20 0 14 1;
+#X connect 20 0 21 1;
+#X connect 21 0 3 0;
+#X connect 23 0 24 0;
+#X connect 23 0 25 0;
+#X connect 24 0 26 1;
+#X connect 26 0 21 0;
+#X connect 27 0 9 1;
+#X connect 27 0 20 0;
+#X connect 27 0 22 0;
+#X connect 28 0 26 0;
+#X restore 327 123 pd std.deviation;
+#N canvas 905 83 262 193 refname+ID 0;
+#X obj 26 47 inlet;
+#X obj 71 96 f \$0;
+#X obj 26 120 pack s f;
+#X obj 26 74 t a b;
+#X obj 26 152 s \$0-refname+ID;
+#X connect 0 0 3 0;
+#X connect 1 0 2 1;
+#X connect 2 0 4 0;
+#X connect 3 0 2 0;
+#X connect 3 1 1 0;
+#X restore 56 129 pd refname+ID;
+#X obj 39 177 s \$0-refname;
+#X obj 39 153 symbol;
+#X obj 39 23 inlet;
+#N canvas 67 138 412 506 load-reference 0;
+#X obj 36 27 inlet;
+#X obj 36 203 soundfiler;
+#X obj 81 112 f \$0;
+#X obj 36 136 pack s f;
+#X obj 36 94 t a b;
+#X obj 36 461 s \$0-do-test;
+#X msg 36 173 read ./\$1.wav \$2-reference;
+#X obj 75 375 pack s s s s s s;
+#X obj 168 297 r \$0-refname;
+#X obj 75 432 stdout;
+#X obj 36 235 sel 512;
+#X obj 36 60 spigot 1;
+#X msg 81 27 0;
+#X text 119 29 at load \, try to read reference file and do test;
+#X msg 75 271 REFERENCE-FILE-ERROR reference file not found:;
+#X msg 168 324 \$1.wav;
+#X obj 168 349 symbol;
+#X obj 75 402 list trim;
+#X obj 127 432 print unit-test;
+#X connect 0 0 11 0;
+#X connect 1 0 10 0;
+#X connect 2 0 3 1;
+#X connect 3 0 6 0;
+#X connect 4 0 3 0;
+#X connect 4 1 2 0;
+#X connect 6 0 1 0;
+#X connect 7 0 17 0;
+#X connect 8 0 15 0;
+#X connect 10 0 5 0;
+#X connect 10 1 14 0;
+#X connect 11 0 4 0;
+#X connect 11 0 12 0;
+#X connect 12 0 11 1;
+#X connect 14 0 7 0;
+#X connect 15 0 16 0;
+#X connect 16 0 7 5;
+#X connect 17 0 9 0;
+#X connect 17 0 18 0;
+#X restore 74 105 pd load-reference;
+#X obj 328 27 inlet;
+#X obj 630 22 inlet;
+#X obj 238 628 outlet;
+#X obj 286 628 outlet;
+#X obj 335 629 outlet;
+#X obj 238 555 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
+-1 -1;
+#X msg 288 508 const 0;
+#X obj 288 531 s \$0-system-under-test;
+#X obj 39 49 unpack s f;
+#X obj 96 78 s \$0-test-delay;
+#N canvas 568 53 379 248 table 0;
+#X obj 45 199 tabwrite \$0-system-under-test;
+#X obj 216 70 f;
+#X obj 245 70 + 1;
+#X obj 45 53 t f b;
+#X msg 231 45 0;
+#X obj 45 22 inlet;
+#X obj 62 172 tabwrite \$0-difference;
+#X obj 77 119 tabread \$0-reference;
+#X obj 77 87 t f f;
+#X obj 231 21 r \$0-test-prepare;
+#X obj 237 135 s \$0-index;
+#X obj 62 145 -;
+#X obj 237 108 moses 512;
+#X connect 1 0 2 0;
+#X connect 1 0 8 0;
+#X connect 1 0 0 1;
+#X connect 1 0 12 0;
+#X connect 2 0 1 1;
+#X connect 3 0 0 0;
+#X connect 3 0 11 0;
+#X connect 3 1 1 0;
+#X connect 4 0 1 1;
+#X connect 5 0 3 0;
+#X connect 7 0 11 1;
+#X connect 8 0 7 0;
+#X connect 8 1 6 1;
+#X connect 9 0 4 0;
+#X connect 11 0 6 0;
+#X connect 12 0 10 0;
+#X restore 328 85 pd table;
+#X obj 238 509 t b b b;
+#N canvas 0 22 256 269 view-system 0;
+#X obj 39 39 inlet;
+#X msg 39 75 arrayviewlistnew;
+#X obj 39 174 s \$0-system-under-test;
+#X obj 67 118 r \$0-test-prepare;
+#X msg 67 144 arrayviewclose;
+#X connect 0 0 1 0;
+#X connect 1 0 2 0;
+#X connect 3 0 4 0;
+#X connect 4 0 2 0;
+#X restore 351 507 pd view-system;
+#N canvas 695 50 264 263 view-difference 0;
+#X obj 39 39 inlet;
+#X obj 39 180 s \$0-difference;
+#X msg 39 75 arrayviewlistnew;
+#X obj 57 108 r \$0-test-prepare;
+#X msg 57 135 arrayviewclose;
+#X connect 0 0 2 0;
+#X connect 2 0 1 0;
+#X connect 3 0 4 0;
+#X connect 4 0 1 0;
+#X restore 584 520 pd view-difference;
+#N canvas 453 143 231 283 view-reference 0;
+#X obj 27 31 inlet;
+#X msg 27 59 arrayviewlistnew;
+#X obj 27 144 s \$0-reference;
+#X obj 42 88 r \$0-test-prepare;
+#X msg 42 114 arrayviewclose;
+#X connect 0 0 1 0;
+#X connect 1 0 2 0;
+#X connect 3 0 4 0;
+#X connect 4 0 2 0;
+#X restore 100 507 pd view-reference;
+#N canvas 704 28 384 625 write-reference 0;
+#X obj 51 344 soundfiler;
+#X obj 51 287 list;
+#X obj 50 16 inlet;
+#X floatatom 82 378 5 0 0 0 - - -;
+#X obj 72 257 r \$0-refname+ID;
+#X text 90 16 bang;
+#X obj 51 124 r \$0-do-write-reference;
+#X obj 143 152 r \$0-abort-write-reference;
+#X obj 51 379 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1
+-1;
+#X obj 51 583 s \$0-do-test;
+#X obj 72 153 delay 500;
+#X obj 257 20 r \$0-refname;
+#X msg 257 46 \$1.wav;
+#X obj 257 72 symbol;
+#X obj 257 99 s \$0-ref-wav-name;
+#N canvas 682 430 395 255 write-reference-popup\$0 0;
+#X obj 88 174 bng 60 400 50 0 \$0-do-write-reference empty continue
+2 28 0 12 -260097 -262144 -1;
+#X obj 234 174 bng 60 300 50 0 \$0-abort-write-reference empty abort
+8 28 0 12 -204786 -262144 -1;
+#X obj 91 67 hsl 200 80 0 127 0 0 \$0-dummysend \$0-dummyreceive empty
+-2 -8 0 10 -262144 -262144 -1 0 1;
+#X symbolatom 95 85 30 0 0 0 - #0-refname #0-dummysend;
+#X symbolatom 95 125 30 0 0 0 - #0-ref-wav-name #0-dummysend;
+#X text 93 67 reference name:;
+#X text 93 108 file name:;
+#X text 24 11 This action will overwrite your reference .wav file with
+the content of \$0-signal-under-test. The action can not be undone!
+;
+#X restore 51 95 pd write-reference-popup\$0;
+#X obj 50 68 s pd-write-reference-popup\$0;
+#X msg 50 43 vis 1;
+#X obj 72 230 s pd-write-reference-popup\$0;
+#X msg 72 205 vis 0;
+#X obj 143 180 delay 200;
+#X msg 51 315 write -wave -bytes 4 \$1 \$2-system-under-test;
+#N canvas 528 482 203 281 index0-511 0;
+#X obj 41 49 inlet;
+#X obj 41 224 outlet;
+#X obj 41 139 until;
+#X msg 41 107 512;
+#X obj 41 169 f;
+#X obj 72 169 + 1;
+#X obj 41 79 t b b;
+#X msg 80 139 0;
+#X connect 0 0 6 0;
+#X connect 2 0 4 0;
+#X connect 3 0 2 0;
+#X connect 4 0 5 0;
+#X connect 4 0 1 0;
+#X connect 5 0 4 1;
+#X connect 6 0 3 0;
+#X connect 6 1 7 0;
+#X connect 7 0 4 1;
+#X restore 51 411 pd index0-511;
+#X obj 70 476 tabread \$0-system-under-test;
+#X obj 70 511 tabwrite \$0-reference;
+#X obj 51 535 == 511;
+#X obj 51 443 t f f f;
+#X obj 51 559 sel 1;
+#X connect 0 0 3 0;
+#X connect 0 0 8 0;
+#X connect 1 0 21 0;
+#X connect 2 0 17 0;
+#X connect 4 0 1 1;
+#X connect 6 0 1 0;
+#X connect 6 0 10 0;
+#X connect 7 0 20 0;
+#X connect 8 0 22 0;
+#X connect 10 0 19 0;
+#X connect 11 0 12 0;
+#X connect 12 0 13 0;
+#X connect 13 0 14 0;
+#X connect 17 0 16 0;
+#X connect 19 0 18 0;
+#X connect 20 0 19 0;
+#X connect 21 0 0 0;
+#X connect 22 0 26 0;
+#X connect 23 0 24 0;
+#X connect 25 0 27 0;
+#X connect 26 0 25 0;
+#X connect 26 1 23 0;
+#X connect 26 2 24 1;
+#X connect 27 0 9 0;
+#X restore 40 208 pd write-reference;
+#N canvas 739 28 261 427 test-result-messages 0;
+#X obj 32 23 inlet;
+#X obj 59 310 stdout;
+#X obj 32 84 sel 0;
+#X obj 89 166 r \$0-refname;
+#X obj 89 193 symbol;
+#X obj 32 56 moses 1e-05;
+#X obj 32 277 t b a;
+#X msg 32 336 UNIT-TEST-DONE;
+#X obj 32 373 stdout;
+#X obj 32 221 pack s f s;
+#X obj 112 309 print unit-test;
+#X obj 85 373 print unit-test;
+#X obj 32 249 list trim;
+#X msg 59 113 STDDEV-SMALL \$1;
+#X msg 32 141 STDDEV-ZERO 0;
+#X msg 95 84 STDDEV-LARGE \$1;
+#N canvas 49 312 252 304 stddev-label 0;
+#X obj 40 29 inlet;
+#X obj 40 92 sel 0;
+#X obj 40 64 moses 1e-05;
+#X msg 103 92 STDDEV-LARGE;
+#X msg 67 121 STDDEV-SMALL;
+#X msg 40 149 STDDEV-ZERO;
+#X msg 40 221 label \$1;
+#X obj 40 191 symbol;
+#X obj 40 250 s \$0-stddev-label;
+#X connect 0 0 2 0;
+#X connect 1 0 5 0;
+#X connect 1 1 4 0;
+#X connect 2 0 1 0;
+#X connect 2 1 3 0;
+#X connect 3 0 7 0;
+#X connect 4 0 7 0;
+#X connect 5 0 7 0;
+#X connect 6 0 8 0;
+#X connect 7 0 6 0;
+#X restore 126 50 pd stddev-label;
+#X connect 0 0 5 0;
+#X connect 0 0 16 0;
+#X connect 2 0 14 0;
+#X connect 2 1 13 0;
+#X connect 3 0 4 0;
+#X connect 4 0 9 2;
+#X connect 5 0 2 0;
+#X connect 5 1 15 0;
+#X connect 6 0 7 0;
+#X connect 6 1 1 0;
+#X connect 6 1 10 0;
+#X connect 7 0 8 0;
+#X connect 7 0 11 0;
+#X connect 9 0 12 0;
+#X connect 12 0 6 0;
+#X connect 13 0 9 0;
+#X connect 14 0 9 0;
+#X connect 15 0 9 0;
+#X restore 327 164 pd test-result-messages;
+#X floatatom 203 247 5 0 0 0 - #0-test-delay -;
+#X text 201 269 delay;
+#N canvas 628 152 504 542 list-drip 0;
+#X obj 68 94 t a a;
+#X obj 68 251 spigot;
+#X obj 101 159 bang;
+#X obj 101 185 1;
+#X obj 207 160 route bang;
+#X obj 170 160 bang;
+#X obj 170 186 0;
+#X obj 101 124 list split 2;
+#X obj 134 348 list split;
+#X obj 191 297 list length;
+#X obj 191 319 >> 1;
+#X obj 68 280 t a a a a;
+#X obj 68 439 list split;
+#X obj 125 391 list length;
+#X obj 125 416 >> 1;
+#X obj 41 29 inlet;
+#X obj 264 186 outlet;
+#X text 83 29 Copyright 2009 by Mathieu Bouchard;
+#X obj 41 63 t b a;
+#X obj 328 80 outlet;
+#X text 383 82 signal end of list;
+#X text 35 502 made compatible with [list-drip]: fbar 2009;
+#X connect 0 0 1 0;
+#X connect 0 1 7 0;
+#X connect 1 0 11 0;
+#X connect 2 0 3 0;
+#X connect 3 0 1 1;
+#X connect 4 1 16 0;
+#X connect 5 0 6 0;
+#X connect 6 0 1 1;
+#X connect 7 0 2 0;
+#X connect 7 2 4 0;
+#X connect 7 2 5 0;
+#X connect 8 0 0 0;
+#X connect 9 0 10 0;
+#X connect 10 0 8 1;
+#X connect 11 0 12 0;
+#X connect 11 1 13 0;
+#X connect 11 2 8 0;
+#X connect 11 3 9 0;
+#X connect 12 1 0 0;
+#X connect 13 0 14 0;
+#X connect 14 0 12 1;
+#X connect 15 0 18 0;
+#X connect 18 0 19 0;
+#X connect 18 1 0 0;
+#X restore 328 52 pd list-drip;
+#X obj 257 555 s \$0-test-prepare;
+#X obj 256 208 r \$0-do-test;
+#N canvas 716 407 203 281 index0-511 0;
+#X obj 41 49 inlet;
+#X obj 41 224 outlet;
+#X obj 41 139 until;
+#X msg 41 107 512;
+#X obj 41 169 f;
+#X obj 72 169 + 1;
+#X obj 41 79 t b b;
+#X msg 80 139 0;
+#X connect 0 0 6 0;
+#X connect 2 0 4 0;
+#X connect 3 0 2 0;
+#X connect 4 0 5 0;
+#X connect 4 0 1 0;
+#X connect 5 0 4 1;
+#X connect 6 0 3 0;
+#X connect 6 1 7 0;
+#X connect 7 0 4 1;
+#X restore 335 605 pd index0-511;
+#X obj 43 371 hsl 195 100 0 127 0 0 empty empty empty -2 -8 0 10 -203904
+-203904 -1 0 1;
+#N canvas 0 22 450 300 (subpatch) 0;
+#X array \$0-reference 512 float 0;
+#X coords 0 1 511 -1 200 100 1;
+#X restore 40 371 graph;
+#X obj 473 371 hsl 195 100 0 127 0 0 empty empty empty -2 -8 0 10 -203904
+-203904 -1 0 1;
+#N canvas 0 22 450 300 (subpatch) 0;
+#X array \$0-difference 512 float 0;
+#X coords 0 1 511 -1 200 100 1;
+#X restore 470 371 graph;
+#X obj 258 371 hsl 195 100 0 127 0 0 empty empty empty -2 -8 0 10 -203904
+-203904 -1 0 1;
+#N canvas 0 22 450 300 (subpatch) 0;
+#X array \$0-system-under-test 512 float 0;
+#X coords 0 1 511 -1 200 100 1;
+#X restore 255 371 graph;
+#X obj 256 239 bng 50 250 50 0 \$0-dummysend \$0-dummyreceive empty
+17 7 0 10 -203904 -204786 -203904;
+#X obj 256 239 bng 50 1000 50 0 \$0-dummysend \$0-dummyreceive done
+7 25 0 14 -203904 -1 -203904;
+#X text 588 21 dummy;
+#X text 73 23 reference name + delay;
+#X text 367 25 floats & lists;
+#X text 40 481 test-bang out;
+#X text 589 481 test-bang out;
+#X text 405 481 index 0 - 511 out;
+#X obj 467 237 cnv 15 100 20 empty empty [unit-test-frame] 2 12 0 14
+-262144 -66577 0;
+#X msg 540 520 vis 1;
+#X obj 540 548 s pd-info-unit-test\$0;
+#N canvas 473 125 566 541 info-unit-test\$0 0;
+#X text 144 474 STDDEV-ZERO 0;
+#X text 144 516 STDDEV-LARGE <stddev>;
+#X text 144 494 STDDEV-SMALL <stddev>;
+#X text 296 495 when standard deviation < 1e-05;
+#X text 296 516 when standard deviation >= 1e-05;
+#X text 296 474 when standard deviation = 0;
+#X text 129 46 ------------------------------------------------------------
+;
+#X text 127 378 ------------------------------------------------------------
+;
+#X text 126 538 ------------------------------------------------------------
+;
+#X text 131 808 Katja Vetter & Fred Jan Kraan \, October 2011;
+#X text 127 556 The reference file must be in the same directory as
+the test. If it is not found when the patch is loaded \, an error is
+reported to the Pd window and stdout:;
+#X text 122 821 ------------------------------------------------------------
+;
+#X text 129 67 1: Test arguments must be sent as a list into the first
+inlet:;
+#X text 149 606 REFERENCE-FILE-ERROR reference file not found: <reference>
+;
+#X text 128 398 The test is automatically executed when the patch is
+loaded \, and can also be started with button 'test'. Difference between
+signal under test and reference is graphed \, and standard deviation
+is computed. A test result message is sent to the Pd window and stdout:
+;
+#X text 124 779 ------------------------------------------------------------
+;
+#X text 26 19 arguments;
+#X obj 29 39 loadbang;
+#X obj 32 407 bng 50 250 50 0 empty empty test 5 25 0 14 -260097 -262144
+-1;
+#X obj 38 555 bng 50 250 50 0 empty empty write 4 25 0 14 -260097 -262144
+-1;
+#X text 124 714 ------------------------------------------------------------
+;
+#X obj 29 94 loadbang;
+#X text 130 98 - reference name \, matching the name of the test patch
+;
+#X text 130 22 how to use [unit-test-frame.pd] in unit test patches
+;
+#X msg 29 66 sqrt 0;
+#X msg 29 121 pipe 100;
+#X text 130 116 - delaytime between test trigger and test snapshot.
+;
+#X text 129 137 2: Messages from the object(s) under test must be sent
+into the second inlet. Floats and lists are both accepted. When testing
+an external object \, consider instantiating it with namespace \, like
+[zexy/wrap].;
+#X text 127 631 A reference file can be created from the content of
+\$0-signal-under-test \, using a Pd which is known to work well (the
+latest release). Use button 'write'. The file will have 512 samples
+in 32 bit .wav format. Even though the test output is not a signal
+\, this is a good format to write.;
+#X text 124 733 [unit-test-frame.pd] uses only vanilla Pd classes.
+For testing external classes \, consider using namespaces like in [zexy/wrap].
+;
+#X text 130 203 Use a bang from one of [unit-test-frame.pd] outlets
+to trigger the object(s) when the test starts. Or use the index 0 -
+511 outlet to generate a series of output values.;
+#X text 131 255 Normalization of the object output (within interval
+0 to 1 or -1 to 1) is useful. It gives a good graph and a meaningful
+stddev. Also note that large numbers are unprecise. Example: the difference
+between 1e+12 in single precision and 1e+12 in double precision is
+27968! Try this on:;
+#X text 149 345 http://www.h-schmidt.net/FloatApplet/IEEE754.html;
+#X connect 17 0 24 0;
+#X connect 21 0 25 0;
+#X restore 555 165 pd info-unit-test\$0;
+#X obj 428 531 s \$0-difference;
+#X obj 384 629 outlet;
+#X obj 238 577 t b b b b;
+#X text 209 481 test-bang out;
+#X connect 0 0 30 0;
+#X connect 1 0 29 0;
+#X connect 2 0 31 0;
+#X connect 3 0 55 0;
+#X connect 6 0 28 0;
+#X connect 7 0 32 0;
+#X connect 11 0 33 0;
+#X connect 11 0 47 0;
+#X connect 14 0 13 0;
+#X connect 15 0 25 0;
+#X connect 17 0 36 0;
+#X connect 22 0 60 0;
+#X connect 23 0 24 0;
+#X connect 23 0 58 0;
+#X connect 25 0 14 0;
+#X connect 25 0 12 0;
+#X connect 25 0 16 0;
+#X connect 25 1 26 0;
+#X connect 28 0 22 0;
+#X connect 28 1 37 0;
+#X connect 28 2 23 0;
+#X connect 36 0 27 0;
+#X connect 38 0 6 0;
+#X connect 39 0 21 0;
+#X connect 55 0 56 0;
+#X connect 60 0 19 0;
+#X connect 60 1 20 0;
+#X connect 60 2 39 0;
+#X connect 60 3 59 0;
+#X coords 0 -1 1 1 650 270 2 30 230;
diff --git a/unit-test-frame~-example.pd b/unit-test-frame~-example.pd
new file mode 100644
index 0000000..39cefd1
--- /dev/null
+++ b/unit-test-frame~-example.pd
@@ -0,0 +1,30 @@
+#N canvas 426 40 714 575 10;
+#X obj 37 297 unit-test-frame~;
+#X obj 333 113 cnv 15 150 150 empty empty empty 20 12 0 14 -233017
+-66577 0;
+#X msg 421 146 0;
+#X obj 358 176 phasor~ 440;
+#X obj 358 203 -~ 0.5;
+#X obj 358 233 bp~ 220 1;
+#X text 354 119 system under test;
+#X obj 25 115 cnv 15 150 150 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X obj 37 204 loadbang;
+#X text 35 158 1 - reference name;
+#X text 35 177 2 - test delay in ms;
+#X text 34 138 test arguments (list):;
+#X text 480 273 More info behind the question mark;
+#X text 332 79 Use a bang from one of [unit-test-frame~] outlets to
+reset phase at test start.;
+#X text 23 16 When testing objects with a memory \, like an IIR filter
+\, set a non-zero delay time (between test trigger and test snapshot).
+This is needed to get the same test result every time \, independent
+of the signal input history.;
+#X msg 37 233 unit-test-frame~-example 200;
+#X connect 0 2 2 0;
+#X connect 2 0 3 1;
+#X connect 3 0 4 0;
+#X connect 4 0 5 0;
+#X connect 5 0 0 1;
+#X connect 8 0 15 0;
+#X connect 15 0 0 0;
diff --git a/unit-test-frame~-example.wav b/unit-test-frame~-example.wav
new file mode 100644
index 0000000..918c233
--- /dev/null
+++ b/unit-test-frame~-example.wav
Binary files differ
diff --git a/unit-test-frame~.pd b/unit-test-frame~.pd
new file mode 100644
index 0000000..9d9873c
--- /dev/null
+++ b/unit-test-frame~.pd
@@ -0,0 +1,460 @@
+#N canvas 433 135 724 590 10;
+#N canvas 213 116 398 498 write-reference 0;
+#X obj 51 344 soundfiler;
+#X obj 51 287 list;
+#X obj 50 16 inlet;
+#X floatatom 82 378 5 0 0 0 - - -;
+#X obj 72 257 r \$0-refname+ID;
+#X text 90 16 bang;
+#X obj 51 124 r \$0-do-write-reference;
+#X obj 143 152 r \$0-abort-write-reference;
+#X obj 51 379 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1
+-1;
+#X obj 241 446 s \$0-do-test;
+#X obj 70 408 tabplay~ \$0-signal-under-test;
+#X msg 51 315 write -wave -bytes 4 \$1 \$2-signal-under-test;
+#X obj 51 450 tabwrite~ \$0-reference;
+#X obj 72 153 delay 500;
+#X obj 257 20 r \$0-refname;
+#X msg 257 46 \$1.wav;
+#X obj 257 71 symbol;
+#X obj 257 99 s \$0-ref-wav-name;
+#N canvas 682 430 395 255 write-reference-popup\$0 0;
+#X obj 88 174 bng 60 400 50 0 \$0-do-write-reference empty continue
+2 28 0 12 -260097 -262144 -1;
+#X obj 234 174 bng 60 300 50 0 \$0-abort-write-reference empty abort
+8 28 0 12 -204786 -262144 -1;
+#X obj 91 67 hsl 200 80 0 127 0 0 \$0-dummysend \$0-dummyreceive empty
+-2 -8 0 10 -262144 -262144 -1 0 1;
+#X symbolatom 95 85 30 0 0 0 - #0-refname #0-dummysend;
+#X symbolatom 95 125 30 0 0 0 - #0-ref-wav-name #0-dummysend;
+#X text 93 67 reference name:;
+#X text 93 108 file name:;
+#X text 24 11 This action will overwrite your reference .wav file with
+the content of \$0-signal-under-test. The action can not be undone!
+;
+#X restore 51 95 pd write-reference-popup\$0;
+#X obj 50 68 s pd-write-reference-popup\$0;
+#X msg 50 43 vis 1;
+#X obj 72 230 s pd-write-reference-popup\$0;
+#X msg 72 205 vis 0;
+#X obj 143 177 delay 200;
+#X connect 0 0 3 0;
+#X connect 0 0 8 0;
+#X connect 1 0 11 0;
+#X connect 2 0 20 0;
+#X connect 4 0 1 1;
+#X connect 6 0 1 0;
+#X connect 6 0 13 0;
+#X connect 7 0 23 0;
+#X connect 8 0 10 0;
+#X connect 8 0 12 0;
+#X connect 10 0 12 0;
+#X connect 10 1 9 0;
+#X connect 11 0 0 0;
+#X connect 13 0 22 0;
+#X connect 14 0 15 0;
+#X connect 15 0 16 0;
+#X connect 16 0 17 0;
+#X connect 20 0 19 0;
+#X connect 22 0 21 0;
+#X connect 23 0 22 0;
+#X restore 43 219 pd write-reference;
+#X obj 42 319 bng 50 250 50 0 empty empty write 4 25 0 14 -260097 -262144
+-1;
+#X obj 255 318 bng 50 250 50 0 empty empty test 5 25 0 14 -260097 -262144
+-1;
+#N canvas 0 22 324 199 record-test&diff 0;
+#X obj 34 18 inlet~;
+#X obj 80 83 -~;
+#X obj 229 158 outlet;
+#X obj 224 19 inlet;
+#X text 262 18 bang;
+#X text 76 19 signal under test;
+#X obj 34 157 tabwrite~ \$0-signal-under-test;
+#X obj 80 114 tabwrite~ \$0-difference;
+#X obj 95 53 tabplay~ \$0-reference;
+#X connect 0 0 6 0;
+#X connect 0 0 1 0;
+#X connect 1 0 7 0;
+#X connect 3 0 6 0;
+#X connect 3 0 8 0;
+#X connect 3 0 7 0;
+#X connect 8 0 1 1;
+#X connect 8 1 2 0;
+#X restore 255 88 pd record-test&diff;
+#N canvas 45 41 288 479 std.deviation 0;
+#X obj 83 46 until;
+#X obj 98 74 + 1;
+#X obj 83 99 f;
+#X obj 83 18 t f b;
+#X msg 159 82 0;
+#X msg 83 -8 512;
+#X obj 110 229 +;
+#X floatatom 110 256 8 0 0 0 - - -;
+#X obj 95 280 f;
+#X text 159 61 clear sums;
+#X obj 55 153 == 511;
+#X obj 55 177 sel 1;
+#X obj 83 122 t f f;
+#X obj 83 -34 inlet;
+#X obj 110 180 t f f;
+#X obj 110 205 *;
+#X obj 95 302 / 512;
+#X obj 95 329 sqrt;
+#X text 122 -32 bang;
+#X obj 95 358 outlet;
+#X text 140 360 stddev;
+#X obj 189 358 s \$0-stddev;
+#X obj 110 152 tabread \$0-difference;
+#X connect 0 0 2 0;
+#X connect 1 0 2 1;
+#X connect 2 0 1 0;
+#X connect 2 0 12 0;
+#X connect 3 0 0 0;
+#X connect 3 1 4 0;
+#X connect 4 0 2 1;
+#X connect 4 0 6 1;
+#X connect 5 0 3 0;
+#X connect 6 0 7 0;
+#X connect 7 0 6 1;
+#X connect 7 0 8 1;
+#X connect 8 0 16 0;
+#X connect 10 0 11 0;
+#X connect 11 0 8 0;
+#X connect 12 0 10 0;
+#X connect 12 1 22 0;
+#X connect 13 0 5 0;
+#X connect 14 0 15 0;
+#X connect 14 1 15 1;
+#X connect 15 0 6 0;
+#X connect 16 0 17 0;
+#X connect 17 0 19 0;
+#X connect 17 0 21 0;
+#X connect 22 0 14 0;
+#X restore 255 113 pd std.deviation;
+#N canvas 346 419 376 223 check-samplerate 0;
+#X obj 96 53 samplerate~;
+#X obj 96 85 == 44100;
+#X obj 96 21 loadbang;
+#X obj 96 119 sel 0;
+#X obj 33 182 outlet;
+#X obj 141 182 stdout;
+#X obj 96 182 print;
+#X obj 33 20 inlet;
+#X obj 33 150 spigot;
+#X msg 96 150 SAMPLE-RATE-ERROR samplerate must be 44100;
+#X connect 0 0 1 0;
+#X connect 1 0 3 0;
+#X connect 1 0 8 1;
+#X connect 2 0 0 0;
+#X connect 3 0 9 0;
+#X connect 7 0 8 0;
+#X connect 8 0 4 0;
+#X connect 9 0 5 0;
+#X connect 9 0 6 0;
+#X restore 255 137 pd check-samplerate;
+#X msg 619 125 \; pd dsp 1;
+#X obj 619 95 loadbang;
+#N canvas 905 83 262 193 refname+ID 0;
+#X obj 26 47 inlet;
+#X obj 71 96 f \$0;
+#X obj 26 120 pack s f;
+#X obj 26 74 t a b;
+#X obj 26 152 s \$0-refname+ID;
+#X connect 0 0 3 0;
+#X connect 1 0 2 1;
+#X connect 2 0 4 0;
+#X connect 3 0 2 0;
+#X connect 3 1 1 0;
+#X restore 46 134 pd refname+ID;
+#X obj 29 190 s \$0-refname;
+#X obj 472 390 hsl 195 100 0 127 0 0 empty empty empty -2 -8 0 10 -204786
+-204786 -1 0 1;
+#N canvas 0 22 450 300 (subpatch) 0;
+#X array \$0-difference 512 float 0;
+#X coords 0 1 511 -1 200 100 1;
+#X restore 469 390 graph;
+#X obj 258 390 hsl 195 100 0 127 0 0 empty empty empty -2 -8 0 10 -204786
+-204786 -1 0 1;
+#X obj 44 390 hsl 195 100 0 127 0 0 empty empty empty -2 -8 0 10 -204786
+-204786 -1 0 1;
+#N canvas 0 22 450 300 (subpatch) 0;
+#X array \$0-reference 512 float 0;
+#X coords 0 1 511 -1 200 100 1;
+#X restore 41 390 graph;
+#N canvas 0 22 450 300 (subpatch) 0;
+#X array \$0-signal-under-test 512 float 0;
+#X coords 0 1 511 -1 200 100 1;
+#X restore 255 390 graph;
+#X text 63 13 reference name;
+#X obj 294 550 outlet;
+#X obj 267 518 t b b;
+#N canvas 739 28 261 427 test-result-messages 0;
+#X obj 32 23 inlet;
+#X obj 59 310 stdout;
+#X obj 32 84 sel 0;
+#X obj 89 166 r \$0-refname;
+#X obj 89 193 symbol;
+#X obj 32 56 moses 1e-05;
+#X obj 32 277 t b a;
+#X msg 32 336 UNIT-TEST-DONE;
+#X obj 32 373 stdout;
+#X obj 32 221 pack s f s;
+#X obj 112 309 print unit-test;
+#X obj 85 373 print unit-test;
+#X obj 32 249 list trim;
+#X msg 59 113 STDDEV-SMALL \$1;
+#X msg 32 141 STDDEV-ZERO 0;
+#X msg 95 84 STDDEV-LARGE \$1;
+#N canvas 49 312 252 304 stddev-label 0;
+#X obj 40 29 inlet;
+#X obj 40 92 sel 0;
+#X obj 40 64 moses 1e-05;
+#X msg 103 92 STDDEV-LARGE;
+#X msg 67 121 STDDEV-SMALL;
+#X msg 40 149 STDDEV-ZERO;
+#X msg 40 221 label \$1;
+#X obj 40 191 symbol;
+#X obj 40 250 s \$0-stddev-label;
+#X connect 0 0 2 0;
+#X connect 1 0 5 0;
+#X connect 1 1 4 0;
+#X connect 2 0 1 0;
+#X connect 2 1 3 0;
+#X connect 3 0 7 0;
+#X connect 4 0 7 0;
+#X connect 5 0 7 0;
+#X connect 6 0 8 0;
+#X connect 7 0 6 0;
+#X restore 126 50 pd stddev-label;
+#X connect 0 0 5 0;
+#X connect 0 0 16 0;
+#X connect 2 0 14 0;
+#X connect 2 1 13 0;
+#X connect 3 0 4 0;
+#X connect 4 0 9 2;
+#X connect 5 0 2 0;
+#X connect 5 1 15 0;
+#X connect 6 0 7 0;
+#X connect 6 1 1 0;
+#X connect 6 1 10 0;
+#X connect 7 0 8 0;
+#X connect 7 0 11 0;
+#X connect 9 0 12 0;
+#X connect 12 0 6 0;
+#X connect 13 0 9 0;
+#X connect 14 0 9 0;
+#X connect 15 0 9 0;
+#X restore 255 162 pd test-result-messages;
+#X text 232 549 test-bang;
+#X obj 472 318 hsl 130 50 0 127 0 0 \$0-dummysend \$0-stddev-label
+STDDEV-ZERO 4 35 0 10 -204786 -204786 -1 0 1;
+#X obj 618 257 bng 50 250 50 0 empty empty ? 15 25 0 30 -260097 -262144
+-1;
+#X floatatom 475 325 18 0 0 0 - #0-stddev -;
+#X obj 29 162 symbol;
+#X obj 45 258 hsl 195 50 0 112 0 0 \$0-dummysend \$0-dummyreceive empty
+-2 -8 0 10 -204786 -204786 -1 0 1;
+#X symbolatom 47 266 25 0 0 0 - #0-refname #0-dummysend;
+#X obj 255 217 r \$0-do-test;
+#X obj 255 258 bng 50 250 50 0 \$0-dummysend \$0-dummyreceive empty
+17 7 0 10 -262144 -204786 -1;
+#X obj 255 258 bng 50 1000 50 0 \$0-dummysend \$0-dummyreceive done
+7 25 0 14 -204786 -1 -204786;
+#X obj 105 319 bng 50 250 50 0 empty empty list 5 25 0 14 -204786 -262144
+-1;
+#N canvas 0 22 254 177 view-difference 0;
+#X obj 39 39 inlet;
+#X obj 39 112 s \$0-difference;
+#X msg 39 75 arrayviewlistnew;
+#X connect 0 0 2 0;
+#X connect 2 0 1 0;
+#X restore 584 512 pd view-difference;
+#N canvas 453 143 247 130 view-reference 0;
+#X obj 27 31 inlet;
+#X obj 27 86 s \$0-reference;
+#X msg 27 59 arrayviewlistnew;
+#X connect 0 0 2 0;
+#X connect 2 0 1 0;
+#X restore 105 515 pd view-reference;
+#N canvas 0 22 268 168 view-signal 0;
+#X obj 39 39 inlet;
+#X obj 39 108 s \$0-signal-under-test;
+#X msg 39 75 arrayviewlistnew;
+#X connect 0 0 2 0;
+#X connect 2 0 1 0;
+#X restore 319 518 pd view-signal;
+#X obj 341 550 outlet;
+#X obj 388 550 outlet;
+#X obj 366 58 delay;
+#X obj 255 14 inlet~;
+#X obj 29 13 inlet;
+#X obj 630 17 inlet;
+#X obj 29 41 unpack s f;
+#X obj 618 318 bng 50 250 50 0 empty empty list 5 25 0 14 -204786 -262144
+-1;
+#X obj 319 318 bng 50 250 50 0 empty empty list 5 25 0 14 -204786 -262144
+-1;
+#X floatatom 205 266 5 0 0 0 - #0-test-delay -;
+#X text 46 286 reference;
+#X text 202 286 delay;
+#X obj 86 73 s \$0-test-delay;
+#X text 557 18 dummy inlet;
+#X text 300 12 signal under test;
+#X obj 463 257 cnv 15 150 25 empty empty [unit-test-frame~] 2 12 0
+14 -262144 -1 0;
+#N canvas 67 138 412 506 load-reference 0;
+#X obj 36 27 inlet;
+#X obj 36 203 soundfiler;
+#X obj 81 112 f \$0;
+#X obj 36 136 pack s f;
+#X obj 36 94 t a b;
+#X obj 36 461 s \$0-do-test;
+#X msg 36 173 read ./\$1.wav \$2-reference;
+#X obj 75 375 pack s s s s s s;
+#X obj 168 297 r \$0-refname;
+#X obj 75 432 stdout;
+#X obj 36 235 sel 512;
+#X obj 36 60 spigot 1;
+#X msg 81 27 0;
+#X text 119 29 at load \, try to read reference file and do test;
+#X msg 75 271 REFERENCE-FILE-ERROR reference file not found:;
+#X msg 168 324 \$1.wav;
+#X obj 168 349 symbol;
+#X obj 75 402 list trim;
+#X obj 127 432 print unit-test;
+#X connect 0 0 11 0;
+#X connect 1 0 10 0;
+#X connect 2 0 3 1;
+#X connect 3 0 6 0;
+#X connect 4 0 3 0;
+#X connect 4 1 2 0;
+#X connect 6 0 1 0;
+#X connect 7 0 17 0;
+#X connect 8 0 15 0;
+#X connect 10 0 5 0;
+#X connect 10 1 14 0;
+#X connect 11 0 4 0;
+#X connect 11 0 12 0;
+#X connect 12 0 11 1;
+#X connect 14 0 7 0;
+#X connect 15 0 16 0;
+#X connect 16 0 7 5;
+#X connect 17 0 9 0;
+#X connect 17 0 18 0;
+#X restore 64 104 pd load-reference;
+#N canvas 473 125 566 541 info-unit-test\$0 0;
+#X text 144 337 STDDEV-ZERO 0;
+#X text 144 379 STDDEV-LARGE <stddev>;
+#X text 144 357 STDDEV-SMALL <stddev>;
+#X text 296 358 when standard deviation < 1e-05;
+#X text 296 379 when standard deviation >= 1e-05;
+#X text 296 337 when standard deviation = 0;
+#X text 130 22 how to use [unit-test-frame~.pd] in unit test patches
+;
+#X text 129 46 ------------------------------------------------------------
+;
+#X text 127 241 ------------------------------------------------------------
+;
+#X text 126 407 ------------------------------------------------------------
+;
+#X text 131 769 Katja Vetter & Fred Jan Kraan \, October 2011;
+#X text 125 672 ------------------------------------------------------------
+;
+#X text 127 421 The reference file must be in the same directory as
+the test. If it is not found when the patch is loaded \, an error is
+reported to the Pd window and stdout:;
+#X text 124 694 [unit-test-frame~.pd] uses only vanilla Pd classes.
+For testing external classes \, consider using namespaces like in [zexy/wrap].
+;
+#X text 122 782 ------------------------------------------------------------
+;
+#X text 129 67 1: Test arguments must be sent as a list into the first
+inlet:;
+#X text 130 116 - delaytime between test trigger and test snapshot
+\, for example to exclude overshoot and ripple from the test.;
+#X text 149 471 REFERENCE-FILE-ERROR reference file not found: <reference>
+;
+#X text 150 648 SAMPLE-RATE-ERROR samplerate must be 44100;
+#X text 128 261 The test is automatically executed when the patch is
+loaded \, and can also be started with button 'test'. Difference between
+signal under test and reference is graphed \, and standard deviation
+is computed. A test result message is sent to the Pd window and stdout:
+;
+#X text 127 496 A reference file can be created from the content of
+\$0-signal-under-test \, using a Pd which is known to work well (the
+latest release). Use button 'write'. The file will have 512 samples
+in 32 bit .wav format.;
+#X text 126 592 The samplerate norm for [unit-test-frame~.pd] is 44100
+Hz. If a different samplerate is detected when the test patch is loaded
+\, an error is reported to the Pd window and stdout:;
+#X text 124 740 ------------------------------------------------------------
+;
+#X msg 29 66 osc~440 0;
+#X text 26 19 arguments;
+#X obj 29 39 loadbang;
+#X obj 32 270 bng 50 250 50 0 empty empty test 5 25 0 14 -260097 -262144
+-1;
+#X obj 38 424 bng 50 250 50 0 empty empty write 4 25 0 14 -260097 -262144
+-1;
+#X text 123 564 ------------------------------------------------------------
+;
+#X obj 29 94 loadbang;
+#X msg 29 121 bp~ 200;
+#X text 129 204 Use a bang from one of [unit-test-frame~.pd] outlets
+to reset a phase etc. when the test starts.;
+#X text 130 98 - reference name \, matching the name of the test patch
+;
+#X text 129 155 2: The signal under test must be sent into the second
+inlet. When testing an external object \, consider instantiating it
+with namespace \, like [zexy/wrap].;
+#X connect 25 0 23 0;
+#X connect 29 0 30 0;
+#X restore 488 96 pd info-unit-test\$0;
+#X msg 538 512 vis 1;
+#X text 337 215 auto-test (after loading / writing reference);
+#X obj 539 541 s pd-info-unit-test\$0;
+#X obj 321 258 hsl 130 50 0 1 0 0 \$0-audiolevel \$0-dummyreceive listen
+88 35 0 10 -204786 -258113 -1 0 0;
+#X floatatom 411 266 5 0 0 0 - #0-audiolevel #0-dummysend;
+#N canvas 0 22 193 209 listen 0;
+#X obj 47 22 inlet~;
+#X obj 68 52 r \$0-audiolevel;
+#X obj 47 161 dac~;
+#X obj 47 88 *~ 0;
+#X obj 47 124 clip~ -1 1;
+#X connect 0 0 3 0;
+#X connect 1 0 3 1;
+#X connect 3 0 4 0;
+#X connect 4 0 2 0;
+#X connect 4 0 2 1;
+#X restore 276 63 pd listen;
+#X connect 1 0 0 0;
+#X connect 2 0 18 0;
+#X connect 3 0 4 0;
+#X connect 4 0 5 0;
+#X connect 5 0 19 0;
+#X connect 7 0 6 0;
+#X connect 18 0 36 0;
+#X connect 18 1 17 0;
+#X connect 18 1 34 0;
+#X connect 18 1 35 0;
+#X connect 22 0 52 0;
+#X connect 24 0 9 0;
+#X connect 27 0 2 0;
+#X connect 30 0 32 0;
+#X connect 36 0 3 1;
+#X connect 36 0 29 0;
+#X connect 37 0 3 0;
+#X connect 37 0 57 0;
+#X connect 38 0 40 0;
+#X connect 40 0 24 0;
+#X connect 40 0 50 0;
+#X connect 40 0 8 0;
+#X connect 40 1 36 1;
+#X connect 40 1 46 0;
+#X connect 41 0 31 0;
+#X connect 42 0 33 0;
+#X connect 52 0 54 0;
+#X coords 0 -1 1 1 650 250 2 30 250;