Bug 1489338 [wpt PR 12887] - Slightly improve AudioBuffer resampling, a=testonly
authorRaymond Toy <rtoy@chromium.org>
Mon, 10 Sep 2018 18:15:50 +0000
changeset 435992 b3addb97e3e5ca4a7700c584c290d92ed8ac7277
parent 435991 8dc164ae68307016777cb9d82ca2fd8aa5f3d6bd
child 435993 b529794168a2bd96e3aba7c600a3d14eb8a48b9f
push id34625
push userdvarga@mozilla.com
push dateThu, 13 Sep 2018 02:31:40 +0000
treeherdermozilla-central@51e9e9660b3e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstestonly
bugs1489338, 12887, 881119, 1211910, 589529
milestone64.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1489338 [wpt PR 12887] - Slightly improve AudioBuffer resampling, a=testonly Automatic update from web-platform-testsSlightly improve AudioBuffer resampling Use simple linear extrapolation to resample the data when we reach the end of the buffer. Previously, the last sample would just be repeated enough times. Manually verified that the test passes on Firefox (nightly) and fails on Chrome without this CL. Bug: 881119 Test: the-audiobuffersourcenode-interface/buffer-resampling.html Change-Id: I1eb6ee089aa5477e03ff7184eb974f769b739528 Reviewed-on: https://chromium-review.googlesource.com/1211910 Commit-Queue: Raymond Toy <rtoy@chromium.org> Reviewed-by: Hongchan Choi <hongchan@chromium.org> Cr-Commit-Position: refs/heads/master@{#589529} -- wpt-commits: 8764370989723f3166cb8aeee5506e93833aa146 wpt-pr: 12887
testing/web-platform/meta/MANIFEST.json
testing/web-platform/tests/webaudio/the-audio-api/the-audiobuffersourcenode-interface/buffer-resampling.html
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -399718,16 +399718,22 @@
     ]
    ],
    "webaudio/the-audio-api/the-audiobuffersourcenode-interface/audiosource-time-limits.html": [
     [
      "/webaudio/the-audio-api/the-audiobuffersourcenode-interface/audiosource-time-limits.html",
      {}
     ]
    ],
+   "webaudio/the-audio-api/the-audiobuffersourcenode-interface/buffer-resampling.html": [
+    [
+     "/webaudio/the-audio-api/the-audiobuffersourcenode-interface/buffer-resampling.html",
+     {}
+    ]
+   ],
    "webaudio/the-audio-api/the-audiobuffersourcenode-interface/ctor-audiobuffersource.html": [
     [
      "/webaudio/the-audio-api/the-audiobuffersourcenode-interface/ctor-audiobuffersource.html",
      {}
     ]
    ],
    "webaudio/the-audio-api/the-audiobuffersourcenode-interface/note-grain-on-play.html": [
     [
@@ -655951,16 +655957,20 @@
   "webaudio/the-audio-api/the-audiobuffersourcenode-interface/audiosource-onended.html": [
    "20ef4a1c6381ffddd73f097de838dfe110b0e4e3",
    "testharness"
   ],
   "webaudio/the-audio-api/the-audiobuffersourcenode-interface/audiosource-time-limits.html": [
    "3ac9c05938c2cac600f548ee796aedc48d470e63",
    "testharness"
   ],
+  "webaudio/the-audio-api/the-audiobuffersourcenode-interface/buffer-resampling.html": [
+   "c181ceb8e0fad83067e11ec8aefe70f79ccf071c",
+   "testharness"
+  ],
   "webaudio/the-audio-api/the-audiobuffersourcenode-interface/ctor-audiobuffersource.html": [
    "c1c3203451e62587b1aa864e85c63617c36c2a3d",
    "testharness"
   ],
   "webaudio/the-audio-api/the-audiobuffersourcenode-interface/note-grain-on-play.html": [
    "37c4462addb675dfe0635e23e8485710b32542df",
    "testharness"
   ],
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-audiobuffersourcenode-interface/buffer-resampling.html
@@ -0,0 +1,101 @@
+<!doctype html>
+<html>
+  <head>
+    <title>Test Extrapolation at end of AudibBuffer in an AudioBufferSourceNode</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/webaudio/resources/audit-util.js"></script>
+    <script src="/webaudio/resources/audit.js"></script>
+  </head>
+  <body>
+    <script>
+      let audit = Audit.createTaskRunner();
+
+      const sampleRate = 48000;
+
+      // For testing we only need a few render quanta.
+      const renderSamples = 512
+
+      // Sample rate for our buffers.  This is the lowest sample rate that is
+      // required to be supported.
+      const bufferRate = 8000;
+
+      // Number of samples in each AudioBuffer; this is fairly arbitrary but
+      // should be less than a render quantum.
+      const bufferLength = 30;
+
+      // Frequency of the sine wave for testing.
+      const frequency = 440;
+
+      audit.define(
+          {
+            label: 'interpolate',
+            description: 'Interpolation of AudioBuffers to context sample rate'
+          },
+          (task, should) => {
+            // The first channel is for the interpolated signal, and the second
+            // channel is for the reference signal from an oscillator.
+            let context = new OfflineAudioContext({
+              numberOfChannels: 2,
+              length: renderSamples,
+              sampleRate: sampleRate
+            });
+
+            let merger = new ChannelMergerNode(
+                context, {numberOfChannels: context.destination.channelCount});
+            merger.connect(context.destination);
+
+            // Create a set of AudioBuffers which are samples from a pure sine
+            // wave with frequency |frequency|.
+            const nBuffers = Math.floor(context.length / bufferLength);
+            const omega = 2 * Math.PI * frequency / bufferRate;
+
+            let frameNumber = 0;
+            let startTime = 0;
+
+            for (let k = 0; k < nBuffers; ++k) {
+              //          let buffer = context.createBuffer(1, bufferLength,
+              //          bufferRate);
+              let buffer = new AudioBuffer(
+                  {length: bufferLength, sampleRate: bufferRate});
+              let data = buffer.getChannelData(0);
+              for (let n = 0; n < bufferLength; ++n) {
+                data[n] = Math.sin(omega * frameNumber);
+                ++frameNumber;
+              }
+              // Create a source using this buffer and start it at the end of
+              // the previous buffer.
+              let src = new AudioBufferSourceNode(context, {buffer: buffer});
+
+              src.connect(merger, 0, 0);
+              src.start(startTime);
+              startTime += buffer.duration;
+            }
+
+            // Create the reference sine signal using an oscillator.
+            let osc = new OscillatorNode(
+                context, {type: 'sine', frequency: frequency});
+            osc.connect(merger, 0, 1);
+            osc.start(0);
+
+            context.startRendering()
+                .then(audioBuffer => {
+                  let actual = audioBuffer.getChannelData(0);
+                  let expected = audioBuffer.getChannelData(1);
+
+                  should(actual, 'Interpolated sine wave')
+                      .beCloseToArray(expected, {absoluteThreshold: 9.0348e-2});
+
+                  // Compute SNR between them.
+                  let snr = 10 * Math.log10(computeSNR(actual, expected));
+
+                  should(snr, `SNR (${snr.toPrecision(4)} dB)`)
+                      .beGreaterThanOrEqualTo(37.17);
+                })
+                .then(() => task.done());
+          });
+
+      audit.run();
+    </script>
+  </body>
+</html>