OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2010 Google Inc. All rights reserved. | 2 * Copyright (C) 2010 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
248 // Limit cutoff to 0 to 1. | 248 // Limit cutoff to 0 to 1. |
249 cutoff = clampTo(cutoff, 0.0, 1.0); | 249 cutoff = clampTo(cutoff, 0.0, 1.0); |
250 | 250 |
251 if (cutoff == 1) { | 251 if (cutoff == 1) { |
252 // When cutoff is 1, the z-transform is 1. | 252 // When cutoff is 1, the z-transform is 1. |
253 setNormalizedCoefficients(index, | 253 setNormalizedCoefficients(index, |
254 1, 0, 0, | 254 1, 0, 0, |
255 1, 0, 0); | 255 1, 0, 0); |
256 } else if (cutoff > 0) { | 256 } else if (cutoff > 0) { |
257 // Compute biquad coefficients for lowpass filter | 257 // Compute biquad coefficients for lowpass filter |
258 resonance = std::max(0.0, resonance); // can't go negative | |
259 double g = pow(10.0, 0.05 * resonance); | |
260 double d = sqrt((4 - sqrt(16 - 16 / (g * g))) / 2); | |
261 | 258 |
| 259 resonance = pow(10, resonance / 20); |
262 double theta = piDouble * cutoff; | 260 double theta = piDouble * cutoff; |
263 double sn = 0.5 * d * sin(theta); | 261 double alpha = sin(theta) / (2 * resonance); |
264 double beta = 0.5 * (1 - sn) / (1 + sn); | 262 double cosw = cos(theta); |
265 double gamma = (0.5 + beta) * cos(theta); | 263 double beta = (1 - cosw) / 2; |
266 double alpha = 0.25 * (0.5 + beta - gamma); | |
267 | 264 |
268 double b0 = 2 * alpha; | 265 double b0 = beta; |
269 double b1 = 2 * 2 * alpha; | 266 double b1 = 2 * beta; |
270 double b2 = 2 * alpha; | 267 double b2 = beta; |
271 double a1 = 2 * -gamma; | |
272 double a2 = 2 * beta; | |
273 | 268 |
274 setNormalizedCoefficients(index, b0, b1, b2, 1, a1, a2); | 269 double a0 = 1 + alpha; |
| 270 double a1 = -2 * cosw; |
| 271 double a2 = 1 - alpha; |
| 272 |
| 273 setNormalizedCoefficients(index, b0, b1, b2, a0, a1, a2); |
275 } else { | 274 } else { |
276 // When cutoff is zero, nothing gets through the filter, so set | 275 // When cutoff is zero, nothing gets through the filter, so set |
277 // coefficients up correctly. | 276 // coefficients up correctly. |
278 setNormalizedCoefficients(index, | 277 setNormalizedCoefficients(index, |
279 0, 0, 0, | 278 0, 0, 0, |
280 1, 0, 0); | 279 1, 0, 0); |
281 } | 280 } |
282 } | 281 } |
283 | 282 |
284 void Biquad::setHighpassParams(int index, double cutoff, double resonance) | 283 void Biquad::setHighpassParams(int index, double cutoff, double resonance) |
285 { | 284 { |
286 // Limit cutoff to 0 to 1. | 285 // Limit cutoff to 0 to 1. |
287 cutoff = clampTo(cutoff, 0.0, 1.0); | 286 cutoff = clampTo(cutoff, 0.0, 1.0); |
288 | 287 |
289 if (cutoff == 1) { | 288 if (cutoff == 1) { |
290 // The z-transform is 0. | 289 // The z-transform is 0. |
291 setNormalizedCoefficients(index, | 290 setNormalizedCoefficients(index, |
292 0, 0, 0, | 291 0, 0, 0, |
293 1, 0, 0); | 292 1, 0, 0); |
294 } else if (cutoff > 0) { | 293 } else if (cutoff > 0) { |
295 // Compute biquad coefficients for highpass filter | 294 // Compute biquad coefficients for highpass filter |
296 resonance = std::max(0.0, resonance); // can't go negative | |
297 double g = pow(10.0, 0.05 * resonance); | |
298 double d = sqrt((4 - sqrt(16 - 16 / (g * g))) / 2); | |
299 | 295 |
| 296 resonance = pow(10, resonance / 20); |
300 double theta = piDouble * cutoff; | 297 double theta = piDouble * cutoff; |
301 double sn = 0.5 * d * sin(theta); | 298 double alpha = sin(theta) / (2 * resonance); |
302 double beta = 0.5 * (1 - sn) / (1 + sn); | 299 double cosw = cos(theta); |
303 double gamma = (0.5 + beta) * cos(theta); | 300 double beta = (1 + cosw) / 2; |
304 double alpha = 0.25 * (0.5 + beta + gamma); | |
305 | 301 |
306 double b0 = 2 * alpha; | 302 double b0 = beta; |
307 double b1 = 2 * -2 * alpha; | 303 double b1 = -2 * beta; |
308 double b2 = 2 * alpha; | 304 double b2 = beta; |
309 double a1 = 2 * -gamma; | |
310 double a2 = 2 * beta; | |
311 | 305 |
312 setNormalizedCoefficients(index, b0, b1, b2, 1, a1, a2); | 306 double a0 = 1 + alpha; |
| 307 double a1 = -2 * cosw; |
| 308 double a2 = 1 - alpha; |
| 309 |
| 310 setNormalizedCoefficients(index, b0, b1, b2, a0, a1, a2); |
313 } else { | 311 } else { |
314 // When cutoff is zero, we need to be careful because the above | 312 // When cutoff is zero, we need to be careful because the above |
315 // gives a quadratic divided by the same quadratic, with poles | 313 // gives a quadratic divided by the same quadratic, with poles |
316 // and zeros on the unit circle in the same place. When cutoff | 314 // and zeros on the unit circle in the same place. When cutoff |
317 // is zero, the z-transform is 1. | 315 // is zero, the z-transform is 1. |
318 setNormalizedCoefficients(index, | 316 setNormalizedCoefficients(index, |
319 1, 0, 0, | 317 1, 0, 0, |
320 1, 0, 0); | 318 1, 0, 0); |
321 } | 319 } |
322 } | 320 } |
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
609 std::complex<double> denominator = | 607 std::complex<double> denominator = |
610 std::complex<double>(1, 0) + (a1 + a2 * z) * z; | 608 std::complex<double>(1, 0) + (a1 + a2 * z) * z; |
611 std::complex<double> response = numerator / denominator; | 609 std::complex<double> response = numerator / denominator; |
612 magResponse[k] = static_cast<float>(abs(response)); | 610 magResponse[k] = static_cast<float>(abs(response)); |
613 phaseResponse[k] = static_cast<float>(atan2(imag(response), real(respons
e))); | 611 phaseResponse[k] = static_cast<float>(atan2(imag(response), real(respons
e))); |
614 } | 612 } |
615 } | 613 } |
616 | 614 |
617 } // namespace blink | 615 } // namespace blink |
618 | 616 |
OLD | NEW |