Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(234)

Side by Side Diff: third_party/WebKit/LayoutTests/webaudio/resources/biquad-filters.js

Issue 1885723003: Implement Biquad lowpass and highpass filters according to spec (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // A biquad filter has a z-transform of 1 // A biquad filter has a z-transform of
2 // H(z) = (b0 + b1 / z + b2 / z^2) / (1 + a1 / z + a2 / z^2) 2 // H(z) = (b0 + b1 / z + b2 / z^2) / (1 + a1 / z + a2 / z^2)
3 // 3 //
4 // The formulas for the various filters were taken from 4 // The formulas for the various filters were taken from
5 // http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt. 5 // http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt.
6 6
7 7
8 // Lowpass filter. 8 // Lowpass filter.
9 function createLowpassFilter(freq, q, gain) { 9 function createLowpassFilter(freq, q, gain) {
10 var b0; 10 var b0;
11 var b1; 11 var b1;
12 var b2; 12 var b2;
13 var a0;
13 var a1; 14 var a1;
14 var a2; 15 var a2;
15 16
16 if (freq == 1) { 17 if (freq == 1) {
17 // The formula below works, except for roundoff. When freq = 1, 18 // The formula below works, except for roundoff. When freq = 1,
18 // the filter is just a wire, so hardwire the coefficients. 19 // the filter is just a wire, so hardwire the coefficients.
19 b0 = 1; 20 b0 = 1;
20 b1 = 0; 21 b1 = 0;
21 b2 = 0; 22 b2 = 0;
23 a0 = 1;
22 a1 = 0; 24 a1 = 0;
23 a2 = 0; 25 a2 = 0;
24 } else { 26 } else {
25 var g = Math.pow(10, q / 20);
26 var d = Math.sqrt((4 - Math.sqrt(16 - 16 / (g * g))) / 2);
27 var theta = Math.PI * freq; 27 var theta = Math.PI * freq;
28 var sn = d * Math.sin(theta) / 2; 28 var alpha = Math.sin(theta) / (2 * Math.pow(10, q / 20));
29 var beta = 0.5 * (1 - sn) / (1 + sn); 29 var cosw = Math.cos(theta);
30 var gamma = (0.5 + beta) * Math.cos(theta); 30 var beta = (1 - cosw) / 2;
31 var alpha = 0.25 * (0.5 + beta - gamma);
32 31
33 b0 = 2 * alpha; 32 b0 = beta;
34 b1 = 4 * alpha; 33 b1 = 2 * beta;
35 b2 = 2 * alpha; 34 b2 = beta;
36 a1 = 2 * (-gamma); 35 a0 = 1 + alpha;
37 a2 = 2 * beta; 36 a1 = -2 * cosw;
37 a2 = 1 - alpha;
38 } 38 }
39 39
40 return {b0 : b0, b1 : b1, b2 : b2, a1 : a1, a2 : a2}; 40 return normalizeFilterCoefficients(b0, b1, b2, a0, a1, a2);
41 } 41 }
42 42
43 function createHighpassFilter(freq, q, gain) { 43 function createHighpassFilter(freq, q, gain) {
44 var b0; 44 var b0;
45 var b1; 45 var b1;
46 var b2; 46 var b2;
47 var a0;
47 var a1; 48 var a1;
48 var a2; 49 var a2;
49 50
50 if (freq == 1) { 51 if (freq == 1) {
51 // The filter is 0 52 // The filter is 0
52 b0 = 0; 53 b0 = 0;
53 b1 = 0; 54 b1 = 0;
54 b2 = 0; 55 b2 = 0;
56 a0 = 1;
55 a1 = 0; 57 a1 = 0;
56 a2 = 0; 58 a2 = 0;
57 } else if (freq == 0) { 59 } else if (freq == 0) {
58 // The filter is 1. Computation of coefficients below is ok, but 60 // The filter is 1. Computation of coefficients below is ok, but
59 // there's a pole at 1 and a zero at 1, so round-off could make 61 // there's a pole at 1 and a zero at 1, so round-off could make
60 // the filter unstable. 62 // the filter unstable.
61 b0 = 1; 63 b0 = 1;
62 b1 = 0; 64 b1 = 0;
63 b2 = 0; 65 b2 = 0;
66 a0 = 1;
64 a1 = 0; 67 a1 = 0;
65 a2 = 0; 68 a2 = 0;
66 } else { 69 } else {
67 var g = Math.pow(10, q / 20);
68 var d = Math.sqrt((4 - Math.sqrt(16 - 16 / (g * g))) / 2);
69 var theta = Math.PI * freq; 70 var theta = Math.PI * freq;
70 var sn = d * Math.sin(theta) / 2; 71 var alpha = Math.sin(theta) / (2 * Math.pow(10, q / 20));
71 var beta = 0.5 * (1 - sn) / (1 + sn); 72 var cosw = Math.cos(theta);
72 var gamma = (0.5 + beta) * Math.cos(theta); 73 var beta = (1 + cosw) / 2;
73 var alpha = 0.25 * (0.5 + beta + gamma);
74 74
75 b0 = 2 * alpha; 75 b0 = beta;
76 b1 = -4 * alpha; 76 b1 = -2 * beta;
77 b2 = 2 * alpha; 77 b2 = beta;
78 a1 = 2 * (-gamma); 78 a0 = 1 + alpha;
79 a2 = 2 * beta; 79 a1 = -2 * cosw;
80 a2 = 1 - alpha;
80 } 81 }
81 82
82 return {b0 : b0, b1 : b1, b2 : b2, a1 : a1, a2 : a2}; 83 return normalizeFilterCoefficients(b0, b1, b2, a0, a1, a2);
83 } 84 }
84 85
85 function normalizeFilterCoefficients(b0, b1, b2, a0, a1, a2) { 86 function normalizeFilterCoefficients(b0, b1, b2, a0, a1, a2) {
86 var scale = 1 / a0; 87 var scale = 1 / a0;
87 88
88 return {b0 : b0 * scale, 89 return {b0 : b0 * scale,
89 b1 : b1 * scale, 90 b1 : b1 * scale,
90 b2 : b2 * scale, 91 b2 : b2 * scale,
91 a1 : a1 * scale, 92 a1 : a1 * scale,
92 a2 : a2 * scale}; 93 a2 : a2 * scale};
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
359 "bandpass": "Bandpass filter", 360 "bandpass": "Bandpass filter",
360 "lowshelf": "Lowshelf filter", 361 "lowshelf": "Lowshelf filter",
361 "highshelf": "Highshelf filter", 362 "highshelf": "Highshelf filter",
362 "peaking": "Peaking filter", 363 "peaking": "Peaking filter",
363 "notch": "Notch filter", 364 "notch": "Notch filter",
364 "allpass": "Allpass filter"}; 365 "allpass": "Allpass filter"};
365 366
366 function createFilter(filterType, freq, q, gain) { 367 function createFilter(filterType, freq, q, gain) {
367 return filterCreatorFunction[filterType](freq, q, gain); 368 return filterCreatorFunction[filterType](freq, q, gain);
368 } 369 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698