| 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 |