#N canvas 369 23 927 723 12;
#X declare -stdpath ./;
#X obj 505 561 metro 100;
#X obj 238 488 phasor~;
#X obj 505 591 snapshot~;
#X obj 37 583 output~;
#X obj 38 477 phasor~;
#X floatatom 38 345 5 -100 1000 0 - - - 0;
#X obj 37 534 tabread4~ \$0-tab;
#X msg 368 345 0.5;
#X msg 404 345 0.01;
#X obj 505 474 loadbang;
#X msg 505 500 1;
#X obj 418 681 +;
#X obj 238 746 tabread4~ \$0-tab;
#X obj 476 681 f;
#X obj 386 658 t f f;
#X obj 219 786 output~;
#X floatatom 487 715 8 0 0 0 - - - 0;
#X obj 418 716 t f b;
#X obj 450 745 f;
#X obj 418 745 -;
#X floatatom 568 650 8 0 0 0 - - - 0;
#X obj 400 772 -;
#X obj 505 536 tgl 15 0 empty empty empty 17 7 0 10 #fcfcfc #000000 #000000 0 1;
#X obj 238 514 -~ 0.5;
#X obj 400 861 + 0.5;
#X obj 37 506 *~ 1e+06;
#X floatatom 400 802 8 0 0 0 - - - 0;
#X obj 618 570 samplerate~;
#X obj 586 569 /;
#X obj 586 544 t f b;
#X obj 568 624 +;
#X obj 400 833 / 10000;
#X obj 238 539 *~ 10000;
#X obj 586 595 * 10000;
#X obj 571 171 samplerate~;
#X obj 571 195 / 2;
#X obj 560 246 tabwrite~ \$0-tab;
#X obj 571 219 osc~;
#X obj 560 126 bng 19 250 50 0 empty empty empty 17 7 0 10 #dfdfdf #000000 #000000;
#X obj 559 284 table \$0-tab 1e+06;
#X obj 38 449 / 1e+06;
#X text 86 344 playback speed \, samples/sec;
#X text 104 476 naive way: just;
#X text 104 491 run a phasor;
#X text 103 507 into tabread4~;
#X text 549 714 new onset is phase plus old onset;
#X obj 404 373 * 1e+06;
#X text 631 652 extrapolated phase of next sample;
#X text 482 746 new onset minus old onset;
#X text 470 780 back up phasor output by amount the onset advanced;
#X text 468 793 (approximately zero but not exactly because of;
#X text 470 807 truncation error!);
#X obj 404 399 t b f;
#X text 463 373 convert to samples;
#X text 448 400 set both last-onset and previous-onset;
#X text 448 423 ... and also reset phasor.;
#X text 461 834 convert phase back to range 0-1;
#X obj 238 451 / 10000;
#X text 45 425 cycles/sec;
#X text 45 413 convert to;
#X text 296 451 cycles/sec;
#X text 240 427 convert to;
#X text 572 489 in order to change onset to reflect it;
#X text 572 473 Each 100 msec \, poll phase of phasor~;
#X text 44 55 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., f 64;
#X text 44 149 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., f 64;
#X text 44 280 The metronome rate is arbitrary but should be fast enough that the phasor~ never has time to wrap., f 64;
#X text 55 643 BAD;
#X text 234 844 GOOD;
#X text 81 22 VARIABLE SPEED PLAYBACK FROM LONG TABLES;
#X msg 386 431 0;
#X text 447 344 <= reset phase. 0.5 causes trouble for the "bad" way.;
#X text 124 574 convert phase to range +/- 5000, f 16;
#X text 634 535 extrapolate snapshot of phase by one sample to sync with next block, f 34;
#X obj 737 17 declare -stdpath ./;
#X msg 669 164 \; pd dsp 1 \, fast-forward 22680;
#X text 539 57 *** The table is now 1 million points and takes about 23 seconds to fill \, we also use the 'fast-forward' message to fill it., f 47;
#X text 665 883 updated for Pd version 0.52;
#X connect 0 0 2 0;
#X connect 1 0 23 0;
#X connect 2 0 30 0;
#X connect 4 0 25 0;
#X connect 5 0 40 0;
#X connect 5 0 57 0;
#X connect 6 0 3 0;
#X connect 6 0 3 1;
#X connect 7 0 4 1;
#X connect 7 0 46 0;
#X connect 8 0 4 1;
#X connect 8 0 46 0;
#X connect 9 0 10 0;
#X connect 10 0 22 0;
#X connect 11 0 13 0;
#X connect 11 0 17 0;
#X connect 11 0 12 1;
#X connect 11 0 16 0;
#X connect 12 0 15 0;
#X connect 12 0 15 1;
#X connect 13 0 11 1;
#X connect 14 0 21 0;
#X connect 14 1 11 0;
#X connect 17 0 18 1;
#X connect 17 0 19 0;
#X connect 17 1 18 0;
#X connect 18 0 19 1;
#X connect 19 0 21 1;
#X connect 21 0 26 0;
#X connect 22 0 0 0;
#X connect 23 0 32 0;
#X connect 24 0 1 1;
#X connect 25 0 6 0;
#X connect 26 0 31 0;
#X connect 27 0 28 1;
#X connect 28 0 33 0;
#X connect 29 0 28 0;
#X connect 29 1 27 0;
#X connect 30 0 14 0;
#X connect 30 0 20 0;
#X connect 31 0 24 0;
#X connect 32 0 2 0;
#X connect 32 0 12 0;
#X connect 33 0 30 1;
#X connect 34 0 35 0;
#X connect 35 0 37 0;
#X connect 37 0 36 0;
#X connect 38 0 34 0;
#X connect 38 0 36 0;
#X connect 38 0 75 0;
#X connect 40 0 4 0;
#X connect 46 0 52 0;
#X connect 52 0 70 0;
#X connect 52 1 18 1;
#X connect 52 1 11 1;
#X connect 57 0 1 0;
#X connect 57 0 29 0;
#X connect 70 0 14 0;
