webrtc_test_audio.js revision a02191e04bc25c4935f804f2c080ae28663d096d
1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// Audio test utilities.
6
7// GetStats reports audio output energy in the [0, 32768] range.
8var MAX_AUDIO_OUTPUT_ENERGY = 32768;
9
10// Gathers |numSamples| samples at |frequency| number of times per second and
11// calls back |callback| with an array with numbers in the [0, 32768] range.
12function gatherAudioLevelSamples(peerConnection, numSamples, frequency,
13                                 callback) {
14  console.log('Gathering ' + numSamples + ' audio samples...');
15  var audioLevelSamples = []
16  var gatherSamples = setInterval(function() {
17    peerConnection.getStats(function(response) {
18      audioLevelSamples.push(getAudioLevelFromStats_(response));
19      if (audioLevelSamples.length == numSamples) {
20        console.log('Gathered all samples.');
21        clearInterval(gatherSamples);
22        callback(audioLevelSamples);
23      }
24    });
25  }, 1000 / frequency);
26}
27
28// Tries to identify the beep-every-half-second signal generated by the fake
29// audio device in media/video/capture/fake_video_capture_device.cc. Fails the
30// test if we can't see a signal. The samples should have been gathered over at
31// least two seconds since we expect to see at least three "peaks" in there
32// (we should see either 3 or 4 depending on how things line up). We are quite
33// generous in what we consider to be a peak since Android devices in particular
34// seem to be flake-prone (they often don't reach anywhere near the max level
35// for some reason).
36function verifyAudioIsPlaying(samples) {
37  var numPeaks = 0;
38  var threshold = MAX_AUDIO_OUTPUT_ENERGY * 0.6;
39  var currentlyOverThreshold = false;
40
41  // Detect when we have been been over the threshold and is going back again
42  // (i.e. count peaks). We should see about one peak per second.
43  for (var i = 0; i < samples.length; ++i) {
44    if (currentlyOverThreshold && samples[i] < threshold)
45      numPeaks++;
46    currentlyOverThreshold = samples[i] >= threshold;
47  }
48
49  console.log('Number of peaks identified: ' + numPeaks);
50
51  if (numPeaks < 2)
52    failTest('Expected to see at least two peaks in audio signal, got ' +
53        numPeaks + '. Dumping samples for analysis: "' + samples + '"');
54}
55
56// If silent (like when muted), we should get very near zero audio level.
57function verifyIsSilent(samples) {
58  var average = 0;
59  for (var i = 0; i < samples.length; ++i)
60    average += samples[i] / samples.length;
61
62  console.log('Average audio level: ' + average);
63  if (average > 500)
64    failTest('Expected silence, but avg audio level was ' + average);
65}
66
67/**
68 * @private
69 */
70function getAudioLevelFromStats_(response) {
71  var reports = response.result();
72  var audioOutputLevels = [];
73  for (var i = 0; i < reports.length; ++i) {
74    var report = reports[i];
75    if (report.names().indexOf('audioOutputLevel') != -1) {
76      audioOutputLevels.push(report.stat('audioOutputLevel'));
77    }
78  }
79  // Should only be one audio level reported, otherwise we get confused.
80  assertEquals(1, audioOutputLevels.length);
81
82  return audioOutputLevels[0];
83}
84