Hi again,

On 04/03/2020 12:58, Claude Heiland-Allen wrote:
On 2020-03-04 11:18, Peter P. wrote:
I am trying to calculate a makeup gain factor for white noise sent into
[bp~] and [vcf~] bandpass objects depending on the center frequency and
the Q (width) so that it measures the same in dBRMS before and after the
filter. I am currently measuring it but am wondering if
b.) if there is an analytical solution to it already
For an un-normalized 2-pole bandpass filter as depicted at [1], I think the overall gain of the filter for white noise input is

sqrt ( integral from 0 to pi of |1/((exp(it) - (1-b)exp(iw))(exp(it) - (1-b)exp(-iw)))|^2 dt )

I tried it on Wolfram Alpha but it didn't succeed (time limit exceeded).  Probably there is no simple closed-form solution?

Then you need to factor in how bp~ [2] and vcf~ [3] convert f and q into w and b, as well as their custom gain factors.

I attached an example with simple numerical integration (using Pd dsp with bang to switch~), seems to work ok (but may be unreliable if q is too high), you could combine with automation for -batch and use that to generate data for surface fitting software?  I may try that later...

I think I made a mistake though: I used vcf~'s f q -> w b calculations, but now realized that maybe vcf~ has 1 (complex) pole and bp~ has 2 (a conjugate pair)?

As a bonus, the patch includes a normalized log-log spectrum graph calculated in DSP using tabsend~/tabreceive~ and order forcing.

[1] http://msp.ucsd.edu/techniques/latest/book-html/node143.html
[2] https://github.com/pure-data/pure-data/blob/e2ef8158e83900734d263a3fda343a47ed0c9e3a/src/d_filter.c#L284-L301 [3] https://github.com/pure-data/pure-data/blob/e2ef8158e83900734d263a3fda343a47ed0c9e3a/src/d_osc.c#L386-L447


Claude
--
https://mathr.co.uk

#N canvas 3 61 450 488 10;
#N canvas 3 61 450 300 \$0-band-pass-filter 0;
#X obj 36 131 cpole~;
#X obj 48 179 cpole~;
#X obj 34 23 inlet~;
#X obj 47 208 outlet~;
#X text 189 22 b;
#X text 312 23 w;
#X obj 140 22 inlet;
#X obj 140 45 expr 1 - $f1;
#X obj 140 68 expr $f1 * cos($f2) \; $f1 * sin($f2);
#X obj 167 134 * -1;
#X obj 263 22 inlet;
#X text 46 261 http://msp.ucsd.edu/techniques/latest/book-html/node143.html
;
#X text 94 239 un-normalized 2-pole bandpass filter as described at
;
#X connect 0 0 1 0;
#X connect 0 1 1 1;
#X connect 1 0 3 0;
#X connect 2 0 0 0;
#X connect 6 0 7 0;
#X connect 7 0 8 0;
#X connect 8 0 1 2;
#X connect 8 0 0 2;
#X connect 8 1 9 0;
#X connect 9 0 1 3;
#X connect 10 0 8 1;
#X restore 68 351 pd \$0-band-pass-filter;
#N canvas 3 78 469 650 \$0-gain-calculation 0;
#X obj 37 85 inlet;
#X text 51 107 b;
#X obj 169 89 inlet;
#X text 185 109 w;
#X obj 288 132 switch~ 65536 1 1;
#X obj 289 82 loadbang;
#X msg 289 105 0;
#X obj 36 155 expr $f1 * cos($f2) \; $f1 * sin($f2);
#X obj 37 129 expr 1 - $f1;
#X obj 25 224 tabplay~ \$0-cos-table;
#X obj 45 250 tabplay~ \$0-sin-table;
#X obj 38 310 *~;
#X obj 81 311 *~;
#X obj 39 287 -~ 0;
#X obj 81 288 -~ 0;
#X obj 120 312 *~;
#X obj 120 289 -~ 0;
#X obj 154 277 * -1;
#X obj 48 356 +~;
#X obj 84 356 +~;
#X obj 50 384 *~;
#X obj 32 413 /~;
#X obj 5 389 sig~ 1;
#X obj 26 493 rpole~ 1;
#X msg 44 466 set 0;
#X obj 14 520 snapshot~;
#X obj 35 197 t b b b f;
#X obj 17 547 / 65536;
#X obj 19 605 outlet;
#X obj 277 491 table \$0-sin-table 65536;
#X obj 276 467 table \$0-cos-table 65536;
#X obj 278 205 loadbang;
#X msg 278 228 65536;
#X obj 278 251 until;
#X obj 278 274 f 0;
#X obj 332 271 + 1;
#X obj 332 294 mod 65536;
#X obj 279 323 / 65536;
#X obj 278 346 * 3.14159;
#X obj 278 370 expr cos($f1) \; sin($f1);
#X obj 278 297 t f f;
#X obj 278 406 tabwrite \$0-cos-table;
#X obj 277 436 tabwrite \$0-sin-table;
#X obj 17 577 sqrt;
#X text 28 29 sqrt(integral from 0 to pi of |1/((exp(it)-(1-b)exp(iw))*(exp(it)-(1-b)(exp(-iw)))|^2
dt);
#X text 28 9 calculate the gain of the two-pole un-normalized band
pass:;
#X text 258 179 precalculate trig tables;
#X text 27 62 also writes the normalized dB spectrum to a table;
#X obj 228 86 inlet;
#X text 243 108 sr;
#N canvas 3 61 701 358 \$0-plot-spectrum 0;
#X obj 132 25 inlet;
#X obj 278 23 inlet;
#X obj 278 46 t b f;
#X text 325 24 sr;
#X msg 273 80 65536;
#X obj 273 103 until;
#X obj 273 126 f 0;
#X obj 327 123 + 1;
#X obj 327 146 mod 65536;
#X obj 274 175 / 65536;
#X obj 273 149 t f f;
#X obj 273 256 tabwrite \$0-freq-table;
#X obj 273 208 expr exp(log(2 * 20 / $f2) * (1 - $f1) + $f1 * log(2
* 20000 / $f2)) * 65536;
#X msg 384 48 44100;
#X obj 383 22 loadbang;
#X obj 44 300 tabsend~ \$0-spectrum;
#X obj 44 92 powtodb~;
#N canvas 3 61 450 300 \$0-order-forcing 0;
#X obj 42 27 inlet~;
#X obj 42 50 tabsend~ \$0-spectrum-linear;
#X obj 42 73 outlet~;
#X connect 0 0 1 0;
#X restore 44 126 pd \$0-order-forcing;
#X obj 44 173 tabread4~ \$0-spectrum-linear;
#X obj 57 149 tabplay~ \$0-freq-table;
#X obj 44 201 -~;
#X obj 44 250 *~ 2;
#N canvas 3 61 450 300 \$0-peak 0;
#X obj 38 97 fexpr~ max($x \, $y);
#X obj 39 18 inlet~;
#N canvas 3 61 450 300 \$0-order-forcing 0;
#X obj 41 50 inlet~;
#X obj 41 73 tabsend~ \$0-spectrum-peak;
#X obj 41 96 outlet~;
#X connect 0 0 1 0;
#X restore 38 120 pd \$0-order-forcing;
#X obj 38 143 +~ 65535;
#X obj 38 166 tabread~ \$0-spectrum-peak;
#X obj 126 21 inlet;
#X msg 126 44 set 0;
#X obj 38 189 outlet~;
#X connect 0 0 2 0;
#X connect 1 0 0 0;
#X connect 2 0 3 0;
#X connect 3 0 4 0;
#X connect 4 0 7 0;
#X connect 5 0 6 0;
#X connect 6 0 0 0;
#X restore 82 200 pd \$0-peak;
#X obj 44 274 +~ 1;
#X obj 44 227 /~ 60;
#X obj 46 35 inlet~;
#X text 146 45 trigger;
#X text 55 55 spectrum;
#X obj 475 46 table \$0-spectrum-linear 65536;
#X text 448 70 table \$0-spectrum is defined in parent;
#X obj 477 92 table \$0-freq-table 65536;
#X obj 479 116 table \$0-spectrum-peak 65536;
#X text 262 309 this part is just an optional bonus;
#X connect 0 0 22 1;
#X connect 0 0 19 0;
#X connect 1 0 2 0;
#X connect 2 0 4 0;
#X connect 2 1 12 1;
#X connect 4 0 5 0;
#X connect 5 0 6 0;
#X connect 6 0 7 0;
#X connect 6 0 10 0;
#X connect 7 0 8 0;
#X connect 8 0 6 1;
#X connect 9 0 12 0;
#X connect 10 0 9 0;
#X connect 10 1 11 1;
#X connect 12 0 11 0;
#X connect 13 0 2 0;
#X connect 14 0 13 0;
#X connect 16 0 17 0;
#X connect 17 0 18 0;
#X connect 18 0 20 0;
#X connect 18 0 22 0;
#X connect 19 0 18 0;
#X connect 20 0 24 0;
#X connect 21 0 23 0;
#X connect 22 0 20 1;
#X connect 23 0 15 0;
#X connect 24 0 21 0;
#X connect 25 0 16 0;
#X restore 111 442 pd \$0-plot-spectrum;
#X text 80 492 integrate;
#X connect 0 0 8 0;
#X connect 2 0 7 1;
#X connect 5 0 6 0;
#X connect 6 0 4 0;
#X connect 7 0 26 0;
#X connect 7 1 14 1;
#X connect 7 1 17 0;
#X connect 8 0 7 0;
#X connect 9 0 13 0;
#X connect 10 0 14 0;
#X connect 10 0 16 0;
#X connect 11 0 18 0;
#X connect 11 0 19 0;
#X connect 12 0 18 1;
#X connect 13 0 11 0;
#X connect 13 0 11 1;
#X connect 14 0 12 0;
#X connect 14 0 12 1;
#X connect 15 0 19 1;
#X connect 16 0 15 0;
#X connect 16 0 15 1;
#X connect 17 0 16 1;
#X connect 18 0 20 0;
#X connect 19 0 20 1;
#X connect 20 0 21 1;
#X connect 21 0 23 0;
#X connect 21 0 50 0;
#X connect 22 0 21 0;
#X connect 23 0 25 0;
#X connect 24 0 23 0;
#X connect 25 0 27 0;
#X connect 26 0 25 0;
#X connect 26 1 4 0;
#X connect 26 2 10 0;
#X connect 26 2 9 0;
#X connect 26 2 24 0;
#X connect 26 2 50 1;
#X connect 26 3 13 1;
#X connect 27 0 43 0;
#X connect 31 0 32 0;
#X connect 32 0 33 0;
#X connect 33 0 34 0;
#X connect 34 0 35 0;
#X connect 34 0 40 0;
#X connect 35 0 36 0;
#X connect 36 0 34 1;
#X connect 37 0 38 0;
#X connect 38 0 39 0;
#X connect 39 0 41 0;
#X connect 39 1 42 0;
#X connect 40 0 37 0;
#X connect 40 1 41 1;
#X connect 40 1 42 1;
#X connect 43 0 28 0;
#X connect 48 0 50 2;
#X restore 66 245 pd \$0-gain-calculation;
#X floatatom 63 201 0 0 1 0 b - -;
#X floatatom 180 195 0 0 0 0 w - -;
#X floatatom 68 279 0 0 0 0 G - -;
#X obj 9 279 noise~;
#X obj 68 319 /~ 1;
#X obj 67 389 env~ 8192;
#X floatatom 67 412 5 0 0 0 - - -;
#X obj 169 318 t b f;
#X obj 130 215 t b f;
#X obj 4 389 env~ 8192;
#X floatatom 4 412 5 0 0 0 - - -;
#X obj 22 359 dac~;
#X obj 172 401 table \$0-spectrum 65536;
#N canvas 3 61 450 300 \$0-coefficient-calculation 0;
#X obj 45 256 outlet;
#X obj 157 257 outlet;
#X obj 33 23 inlet;
#X obj 142 25 inlet;
#X text 151 53 f;
#X text 42 52 q;
#X obj 233 26 inlet;
#X text 247 56 sr;
#X obj 142 80 /;
#X obj 33 115 expr if($f1 > 0 \, 1 / $f1 \, 0);
#X obj 46 149 *;
#X obj 46 195 clip 0 1;
#X text 62 234 b;
#X obj 151 153 * 3.14159;
#X obj 151 181 * 2;
#X text 171 236 w;
#X connect 2 0 9 0;
#X connect 3 0 8 0;
#X connect 6 0 8 1;
#X connect 8 0 13 0;
#X connect 9 0 10 0;
#X connect 10 0 11 0;
#X connect 11 0 0 0;
#X connect 13 0 14 0;
#X connect 14 0 1 0;
#X connect 14 0 10 1;
#X restore 64 172 pd \$0-coefficient-calculation;
#X obj 236 50 bang~;
#X obj 237 71 samplerate~;
#X obj 126 140 t b f;
#X floatatom 130 114 8 20 20000 0 hz - -;
#X floatatom 64 113 5 1e-06 1e+06 0 q - -;
#X msg 61 87 3;
#X obj 171 49 t b b;
#X msg 131 90 440;
#X obj 171 27 loadbang;
#X msg 334 164 \; pd dsp 1;
#X msg 334 200 \; pd dsp 0;
#X floatatom 239 122 5 1e-06 1e+06 0 sr - -;
#X obj 237 94 spigot 1;
#X obj 297 97 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 1
1;
#X obj 240 147 change;
#X obj 178 138 bang;
#X msg 296 50 1;
#X text 138 424 log-frequency \, log-gain (dB) \, peak-normalized;
#X obj 104 301 rmstodb;
#X obj 104 324 - 100;
#X floatatom 131 282 5 0 0 0 dB - -;
#X floatatom 177 74 5 16 128 0 note - -;
#X obj 177 96 mtof;
#X text 16 8 how to normalize a band-pass filter with white noise input
;
#X text 13 460 (copyleft) 2020 Claude Heiland-Allen https://mathr.co.uk
;
#X connect 0 0 7 0;
#X connect 0 0 13 1;
#X connect 1 0 4 0;
#X connect 2 0 1 0;
#X connect 2 0 0 1;
#X connect 3 0 9 0;
#X connect 3 0 10 0;
#X connect 4 0 6 1;
#X connect 4 0 34 0;
#X connect 5 0 11 0;
#X connect 5 0 6 0;
#X connect 5 0 13 0;
#X connect 6 0 0 0;
#X connect 7 0 8 0;
#X connect 9 0 0 1;
#X connect 9 1 0 2;
#X connect 10 0 1 0;
#X connect 10 1 1 1;
#X connect 11 0 12 0;
#X connect 15 0 2 0;
#X connect 15 1 3 0;
#X connect 16 0 17 0;
#X connect 17 0 28 0;
#X connect 18 0 15 0;
#X connect 18 1 15 1;
#X connect 19 0 18 0;
#X connect 20 0 15 0;
#X connect 21 0 20 0;
#X connect 22 0 21 0;
#X connect 22 0 23 0;
#X connect 22 0 32 0;
#X connect 22 1 25 0;
#X connect 23 0 19 0;
#X connect 24 0 22 0;
#X connect 27 0 30 0;
#X connect 28 0 27 0;
#X connect 29 0 28 1;
#X connect 30 0 31 0;
#X connect 30 0 1 2;
#X connect 30 0 15 2;
#X connect 31 0 15 1;
#X connect 32 0 29 0;
#X connect 34 0 35 0;
#X connect 35 0 36 0;
#X connect 37 0 38 0;
#X connect 38 0 19 0;
_______________________________________________
[email protected] mailing list
UNSUBSCRIBE and account-management -> 
https://lists.puredata.info/listinfo/pd-list

Reply via email to