bug 1024182 test normalization of convolution buffers via response concatenation r?dminor draft
authorKarl Tomlinson <karlt+@karlt.net>
Wed, 16 Aug 2017 12:55:16 +1200
changeset 649733 b04b6cbcdd201d65abcbcf5fc1185ec0d780da01
parent 645137 7f323e9a911b8c348b235196c2a59084d0569620
child 727166 91cefec32eafd501d4b1b75ee1bb34a47657e56a
push id75126
push userktomlinson@mozilla.com
push dateMon, 21 Aug 2017 07:26:34 +0000
reviewersdminor
bugs1024182
milestone57.0a1
bug 1024182 test normalization of convolution buffers via response concatenation r?dminor MozReview-Commit-ID: AktlZvTXvWn
dom/media/webaudio/test/mochitest.ini
dom/media/webaudio/test/test_convolverNodeNormalization.html
--- a/dom/media/webaudio/test/mochitest.ini
+++ b/dom/media/webaudio/test/mochitest.ini
@@ -107,16 +107,17 @@ skip-if = toolkit == 'android' # bug 105
 [test_channelSplitterNode.html]
 [test_channelSplitterNodeWithVolume.html]
 skip-if = (android_version == '18' && debug) # bug 1158417
 [test_convolverNode.html]
 [test_convolverNode_mono_mono.html]
 [test_convolverNodeChannelCount.html]
 [test_convolverNodeDelay.html]
 [test_convolverNodeFiniteInfluence.html]
+[test_convolverNodeNormalization.html]
 [test_convolverNodePassThrough.html]
 [test_convolverNodeWithGain.html]
 [test_currentTime.html]
 [test_decodeAudioDataOnDetachedBuffer.html]
 [test_decodeAudioDataPromise.html]
 [test_decodeMultichannel.html]
 [test_decodeOpusTail.html]
 [test_delayNode.html]
new file mode 100644
--- /dev/null
+++ b/dom/media/webaudio/test/test_convolverNodeNormalization.html
@@ -0,0 +1,83 @@
+<!DOCTYPE html>
+<title>Test normalization of convolution buffers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+// Constants from
+// https://www.w3.org/TR/2015/WD-webaudio-20151208/#widl-ConvolverNode-normalize
+const GainCalibration = 0.00125;
+const GainCalibrationSampleRate = 44100;
+
+const sampleRate = GainCalibrationSampleRate;
+const LENGTH = 12800;
+// tolerate 16-bit math.
+const EPSILON = 1.0 / Math.pow(2, 15);
+
+function test_normalization_via_response_concat(delayIndex)
+{
+  var context = new OfflineAudioContext(1, LENGTH, sampleRate);
+
+  var impulse = context.createBuffer(1, 1, sampleRate);
+  impulse.getChannelData(0)[0] = 1.0;
+  var source = context.createBufferSource();
+  source.buffer = impulse;
+  source.start(0);
+
+  // Construct a set of adjacent responses in such a way that, when each is
+  // convolved with the impulse, they can be merged to produce a constant.
+
+  // The 5/4 ratio provides a range of lengths with different offsets within
+  // blocks.
+  var i = 0;
+  for (var responseEnd = 1;
+       i < LENGTH;
+       responseEnd = Math.floor((5 * responseEnd) / 4) + 1) {
+    var responseBuffer = context.createBuffer(1, responseEnd, sampleRate);
+    var response = responseBuffer.getChannelData(0);
+    var responseStart = i;
+    // The values in the response should be normalized, and so the output
+    // should not be dependent on the value.  Pick a changing value to test
+    // this.
+    var value = responseStart + 1;
+    for (; i < responseEnd; ++i) {
+      response[i] = value;
+    }
+    var convolver = context.createConvolver();
+    convolver.normalize = true;
+    convolver.buffer = responseBuffer;
+    convolver.connect(context.destination);
+    // Undo the normalization calibration by scaling the impulse so as to
+    // expect unit pulse output from the convolver.
+    var gain = context.createGain();
+    gain.gain.value =
+      Math.sqrt((responseEnd - responseStart) / responseEnd) / GainCalibration;
+    gain.connect(convolver);
+    source.connect(gain);
+  }
+
+  return context.startRendering().
+    then((buffer) => {
+      var output = buffer.getChannelData(0);
+      var max = output[0];
+      var maxIndex = 0;
+      var min = max;
+      var minIndex = 0;
+      for (var i = 1; i < buffer.length; ++i) {
+        if (output[i] > max) {
+          max = output[i];
+          maxIndex = i;
+        } else if (output[i] < min) {
+          min = output[i];
+          minIndex = i;
+        }
+      }
+      assert_approx_equals(output[maxIndex], 1.0, EPSILON,
+                           "max output at " + maxIndex);
+      assert_approx_equals(output[minIndex], 1.0, EPSILON,
+                           "min output at " + minIndex);
+    });
+}
+
+promise_test(test_normalization_via_response_concat,
+             "via response concatenation");
+</script>