Chromium Code Reviews| 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 19 matching lines...) Expand all Loading... | |
| 30 | 30 |
| 31 #if ENABLE(WEB_AUDIO) | 31 #if ENABLE(WEB_AUDIO) |
| 32 | 32 |
| 33 #include "platform/audio/Biquad.h" | 33 #include "platform/audio/Biquad.h" |
| 34 | 34 |
| 35 #include "platform/audio/AudioUtilities.h" | 35 #include "platform/audio/AudioUtilities.h" |
| 36 #include "platform/audio/DenormalDisabler.h" | 36 #include "platform/audio/DenormalDisabler.h" |
| 37 #include "wtf/MathExtras.h" | 37 #include "wtf/MathExtras.h" |
| 38 | 38 |
| 39 #include <algorithm> | 39 #include <algorithm> |
| 40 #include <complex> | |
|
Raymond Toy
2015/12/17 19:45:55
Why is <complex> needed now?
Daniel Bratell
2015/12/17 22:58:19
It should always have been there but luckily someo
| |
| 40 #include <stdio.h> | 41 #include <stdio.h> |
| 41 | 42 |
| 42 #if OS(MACOSX) | 43 #if OS(MACOSX) |
| 43 #include <Accelerate/Accelerate.h> | 44 #include <Accelerate/Accelerate.h> |
| 44 #endif | 45 #endif |
| 45 | 46 |
| 46 namespace blink { | 47 namespace blink { |
| 47 | 48 |
| 48 #if OS(MACOSX) | 49 #if OS(MACOSX) |
| 49 const int kBufferSize = 1024; | 50 const int kBufferSize = 1024; |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 268 ippsIIRGetStateSize64f_BiQuad_32f(1, &bufferSize); | 269 ippsIIRGetStateSize64f_BiQuad_32f(1, &bufferSize); |
| 269 ippsZero_8u(m_ippInternalBuffer, bufferSize); | 270 ippsZero_8u(m_ippInternalBuffer, bufferSize); |
| 270 | 271 |
| 271 #endif | 272 #endif |
| 272 m_x1 = m_x2 = m_y1 = m_y2 = 0; | 273 m_x1 = m_x2 = m_y1 = m_y2 = 0; |
| 273 } | 274 } |
| 274 | 275 |
| 275 void Biquad::setLowpassParams(int index, double cutoff, double resonance) | 276 void Biquad::setLowpassParams(int index, double cutoff, double resonance) |
| 276 { | 277 { |
| 277 // Limit cutoff to 0 to 1. | 278 // Limit cutoff to 0 to 1. |
| 278 cutoff = std::max(0.0, std::min(cutoff, 1.0)); | 279 cutoff = clampTo(cutoff, 0.0, 1.0); |
| 279 | 280 |
| 280 if (cutoff == 1) { | 281 if (cutoff == 1) { |
| 281 // When cutoff is 1, the z-transform is 1. | 282 // When cutoff is 1, the z-transform is 1. |
| 282 setNormalizedCoefficients(index, | 283 setNormalizedCoefficients(index, |
| 283 1, 0, 0, | 284 1, 0, 0, |
| 284 1, 0, 0); | 285 1, 0, 0); |
| 285 } else if (cutoff > 0) { | 286 } else if (cutoff > 0) { |
| 286 // Compute biquad coefficients for lowpass filter | 287 // Compute biquad coefficients for lowpass filter |
| 287 resonance = std::max(0.0, resonance); // can't go negative | 288 resonance = std::max(0.0, resonance); // can't go negative |
| 288 double g = pow(10.0, 0.05 * resonance); | 289 double g = pow(10.0, 0.05 * resonance); |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 306 // coefficients up correctly. | 307 // coefficients up correctly. |
| 307 setNormalizedCoefficients(index, | 308 setNormalizedCoefficients(index, |
| 308 0, 0, 0, | 309 0, 0, 0, |
| 309 1, 0, 0); | 310 1, 0, 0); |
| 310 } | 311 } |
| 311 } | 312 } |
| 312 | 313 |
| 313 void Biquad::setHighpassParams(int index, double cutoff, double resonance) | 314 void Biquad::setHighpassParams(int index, double cutoff, double resonance) |
| 314 { | 315 { |
| 315 // Limit cutoff to 0 to 1. | 316 // Limit cutoff to 0 to 1. |
| 316 cutoff = std::max(0.0, std::min(cutoff, 1.0)); | 317 cutoff = clampTo(cutoff, 0.0, 1.0); |
| 317 | 318 |
| 318 if (cutoff == 1) { | 319 if (cutoff == 1) { |
| 319 // The z-transform is 0. | 320 // The z-transform is 0. |
| 320 setNormalizedCoefficients(index, | 321 setNormalizedCoefficients(index, |
| 321 0, 0, 0, | 322 0, 0, 0, |
| 322 1, 0, 0); | 323 1, 0, 0); |
| 323 } else if (cutoff > 0) { | 324 } else if (cutoff > 0) { |
| 324 // Compute biquad coefficients for highpass filter | 325 // Compute biquad coefficients for highpass filter |
| 325 resonance = std::max(0.0, resonance); // can't go negative | 326 resonance = std::max(0.0, resonance); // can't go negative |
| 326 double g = pow(10.0, 0.05 * resonance); | 327 double g = pow(10.0, 0.05 * resonance); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 370 taps[5] = m_a2[0]; | 371 taps[5] = m_a2[0]; |
| 371 m_biquadState = 0; | 372 m_biquadState = 0; |
| 372 | 373 |
| 373 ippsIIRInit64f_BiQuad_32f(&m_biquadState, taps, 1, 0, m_ippInternalBuffer); | 374 ippsIIRInit64f_BiQuad_32f(&m_biquadState, taps, 1, 0, m_ippInternalBuffer); |
| 374 #endif // USE(WEBAUDIO_IPP) | 375 #endif // USE(WEBAUDIO_IPP) |
| 375 } | 376 } |
| 376 | 377 |
| 377 void Biquad::setLowShelfParams(int index, double frequency, double dbGain) | 378 void Biquad::setLowShelfParams(int index, double frequency, double dbGain) |
| 378 { | 379 { |
| 379 // Clip frequencies to between 0 and 1, inclusive. | 380 // Clip frequencies to between 0 and 1, inclusive. |
| 380 frequency = std::max(0.0, std::min(frequency, 1.0)); | 381 frequency = clampTo(frequency, 0.0, 1.0); |
| 381 | 382 |
| 382 double A = pow(10.0, dbGain / 40); | 383 double A = pow(10.0, dbGain / 40); |
| 383 | 384 |
| 384 if (frequency == 1) { | 385 if (frequency == 1) { |
| 385 // The z-transform is a constant gain. | 386 // The z-transform is a constant gain. |
| 386 setNormalizedCoefficients(index, | 387 setNormalizedCoefficients(index, |
| 387 A * A, 0, 0, | 388 A * A, 0, 0, |
| 388 1, 0, 0); | 389 1, 0, 0); |
| 389 } else if (frequency > 0) { | 390 } else if (frequency > 0) { |
| 390 double w0 = piDouble * frequency; | 391 double w0 = piDouble * frequency; |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 407 // When frequency is 0, the z-transform is 1. | 408 // When frequency is 0, the z-transform is 1. |
| 408 setNormalizedCoefficients(index, | 409 setNormalizedCoefficients(index, |
| 409 1, 0, 0, | 410 1, 0, 0, |
| 410 1, 0, 0); | 411 1, 0, 0); |
| 411 } | 412 } |
| 412 } | 413 } |
| 413 | 414 |
| 414 void Biquad::setHighShelfParams(int index, double frequency, double dbGain) | 415 void Biquad::setHighShelfParams(int index, double frequency, double dbGain) |
| 415 { | 416 { |
| 416 // Clip frequencies to between 0 and 1, inclusive. | 417 // Clip frequencies to between 0 and 1, inclusive. |
| 417 frequency = std::max(0.0, std::min(frequency, 1.0)); | 418 frequency = clampTo(frequency, 0.0, 1.0); |
| 418 | 419 |
| 419 double A = pow(10.0, dbGain / 40); | 420 double A = pow(10.0, dbGain / 40); |
| 420 | 421 |
| 421 if (frequency == 1) { | 422 if (frequency == 1) { |
| 422 // The z-transform is 1. | 423 // The z-transform is 1. |
| 423 setNormalizedCoefficients(index, | 424 setNormalizedCoefficients(index, |
| 424 1, 0, 0, | 425 1, 0, 0, |
| 425 1, 0, 0); | 426 1, 0, 0); |
| 426 } else if (frequency > 0) { | 427 } else if (frequency > 0) { |
| 427 double w0 = piDouble * frequency; | 428 double w0 = piDouble * frequency; |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 446 // When frequency = 0, the filter is just a gain, A^2. | 447 // When frequency = 0, the filter is just a gain, A^2. |
| 447 setNormalizedCoefficients(index, | 448 setNormalizedCoefficients(index, |
| 448 A * A, 0, 0, | 449 A * A, 0, 0, |
| 449 1, 0, 0); | 450 1, 0, 0); |
| 450 } | 451 } |
| 451 } | 452 } |
| 452 | 453 |
| 453 void Biquad::setPeakingParams(int index, double frequency, double Q, double dbGa in) | 454 void Biquad::setPeakingParams(int index, double frequency, double Q, double dbGa in) |
| 454 { | 455 { |
| 455 // Clip frequencies to between 0 and 1, inclusive. | 456 // Clip frequencies to between 0 and 1, inclusive. |
| 456 frequency = std::max(0.0, std::min(frequency, 1.0)); | 457 frequency = clampTo(frequency, 0.0, 1.0); |
| 457 | 458 |
| 458 // Don't let Q go negative, which causes an unstable filter. | 459 // Don't let Q go negative, which causes an unstable filter. |
| 459 Q = std::max(0.0, Q); | 460 Q = std::max(0.0, Q); |
| 460 | 461 |
| 461 double A = pow(10.0, dbGain / 40); | 462 double A = pow(10.0, dbGain / 40); |
| 462 | 463 |
| 463 if (frequency > 0 && frequency < 1) { | 464 if (frequency > 0 && frequency < 1) { |
| 464 if (Q > 0) { | 465 if (Q > 0) { |
| 465 double w0 = piDouble * frequency; | 466 double w0 = piDouble * frequency; |
| 466 double alpha = sin(w0) / (2 * Q); | 467 double alpha = sin(w0) / (2 * Q); |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 488 // When frequency is 0 or 1, the z-transform is 1. | 489 // When frequency is 0 or 1, the z-transform is 1. |
| 489 setNormalizedCoefficients(index, | 490 setNormalizedCoefficients(index, |
| 490 1, 0, 0, | 491 1, 0, 0, |
| 491 1, 0, 0); | 492 1, 0, 0); |
| 492 } | 493 } |
| 493 } | 494 } |
| 494 | 495 |
| 495 void Biquad::setAllpassParams(int index, double frequency, double Q) | 496 void Biquad::setAllpassParams(int index, double frequency, double Q) |
| 496 { | 497 { |
| 497 // Clip frequencies to between 0 and 1, inclusive. | 498 // Clip frequencies to between 0 and 1, inclusive. |
| 498 frequency = std::max(0.0, std::min(frequency, 1.0)); | 499 frequency = clampTo(frequency, 0.0, 1.0); |
| 499 | 500 |
| 500 // Don't let Q go negative, which causes an unstable filter. | 501 // Don't let Q go negative, which causes an unstable filter. |
| 501 Q = std::max(0.0, Q); | 502 Q = std::max(0.0, Q); |
| 502 | 503 |
| 503 if (frequency > 0 && frequency < 1) { | 504 if (frequency > 0 && frequency < 1) { |
| 504 if (Q > 0) { | 505 if (Q > 0) { |
| 505 double w0 = piDouble * frequency; | 506 double w0 = piDouble * frequency; |
| 506 double alpha = sin(w0) / (2 * Q); | 507 double alpha = sin(w0) / (2 * Q); |
| 507 double k = cos(w0); | 508 double k = cos(w0); |
| 508 | 509 |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 528 // When frequency is 0 or 1, the z-transform is 1. | 529 // When frequency is 0 or 1, the z-transform is 1. |
| 529 setNormalizedCoefficients(index, | 530 setNormalizedCoefficients(index, |
| 530 1, 0, 0, | 531 1, 0, 0, |
| 531 1, 0, 0); | 532 1, 0, 0); |
| 532 } | 533 } |
| 533 } | 534 } |
| 534 | 535 |
| 535 void Biquad::setNotchParams(int index, double frequency, double Q) | 536 void Biquad::setNotchParams(int index, double frequency, double Q) |
| 536 { | 537 { |
| 537 // Clip frequencies to between 0 and 1, inclusive. | 538 // Clip frequencies to between 0 and 1, inclusive. |
| 538 frequency = std::max(0.0, std::min(frequency, 1.0)); | 539 frequency = clampTo(frequency, 0.0, 1.0); |
| 539 | 540 |
| 540 // Don't let Q go negative, which causes an unstable filter. | 541 // Don't let Q go negative, which causes an unstable filter. |
| 541 Q = std::max(0.0, Q); | 542 Q = std::max(0.0, Q); |
| 542 | 543 |
| 543 if (frequency > 0 && frequency < 1) { | 544 if (frequency > 0 && frequency < 1) { |
| 544 if (Q > 0) { | 545 if (Q > 0) { |
| 545 double w0 = piDouble * frequency; | 546 double w0 = piDouble * frequency; |
| 546 double alpha = sin(w0) / (2 * Q); | 547 double alpha = sin(w0) / (2 * Q); |
| 547 double k = cos(w0); | 548 double k = cos(w0); |
| 548 | 549 |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 652 std::complex<double>(1, 0) + (a1 + a2 * z) * z; | 653 std::complex<double>(1, 0) + (a1 + a2 * z) * z; |
| 653 std::complex<double> response = numerator / denominator; | 654 std::complex<double> response = numerator / denominator; |
| 654 magResponse[k] = static_cast<float>(abs(response)); | 655 magResponse[k] = static_cast<float>(abs(response)); |
| 655 phaseResponse[k] = static_cast<float>(atan2(imag(response), real(respons e))); | 656 phaseResponse[k] = static_cast<float>(atan2(imag(response), real(respons e))); |
| 656 } | 657 } |
| 657 } | 658 } |
| 658 | 659 |
| 659 } // namespace blink | 660 } // namespace blink |
| 660 | 661 |
| 661 #endif // ENABLE(WEB_AUDIO) | 662 #endif // ENABLE(WEB_AUDIO) |
| OLD | NEW |