chrome_webrtc_audio_quality_browsertest.cc revision 03b57e008b61dfcb1fbad3aea950ae0e001748b0
1324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// Copyright 2013 The Chromium Authors. All rights reserved. 2324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// Use of this source code is governed by a BSD-style license that can be 3324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// found in the LICENSE file. 4324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 5324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include <ctime> 6324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 7324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "base/command_line.h" 8324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "base/file_util.h" 9324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "base/path_service.h" 10324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "base/process/launch.h" 11324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "base/scoped_native_library.h" 12324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "base/strings/stringprintf.h" 13324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "chrome/browser/media/webrtc_browsertest_base.h" 14324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "chrome/browser/media/webrtc_browsertest_common.h" 15324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "chrome/browser/profiles/profile.h" 16324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "chrome/browser/ui/browser.h" 17324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "chrome/browser/ui/browser_tabstrip.h" 18324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "chrome/browser/ui/tabs/tab_strip_model.h" 19324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "chrome/common/chrome_paths.h" 20324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "chrome/common/chrome_switches.h" 21324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "chrome/test/base/ui_test_utils.h" 22324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "content/public/test/browser_test_utils.h" 23324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "media/base/media_switches.h" 24324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "net/test/embedded_test_server/embedded_test_server.h" 25324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "testing/perf/perf_test.h" 26324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 27324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// These are relative to the reference file dir defined by 28324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// webrtc_browsertest_common.h (i.e. chrome/test/data/webrtc/resources). 29324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic const base::FilePath::CharType kReferenceFile[] = 30324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#if defined (OS_WIN) 31324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver FILE_PATH_LITERAL("human-voice-win.wav"); 32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#else 33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver FILE_PATH_LITERAL("human-voice-linux.wav"); 34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#endif 35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// The javascript will load the reference file relative to its location, 37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// which is in /webrtc on the web server. The files we are looking for are in 38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// webrtc/resources in the chrome/test/data folder. 39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic const char kReferenceFileRelativeUrl[] = 40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#if defined (OS_WIN) 41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver "resources/human-voice-win.wav"; 42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#else 43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver "resources/human-voice-linux.wav"; 44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#endif 45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic const char kMainWebrtcTestHtmlPage[] = 47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver "/webrtc/webrtc_audio_quality_test.html"; 48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// Test we can set up a WebRTC call and play audio through it. 50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// 51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// If you're not a googler and want to run this test, you need to provide a 52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// pesq binary for your platform (and sox.exe on windows). Read more on how 53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// resources are managed in chrome/test/data/webrtc/resources/README. 54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// 55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// This test will only work on machines that have been configured to record 56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// their own input. 57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// 58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// On Linux: 59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// 1. # sudo apt-get install pavucontrol sox 60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// 2. For the user who will run the test: # pavucontrol 61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// 3. In a separate terminal, # arecord dummy 62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// 4. In pavucontrol, go to the recording tab. 63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// 5. For the ALSA plug-in [aplay]: ALSA Capture from, change from <x> to 64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// <Monitor of x>, where x is whatever your primary sound device is called. 65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// 6. Try launching chrome as the target user on the target machine, try 66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// playing, say, a YouTube video, and record with # arecord -f dat tmp.dat. 67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// Verify the recording with aplay (should have recorded what you played 68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// from chrome). 69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// 70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// Note: the volume for ALL your input devices will be forced to 100% by 71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// running this test on Linux. 72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// 73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// On Windows 7: 74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// 1. Control panel > Sound > Manage audio devices. 75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// 2. In the recording tab, right-click in an empty space in the pane with the 76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// devices. Tick 'show disabled devices'. 77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// 3. You should see a 'stero mix' device - this is what your speakers output. 78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// Right click > Properties. 79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// 4. In the Listen tab for the mix device, check the 'listen to this device' 80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// checkbox. Ensure the mix device is the default recording device. 81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// 5. Launch chrome and try playing a video with sound. You should see 82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// in the volume meter for the mix device. Configure the mix device to have 83324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// 50 / 100 in level. Also go into the playback tab, right-click Speakers, 84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// and set that level to 50 / 100. Otherwise you will get distortion in 85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// the recording. 86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass WebRtcAudioQualityBrowserTest : public WebRtcTestBase { 87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public: 88324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver WebRtcAudioQualityBrowserTest() {} 89324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver virtual void SetUpInProcessBrowserTestFixture() OVERRIDE { 90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver DetectErrorsInJavaScript(); // Look for errors in our rather complex js. 91324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 92324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // This test expects real device handling and requires a real webcam / audio 95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // device; it will not work with fake devices. 96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver EXPECT_FALSE(command_line->HasSwitch( 97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver switches::kUseFakeDeviceForMediaStream)); 98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver EXPECT_FALSE(command_line->HasSwitch( 99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver switches::kUseFakeUIForMediaStream)); 100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 101 102 void AddAudioFile(const std::string& input_file_relative_url, 103 content::WebContents* tab_contents) { 104 EXPECT_EQ("ok-added", ExecuteJavascript( 105 "addAudioFile('" + input_file_relative_url + "')", tab_contents)); 106 } 107 108 void PlayAudioFile(content::WebContents* tab_contents) { 109 EXPECT_EQ("ok-playing", ExecuteJavascript("playAudioFile()", tab_contents)); 110 } 111 112 base::FilePath CreateTemporaryWaveFile() { 113 base::FilePath filename; 114 EXPECT_TRUE(base::CreateTemporaryFile(&filename)); 115 base::FilePath wav_filename = 116 filename.AddExtension(FILE_PATH_LITERAL(".wav")); 117 EXPECT_TRUE(base::Move(filename, wav_filename)); 118 return wav_filename; 119 } 120}; 121 122class AudioRecorder { 123 public: 124 AudioRecorder(): recording_application_(base::kNullProcessHandle) {} 125 ~AudioRecorder() {} 126 127 // Starts the recording program for the specified duration. Returns true 128 // on success. 129 bool StartRecording(int duration_sec, const base::FilePath& output_file, 130 bool mono) { 131 EXPECT_EQ(base::kNullProcessHandle, recording_application_) 132 << "Tried to record, but is already recording."; 133 134 CommandLine command_line(CommandLine::NO_PROGRAM); 135#if defined(OS_WIN) 136 // This disable is required to run SoundRecorder.exe on 64-bit Windows 137 // from a 32-bit binary. We need to load the wow64 disable function from 138 // the DLL since it doesn't exist on Windows XP. 139 // TODO(phoglund): find some cleaner solution than using SoundRecorder.exe. 140 base::ScopedNativeLibrary kernel32_lib(base::FilePath(L"kernel32")); 141 if (kernel32_lib.is_valid()) { 142 typedef BOOL (WINAPI* Wow64DisableWow64FSRedirection)(PVOID*); 143 Wow64DisableWow64FSRedirection wow_64_disable_wow_64_fs_redirection; 144 wow_64_disable_wow_64_fs_redirection = 145 reinterpret_cast<Wow64DisableWow64FSRedirection>( 146 kernel32_lib.GetFunctionPointer( 147 "Wow64DisableWow64FsRedirection")); 148 if (wow_64_disable_wow_64_fs_redirection != NULL) { 149 PVOID* ignored = NULL; 150 wow_64_disable_wow_64_fs_redirection(ignored); 151 } 152 } 153 154 char duration_in_hms[128] = {0}; 155 struct tm duration_tm = {0}; 156 duration_tm.tm_sec = duration_sec; 157 EXPECT_NE(0u, strftime(duration_in_hms, arraysize(duration_in_hms), 158 "%H:%M:%S", &duration_tm)); 159 160 command_line.SetProgram( 161 base::FilePath(FILE_PATH_LITERAL("SoundRecorder.exe"))); 162 command_line.AppendArg("/FILE"); 163 command_line.AppendArgPath(output_file); 164 command_line.AppendArg("/DURATION"); 165 command_line.AppendArg(duration_in_hms); 166#else 167 int num_channels = mono ? 1 : 2; 168 command_line.SetProgram(base::FilePath("arecord")); 169 command_line.AppendArg("-d"); 170 command_line.AppendArg(base::StringPrintf("%d", duration_sec)); 171 command_line.AppendArg("-f"); 172 command_line.AppendArg("dat"); 173 command_line.AppendArg("-c"); 174 command_line.AppendArg(base::StringPrintf("%d", num_channels)); 175 command_line.AppendArgPath(output_file); 176#endif 177 178 VLOG(0) << "Running " << command_line.GetCommandLineString(); 179 return base::LaunchProcess(command_line, base::LaunchOptions(), 180 &recording_application_); 181 } 182 183 // Joins the recording program. Returns true on success. 184 bool WaitForRecordingToEnd() { 185 int exit_code = -1; 186 base::WaitForExitCode(recording_application_, &exit_code); 187 return exit_code == 0; 188 } 189 private: 190 base::ProcessHandle recording_application_; 191}; 192 193bool ForceMicrophoneVolumeTo100Percent() { 194#if defined(OS_WIN) 195 // Note: the force binary isn't in tools since it's one of our own. 196 CommandLine command_line(test::GetReferenceFilesDir().Append( 197 FILE_PATH_LITERAL("force_mic_volume_max.exe"))); 198 VLOG(0) << "Running " << command_line.GetCommandLineString(); 199 std::string result; 200 if (!base::GetAppOutput(command_line, &result)) { 201 LOG(ERROR) << "Failed to set source volume: output was " << result; 202 return false; 203 } 204#else 205 // Just force the volume of, say the first 5 devices. A machine will rarely 206 // have more input sources than that. This is way easier than finding the 207 // input device we happen to be using. 208 for (int device_index = 0; device_index < 5; ++device_index) { 209 std::string result; 210 const std::string kHundredPercentVolume = "65536"; 211 CommandLine command_line(base::FilePath(FILE_PATH_LITERAL("pacmd"))); 212 command_line.AppendArg("set-source-volume"); 213 command_line.AppendArg(base::StringPrintf("%d", device_index)); 214 command_line.AppendArg(kHundredPercentVolume); 215 VLOG(0) << "Running " << command_line.GetCommandLineString(); 216 if (!base::GetAppOutput(command_line, &result)) { 217 LOG(ERROR) << "Failed to set source volume: output was " << result; 218 return false; 219 } 220 } 221#endif 222 return true; 223} 224 225// Removes silence from beginning and end of the |input_audio_file| and writes 226// the result to the |output_audio_file|. Returns true on success. 227bool RemoveSilence(const base::FilePath& input_file, 228 const base::FilePath& output_file) { 229 // SOX documentation for silence command: http://sox.sourceforge.net/sox.html 230 // To remove the silence from both beginning and end of the audio file, we 231 // call sox silence command twice: once on normal file and again on its 232 // reverse, then we reverse the final output. 233 // Silence parameters are (in sequence): 234 // ABOVE_PERIODS: The period for which silence occurs. Value 1 is used for 235 // silence at beginning of audio. 236 // DURATION: the amount of time in seconds that non-silence must be detected 237 // before sox stops trimming audio. 238 // THRESHOLD: value used to indicate what sample value is treates as silence. 239 const char* kAbovePeriods = "1"; 240 const char* kDuration = "2"; 241 const char* kTreshold = "5%"; 242 243#if defined(OS_WIN) 244 base::FilePath sox_path = test::GetReferenceFilesDir().Append( 245 FILE_PATH_LITERAL("tools/sox.exe")); 246 if (!base::PathExists(sox_path)) { 247 LOG(ERROR) << "Missing sox.exe binary in " << sox_path.value() 248 << "; you may have to provide this binary yourself."; 249 return false; 250 } 251 CommandLine command_line(sox_path); 252#else 253 CommandLine command_line(base::FilePath(FILE_PATH_LITERAL("sox"))); 254#endif 255 command_line.AppendArgPath(input_file); 256 command_line.AppendArgPath(output_file); 257 command_line.AppendArg("silence"); 258 command_line.AppendArg(kAbovePeriods); 259 command_line.AppendArg(kDuration); 260 command_line.AppendArg(kTreshold); 261 command_line.AppendArg("reverse"); 262 command_line.AppendArg("silence"); 263 command_line.AppendArg(kAbovePeriods); 264 command_line.AppendArg(kDuration); 265 command_line.AppendArg(kTreshold); 266 command_line.AppendArg("reverse"); 267 268 VLOG(0) << "Running " << command_line.GetCommandLineString(); 269 std::string result; 270 bool ok = base::GetAppOutput(command_line, &result); 271 VLOG(0) << "Output was:\n\n" << result; 272 return ok; 273} 274 275bool CanParseAsFloat(const std::string& value) { 276 return atof(value.c_str()) != 0 || value == "0"; 277} 278 279// Runs PESQ to compare |reference_file| to a |actual_file|. The |sample_rate| 280// can be either 16000 or 8000. 281// 282// PESQ is only mono-aware, so the files should preferably be recorded in mono. 283// Furthermore it expects the file to be 16 rather than 32 bits, even though 284// 32 bits might work. The audio bandwidth of the two files should be the same 285// e.g. don't compare a 32 kHz file to a 8 kHz file. 286// 287// The raw score in MOS is written to |raw_mos|, whereas the MOS-LQO score is 288// written to mos_lqo. The scores are returned as floats in string form (e.g. 289// "3.145", etc). Returns true on success. 290bool RunPesq(const base::FilePath& reference_file, 291 const base::FilePath& actual_file, 292 int sample_rate, std::string* raw_mos, std::string* mos_lqo) { 293 // PESQ will break if the paths are too long (!). 294 EXPECT_LT(reference_file.value().length(), 128u); 295 EXPECT_LT(actual_file.value().length(), 128u); 296 297#if defined(OS_WIN) 298 base::FilePath pesq_path = 299 test::GetReferenceFilesDir().Append(FILE_PATH_LITERAL("tools/pesq.exe")); 300#else 301 base::FilePath pesq_path = 302 test::GetReferenceFilesDir().Append(FILE_PATH_LITERAL("tools/pesq")); 303#endif 304 305 if (!base::PathExists(pesq_path)) { 306 LOG(ERROR) << "Missing PESQ binary in " << pesq_path.value() 307 << "; you may have to provide this binary yourself."; 308 return false; 309 } 310 311 CommandLine command_line(pesq_path); 312 command_line.AppendArg(base::StringPrintf("+%d", sample_rate)); 313 command_line.AppendArgPath(reference_file); 314 command_line.AppendArgPath(actual_file); 315 316 VLOG(0) << "Running " << command_line.GetCommandLineString(); 317 std::string result; 318 if (!base::GetAppOutput(command_line, &result)) { 319 LOG(ERROR) << "Failed to run PESQ."; 320 return false; 321 } 322 VLOG(0) << "Output was:\n\n" << result; 323 324 const std::string result_anchor = "Prediction (Raw MOS, MOS-LQO): = "; 325 std::size_t anchor_pos = result.find(result_anchor); 326 if (anchor_pos == std::string::npos) { 327 LOG(ERROR) << "PESQ was not able to compute a score; we probably recorded " 328 << "only silence."; 329 return false; 330 } 331 332 // There are two tab-separated numbers on the format x.xxx, e.g. 5 chars each. 333 std::size_t first_number_pos = anchor_pos + result_anchor.length(); 334 *raw_mos = result.substr(first_number_pos, 5); 335 EXPECT_TRUE(CanParseAsFloat(*raw_mos)) << "Failed to parse raw MOS number."; 336 *mos_lqo = result.substr(first_number_pos + 5 + 1, 5); 337 EXPECT_TRUE(CanParseAsFloat(*mos_lqo)) << "Failed to parse MOS LQO number."; 338 339 return true; 340} 341 342#if defined(OS_LINUX) || defined(OS_WIN) 343// Only implemented on Linux and Windows for now. 344#define MAYBE_MANUAL_TestAudioQuality MANUAL_TestAudioQuality 345#else 346#define MAYBE_MANUAL_TestAudioQuality DISABLED_MANUAL_TestAudioQuality 347#endif 348 349IN_PROC_BROWSER_TEST_F(WebRtcAudioQualityBrowserTest, 350 MAYBE_MANUAL_TestAudioQuality) { 351 if (OnWinXp()) { 352 LOG(ERROR) << "This test is not implemented for Windows XP."; 353 return; 354 } 355 if (OnWin8()) { 356 // http://crbug.com/379798. 357 LOG(ERROR) << "Temporarily disabled for Win 8."; 358 return; 359 } 360 ASSERT_TRUE(test::HasReferenceFilesInCheckout()); 361 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); 362 363 ASSERT_TRUE(ForceMicrophoneVolumeTo100Percent()); 364 365 ui_test_utils::NavigateToURL( 366 browser(), embedded_test_server()->GetURL(kMainWebrtcTestHtmlPage)); 367 content::WebContents* left_tab = 368 browser()->tab_strip_model()->GetActiveWebContents(); 369 370 chrome::AddTabAt(browser(), GURL(), -1, true); 371 content::WebContents* right_tab = 372 browser()->tab_strip_model()->GetActiveWebContents(); 373 ui_test_utils::NavigateToURL( 374 browser(), embedded_test_server()->GetURL(kMainWebrtcTestHtmlPage)); 375 376 // Prepare the peer connections manually in this test since we don't add 377 // getUserMedia-derived media streams in this test like the other tests. 378 EXPECT_EQ("ok-peerconnection-created", 379 ExecuteJavascript("preparePeerConnection()", left_tab)); 380 EXPECT_EQ("ok-peerconnection-created", 381 ExecuteJavascript("preparePeerConnection()", right_tab)); 382 383 AddAudioFile(kReferenceFileRelativeUrl, left_tab); 384 385 NegotiateCall(left_tab, right_tab); 386 387 // Note: the media flow isn't necessarily established on the connection just 388 // because the ready state is ok on both sides. We sleep a bit between call 389 // establishment and playing to avoid cutting of the beginning of the audio 390 // file. 391 test::SleepInJavascript(left_tab, 2000); 392 393 base::FilePath recording = CreateTemporaryWaveFile(); 394 395 // Note: the sound clip is about 10 seconds: record for 15 seconds to get some 396 // safety margins on each side. 397 AudioRecorder recorder; 398 static int kRecordingTimeSeconds = 15; 399 ASSERT_TRUE(recorder.StartRecording(kRecordingTimeSeconds, recording, true)); 400 401 PlayAudioFile(left_tab); 402 403 ASSERT_TRUE(recorder.WaitForRecordingToEnd()); 404 VLOG(0) << "Done recording to " << recording.value() << std::endl; 405 406 HangUp(left_tab); 407 408 base::FilePath trimmed_recording = CreateTemporaryWaveFile(); 409 410 ASSERT_TRUE(RemoveSilence(recording, trimmed_recording)); 411 VLOG(0) << "Trimmed silence: " << trimmed_recording.value() << std::endl; 412 413 std::string raw_mos; 414 std::string mos_lqo; 415 base::FilePath reference_file_in_test_dir = 416 test::GetReferenceFilesDir().Append(kReferenceFile); 417 ASSERT_TRUE(RunPesq(reference_file_in_test_dir, trimmed_recording, 16000, 418 &raw_mos, &mos_lqo)); 419 420 perf_test::PrintResult("audio_pesq", "", "raw_mos", raw_mos, "score", true); 421 perf_test::PrintResult("audio_pesq", "", "mos_lqo", mos_lqo, "score", true); 422 423 EXPECT_TRUE(base::DeleteFile(recording, false)); 424 EXPECT_TRUE(base::DeleteFile(trimmed_recording, false)); 425} 426