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