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:
Dan Minor 2016-05-12 09:15:18 -04:00
Родитель 231c8ebb0a
Коммит 7c5f125b1c
2 изменённых файлов: 21 добавлений и 5 удалений

Просмотреть файл

@ -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)));
}