/
fx.pitch.shift.pvoc~.pd
595 lines (595 loc) · 14.3 KB
/
fx.pitch.shift.pvoc~.pd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
#N canvas 301 272 678 298 10;
#N canvas 447 394 721 323 processing 0;
#N canvas 0 110 466 295 hann-window 0;
#X obj 288 130 osc~;
#X obj 288 155 *~ -0.5;
#X obj 288 179 +~ 0.5;
#X obj 26 118 samplerate~;
#X obj 26 142 /;
#X msg 161 71 resize \$1;
#X msg 292 95 0;
#X obj 240 96 t f b;
#X obj 26 94 t b f f;
#X text 22 8 calculate Hann window table (variable window size) and
constants window-hz (fundamental frequency of analysis).;
#X obj 241 212 tabwrite~ \$0.hann;
#X obj 26 67 r \$0.window.size;
#X obj 26 166 s \$0.window.hz;
#X obj 161 95 s \$0.hann;
#X obj 240 70 r \$0.window.hz;
#X connect 0 0 1 0;
#X connect 1 0 2 0;
#X connect 2 0 10 0;
#X connect 3 0 4 0;
#X connect 4 0 12 0;
#X connect 5 0 13 0;
#X connect 6 0 0 1;
#X connect 7 0 0 0;
#X connect 7 1 6 0;
#X connect 7 1 10 0;
#X connect 8 0 3 0;
#X connect 8 1 4 1;
#X connect 8 2 5 0;
#X connect 11 0 8 0;
#X connect 14 0 7 0;
#X restore 307 277 pd hann-window;
#X obj 16 15 inlet~;
#X obj 19 238 outlet~;
#X obj 309 27 inlet;
#X obj 306 160 table \$0.prev.imag.l 4096;
#X obj 306 179 table \$0.prev.real.l 4096;
#X obj 306 198 table \$0.prev.imag.r 4096;
#X obj 306 217 table \$0.prev.real.r 4096;
#X obj 306 236 table \$0.hann;
#X msg 511 64 2048;
#X obj 511 42 loadbang;
#N canvas 40 20 750 770 fft.analysis.l 0;
#X obj 51 477 *~;
#X obj 18 477 *~;
#X obj 18 499 -~;
#X obj 167 475 *~;
#X obj 136 475 *~;
#X obj 136 497 +~;
#X obj 109 193 *~;
#X obj 78 193 *~;
#X obj 50 193 *~;
#X obj 19 193 *~;
#X obj 19 218 +~;
#X obj 127 379 *~;
#X obj 20 622 *~;
#X obj 236 175 rfft~;
#X obj 108 161 rfft~;
#X obj 19 564 rifft~;
#X obj 21 646 outlet~;
#X obj 97 379 *~;
#X obj 97 401 +~;
#X obj 124 218 -~;
#X obj 18 431 *~;
#X obj 51 432 *~;
#X obj 21 728 block~;
#X obj 19 349 +~ 1e-15;
#X obj 19 598 *~;
#X obj 127 643 expr 2/(3*$f1);
#X msg 21 703 set \$1 4;
#X obj 97 425 q8_rsqrt~;
#X obj 121 69 *~;
#X obj 89 69 *~;
#X obj 89 91 +~;
#X obj 159 94 q8_rsqrt~;
#X obj 159 71 +~ 1e-20;
#X obj 73 119 *~;
#X obj 19 118 *~;
#X obj 29 245 lrshift~ 1;
#X obj 24 269 lrshift~ -1;
#X obj 141 245 lrshift~ 1;
#X obj 133 269 lrshift~ -1;
#X obj 19 325 +~;
#X obj 125 331 +~;
#N canvas 0 0 554 671 read-windows 0;
#X obj 18 358 line~;
#X obj 16 523 outlet~;
#X obj 125 531 outlet~;
#X text 220 313 "back" window 1/4 cycle behind "front" one;
#X obj 18 266 pack f f;
#X obj 31 143 t b f;
#X obj 31 184 -;
#X obj 90 145 *;
#X obj 90 114 - 1;
#X obj 90 57 mtof;
#X obj 90 77 / 440;
#X obj 90 38 + 69;
#X obj 353 123 samplerate~;
#X obj 328 102 t f b;
#X obj 328 141 /;
#X obj 328 163 * 1000;
#X text 376 163 window size (ms);
#X obj 18 207 f;
#X obj 16 492 *~;
#X obj 124 503 *~;
#X obj 18 75 bang~;
#X obj 31 164 100;
#X obj 197 286 *;
#X obj 206 263 t b f;
#X text 235 288 stretched window size (ms);
#X obj 220 210 / 4;
#X text 252 207 computation time for an overlap of 4;
#X obj 18 230 / 4;
#X obj 71 229 / 4;
#X obj 17 393 +~;
#X obj 193 310 / 4;
#X obj 135 369 / 4;
#X text 47 395 '+' since a bigger value in vd~ means 'earlier'.;
#X text 114 110 subtract speed of read-out \, when;
#X text 114 122 delay-time is static;
#X text 134 37 convert cents of halftones to read-out speed;
#X text 41 229 *);
#X text 93 229 *);
#X text 162 367 *);
#X text 67 336 *);
#X obj 18 287 t l b;
#X obj 43 309 100;
#X obj 43 333 / 4;
#X text 57 165 initial delay (ms);
#X text 71 307 initial delay (ms);
#X text 21 556 *);
#X text 24 572 it seems that if a time is specified in ms instead of
samples \, the value has to be divided by the overlap factor (4 in
this case) in order for the vd~ to read out the desired amount of samples.
i'm still unsure what the reason for this might be.;
#X obj 90 -6 r \$0.transpo;
#X obj 328 81 r \$0.window.size;
#X obj 164 468 tabreceive~ \$0.hann;
#X obj 16 441 vd~ \$0.input.l;
#X obj 123 443 vd~ \$0.input.l;
#X obj 88 195 r \$0.latency;
#X obj 102 274 r \$0.latency;
#X connect 0 0 29 0;
#X connect 0 0 51 0;
#X connect 4 0 40 0;
#X connect 5 0 21 0;
#X connect 5 1 6 1;
#X connect 6 0 17 1;
#X connect 7 0 5 0;
#X connect 8 0 7 0;
#X connect 9 0 10 0;
#X connect 10 0 8 0;
#X connect 10 0 22 0;
#X connect 11 0 9 0;
#X connect 12 0 14 1;
#X connect 13 0 14 0;
#X connect 13 1 12 0;
#X connect 14 0 15 0;
#X connect 15 0 7 1;
#X connect 15 0 23 0;
#X connect 15 0 25 0;
#X connect 17 0 27 0;
#X connect 18 0 1 0;
#X connect 19 0 2 0;
#X connect 20 0 17 0;
#X connect 21 0 6 0;
#X connect 22 0 30 0;
#X connect 23 0 22 0;
#X connect 23 1 22 1;
#X connect 25 0 28 0;
#X connect 27 0 4 0;
#X connect 28 0 4 1;
#X connect 29 0 50 0;
#X connect 30 0 31 0;
#X connect 31 0 29 1;
#X connect 40 0 0 0;
#X connect 40 1 41 0;
#X connect 41 0 42 0;
#X connect 42 0 0 0;
#X connect 47 0 11 0;
#X connect 48 0 13 0;
#X connect 49 0 19 1;
#X connect 49 0 18 1;
#X connect 50 0 18 0;
#X connect 51 0 19 0;
#X connect 52 0 21 1;
#X connect 53 0 41 1;
#X restore 442 106 pd read-windows;
#X text 318 304 the left part is taken from miller puckette's audio
example I07.phase.vocoder.pd from the doc.;
#X obj 52 598 tabreceive~ \$0.hann;
#X obj 127 622 r \$0.window.size;
#X obj 35 300 *~ 1;
#X obj 159 312 *~ 1;
#X obj 21 679 r \$0.window.size;
#X obj 20 8 tabreceive~ \$0.prev.real.l;
#X obj 73 29 tabreceive~ \$0.prev.imag.l;
#X obj 137 543 tabsend~ \$0.prev.imag.l;
#X obj 136 567 tabsend~ \$0.prev.real.l;
#X connect 0 0 2 1;
#X connect 1 0 2 0;
#X connect 2 0 15 0;
#X connect 2 0 51 0;
#X connect 3 0 5 1;
#X connect 4 0 5 0;
#X connect 5 0 15 1;
#X connect 5 0 50 0;
#X connect 6 0 19 1;
#X connect 7 0 19 0;
#X connect 8 0 10 1;
#X connect 9 0 10 0;
#X connect 10 0 36 0;
#X connect 10 0 35 0;
#X connect 10 0 39 0;
#X connect 11 0 18 1;
#X connect 12 0 16 0;
#X connect 13 0 1 1;
#X connect 13 0 3 1;
#X connect 13 1 0 1;
#X connect 13 1 4 1;
#X connect 14 0 9 1;
#X connect 14 0 7 1;
#X connect 14 1 6 1;
#X connect 14 1 8 1;
#X connect 15 0 24 0;
#X connect 17 0 18 0;
#X connect 18 0 27 0;
#X connect 19 0 37 0;
#X connect 19 0 38 0;
#X connect 19 0 40 0;
#X connect 20 0 1 0;
#X connect 20 0 4 0;
#X connect 21 0 0 0;
#X connect 21 0 3 0;
#X connect 23 0 17 1;
#X connect 23 0 17 0;
#X connect 23 0 20 0;
#X connect 24 0 12 0;
#X connect 25 0 12 1;
#X connect 26 0 22 0;
#X connect 27 0 20 1;
#X connect 27 0 21 1;
#X connect 28 0 30 1;
#X connect 29 0 30 0;
#X connect 30 0 32 0;
#X connect 31 0 33 1;
#X connect 31 0 34 1;
#X connect 32 0 31 0;
#X connect 33 0 8 0;
#X connect 33 0 7 0;
#X connect 34 0 9 0;
#X connect 34 0 6 0;
#X connect 35 0 45 0;
#X connect 36 0 45 0;
#X connect 37 0 46 0;
#X connect 38 0 46 0;
#X connect 39 0 23 0;
#X connect 40 0 11 0;
#X connect 40 0 11 1;
#X connect 40 0 21 0;
#X connect 41 0 14 0;
#X connect 41 1 13 0;
#X connect 43 0 24 1;
#X connect 44 0 25 0;
#X connect 45 0 39 1;
#X connect 46 0 40 1;
#X connect 47 0 26 0;
#X connect 48 0 29 1;
#X connect 48 0 29 0;
#X connect 48 0 34 0;
#X connect 49 0 28 1;
#X connect 49 0 28 0;
#X connect 49 0 33 0;
#X restore 18 142 pd fft.analysis.l;
#X obj 309 122 s \$0.transpo;
#X obj 511 87 s \$0.window.size;
#X obj 77 17 inlet~;
#X obj 98 239 outlet~;
#X obj 617 27 inlet;
#X obj 617 50 switch~;
#X obj 16 96 delwrite~ \$0.input.l 1000;
#X obj 76 67 delwrite~ \$0.input.r 1000;
#N canvas 40 20 750 770 fft.analysis.r 0;
#X obj 51 477 *~;
#X obj 18 477 *~;
#X obj 18 499 -~;
#X obj 167 475 *~;
#X obj 136 475 *~;
#X obj 136 497 +~;
#X obj 109 193 *~;
#X obj 78 193 *~;
#X obj 50 193 *~;
#X obj 19 193 *~;
#X obj 19 218 +~;
#X obj 127 379 *~;
#X obj 20 622 *~;
#X obj 236 175 rfft~;
#X obj 108 161 rfft~;
#X obj 19 564 rifft~;
#X obj 21 646 outlet~;
#X obj 97 379 *~;
#X obj 97 401 +~;
#X obj 124 218 -~;
#X obj 18 431 *~;
#X obj 51 432 *~;
#X obj 21 728 block~;
#X obj 19 349 +~ 1e-15;
#X obj 19 598 *~;
#X obj 127 643 expr 2/(3*$f1);
#X msg 21 703 set \$1 4;
#X obj 97 425 q8_rsqrt~;
#X obj 121 69 *~;
#X obj 89 69 *~;
#X obj 89 91 +~;
#X obj 159 94 q8_rsqrt~;
#X obj 159 71 +~ 1e-20;
#X obj 73 119 *~;
#X obj 19 118 *~;
#X obj 29 245 lrshift~ 1;
#X obj 24 269 lrshift~ -1;
#X obj 141 245 lrshift~ 1;
#X obj 133 269 lrshift~ -1;
#X obj 19 325 +~;
#X obj 125 331 +~;
#N canvas 139 105 510 684 read-windows 0;
#X obj 18 358 line~;
#X obj 16 523 outlet~;
#X obj 125 531 outlet~;
#X text 220 313 "back" window 1/4 cycle behind "front" one;
#X obj 18 266 pack f f;
#X obj 31 143 t b f;
#X obj 31 184 -;
#X obj 90 145 *;
#X obj 90 114 - 1;
#X obj 90 57 mtof;
#X obj 90 77 / 440;
#X obj 90 38 + 69;
#X obj 353 123 samplerate~;
#X obj 328 102 t f b;
#X obj 328 141 /;
#X obj 328 163 * 1000;
#X text 376 163 window size (ms);
#X obj 18 207 f;
#X obj 16 492 *~;
#X obj 124 503 *~;
#X obj 18 75 bang~;
#X obj 31 164 100;
#X obj 197 286 *;
#X obj 206 263 t b f;
#X text 235 288 stretched window size (ms);
#X obj 220 210 / 4;
#X text 252 207 computation time for an overlap of 4;
#X obj 18 230 / 4;
#X obj 71 229 / 4;
#X obj 17 393 +~;
#X obj 193 310 / 4;
#X obj 135 369 / 4;
#X text 47 395 '+' since a bigger value in vd~ means 'earlier'.;
#X text 114 110 subtract speed of read-out \, when;
#X text 114 122 delay-time is static;
#X text 134 37 convert cents of halftones to read-out speed;
#X text 41 229 *);
#X text 93 229 *);
#X text 162 367 *);
#X text 67 336 *);
#X obj 18 287 t l b;
#X obj 43 309 100;
#X obj 43 333 / 4;
#X text 57 165 initial delay (ms);
#X text 71 307 initial delay (ms);
#X text 21 556 *);
#X text 24 572 it seems that if a time is specified in ms instead of
samples \, the value has to be divided by the overlap factor (4 in
this case) in order for the vd~ to read out the desired amount of samples.
i'm still unsure what the reason for this might be.;
#X obj 90 -6 r \$0.transpo;
#X obj 328 81 r \$0.window.size;
#X obj 164 468 tabreceive~ \$0.hann;
#X obj 16 441 vd~ \$0.input.r;
#X obj 123 443 vd~ \$0.input.r;
#X obj 88 195 r \$0.latency;
#X obj 102 274 r \$0.latency;
#X connect 0 0 29 0;
#X connect 0 0 51 0;
#X connect 4 0 40 0;
#X connect 5 0 21 0;
#X connect 5 1 6 1;
#X connect 6 0 17 1;
#X connect 7 0 5 0;
#X connect 8 0 7 0;
#X connect 9 0 10 0;
#X connect 10 0 8 0;
#X connect 10 0 22 0;
#X connect 11 0 9 0;
#X connect 12 0 14 1;
#X connect 13 0 14 0;
#X connect 13 1 12 0;
#X connect 14 0 15 0;
#X connect 15 0 7 1;
#X connect 15 0 23 0;
#X connect 15 0 25 0;
#X connect 17 0 27 0;
#X connect 18 0 1 0;
#X connect 19 0 2 0;
#X connect 20 0 17 0;
#X connect 21 0 6 0;
#X connect 22 0 30 0;
#X connect 23 0 22 0;
#X connect 23 1 22 1;
#X connect 25 0 28 0;
#X connect 27 0 4 0;
#X connect 28 0 4 1;
#X connect 29 0 50 0;
#X connect 30 0 31 0;
#X connect 31 0 29 1;
#X connect 40 0 0 0;
#X connect 40 1 41 0;
#X connect 41 0 42 0;
#X connect 42 0 0 0;
#X connect 47 0 11 0;
#X connect 48 0 13 0;
#X connect 49 0 19 1;
#X connect 49 0 18 1;
#X connect 50 0 18 0;
#X connect 51 0 19 0;
#X connect 52 0 21 1;
#X connect 53 0 41 1;
#X restore 442 106 pd read-windows;
#X text 318 304 the left part is taken from miller puckette's audio
example I07.phase.vocoder.pd from the doc.;
#X obj 52 598 tabreceive~ \$0.hann;
#X obj 127 622 r \$0.window.size;
#X obj 35 300 *~ 1;
#X obj 159 312 *~ 1;
#X obj 21 679 r \$0.window.size;
#X obj 20 8 tabreceive~ \$0.prev.real.r;
#X obj 73 29 tabreceive~ \$0.prev.imag.r;
#X obj 137 543 tabsend~ \$0.prev.imag.r;
#X obj 136 567 tabsend~ \$0.prev.real.r;
#X connect 0 0 2 1;
#X connect 1 0 2 0;
#X connect 2 0 15 0;
#X connect 2 0 51 0;
#X connect 3 0 5 1;
#X connect 4 0 5 0;
#X connect 5 0 15 1;
#X connect 5 0 50 0;
#X connect 6 0 19 1;
#X connect 7 0 19 0;
#X connect 8 0 10 1;
#X connect 9 0 10 0;
#X connect 10 0 36 0;
#X connect 10 0 35 0;
#X connect 10 0 39 0;
#X connect 11 0 18 1;
#X connect 12 0 16 0;
#X connect 13 0 1 1;
#X connect 13 0 3 1;
#X connect 13 1 0 1;
#X connect 13 1 4 1;
#X connect 14 0 9 1;
#X connect 14 0 7 1;
#X connect 14 1 6 1;
#X connect 14 1 8 1;
#X connect 15 0 24 0;
#X connect 17 0 18 0;
#X connect 18 0 27 0;
#X connect 19 0 37 0;
#X connect 19 0 38 0;
#X connect 19 0 40 0;
#X connect 20 0 1 0;
#X connect 20 0 4 0;
#X connect 21 0 0 0;
#X connect 21 0 3 0;
#X connect 23 0 17 1;
#X connect 23 0 17 0;
#X connect 23 0 20 0;
#X connect 24 0 12 0;
#X connect 25 0 12 1;
#X connect 26 0 22 0;
#X connect 27 0 20 1;
#X connect 27 0 21 1;
#X connect 28 0 30 1;
#X connect 29 0 30 0;
#X connect 30 0 32 0;
#X connect 31 0 33 1;
#X connect 31 0 34 1;
#X connect 32 0 31 0;
#X connect 33 0 8 0;
#X connect 33 0 7 0;
#X connect 34 0 9 0;
#X connect 34 0 6 0;
#X connect 35 0 45 0;
#X connect 36 0 45 0;
#X connect 37 0 46 0;
#X connect 38 0 46 0;
#X connect 39 0 23 0;
#X connect 40 0 11 0;
#X connect 40 0 11 1;
#X connect 40 0 21 0;
#X connect 41 0 14 0;
#X connect 41 1 13 0;
#X connect 43 0 24 1;
#X connect 44 0 25 0;
#X connect 45 0 39 1;
#X connect 46 0 40 1;
#X connect 47 0 26 0;
#X connect 48 0 29 1;
#X connect 48 0 29 0;
#X connect 48 0 34 0;
#X connect 49 0 28 1;
#X connect 49 0 28 0;
#X connect 49 0 33 0;
#X restore 97 169 pd fft.analysis.r;
#X obj 339 99 s \$0.latency;
#X obj 309 56 t a a;
#N canvas 998 307 217 230 latency 0;
#X obj 19 22 inlet;
#X obj 19 194 outlet;
#X obj 19 48 / 12;
#X obj 19 95 pow;
#X msg 19 72 2 \$1;
#X obj 19 117 max 1;
#X obj 119 73 samplerate~;
#X obj 119 93 * 0.001;
#X obj 89 29 r \$0.window.size;
#X obj 89 53 t a b;
#X obj 89 115 /;
#X obj 19 161 *;
#X connect 0 0 2 0;
#X connect 2 0 4 0;
#X connect 3 0 5 0;
#X connect 4 0 3 0;
#X connect 5 0 11 0;
#X connect 6 0 7 0;
#X connect 7 0 10 1;
#X connect 8 0 9 0;
#X connect 9 0 10 0;
#X connect 9 1 6 0;
#X connect 10 0 11 1;
#X connect 11 0 1 0;
#X restore 339 77 pd latency;
#X connect 1 0 18 0;
#X connect 3 0 22 0;
#X connect 9 0 13 0;
#X connect 10 0 9 0;
#X connect 11 0 2 0;
#X connect 14 0 19 0;
#X connect 16 0 17 0;
#X connect 20 0 15 0;
#X connect 22 0 12 0;
#X connect 22 1 23 0;
#X connect 23 0 21 0;
#X restore 139 141 pd processing;
#X obj 71 25 inlet~;
#X obj 153 31 inlet~;
#X obj 70 277 outlet~;
#X obj 128 278 outlet~;
#X obj 542 195 param.group;
#X obj 595 146 loadbang;
#X obj 595 170 dollarg;
#X obj 542 122 inlet params;
#X obj 71 233 mix.wet.stereo~ 1;
#X obj 236 39 param.atom transpose 0 -24 24;
#X obj 287 111 sel 1;
#X obj 287 158 line;
#X msg 343 134 0 50;
#X msg 287 134 127 50;
#X obj 287 83 param.atom switch false;
#X text 268 226 based on pd doc: I07.phase.vocoder.pd;
#X text 267 244 adapted by: Roman Haefeli;
#X text 267 266 version: 2008-03-05;
#X connect 0 0 9 2;
#X connect 0 1 9 3;
#X connect 1 0 0 0;
#X connect 1 0 9 0;
#X connect 2 0 0 1;
#X connect 2 0 9 1;
#X connect 6 0 7 0;
#X connect 7 0 5 1;
#X connect 7 1 5 2;
#X connect 8 0 5 0;
#X connect 9 0 3 0;
#X connect 9 1 4 0;
#X connect 9 2 0 3;
#X connect 10 0 0 2;
#X connect 11 0 14 0;
#X connect 11 1 13 0;
#X connect 12 0 9 4;
#X connect 13 0 12 0;
#X connect 14 0 12 0;
#X connect 15 0 11 0;