Bug 1265408 - Avoid subnormals in IIRFilter; r=karlt
☠☠ backed out by 9870ee9198c8 ☠ ☠
authorDan Minor <dminor@mozilla.com>
Mon, 30 May 2016 05:36:11 -0400
changeset 325783 784521a9cc94ad399d1405ada007f06d255c6c29
parent 325782 9ab327850c5fc9e21b41a29d091ba35ee69e454e
child 325784 1b0ec5cf4d30e4f1d738f98cef1cfa5157c5822e
push id9858
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 14:37:10 +0000
treeherdermozilla-aurora@203106ef6cb6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
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.)
     //