#N canvas 485 38 631 544 12;
#X declare -stdpath ./;
#N canvas 352 24 545 673 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 151 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 text 379 355 modulus;
#X obj 110 443 *~;
#X obj 357 459 block~ 1024 4;
#X obj 110 391 clip~;
#X obj 86 177 tabreceive~ \$0-hann;
#X obj 356 499 loadbang;
#X obj 143 342 r squelch;
#X obj 142 365 expr 0.01*$f1*$f1;
#X obj 110 287 +~ 1e-20;
#X obj 110 503 *~ 0.00065;
#X obj 86 603 tabreceive~ \$0-hann;
#X obj 298 268 *~;
#X obj 298 239 inlet~;
#X obj 331 269 tabreceive~ \$0-hann;
#X text 379 372 of control;
#X text 377 389 amplitude;
#X text 187 242 reciprocal;
#X text 190 261 modulus of;
#X text 186 281 filter input;
#X text 187 300 amplitude;
#X text 114 152 filter input;
#X text 363 239 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 text 148 440 multiply the two amplitude;
#X text 146 457 factors (for compression;
#X text 148 473 and to apply new timbre);
#X msg 356 522 \; window-size 1024 \; squelch 30 \; squelch-set set 30;
#X obj 110 314 rsqrt~;
#X obj 298 374 sqrt~;
#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 44 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 23 0;
#X connect 16 0 24 0;
#X connect 18 0 16 0;
#X connect 19 0 5 1;
#X connect 20 0 42 0;
#X connect 21 0 22 0;
#X connect 22 0 18 2;
#X connect 23 0 43 0;
#X connect 24 0 0 1;
#X connect 24 0 1 1;
#X connect 25 0 8 1;
#X connect 26 0 10 0;
#X connect 27 0 26 0;
#X connect 28 0 26 1;
#X connect 43 0 18 0;
#X connect 44 0 16 1;
#X restore 103 421 pd fft-analysis;
#X text 41 399 filter;
#X text 43 414 input;
#X text 223 415 source;
#X text 224 396 control;
#X floatatom 54 262 4 0 500 0 - squelch-set - 0;
#X obj 54 286 s squelch;
#X obj 103 457 output~;
#X msg 158 240 ../sound/bell.aiff;
#X msg 164 262 ../sound/voice.wav;
#X msg 169 285 ../sound/voice2.wav;
#X obj 158 316 s read-sound1;
#X msg 334 242 ../sound/bell.aiff;
#X msg 341 264 ../sound/voice.wav;
#X msg 347 287 ../sound/voice2.wav;
#X obj 334 317 s read-sound2;
#X text 347 218 control source;
#X text 170 217 filter input;
#X text 246 193 change input sounds;
#X floatatom 413 383 8 0 0 0 - \$0-samp-msec - 0;
#N canvas 386 50 626 626 test-signals 0;
#X obj 80 481 line~;
#X obj 80 561 outlet~;
#X msg 80 455 0 \, \$1 \$2;
#X obj 80 429 pack 0 0;
#X obj 204 356 /;
#X obj 227 331 * 0.001;
#X obj 80 534 hip~ 5;
#X obj 81 215 loadbang;
#X msg 80 354 1;
#X obj 80 376 metro 1000;
#X obj 181 304 t b b f;
#X obj 103 274 t b f;
#X obj 80 506 tabread4~ \$0-sample;
#X text 61 26 test signal: looped sample playback;
#X obj 117 132 hip~ 5;
#X obj 117 108 adc~ 1;
#X obj 178 128 s insamprate;
#X obj 108 71 inlet;
#X obj 178 104 samplerate~;
#X obj 103 250 r \$0-samplength;
#X obj 181 278 r \$0-insamprate;
#X obj 108 160 tabwrite~ \$0-sample;
#X obj 336 480 line~;
#X obj 336 557 outlet~;
#X msg 336 454 0 \, \$1 \$2;
#X obj 336 428 pack 0 0;
#X obj 460 371 /;
#X obj 483 340 * 0.001;
#X obj 336 533 hip~ 5;
#X obj 336 226 loadbang;
#X msg 336 350 1;
#X obj 336 375 metro 1000;
#X obj 437 309 t b b f;
#X obj 363 277 t b f;
#X obj 320 135 hip~ 5;
#X obj 320 111 adc~ 1;
#X obj 311 76 inlet;
#X obj 382 109 samplerate~;
#X obj 382 133 s insamprate2;
#X obj 311 160 tabwrite~ \$0-sample2;
#X obj 362 253 r \$0-samplength2;
#X obj 437 283 r \$0-insamprate2;
#X obj 336 505 tabread4~ \$0-sample2;
#X obj 80 401 float;
#X obj 336 400 float;
#X connect 0 0 12 0;
#X connect 2 0 0 0;
#X connect 3 0 2 0;
#X connect 4 0 3 1;
#X connect 4 0 9 1;
#X connect 5 0 4 1;
#X connect 6 0 1 0;
#X connect 7 0 8 0;
#X connect 8 0 9 0;
#X connect 9 0 43 0;
#X connect 10 0 8 0;
#X connect 10 1 4 0;
#X connect 10 2 5 0;
#X connect 11 0 8 0;
#X connect 11 1 4 0;
#X connect 11 1 43 1;
#X connect 12 0 6 0;
#X connect 14 0 21 0;
#X connect 15 0 14 0;
#X connect 17 0 18 0;
#X connect 17 0 21 0;
#X connect 18 0 16 0;
#X connect 19 0 11 0;
#X connect 20 0 10 0;
#X connect 22 0 42 0;
#X connect 24 0 22 0;
#X connect 25 0 24 0;
#X connect 26 0 25 1;
#X connect 26 0 31 1;
#X connect 27 0 26 1;
#X connect 28 0 23 0;
#X connect 29 0 30 0;
#X connect 30 0 31 0;
#X connect 31 0 44 0;
#X connect 32 0 30 0;
#X connect 32 1 26 0;
#X connect 32 2 27 0;
#X connect 33 0 30 0;
#X connect 33 1 26 0;
#X connect 33 1 44 1;
#X connect 34 0 39 0;
#X connect 35 0 34 0;
#X connect 36 0 37 0;
#X connect 36 0 39 0;
#X connect 37 0 38 0;
#X connect 40 0 33 0;
#X connect 41 0 32 0;
#X connect 42 0 28 0;
#X connect 43 0 3 0;
#X connect 44 0 25 0;
#X restore 101 392 pd test-signals;
#X f 16;
#N canvas 388 86 710 358 insample2 0;
#N canvas 0 50 450 300 (subpatch) 0;
#X array \$0-sample2 62079 float 0;
#X coords 0 1 62078 -1 400 150 1;
#X restore 275 54 graph;
#X obj 27 74 unpack s f;
#X obj 26 191 soundfiler;
#X text 364 250 read a sample;
#X obj 284 249 loadbang;
#X obj 27 100 t s b;
#X obj 27 135 pack s s;
#X msg 27 163 read -resize \$1 \$2;
#X obj 27 47 t a b;
#X obj 26 254 /;
#X obj 26 278 * 1000;
#X obj 27 18 r read-sound2;
#X obj 124 74 s \$0-insamprate2;
#X obj 80 104 symbol \$0-sample2;
#X obj 36 218 s \$0-samplength2;
#X obj 64 251 r \$0-insamprate2;
#X obj 26 301 s \$0-samp2-msec;
#X msg 284 273 \; read-sound2 ../sound/voice.wav;
#X obj 125 46 f 44100;
#X connect 1 0 5 0;
#X connect 1 1 12 0;
#X connect 2 0 9 0;
#X connect 2 0 14 0;
#X connect 4 0 17 0;
#X connect 5 0 6 0;
#X connect 5 1 13 0;
#X connect 6 0 7 0;
#X connect 7 0 2 0;
#X connect 8 0 1 0;
#X connect 8 1 18 0;
#X connect 9 0 10 0;
#X connect 10 0 16 0;
#X connect 11 0 8 0;
#X connect 13 0 6 1;
#X connect 15 0 9 1;
#X connect 18 0 12 0;
#X restore 293 404 pd insample2;
#N canvas 498 195 722 350 insample1 0;
#N canvas 0 50 450 300 (subpatch) 0;
#X array \$0-sample 155944 float 2;
#X coords 0 1 155944 -1 400 150 1;
#X restore 259 42 graph;
#X obj 19 74 unpack s f;
#X obj 19 184 soundfiler;
#X text 356 250 read a sample;
#X obj 276 249 loadbang;
#X obj 19 100 t s b;
#X obj 72 104 symbol \$0-sample;
#X obj 19 135 pack s s;
#X msg 19 160 read -resize \$1 \$2;
#X obj 19 47 t a b;
#X obj 29 210 s \$0-samplength;
#X obj 116 74 s \$0-insamprate;
#X obj 19 247 /;
#X obj 19 275 * 1000;
#X obj 19 298 s \$0-samp-msec;
#X obj 57 247 r \$0-insamprate;
#X obj 19 23 r read-sound1;
#X msg 276 273 \; read-sound1 ../sound/bell.aiff;
#X obj 116 46 f 44100;
#X connect 1 0 5 0;
#X connect 1 1 11 0;
#X connect 2 0 10 0;
#X connect 2 0 12 0;
#X connect 4 0 17 0;
#X connect 5 0 7 0;
#X connect 5 1 6 0;
#X connect 6 0 7 1;
#X connect 7 0 8 0;
#X connect 8 0 2 0;
#X connect 9 0 1 0;
#X connect 9 1 18 0;
#X connect 12 0 13 0;
#X connect 13 0 14 0;
#X connect 15 0 12 1;
#X connect 16 0 9 0;
#X connect 18 0 11 0;
#X restore 293 382 pd insample1;
#X floatatom 412 406 8 0 0 0 - \$0-samp2-msec - 0;
#N canvas 163 152 567 523 hann-window 0;
#N canvas 0 0 450 300 (subpatch) 0;
#X array \$0-hann 1024 float 0;
#X coords 0 1 1023 0 300 100 1;
#X restore 110 394 graph;
#X obj 327 184 osc~;
#X obj 327 209 *~ -0.5;
#X obj 327 233 +~ 0.5;
#X obj 310 276 tabwrite~ \$0-hann;
#X obj 86 113 r window-size;
#X obj 157 237 /;
#X obj 175 205 samplerate~;
#X obj 157 315 s window-sec;
#X obj 67 251 swap;
#X obj 67 275 /;
#X obj 67 299 s window-hz;
#X obj 168 265 * 1000;
#X obj 168 292 s window-msec;
#X obj 86 148 t f b f;
#X msg 175 155 resize \$1;
#X obj 175 179 s \$0-hann;
#X obj 279 122 r window-hz;
#X msg 352 154 0;
#X obj 279 150 t f b;
#X text 56 20 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 293 427 pd hann-window;
#X text 475 383 sample lengths \,;
#X text 479 406 msec;
#X text 61 54 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 67;
#X text 387 475 updated for Pd version 0.39;
#X obj 451 20 declare -stdpath ./;
#X obj 210 365 bng 19 250 50 0 empty empty empty 0 -6 0 8 #dfdfdf #000000 #000000;
#X text 121 365 <- record ->;
#X text 88 17 CORT&ZACK's SECRET;
#X obj 101 366 bng 19 250 50 0 empty empty empty 0 -6 0 8 #dfdfdf #000000 #000000;
#X connect 0 0 7 0;
#X connect 5 0 6 0;
#X connect 8 0 11 0;
#X connect 9 0 11 0;
#X connect 10 0 11 0;
#X connect 12 0 15 0;
#X connect 13 0 15 0;
#X connect 14 0 15 0;
#X connect 20 0 0 0;
#X connect 20 1 0 1;
#X connect 30 0 20 1;
#X connect 33 0 20 0;
