Bug 1265408 - Avoid subnormals in IIRFilter; r=karlt draft
authorDan Minor <dminor@mozilla.com>
Mon, 30 May 2016 05:36:11 -0400
changeset 375224 07e566f903b8747f97ba15d84662f14e430f546b
parent 375223 4dc066366e54ce6100dd2672966f5d61d859b693
child 375225 f52001816a4b507a44c755ad1fa5e10b8a1e7986
child 375233 e943d454220dcdf02fbe976299ffc43f6c2a1fe9
push id20195
push userdminor@mozilla.com
push dateFri, 03 Jun 2016 18:18:51 +0000
reviewerskarlt
bugs1265408
milestone49.0a1
Bug 1265408 - Avoid subnormals in IIRFilter; r=karlt MozReview-Commit-ID: F4NUE8834tM
dom/media/webaudio/blink/Biquad.cpp
dom/media/webaudio/blink/IIRFilter.cpp
--- a/dom/media/webaudio/blink/Biquad.cpp
+++ b/dom/media/webaudio/blink/Biquad.cpp
@@ -71,16 +71,17 @@ void Biquad::process(const float* source
         x2 = x1;
         x1 = x;
         y2 = y1;
         y1 = y;
     }
 
     // Avoid introducing a stream of subnormals when input is silent and the
     // tail approaches zero.
+    // TODO: Remove this code when Bug 1157635 is fixed.
     if (x1 == 0.0 && x2 == 0.0 && (y1 != 0.0 || y2 != 0.0) &&
         fabs(y1) < FLT_MIN && fabs(y2) < FLT_MIN) {
       // Flush future values to zero (until there is new input).
       y1 = y2 = 0.0;
       // Flush calculated values.
       for (int i = framesToProcess; i-- && fabsf(destP[i]) < FLT_MIN; ) {
         destP[i] = 0.0f;
       }
--- a/dom/media/webaudio/blink/IIRFilter.cpp
+++ b/dom/media/webaudio/blink/IIRFilter.cpp
@@ -93,17 +93,23 @@ void IIRFilter::process(const float* sou
             yn -= feedback[k] * yBuffer[(m_bufferIndex - k) & (kBufferLength - 1)];
 
         // Save the current input and output values in the memory buffers for the next output.
         m_xBuffer[m_bufferIndex] = sourceP[n];
         m_yBuffer[m_bufferIndex] = yn;
 
         m_bufferIndex = (m_bufferIndex + 1) & (kBufferLength - 1);
 
-        destP[n] = yn;
+        // Avoid introducing a stream of subnormals
+        // TODO: Remove this code when Bug 1157635 is fixed.
+        if (fabs(yn) >= FLT_MIN) {
+            destP[n] = yn;
+        } else {
+            destP[n] = 0.0;
+        }
     }
 }
 
 void IIRFilter::getFrequencyResponse(int nFrequencies, const float* frequency, float* magResponse, float* phaseResponse)
 {
     // Evaluate the z-transform of the filter at the given normalized frequencies from 0 to 1. (One
     // corresponds to the Nyquist frequency.)
     //