#N canvas 557 371 620 428 12; #N canvas 297 254 646 523 fft-analysis 0; #X obj 115 409 *~; #X obj 75 409 *~; #X obj 76 114 *~; #X obj 77 88 inlet~; #X obj 76 137 rfft~; #X obj 75 466 *~; #X obj 171 177 *~; #X obj 75 432 rifft~; #X obj 75 489 outlet~; #X obj 137 177 *~; #X obj 137 200 +~; #X obj 461 85 block~ 1024 4; #X obj 137 351 clip~; #X obj 178 306 r squelch; #X obj 110 114 tabreceive~ \$0-hann; #X obj 177 329 expr 0.01*$f1*$f1; #X obj 461 116 loadbang; #X obj 137 381 *~ 0.00065; #X obj 137 225 +~ 1e-20; #X obj 136 262 q8_rsqrt~; #X obj 109 466 tabreceive~ \$0-hann; #X text 31 5 As in the previous patch \, this works by multiplying each channel of the Fourier analysis by a real number computed from the magnitude. If the magnutude is "m" \, the correction factor is 1/m \, but only to an upper limit controlled by the "squelch" parameter. ; #X text 211 174 squared magnitude; #X text 219 225 protect against divide-by-zero; #X text 223 261 quick 8-bit-accurate reciprocal square root; #X text 222 277 (done by table lookup - about 0.25% accurate); #X text 193 351 limit the gain to squelch*squelch/100; #X text 238 381 normalize for 1024-point \, overlap-4 Hann; #X text 151 409 multiply gain by real and complex part; #X text 152 429 of the amplitude; #X text 130 137 outputs complex amplitudes; #X msg 461 139 \; pd dsp 1 \; window-size 1024 \; squelch 10 \; squelch-set set 10; #X connect 0 0 7 1; #X connect 1 0 7 0; #X connect 2 0 4 0; #X connect 3 0 2 0; #X connect 4 0 9 0; #X connect 4 0 9 1; #X connect 4 0 1 0; #X connect 4 1 6 0; #X connect 4 1 6 1; #X connect 4 1 0 0; #X connect 5 0 8 0; #X connect 6 0 10 1; #X connect 7 0 5 0; #X connect 9 0 10 0; #X connect 10 0 18 0; #X connect 12 0 17 0; #X connect 13 0 15 0; #X connect 14 0 2 1; #X connect 15 0 12 2; #X connect 16 0 31 0; #X connect 17 0 0 1; #X connect 17 0 1 1; #X connect 18 0 19 0; #X connect 19 0 12 0; #X connect 20 0 5 1; #X restore 42 330 pd fft-analysis; #X floatatom 57 196 0 0 500 0 - squelch-set -; #X obj 57 220 s squelch; #N canvas 240 72 427 657 test-signal 0; #X obj 90 444 line~; #X obj 90 369 f; #X obj 90 524 outlet~; #X msg 90 423 0 \, \$1 \$2; #X obj 90 397 pack 0 0; #X obj 190 344 /; #X obj 317 295 * 0.001; #X obj 90 497 hip~ 5; #X obj 35 246 loadbang; #X msg 90 322 1; #X obj 90 344 metro 1000; #X obj 259 272 t b b f; #X obj 117 270 t b f; #X obj 90 469 tabread4~ \$0-sample; #X text 21 28 test signal: looped sample playback; #X obj 77 131 hip~ 5; #X obj 77 107 adc~ 1; #X obj 139 131 s insamprate; #X obj 67 70 inlet; #X obj 139 107 samplerate~; #X obj 116 246 r \$0-samplength; #X obj 259 246 r \$0-insamprate; #X obj 67 154 tabwrite~ \$0-sample; #X connect 0 0 13 0; #X connect 1 0 4 0; #X connect 3 0 0 0; #X connect 4 0 3 0; #X connect 5 0 4 1; #X connect 5 0 10 1; #X connect 6 0 5 1; #X connect 7 0 2 0; #X connect 8 0 9 0; #X connect 9 0 10 0; #X connect 10 0 1 0; #X connect 11 0 9 0; #X connect 11 1 5 0; #X connect 11 2 6 0; #X connect 12 0 9 0; #X connect 12 1 5 0; #X connect 12 1 1 1; #X connect 13 0 7 0; #X connect 15 0 22 0; #X connect 16 0 15 0; #X connect 18 0 19 0; #X connect 18 0 22 0; #X connect 19 0 17 0; #X connect 20 0 12 0; #X connect 21 0 11 0; #X restore 43 303 pd test-signal; #X obj 43 359 output~; #N canvas 388 86 722 350 insample 0; #N canvas 0 0 450 300 (subpatch) 0; #X array \$0-sample 155948 float 0; #X coords 0 1 155947 -1 400 150 1; #X restore 259 24 graph; #X obj 19 23 r read-sample; #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 75 99 symbol \$0-sample; #X obj 19 135 pack s s; #X msg 19 160 read -resize \$1 \$2; #X obj 74 46 44100; #X obj 19 47 t a b; #X msg 276 273 \; read-sample ../sound/bell.aiff; #X obj 29 208 s \$0-samplength; #X obj 116 74 s \$0-insamprate; #X obj 19 247 /; #X obj 19 271 * 1000; #X obj 19 294 s \$0-samp-msec; #X obj 57 247 r \$0-insamprate; #X connect 1 0 11 0; #X connect 2 0 6 0; #X connect 2 1 14 0; #X connect 3 0 13 0; #X connect 3 0 15 0; #X connect 5 0 12 0; #X connect 6 0 8 0; #X connect 6 1 7 0; #X connect 7 0 8 1; #X connect 8 0 9 0; #X connect 9 0 3 0; #X connect 10 0 14 0; #X connect 11 0 2 0; #X connect 11 1 10 0; #X connect 15 0 16 0; #X connect 16 0 17 0; #X connect 18 0 15 1; #X restore 223 313 pd insample; #X text 362 406 updated for Pd version 0.39; #X text 56 43 Here we divide each complex channel in the Fourier analysis by its own magnitude to "flatten" the spectrum. The "squelch" control limits the amplitude boost the algorithm will apply. If infinite \, you'll get a white spectrum. If less \, the louder parts of the spectrum will be flattened but the quieter ones will only be boosted by the squelch value.; #X text 73 6 DYNAMIC RANGE COMPRESSION BY FOURIER ANALYSIS CHANNEL ; #X floatatom 223 366 5 0 0 0 - #0-samp-msec -; #X obj 43 282 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X text 62 281 <- record; #X text 276 365 sample length \, msec; #X msg 292 183 ../sound/bell.aiff; #X msg 292 208 ../sound/voice.wav; #X msg 292 233 ../sound/voice2.wav; #X text 91 197 <- squelch; #X text 295 161 change input sound; #X obj 292 259 s read-sample; #N canvas 0 110 565 454 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 82 311 graph; #X obj 378 165 osc~; #X obj 378 190 *~ -0.5; #X obj 378 214 +~ 0.5; #X obj 331 247 tabwrite~ \$0-hann; #X obj 37 88 r window-size; #X obj 38 173 /; #X obj 127 142 samplerate~; #X obj 38 251 s window-sec; #X obj 177 204 swap; #X obj 177 228 /; #X obj 177 252 s window-hz; #X obj 49 201 * 1000; #X obj 49 228 s window-msec; #X obj 38 115 t f b f; #X msg 173 92 resize \$1; #X obj 173 116 s \$0-hann; #X obj 330 105 r window-hz; #X msg 382 130 0; #X obj 330 131 t f b; #X text 15 8 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).; #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 223 335 pd hann-window; #X connect 0 0 4 0; #X connect 0 0 4 1; #X connect 1 0 2 0; #X connect 3 0 0 0; #X connect 10 0 3 0; #X connect 13 0 18 0; #X connect 14 0 18 0; #X connect 15 0 18 0;