#N canvas 489 71 701 624 12;
#X text 55 71 This patch takes a sound \, analyzes windows in it both for channel magnitude and for phase precession in each channel (compared to another overlapping window). The real-time output recreates the same magnitudes and phase precession \, although the phases themselves are in general different. You can control either the location or its motion (setting location stops motion \, while setting a non-zero motion causes the location to change automatically). "Rewind" goes back to the beginning. You can use different window sizes (use the message boxes - the number box is for readout). The "lock" feature forces phase coherency between neighboring channels \, which makes a more present sound but can add artifacts to the sound. Look into the [pd fft-analysis] subppatch to see the workings., f 82;
#X text 55 219 Note: The algorithm was altered and updated in Pd version 0.44 in a way that affected the result., f 82;
#X obj 27 20 cnv 5 5 25 empty empty Phase\ Vocoder\ for\ Time\ Stretching\ and\ Contraction 15 13 0 16 #dfdfdf #202020 0;
#X floatatom 421 324 5 0 0 0 - transpo-set - 0;
#X floatatom 47 366 7 0 0 0 - location-set - 0;
#N canvas 457 34 740 709 fft-analysis 0;
#X obj 54 483 *~;
#X obj 21 483 *~;
#X obj 21 505 -~;
#X obj 170 481 *~;
#X obj 139 481 *~;
#X obj 139 503 +~;
#X obj 112 199 *~;
#X obj 81 199 *~;
#X obj 53 199 *~;
#X obj 22 199 *~;
#X obj 22 224 +~;
#X obj 126 391 *~;
#X obj 22 628 *~;
#X obj 237 436 rfft~;
#X obj 121 167 rfft~;
#X obj 21 570 rifft~;
#X obj 23 682 outlet~;
#X obj 96 391 *~;
#X obj 96 413 +~;
#X obj 127 224 -~;
#X obj 21 437 *~;
#X obj 54 438 *~;
#X obj 83 632 r window-size;
#X obj 336 593 r window-size;
#X obj 336 642 block~;
#X obj 22 355 +~ 1e-15;
#X obj 21 604 *~;
#X obj 61 603 tabreceive~ \$0-hann;
#X obj 83 654 expr 2/(3*$f1);
#X obj 529 569 loadbang;
#X msg 336 617 set \$1 4;
#N canvas 210 23 1035 713 read-windows 0;
#X obj 139 632 *~;
#X obj 462 383 r window-size;
#X obj 269 247 f;
#X obj 193 16 r window-size;
#X obj 193 64 /;
#X obj 318 634 *~;
#X obj 269 196 bang~;
#X obj 139 496 line~;
#X obj 193 89 * 1000;
#X obj 391 161 r speed;
#X obj 287 221 r location;
#X obj 311 249 +;
#X obj 391 214 *;
#X obj 287 306 / 1000;
#X obj 269 333 *;
#X text 301 333 reading location (samples);
#X obj 158 539 / 4;
#X obj 391 184 * 0.01;
#X floatatom 462 440 7 0 0 0 - - - 0;
#X obj 462 416 *;
#X obj 582 289 r transpo;
#X obj 582 313 * 0.01;
#X obj 582 337 + 69;
#X obj 582 362 mtof;
#X obj 582 389 / 440;
#X obj 497 416 t b f;
#X obj 139 658 outlet~;
#X obj 318 659 outlet~;
#X obj 336 603 tabreceive~ \$0-hann;
#X obj 756 355 r location;
#X msg 756 378 0;
#X obj 756 401 s speed;
#X obj 771 495 r speed;
#X msg 771 519 set \$1;
#X obj 771 544 s speed-set;
#X text 520 438 stretched window size (samples), f 16;
#X obj 880 494 r transpo;
#X msg 880 520 set \$1;
#X obj 880 545 s transpo-set;
#X obj 814 88 r location;
#X msg 828 274 set \$1;
#X obj 814 134 t b f;
#X obj 828 251 f;
#X obj 756 165 int;
#X obj 756 197 sel 0;
#X msg 815 168 1;
#X msg 815 191 0;
#X obj 756 222 del 300;
#X obj 828 300 s location-set;
#X obj 139 596 tabread4~ \$0-sample;
#X obj 317 576 tabread4~ \$0-sample;
#X obj 287 282 r \$0-insamprate;
#X obj 514 487 r rewind;
#X msg 514 665 \; location \$1;
#X floatatom 192 111 5 0 0 0 - - - 0;
#X obj 193 40 t f b;
#X obj 225 64 samplerate~;
#X obj 192 136 / 4;
#X obj 346 253 s see-loc;
#X obj 823 110 r see-loc;
#X obj 306 359 / 2;
#X obj 269 359 -;
#X text 342 356 back up 1/2 window;
#X obj 139 562 -~;
#X text 330 17 Read two windows out of the recorded sample \, one 1/4 ahead of the other. The mid point of the front window is specified by "location". If "speed" is nonzero \, "location" automatically precesses., f 45;
#X obj 514 641 * -0.5;
#X text 17 547 "back" window 1/4 cycle behind "front" one, f 16;
#X text 223 136 computation period (msec) for overlap of 4;
#X text 245 110 msec in a window;
#X obj 514 587 /;
#X obj 514 615 * 1000;
#X obj 514 563 t f b;
#X obj 546 587 samplerate~;
#X obj 514 540 f;
#X msg 883 645 \; rewind bang \; speed \$1;
#X obj 883 618 r auto;
#X obj 768 619 r no-detune;
#X text 759 449 reflect control changes;
#X text 759 466 in main window.;
#X text 798 587 misc controls;
#X obj 139 414 f;
#X obj 139 385 b;
#X msg 139 468 0 \, \$1 \$2;
#X msg 768 641 \; transpo 0;
#X text 710 28 if location changes \, update number box in main window via "location-set" \, but taking care to limit frequency of updates., f 38;
#X text 834 367 setting location by hand sets speed to zero., f 19;
#X text 543 512 "rewind" control takes us to a location depending on stretched window size., f 25;
#X text 427 207 loop to precess the location according to the "speed" parameter., f 22;
#X obj 139 441 pack f f;
#X connect 0 0 26 0;
#X connect 1 0 19 0;
#X connect 2 0 11 0;
#X connect 2 0 14 0;
#X connect 3 0 55 0;
#X connect 4 0 8 0;
#X connect 5 0 27 0;
#X connect 6 0 2 0;
#X connect 7 0 63 0;
#X connect 7 0 50 0;
#X connect 8 0 54 0;
#X connect 9 0 17 0;
#X connect 10 0 2 1;
#X connect 11 0 2 1;
#X connect 11 0 58 0;
#X connect 12 0 11 1;
#X connect 13 0 14 1;
#X connect 14 0 61 0;
#X connect 16 0 63 1;
#X connect 17 0 12 0;
#X connect 18 0 16 0;
#X connect 18 0 60 0;
#X connect 18 0 73 1;
#X connect 18 0 80 1;
#X connect 19 0 18 0;
#X connect 20 0 21 0;
#X connect 21 0 22 0;
#X connect 22 0 23 0;
#X connect 23 0 24 0;
#X connect 24 0 25 0;
#X connect 25 0 19 0;
#X connect 25 1 19 1;
#X connect 28 0 5 1;
#X connect 28 0 0 1;
#X connect 29 0 30 0;
#X connect 30 0 31 0;
#X connect 32 0 33 0;
#X connect 33 0 34 0;
#X connect 36 0 37 0;
#X connect 37 0 38 0;
#X connect 39 0 41 0;
#X connect 40 0 48 0;
#X connect 41 0 43 0;
#X connect 41 1 42 1;
#X connect 42 0 40 0;
#X connect 43 0 44 0;
#X connect 44 0 45 0;
#X connect 44 0 47 0;
#X connect 45 0 43 1;
#X connect 46 0 43 1;
#X connect 47 0 46 0;
#X connect 47 0 42 0;
#X connect 49 0 0 0;
#X connect 50 0 5 0;
#X connect 51 0 13 0;
#X connect 52 0 73 0;
#X connect 54 0 57 0;
#X connect 55 0 4 0;
#X connect 55 1 56 0;
#X connect 56 0 4 1;
#X connect 57 0 12 1;
#X connect 57 0 88 1;
#X connect 59 0 41 0;
#X connect 60 0 61 1;
#X connect 61 0 81 0;
#X connect 61 0 49 1;
#X connect 61 0 50 1;
#X connect 63 0 49 0;
#X connect 65 0 53 0;
#X connect 69 0 70 0;
#X connect 70 0 65 0;
#X connect 71 0 69 0;
#X connect 71 1 72 0;
#X connect 72 0 69 1;
#X connect 73 0 71 0;
#X connect 75 0 74 0;
#X connect 76 0 83 0;
#X connect 80 0 88 0;
#X connect 81 0 80 0;
#X connect 82 0 7 0;
#X connect 88 0 82 0;
#X restore 121 139 pd read-windows;
#X text 250 21 recall previous output amplitude. Its phase will be added to the phase difference we measure from two windows in the the recorded sound., f 66;
#X obj 124 75 *~;
#X obj 97 75 *~;
#X obj 97 97 +~;
#X obj 162 77 +~ 1e-20;
#X obj 81 125 *~;
#X obj 22 124 *~;
#X obj 180 299 r lock;
#X obj 32 251 lrshift~ 1;
#X obj 27 275 lrshift~ -1;
#X obj 144 251 lrshift~ 1;
#X obj 136 275 lrshift~ -1;
#X obj 40 306 *~;
#X obj 162 326 *~;
#X obj 22 331 +~;
#X obj 128 326 +~;
#X text 250 173 Take FT of the window in back. Multiply its conjugate by the normalized previous output. The result has the magnitude of the input sound and phase (previous output phase) minus (back window phase)., f 66;
#X text 250 369 Normalize again \, this time taking care to salt each channel with 1e-15 so that we get a unit complex number even if everything was zero heretofore., f 66;
#X text 285 431 Now take the FT of the forward window and multiply it by the unit complex number from above. The magnitude will be that of the forward window and the phase will be the previous output phase plus the phase difference between the two analysis windows -- except that if "lock" is on \, they will be modified to agree progressively better with the inter-channel phase relationships of the input., f 61;
#X text 250 245 If "lock" is on \, encourage neighboring channels to stay in phase by adding the two neighboring complex amplitudes. The result will tend toward the channel with the strongest amplitude. If the phase relationships between channels in the output and those in the input are in parallel \, then neighboring channels of the quotient will all have the same phase and this will not change any phases. (lrshift shifts the signal to the left or right depending on its argument.), f 66;
#X text 250 130 Read two windows \, one 1/4 length behind the other \, of the input sound \, with Hann window function (see inside)., f 66;
#X text 307 556 'set' message to block allows variable size, f 22;
#X msg 529 595 \; window-size 2048 \; transpo 0 \; rewind bang;
#X obj 139 538 send~ prev-imag;
#X obj 139 568 send~ prev-real;
#X obj 23 12 receive~ prev-real;
#X obj 81 35 receive~ prev-imag;
#X obj 162 100 rsqrt~;
#X text 250 72 divide by the magnitude to make a unit-magnitude complex amplitude (phase only). The 1e-20 is to prevent overflows. [rsqrt~] is reciprocal square root., f 66;
#X obj 96 437 rsqrt~;
#X connect 0 0 2 1;
#X connect 1 0 2 0;
#X connect 2 0 15 0;
#X connect 2 0 56 0;
#X connect 3 0 5 1;
#X connect 4 0 5 0;
#X connect 5 0 15 1;
#X connect 5 0 55 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 41 0;
#X connect 10 0 40 0;
#X connect 10 0 46 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 26 0;
#X connect 17 0 18 0;
#X connect 18 0 61 0;
#X connect 19 0 42 0;
#X connect 19 0 43 0;
#X connect 19 0 47 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 22 0 28 0;
#X connect 23 0 30 0;
#X connect 25 0 17 1;
#X connect 25 0 17 0;
#X connect 25 0 20 0;
#X connect 26 0 12 0;
#X connect 27 0 26 1;
#X connect 28 0 12 1;
#X connect 29 0 54 0;
#X connect 30 0 24 0;
#X connect 31 0 14 0;
#X connect 31 1 13 0;
#X connect 33 0 35 1;
#X connect 34 0 35 0;
#X connect 35 0 36 0;
#X connect 36 0 59 0;
#X connect 37 0 8 0;
#X connect 37 0 7 0;
#X connect 38 0 9 0;
#X connect 38 0 6 0;
#X connect 39 0 44 1;
#X connect 39 0 45 1;
#X connect 40 0 44 0;
#X connect 41 0 44 0;
#X connect 42 0 45 0;
#X connect 43 0 45 0;
#X connect 44 0 46 1;
#X connect 45 0 47 1;
#X connect 46 0 25 0;
#X connect 47 0 11 0;
#X connect 47 0 11 1;
#X connect 47 0 21 0;
#X connect 57 0 34 1;
#X connect 57 0 34 0;
#X connect 57 0 38 0;
#X connect 58 0 33 1;
#X connect 58 0 33 0;
#X connect 58 0 37 0;
#X connect 59 0 37 1;
#X connect 59 0 38 1;
#X connect 61 0 20 1;
#X connect 61 0 21 1;
#X restore 45 478 pd fft-analysis;
#X obj 421 355 s transpo;
#X text 134 355 hundredths;
#X text 340 339 normal;
#X obj 45 516 output~;
#N canvas 385 188 595 536 hann-window 0;
#N canvas 0 0 450 300 (subpatch) 0;
#X array \$0-hann 2048 float 0;
#X coords 0 1 2047 0 300 100 1;
#X restore 148 395 graph;
#X obj 366 185 osc~;
#X obj 366 210 *~ -0.5;
#X obj 366 234 +~ 0.5;
#X obj 349 277 tabwrite~ \$0-hann;
#X obj 124 114 r window-size;
#X obj 195 238 /;
#X obj 213 206 samplerate~;
#X obj 195 316 s window-sec;
#X obj 105 252 swap;
#X obj 105 276 /;
#X obj 105 300 s window-hz;
#X obj 206 266 * 1000;
#X obj 206 293 s window-msec;
#X obj 124 149 t f b f;
#X msg 213 156 resize \$1;
#X obj 213 180 s \$0-hann;
#X obj 317 123 r window-hz;
#X msg 391 155 0;
#X obj 317 151 t f b;
#X text 94 21 calculate Hann window table (variable window size) and constants window-hz (fundamental frequency of analysis) \, window-sec and window-msec (analysis window size in seconds and msec)., f 56;
#X connect 1 0 2 0;
#X connect 2 0 3 0;
#X connect 3 0 4 0;
#X connect 5 0 14 0;
#X connect 6 0 8 0;
#X connect 6 0 12 0;
#X connect 7 0 6 1;
#X connect 7 0 9 1;
#X connect 9 0 10 0;
#X connect 9 1 10 1;
#X connect 10 0 11 0;
#X connect 12 0 13 0;
#X connect 14 0 6 0;
#X connect 14 0 9 0;
#X connect 14 1 7 0;
#X connect 14 2 15 0;
#X connect 15 0 16 0;
#X connect 17 0 19 0;
#X connect 18 0 1 1;
#X connect 19 0 1 0;
#X connect 19 1 4 0;
#X connect 19 1 18 0;
#X restore 381 549 pd hann-window;
#N canvas 724 173 764 665 insample 0;
#N canvas 0 0 450 300 (subpatch) 0;
#X array \$0-sample 62079 float 2;
#X coords 0 1 62079 -1 363 214 1 0 0;
#X restore 344 349 graph;
#X obj 78 123 r read-sample;
#X obj 59 264 soundfiler;
#X obj 58 481 loadbang;
#X obj 112 171 symbol \$0-sample;
#X obj 59 203 pack s s;
#X msg 59 233 read -resize \$1 \$2;
#X obj 59 404 s \$0-samplength;
#X obj 90 317 /;
#X obj 90 348 * 1000;
#X obj 90 371 s \$0-samp-msec;
#X obj 289 90 adc~ 1;
#X obj 357 22 inlet;
#X obj 392 61 samplerate~;
#X obj 357 213 tabwrite~ \$0-sample, f 20;
#X obj 392 127 s \$0-insamprate;
#X msg 58 506 \; read-sample ../sound/voice.wav;
#X obj 59 22 inlet;
#X obj 59 69 openpanel;
#X text 128 481 read default sample;
#X msg 126 291 \$1;
#X obj 126 319 s \$0-insamprate;
#X obj 59 168 t a b;
#X obj 513 194 s \$0-samplength;
#X obj 377 187 s \$0-samp-msec;
#X msg 377 161 2000;
#X obj 513 111 * 2;
#X msg 533 164 s \$0-sample;
#X msg 533 139 resize \$1;
#X text 410 21 record 2 seconds;
#X connect 1 0 22 0;
#X connect 2 0 7 0;
#X connect 2 0 8 0;
#X connect 2 1 20 0;
#X connect 3 0 16 0;
#X connect 4 0 5 1;
#X connect 5 0 6 0;
#X connect 6 0 2 0;
#X connect 8 0 9 0;
#X connect 9 0 10 0;
#X connect 11 0 14 0;
#X connect 12 0 13 0;
#X connect 12 0 14 0;
#X connect 12 0 25 0;
#X connect 13 0 15 0;
#X connect 13 0 26 0;
#X connect 17 0 18 0;
#X connect 18 0 22 0;
#X connect 20 0 21 0;
#X connect 20 0 8 1;
#X connect 22 0 5 0;
#X connect 22 1 4 0;
#X connect 25 0 24 0;
#X connect 26 0 23 0;
#X connect 26 0 28 0;
#X connect 28 0 27 0;
#X restore 381 514 pd insample;
#X f 12;
#X floatatom 537 524 9 0 0 0 - \$0-samp-msec - 0;
#X msg 189 475 ../sound/bell.aiff;
#X msg 198 498 ../sound/voice.wav;
#X msg 202 520 ../sound/voice2.wav;
#X obj 189 551 s read-sample;
#X obj 422 384 tgl 22 0 empty empty empty 0 -6 0 8 #dfdfdf #000000 #000000 0 1;
#X obj 47 388 s location;
#X obj 225 391 s rewind;
#X msg 303 315 200;
#X msg 311 339 100;
#X msg 318 363 20;
#X text 332 314 contract;
#X text 348 363 expand;
#X obj 422 414 s lock;
#X text 47 311 location;
#X text 44 327 (stops;
#X text 49 342 motion);
#X text 135 339 motion in;
#X text 192 453 read input sound;
#X floatatom 551 453 7 0 0 0 - window-size - 0;
#X msg 550 326 512;
#X msg 556 349 1024;
#X msg 561 372 2048;
#X msg 566 395 4096;
#X obj 550 421 s window-size;
#X text 547 284 window size \,;
#X text 547 299 samples;
#X text 81 287 ------- location controls -------;
#X obj 303 391 s auto;
#X obj 419 290 bng 22 250 50 0 no-detune empty empty 0 -6 0 8 #dfdfdf #000000 #000000;
#X obj 225 362 bng 22 250 50 0 empty empty empty 0 -6 0 8 #dfdfdf #000000 #000000;
#X obj 381 460 bng 22 250 50 0 empty empty empty 0 -6 0 8 #dfdfdf #000000 #000000;
#X obj 462 485 bng 22 250 50 0 empty empty empty 0 -6 0 8 #dfdfdf #000000 #000000;
#X text 461 317 detune in cents, f 8;
#X text 442 292 no detune;
#X text 585 325 <-- set;
#X text 405 460 <-- load file;
#X text 388 486 record -->;
#X text 535 547 sample length in msec, f 13;
#X text 550 473 window size;
#X obj 140 384 nbx 5 17 -1e+37 1e+37 0 0 speed speed-set empty 0 -10 0 12 #dfdfdf #000000 #000000 0 256;
#X connect 3 0 6 0;
#X connect 4 0 18 0;
#X connect 5 0 9 0;
#X connect 13 0 16 0;
#X connect 14 0 16 0;
#X connect 15 0 16 0;
#X connect 17 0 25 0;
#X connect 20 0 40 0;
#X connect 21 0 40 0;
#X connect 22 0 40 0;
#X connect 32 0 36 0;
#X connect 33 0 36 0;
#X connect 34 0 36 0;
#X connect 35 0 36 0;
#X connect 42 0 19 0;
#X connect 43 0 11 0;
#X connect 44 0 11 1;
