#N canvas 424 39 670 638 12;
#X declare -stdpath ./;
#N canvas 352 38 540 704 fft-analysis 0;
#X obj 92 534 *~;
#X obj 53 534 *~;
#X obj 330 325 *~;
#X obj 298 325 *~;
#X obj 298 351 +~;
#X obj 53 176 *~;
#X obj 53 147 inlet~;
#X obj 53 199 rfft~;
#X obj 53 603 *~;
#X obj 144 238 *~;
#X obj 298 297 rfft~;
#X obj 53 568 rifft~;
#X obj 53 636 outlet~;
#X obj 110 238 *~;
#X obj 110 261 +~;
#X obj 110 443 *~;
#X obj 110 391 clip~;
#X obj 86 177 tabreceive~ \$0-hann;
#X obj 142 341 r squelch;
#X obj 142 365 expr 0.01*$f1*$f1;
#X obj 110 287 +~ 1e-20;
#X obj 86 603 tabreceive~ \$0-hann;
#X obj 298 268 *~;
#X obj 298 147 inlet~;
#X obj 316 237 tabreceive~ \$0-hann;
#X text 108 146 filter input;
#X text 356 146 control source;
#X text 360 296 Fourier transform;
#X text 43 19 Internal workings of the timbre stamping algorithm. First the "filter input" is treated as in the compressor patch \, multiplying each channel amplitude by one over its modulus (but limited by the "squelch" parameter.) It is then multiplied by the modulus of the channel amplitude for the control source (which is Fourier analyzed in parallel with the filter input.);
#X obj 110 312 rsqrt~;
#X obj 298 374 sqrt~;
#X text 365 353 modulus of control amplitude, f 10;
#X text 148 440 multiply the two amplitude factors (for compression and to apply new timbre), f 26;
#X text 181 254 reciprocal modulus of filter input amplitude, f 12;
#X obj 375 460 r window-size;
#X msg 375 486 set \$1 4;
#X obj 375 512 block~;
#X obj 157 533 expr 2/(3*$f1);
#X obj 157 504 r window-size;
#X text 272 533 normalize;
#X obj 110 503 *~ 0;
#X connect 0 0 11 1;
#X connect 1 0 11 0;
#X connect 2 0 4 1;
#X connect 3 0 4 0;
#X connect 4 0 30 0;
#X connect 5 0 7 0;
#X connect 6 0 5 0;
#X connect 7 0 13 0;
#X connect 7 0 13 1;
#X connect 7 0 1 0;
#X connect 7 1 9 0;
#X connect 7 1 9 1;
#X connect 7 1 0 0;
#X connect 8 0 12 0;
#X connect 9 0 14 1;
#X connect 10 0 3 0;
#X connect 10 0 3 1;
#X connect 10 1 2 0;
#X connect 10 1 2 1;
#X connect 11 0 8 0;
#X connect 13 0 14 0;
#X connect 14 0 20 0;
#X connect 15 0 40 0;
#X connect 16 0 15 0;
#X connect 17 0 5 1;
#X connect 18 0 19 0;
#X connect 19 0 16 2;
#X connect 20 0 29 0;
#X connect 21 0 8 1;
#X connect 22 0 10 0;
#X connect 23 0 22 0;
#X connect 24 0 22 1;
#X connect 29 0 16 0;
#X connect 30 0 15 1;
#X connect 34 0 35 0;
#X connect 35 0 36 0;
#X connect 37 0 40 1;
#X connect 38 0 37 0;
#X connect 40 0 0 1;
#X connect 40 0 1 1;
#X restore 102 485 pd fft-analysis;
#X obj 102 521 output~;
#N canvas 386 50 506 348 test-signals 0;
#X obj 76 241 outlet~;
#X text 122 30 test signal: looped sample playback;
#X obj 76 157 *~;
#X obj 76 123 phasor~;
#X obj 76 94 r \$0-hz1;
#X obj 110 158 r \$0-size1;
#X obj 76 197 tabread4~ \$0-sample1;
#X obj 286 241 outlet~;
#X obj 286 157 *~;
#X obj 286 123 phasor~;
#X obj 286 94 r \$0-hz2;
#X obj 320 158 r \$0-size2;
#X obj 286 197 tabread4~ \$0-sample2;
#X connect 2 0 6 0;
#X connect 3 0 2 0;
#X connect 4 0 3 0;
#X connect 5 0 2 1;
#X connect 6 0 0 0;
#X connect 8 0 12 0;
#X connect 9 0 8 0;
#X connect 10 0 9 0;
#X connect 11 0 8 1;
#X connect 12 0 7 0;
#X restore 100 436 pd test-signals;
#X f 16;
#X text 63 71 This is a Fourier-based "vocoder" (perhaps better called a "timbre stamp") like the one the Convolution brothers use. The "control source" is analyzed to get its spectral envelope \, which is then stamped onto the "filter input" by adjusting the amplitudes of its Fourier transform. The "filter input" is first whitened by the compression algorithm from the previous patch in this series. The best value of "squelch" to use depends critically on what kind of sounds are used for the filter input and the control source., f 76;
#X obj 44 19 cnv 5 5 25 empty empty Cort\ &\ Zack's\ Secret 15 13 0 16 #dfdfdf #202020 0;
#X text 47 451 filter input, f 6;
#X text 222 448 control source, f 7;
#X obj 418 312 bng 19 250 50 0 empty empty empty 0 -10 0 12 #dfdfdf #000000 #000000;
#X msg 392 234 ../sound/bell.aiff;
#X msg 401 257 ../sound/voice.wav;
#X msg 408 281 ../sound/voice2.wav;
#X text 445 311 choose a file;
#X obj 392 207 loadbang;
#X obj 477 339 bng 19 250 50 0 empty empty empty 0 -10 0 12 #dfdfdf #000000 #000000;
#X text 503 335 record 2 sec, f 6;
#N canvas 621 135 735 607 insample1 0;
#N canvas 0 0 450 300 (subpatch) 0;
#X array \$0-sample1 155944 float 2;
#X coords 0 1 155944 -1 279 142 1 0 0;
#X restore 375 268 graph;
#X obj 121 246 soundfiler;
#X msg 188 276 \$1;
#X obj 163 307 swap;
#X obj 163 335 /;
#X floatatom 163 395 10 0 0 0 - - - 0;
#X obj 42 124 openpanel;
#X msg 121 215 read -resize \$1 \$2;
#X obj 121 188 pack s s;
#X obj 121 160 t a b;
#X floatatom 121 468 9 0 0 0 - - - 0;
#X floatatom 206 309 6 0 0 0 - - - 0;
#X text 219 271 sample rate, f 6;
#X obj 54 19 inlet;
#X obj 54 63 route bang;
#X obj 42 97 bng 19 250 50 0 empty empty empty 0 -10 0 12 #dfdfdf #000000 #000000;
#X obj 352 107 adc~ 1;
#X obj 407 19 inlet;
#X obj 556 78 samplerate~;
#X msg 569 140 resize \$1;
#X obj 556 111 * 2;
#X text 588 112 2 seconds;
#X text 169 57 Subpatch to initialize patch \, load file into array and record., f 22;
#X msg 453 88 0.5;
#X obj 174 160 symbol \$0-sample1;
#X obj 163 421 s \$0-hz1;
#X obj 121 502 s \$0-size1;
#X obj 556 199 s \$0-size1;
#X obj 569 167 s \$0-sample1;
#X obj 407 170 tabwrite~ \$0-sample1;
#X obj 453 113 s \$0-hz1;
#X connect 1 0 3 0;
#X connect 1 0 10 0;
#X connect 1 1 2 0;
#X connect 2 0 3 1;
#X connect 2 0 11 0;
#X connect 3 0 4 0;
#X connect 3 1 4 1;
#X connect 4 0 5 0;
#X connect 5 0 25 0;
#X connect 6 0 9 0;
#X connect 7 0 1 0;
#X connect 8 0 7 0;
#X connect 9 0 8 0;
#X connect 9 1 24 0;
#X connect 10 0 26 0;
#X connect 13 0 14 0;
#X connect 14 0 15 0;
#X connect 14 1 9 0;
#X connect 15 0 6 0;
#X connect 16 0 29 0;
#X connect 17 0 18 0;
#X connect 17 0 23 0;
#X connect 17 0 29 0;
#X connect 18 0 20 0;
#X connect 19 0 28 0;
#X connect 20 0 19 0;
#X connect 20 0 27 0;
#X connect 23 0 30 0;
#X connect 24 0 8 1;
#X restore 396 365 pd insample1;
#X obj 417 518 bng 19 250 50 0 empty empty empty 0 -10 0 12 #dfdfdf #000000 #000000;
#X msg 407 487 ../sound/voice2.wav;
#X text 444 517 choose a file;
#X obj 391 413 loadbang;
#X obj 476 545 bng 19 250 50 0 empty empty empty 0 -10 0 12 #dfdfdf #000000 #000000;
#X text 502 541 record 2 sec, f 6;
#N canvas 621 135 735 607 insample2 0;
#N canvas 0 0 450 300 (subpatch) 0;
#X array \$0-sample2 62079 float 2;
#X coords 0 1 62079 -1 279 142 1 0 0;
#X restore 375 268 graph;
#X obj 121 246 soundfiler;
#X msg 188 276 \$1;
#X obj 163 307 swap;
#X obj 163 335 /;
#X floatatom 163 395 10 0 0 0 - - - 0;
#X obj 42 124 openpanel;
#X msg 121 215 read -resize \$1 \$2;
#X obj 121 188 pack s s;
#X obj 121 160 t a b;
#X floatatom 121 468 9 0 0 0 - - - 0;
#X floatatom 206 309 6 0 0 0 - - - 0;
#X text 219 271 sample rate, f 6;
#X obj 54 19 inlet;
#X obj 54 63 route bang;
#X obj 42 97 bng 19 250 50 0 empty empty empty 0 -10 0 12 #dfdfdf #000000 #000000;
#X obj 352 107 adc~ 1;
#X obj 407 19 inlet;
#X obj 561 78 samplerate~;
#X msg 574 140 resize \$1;
#X obj 561 111 * 2;
#X text 593 112 2 seconds;
#X text 169 57 Subpatch to initialize patch \, load file into array and record., f 22;
#X msg 453 88 0.5;
#X obj 121 502 s \$0-size2;
#X obj 163 421 s \$0-hz2;
#X obj 561 199 s \$0-size2;
#X obj 574 167 s \$0-sample2;
#X obj 453 113 s \$0-hz2;
#X obj 407 170 tabwrite~ \$0-sample2;
#X obj 174 160 symbol \$0-sample2;
#X connect 1 0 3 0;
#X connect 1 0 10 0;
#X connect 1 1 2 0;
#X connect 2 0 3 1;
#X connect 2 0 11 0;
#X connect 3 0 4 0;
#X connect 3 1 4 1;
#X connect 4 0 5 0;
#X connect 5 0 25 0;
#X connect 6 0 9 0;
#X connect 7 0 1 0;
#X connect 8 0 7 0;
#X connect 9 0 8 0;
#X connect 9 1 30 0;
#X connect 10 0 24 0;
#X connect 13 0 14 0;
#X connect 14 0 15 0;
#X connect 14 1 9 0;
#X connect 15 0 6 0;
#X connect 16 0 29 0;
#X connect 17 0 18 0;
#X connect 17 0 23 0;
#X connect 17 0 29 0;
#X connect 18 0 20 0;
#X connect 19 0 27 0;
#X connect 20 0 19 0;
#X connect 20 0 26 0;
#X connect 23 0 28 0;
#X connect 30 0 8 1;
#X restore 395 571 pd insample2;
#X msg 391 440 ../sound/voice.wav;
#X msg 400 463 ../sound/bell.aiff;
#X floatatom 214 306 5 1 200 1 squelch - squelch 16;
#X text 463 207 FILTER INPUT;
#X text 462 412 CONTROL SOURCE;
#X obj 461 24 declare -stdpath ./;
#N canvas 580 123 518 506 hann-window 0;
#N canvas 0 0 450 300 (subpatch) 0;
#X array \$0-hann 1024 float 0;
#X coords 0 1 1023 0 227 152 1;
#X restore 240 262 graph;
#X obj 112 366 osc~;
#X obj 112 391 *~ -0.5;
#X obj 112 415 +~ 0.5;
#X obj 95 458 tabwrite~ \$0-hann;
#X obj 64 236 swap;
#X obj 64 260 /;
#X msg 140 150 resize \$1;
#X obj 140 174 s \$0-hann;
#X msg 137 336 0;
#X obj 64 332 t f b;
#X obj 75 114 s window-size;
#X floatatom 64 294 8 0 0 0 - - - 0;
#X text 130 294 window hz;
#X text 246 123 Calculate Hann window table (variable window size) by getting the period of the window and Hz. Also get the analysis window size in seconds and msec., f 33;
#X obj 89 206 samplerate~;
#X obj 64 160 t f b f;
#X obj 64 60 inlet;
#X connect 1 0 2 0;
#X connect 2 0 3 0;
#X connect 3 0 4 0;
#X connect 5 0 6 0;
#X connect 5 1 6 1;
#X connect 6 0 12 0;
#X connect 7 0 8 0;
#X connect 9 0 1 1;
#X connect 10 0 1 0;
#X connect 10 1 4 0;
#X connect 10 1 9 0;
#X connect 12 0 10 0;
#X connect 15 0 5 1;
#X connect 16 0 5 0;
#X connect 16 1 15 0;
#X connect 16 2 7 0;
#X connect 17 0 11 0;
#X connect 17 0 16 0;
#X restore 96 383 pd hann-window;
#X floatatom 96 350 5 0 0 0 - - - 0;
#X msg 96 209 512;
#X obj 106 233 loadbang;
#X msg 106 257 1024;
#X msg 116 283 2048;
#X msg 127 312 4096;
#X obj 214 246 loadbang;
#X msg 214 273 30;
#X connect 0 0 1 0;
#X connect 2 0 0 0;
#X connect 2 1 0 1;
#X connect 7 0 15 0;
#X connect 8 0 15 0;
#X connect 9 0 15 0;
#X connect 10 0 15 0;
#X connect 12 0 8 0;
#X connect 13 0 15 1;
#X connect 16 0 22 0;
#X connect 17 0 22 0;
#X connect 19 0 23 0;
#X connect 20 0 22 1;
#X connect 23 0 22 0;
#X connect 24 0 22 0;
#X connect 30 0 29 0;
#X connect 31 0 30 0;
#X connect 32 0 33 0;
#X connect 33 0 30 0;
#X connect 34 0 30 0;
#X connect 35 0 30 0;
#X connect 36 0 37 0;
#X connect 37 0 25 0;
