Home | History | Annotate | Download | only in media
      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.
      8 var 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.
     12 function 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       audioOutputLevels = getAudioLevelFromStats_(response);
     19       if (audioOutputLevels.length == 0) {
     20         // The call probably isn't up yet.
     21         return;
     22       }
     23 
     24       // If more than one audio level is reported we get confused.
     25       assertEquals(1, audioOutputLevels.length);
     26       audioLevelSamples.push(audioOutputLevels[0]);
     27 
     28       if (audioLevelSamples.length == numSamples) {
     29         console.log('Gathered all samples.');
     30         clearInterval(gatherSamples);
     31         callback(audioLevelSamples);
     32       }
     33     });
     34   }, 1000 / frequency);
     35 }
     36 
     37 // Tries to identify the beep-every-half-second signal generated by the fake
     38 // audio device in media/video/capture/fake_video_capture_device.cc. Fails the
     39 // test if we can't see a signal. The samples should have been gathered over at
     40 // least two seconds since we expect to see at least three "peaks" in there
     41 // (we should see either 3 or 4 depending on how things line up).
     42 //
     43 // If |beLenient| is specified, we assume we're running on a slow device or
     44 // or under TSAN, and relax the checks quite a bit.
     45 function verifyAudioIsPlaying(samples, beLenient) {
     46   var numPeaks = 0;
     47   var threshold = MAX_AUDIO_OUTPUT_ENERGY * 0.7;
     48   if (beLenient)
     49     threshold = MAX_AUDIO_OUTPUT_ENERGY * 0.6;
     50   var currentlyOverThreshold = false;
     51 
     52   // Detect when we have been been over the threshold and is going back again
     53   // (i.e. count peaks). We should see about one peak per second.
     54   for (var i = 0; i < samples.length; ++i) {
     55     if (currentlyOverThreshold && samples[i] < threshold)
     56       numPeaks++;
     57     currentlyOverThreshold = samples[i] >= threshold;
     58   }
     59 
     60   console.log('Number of peaks identified: ' + numPeaks);
     61 
     62   var expectedPeaks = 2;
     63   if (beLenient)
     64     expectedPeaks = 1;
     65 
     66   if (numPeaks < expectedPeaks)
     67     failTest('Expected to see at least ' + expectedPeaks + ' peak(s) in ' +
     68         'audio signal, got ' + numPeaks + '. Dumping samples for analysis: "' +
     69         samples + '"');
     70 }
     71 
     72 // If silent (like when muted), we should get very near zero audio level.
     73 function verifyIsSilent(samples) {
     74   var average = 0;
     75   for (var i = 0; i < samples.length; ++i)
     76     average += samples[i] / samples.length;
     77 
     78   console.log('Average audio level: ' + average);
     79   if (average > 500)
     80     failTest('Expected silence, but avg audio level was ' + average);
     81 }
     82 
     83 /**
     84  * @private
     85  */
     86 function getAudioLevelFromStats_(response) {
     87   var reports = response.result();
     88   var audioOutputLevels = [];
     89   for (var i = 0; i < reports.length; ++i) {
     90     var report = reports[i];
     91     if (report.names().indexOf('audioOutputLevel') != -1) {
     92       audioOutputLevels.push(report.stat('audioOutputLevel'));
     93     }
     94   }
     95   return audioOutputLevels;
     96 }
     97