Bug 1081819 - Add mochitest for piping WebAudio in and out of PeerConnection. r=jesup,padenot
☠☠ backed out by 22a0f682dfd8 ☠ ☠
authorAndreas Pehrson <pehrsons@gmail.com>
Mon, 02 Mar 2015 18:07:20 +0800
changeset 231888 6f6d897fc65c387bec4ade5cd7511d41d1e19cee
parent 231887 796e84a25f163f691e0b44ad2359ff3660303eb0
child 231889 b06982ec6797d8351b9ec8bc6103cbb599acd5e8
push id28362
push userryanvm@gmail.com
push dateWed, 04 Mar 2015 21:35:51 +0000
treeherdermozilla-central@56492f7244a9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjesup, padenot
bugs1081819
milestone39.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 1081819 - Add mochitest for piping WebAudio in and out of PeerConnection. r=jesup,padenot
dom/media/tests/mochitest/mochitest.ini
dom/media/tests/mochitest/test_peerConnection_webAudio.html
--- a/dom/media/tests/mochitest/mochitest.ini
+++ b/dom/media/tests/mochitest/mochitest.ini
@@ -173,11 +173,13 @@ skip-if = toolkit == 'gonk' # b2g (Bug 1
 [test_peerConnection_addSecondVideoStreamNoBundle.html]
 skip-if = toolkit == 'gonk' # b2g (Bug 1059867)
 [test_peerConnection_removeThenAddVideoTrackNoBundle.html]
 skip-if = toolkit == 'gonk' # b2g (Bug 1059867)
 [test_peerConnection_addDataChannel.html]
 skip-if = toolkit == 'gonk' # b2g (Bug 1059867)
 [test_peerConnection_addDataChannelNoBundle.html]
 skip-if = toolkit == 'gonk' # b2g (Bug 1059867)
+[test_peerConnection_webAudio.html]
+skip-if = toolkit == 'gonk' # b2g (Bug 1059867)
 
 # Bug 950317: Hack for making a cleanup hook after finishing all WebRTC cases
 [test_zmedia_cleanup.html]
new file mode 100644
--- /dev/null
+++ b/dom/media/tests/mochitest/test_peerConnection_webAudio.html
@@ -0,0 +1,97 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <script type="application/javascript" src="pc.js"></script>
+</head>
+<body>
+<pre id="test">
+<script type="application/javascript;version=1.8">
+createHTML({
+  bug: "1081819",
+  title: "WebAudio on both input and output side of peerconnection"
+});
+
+// This tests WebAudio as input to a PeerConnection and a PeerConnection as
+// input to WebAudio. This is done by piping a 700Hz oscillator through an
+// analyser on the input side, the PeerConnection, and an analyser on the
+// output side. We then sanity check the audio by comparing the frequency domain
+// data from both analysers.
+
+runNetworkTest(function() {
+  var test = new PeerConnectionTest();
+
+  var audioContext = new AudioContext();
+  var inputAnalyser;
+  var outputAnalyser;
+
+  test.setMediaConstraints([{audio: true}], []);
+  test.chain.replace("PC_LOCAL_GUM", [
+    function PC_LOCAL_WEBAUDIO_SOURCE(test) {
+      var oscillator = audioContext.createOscillator();
+      oscillator.type = 'sine';
+      oscillator.frequency.value = 700;
+      oscillator.start();
+      inputAnalyser = audioContext.createAnalyser();
+      var dest = audioContext.createMediaStreamDestination();
+
+      oscillator.connect(inputAnalyser);
+      inputAnalyser.connect(dest);
+      test.pcLocal.attachMedia(dest.stream, 'audio', 'local');
+
+      return Promise.resolve();
+    }
+  ]);
+  test.chain.insertBefore("PC_REMOTE_SETUP_ADDSTREAM_HANDLER", [
+    function PC_REMOTE_REPLACE_ATTACHMEDIA(test) {
+      var realAttachMedia = test.pcRemote.attachMedia.bind(test.pcRemote);
+      test.pcRemote.attachMedia = function(stream, type, side) {
+        var source = audioContext.createMediaStreamSource(stream);
+        outputAnalyser = audioContext.createAnalyser();
+        var dest = audioContext.createMediaStreamDestination();
+
+        source.connect(outputAnalyser);
+        outputAnalyser.connect(dest);
+        realAttachMedia(dest.stream, type, side);
+      };
+      return Promise.resolve();
+  }]);
+  test.chain.append([
+    function CHECK_AUDIO_FLOW(test) {
+      var inputData = new Uint8Array(inputAnalyser.frequencyBinCount);
+      inputAnalyser.getByteFrequencyData(inputData);
+
+      var outputData = new Uint8Array(outputAnalyser.frequencyBinCount);
+      outputAnalyser.getByteFrequencyData(outputData);
+
+      is(inputData.length, outputData.length, "Equally sized datasets");
+      var numChecks = 0;
+      var sanityCheckFrequencyValue = function(i, input, output) {
+        // This is for sanity check only. The audio encoding applied on the
+        // output will cause some fairly large deviations from the input around
+        // the oscillator's frequency. However, the input analyser will reach
+        // its max value of 255 for multiple indices, so allowing a deviation
+        // of 50 for these is fine.
+        if (input < 200 && output < 200) {
+          // Save us some log output by skipping when both input and output
+          // are sufficiently low. 200 is a bit higher than preferred, but on
+          // Android we've seen the output being quite high (100-150) when
+          // input is fairly low (0-50), i.e., on frequencies neighboring 700Hz.
+          return 0;
+        }
+        ok(Math.abs(input - output) < 50,
+           "Sane audio frequency values at index " + i + "/" + inputData.length +
+           ", input=" + input + ", output=" + output);
+        return 1;
+      }
+      for (i = 0; i < inputData.length; ++i) {
+        numChecks += sanityCheckFrequencyValue(i, inputData[i], outputData[i]);
+      }
+      isnot(numChecks, 0, "Should have had some non-zero values analyzed");
+      return Promise.resolve();
+    }]);
+  test.run();
+});
+</script>
+</pre>
+</body>
+</html>