#N canvas 332 70 817 861 12;
#X obj 399 526 metro 100;
#X obj 212 472 phasor~;
#X obj 399 556 snapshot~;
#X text 561 824 updated for Pd version 0.42;
#X obj 23 557 output~;
#X obj 23 461 phasor~;
#X floatatom 23 329 5 -100 1000 0 - - -;
#X obj 23 518 tabread4~ \$0-tab;
#X msg 290 329 0.5;
#X msg 326 329 0.01;
#X obj 398 455 loadbang;
#X msg 399 478 1;
#X obj 344 635 +;
#X obj 144 680 tabread4~ \$0-tab;
#X obj 375 634 f;
#X obj 312 612 t f f;
#X obj 145 712 output~;
#X floatatom 455 667 8 0 0 0 - - -;
#X obj 344 670 t f b;
#X obj 377 699 f;
#X obj 344 699 -;
#X floatatom 457 612 8 0 0 0 - - -;
#X obj 326 726 -;
#X obj 399 507 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 1
1;
#X obj 212 498 -~ 0.5;
#X obj 290 811 + 0.5;
#X obj 22 490 *~ 1e+06;
#X floatatom 326 753 8 0 0 0 - - -;
#X obj 530 519 samplerate~;
#X obj 484 546 /;
#X obj 484 519 t f b;
#X obj 451 589 +;
#X obj 295 787 / 10000;
#X obj 212 523 *~ 10000;
#X obj 484 570 * 10000;
#X obj 532 155 samplerate~;
#X obj 532 179 / 2;
#X obj 521 93 loadbang;
#X obj 521 230 tabwrite~ \$0-tab;
#X obj 532 203 osc~;
#X obj 521 134 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
-1 -1;
#X msg 545 116 \; pd dsp 1;
#X obj 520 258 table \$0-tab 1e+06;
#X text 488 61 and will take about 20 seconds to fill.;
#X text 488 45 *** The table is now 1 million points \,;
#X obj 23 433 / 1e+06;
#X text 61 328 playback speed \, samples/sec;
#X text 89 460 naive way: just;
#X text 89 475 run a phasor;
#X text 88 491 into tabread4~;
#X text 454 680 new onset is phase plus old onset;
#X obj 341 357 * 1e+06;
#X text 458 626 extrapolated phase of next sample;
#X text 409 700 new onset minus old onset;
#X text 389 726 back up phasor output by amount the onset advanced
;
#X text 387 739 (approximately zero but not exactly because of;
#X text 389 753 truncation error!);
#X obj 341 383 t b f;
#X text 400 357 convert to samples;
#X text 385 384 set both last-onset and previous-onset;
#X text 385 407 ... and also reset phasor.;
#X text 354 791 convert phase back to range 0-1;
#X text 215 548 convert phase to;
#X text 215 562 range +/-5000;
#X obj 212 435 / 10000;
#X text 40 410 cycles/sec;
#X text 30 400 convert to;
#X text 216 412 cycles/sec;
#X text 206 402 convert to;
#X text 469 472 in order to change onset to reflect it;
#X text 469 456 Each 100 msec \, poll phase of phasor~;
#X text 24 29 Here is how to use the tabread~ "onset" input to allow
clean varispeed playback from a long table. At left \, a phasor~ is
naively rescaled to the size of the table. At right \, the phasor~
gets only a 10000-point range about a moving "onset". Ten times per
second \, we poll the phasor~ phase \, sum its value into the onset
\, and back up the phase of the phasor~ correspondingly.;
#X text 22 143 The tricky bits are \, first \, that we need to poll
the phasor~ phase one sample into the future (so we add the per-sample
increment into the snapshot~ result). Second \, we can't just reset
the phasor~ to a fixed point - instead \, we measure how much the onset
has actually increased (which has truncation error from summing in
the phase snapshot) \, and subtract that increase from the phase \,
giving a value that differs from zero by the truncation error but reflects
the true phase we should reset to for continuity.;
#X text 24 287 The metronome rate is arbitrary but should be fast enough
that the phasor~ never has time to wrap.;
#X text 518 539 extrapolate snapshot of phase by one;
#X text 517 552 sample to sync with next block;
#X text 41 617 BAD;
#X text 160 770 GOOD;
#X text 195 9 VARIABLE SPEED PLAYBACK FROM LONG TABLES;
#X msg 340 408 0;
#X text 369 328 <- reset phase. 0.5 causes trouble for the "bad" way.
;
#X connect 0 0 2 0;
#X connect 1 0 24 0;
#X connect 2 0 31 0;
#X connect 5 0 26 0;
#X connect 6 0 45 0;
#X connect 6 0 64 0;
#X connect 7 0 4 0;
#X connect 7 0 4 1;
#X connect 8 0 5 1;
#X connect 8 0 51 0;
#X connect 9 0 5 1;
#X connect 9 0 51 0;
#X connect 10 0 11 0;
#X connect 11 0 23 0;
#X connect 12 0 14 0;
#X connect 12 0 18 0;
#X connect 12 0 13 1;
#X connect 12 0 17 0;
#X connect 13 0 16 0;
#X connect 13 0 16 1;
#X connect 14 0 12 1;
#X connect 15 0 22 0;
#X connect 15 1 12 0;
#X connect 18 0 19 1;
#X connect 18 0 20 0;
#X connect 18 1 19 0;
#X connect 19 0 20 1;
#X connect 20 0 22 1;
#X connect 22 0 27 0;
#X connect 22 0 32 0;
#X connect 23 0 0 0;
#X connect 24 0 33 0;
#X connect 25 0 1 1;
#X connect 26 0 7 0;
#X connect 28 0 29 1;
#X connect 29 0 34 0;
#X connect 30 0 29 0;
#X connect 30 1 28 0;
#X connect 31 0 15 0;
#X connect 31 0 21 0;
#X connect 32 0 25 0;
#X connect 33 0 2 0;
#X connect 33 0 13 0;
#X connect 34 0 31 1;
#X connect 35 0 36 0;
#X connect 36 0 39 0;
#X connect 37 0 40 0;
#X connect 37 0 41 0;
#X connect 39 0 38 0;
#X connect 40 0 35 0;
#X connect 40 0 38 0;
#X connect 45 0 5 0;
#X connect 51 0 57 0;
#X connect 57 0 79 0;
#X connect 57 1 19 1;
#X connect 57 1 12 1;
#X connect 64 0 1 0;
#X connect 64 0 30 0;
#X connect 79 0 15 0;
