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 648596 5da7e2c2a062ba2110dcab86f24b7a054722d544
parent 648595 3543061c2e4f672ab1f2066bab3f19183443dc5a
child 648597 442fcfdf9246941fb0e62c5577be45b9322c7062
push id74809
push userktomlinson@mozilla.com
push dateFri, 18 Aug 2017 01:10:01 +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,80 @@
+<!DOCTYPE html>
+<title>Test normalization of convolution buffers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+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[maxIndex], 1.0, EPSILON,
+                           "min output at " + minIndex);
+    });
+}
+
+promise_test(test_normalization_via_response_concat,
+             "via response concatenation");
+</script>