зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1265408 - Avoid complex division in getFrequencyResponse; r=padenot
Using the division operator on std::complex values fails on our linux64 AWS test machines, yielding infinities and NaNs for valid inputs. Presumably this could affect machines in the wild as well. This patch removes the use of the division operator and replaces it with real operations. MozReview-Commit-ID: 4s7xUf9ja0F --HG-- extra : rebase_source : 9c1946c812be78aa25845402866795655bfc9af1 extra : source : 4dd3a54d766d9960319f6356064ccdd9d3feda88
This commit is contained in:
Родитель
231c8ebb0a
Коммит
7c5f125b1c
|
@ -457,7 +457,15 @@ void Biquad::getFrequencyResponse(int nFrequencies,
|
|||
Complex z = Complex(cos(omega), sin(omega));
|
||||
Complex numerator = b0 + (b1 + b2 * z) * z;
|
||||
Complex denominator = Complex(1, 0) + (a1 + a2 * z) * z;
|
||||
Complex response = numerator / denominator;
|
||||
// Strangely enough, using complex division:
|
||||
// e.g. Complex response = numerator / denominator;
|
||||
// fails on our test machines, yielding infinities and NaNs, so we do
|
||||
// things the long way here.
|
||||
double n = norm(denominator);
|
||||
double r = (real(numerator)*real(denominator) + imag(numerator)*imag(denominator)) / n;
|
||||
double i = (imag(numerator)*real(denominator) - real(numerator)*imag(denominator)) / n;
|
||||
std::complex<double> response = std::complex<double>(r, i);
|
||||
|
||||
magResponse[k] = static_cast<float>(abs(response));
|
||||
phaseResponse[k] = static_cast<float>(atan2(imag(response), real(response)));
|
||||
}
|
||||
|
|
|
@ -129,7 +129,15 @@ void IIRFilter::getFrequencyResponse(int nFrequencies, const float* frequency, f
|
|||
|
||||
std::complex<double> numerator = evaluatePolynomial(m_feedforward->Elements(), zRecip, m_feedforward->Length() - 1);
|
||||
std::complex<double> denominator = evaluatePolynomial(m_feedback->Elements(), zRecip, m_feedback->Length() - 1);
|
||||
std::complex<double> response = numerator / denominator;
|
||||
// Strangely enough, using complex division:
|
||||
// e.g. Complex response = numerator / denominator;
|
||||
// fails on our test machines, yielding infinities and NaNs, so we do
|
||||
// things the long way here.
|
||||
double n = norm(denominator);
|
||||
double r = (real(numerator)*real(denominator) + imag(numerator)*imag(denominator)) / n;
|
||||
double i = (imag(numerator)*real(denominator) - real(numerator)*imag(denominator)) / n;
|
||||
std::complex<double> response = std::complex<double>(r, i);
|
||||
|
||||
magResponse[k] = static_cast<float>(abs(response));
|
||||
phaseResponse[k] = static_cast<float>(atan2(imag(response), real(response)));
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче