| 445 | } |
| 446 | |
| 447 | void Biquad::getFrequencyResponse(size_t nFrequencies, |
| 448 | const float * frequency, |
| 449 | float * magResponse, |
| 450 | float * phaseResponse) |
| 451 | { |
| 452 | // Evaluate the Z-transform of the filter at given normalized |
| 453 | // frequency from 0 to 1. (1 corresponds to the Nyquist |
| 454 | // frequency.) |
| 455 | // |
| 456 | // The z-transform of the filter is |
| 457 | // |
| 458 | // H(z) = (b0 + b1*z^(-1) + b2*z^(-2))/(1 + a1*z^(-1) + a2*z^(-2)) |
| 459 | // |
| 460 | // Evaluate as |
| 461 | // |
| 462 | // b0 + (b1 + b2*z1)*z1 |
| 463 | // -------------------- |
| 464 | // 1 + (a1 + a2*z1)*z1 |
| 465 | // |
| 466 | // with z1 = 1/z and z = exp(j*pi*frequency). Hence z1 = exp(-j*pi*frequency) |
| 467 | |
| 468 | // Make local copies of the coefficients as a micro-optimization. |
| 469 | double b0 = m_b0; |
| 470 | double b1 = m_b1; |
| 471 | double b2 = m_b2; |
| 472 | double a1 = m_a1; |
| 473 | double a2 = m_a2; |
| 474 | |
| 475 | for (size_t k = 0; k < nFrequencies; ++k) |
| 476 | { |
| 477 | double omega = -static_cast<double>(LAB_PI) * frequency[k]; |
| 478 | complex<double> z = complex<double>(cos(omega), sin(omega)); |
| 479 | complex<double> numerator = b0 + (b1 + b2 * z) * z; |
| 480 | complex<double> denominator = complex<double>(1, 0) + (a1 + a2 * z) * z; |
| 481 | complex<double> response = numerator / denominator; |
| 482 | magResponse[k] = static_cast<float>(abs(response)); |
| 483 | phaseResponse[k] = static_cast<float>(atan2(imag(response), real(response))); |
| 484 | } |
| 485 | } |
| 486 | |
| 487 | } // namespace lab |
nothing calls this directly
no outgoing calls
no test coverage detected