OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <ctime> | 5 #include <ctime> |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/files/file_enumerator.h" | 8 #include "base/files/file_enumerator.h" |
9 #include "base/files/file_util.h" | 9 #include "base/files/file_util.h" |
10 #include "base/files/scoped_temp_dir.h" | 10 #include "base/files/scoped_temp_dir.h" |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
121 // 50 / 100 in level. Also go into the playback tab, right-click Speakers, | 121 // 50 / 100 in level. Also go into the playback tab, right-click Speakers, |
122 // and set that level to 50 / 100. Otherwise you will get distortion in | 122 // and set that level to 50 / 100. Otherwise you will get distortion in |
123 // the recording. | 123 // the recording. |
124 class MAYBE_WebRtcAudioQualityBrowserTest : public WebRtcTestBase { | 124 class MAYBE_WebRtcAudioQualityBrowserTest : public WebRtcTestBase { |
125 public: | 125 public: |
126 MAYBE_WebRtcAudioQualityBrowserTest() {} | 126 MAYBE_WebRtcAudioQualityBrowserTest() {} |
127 void SetUpInProcessBrowserTestFixture() override { | 127 void SetUpInProcessBrowserTestFixture() override { |
128 DetectErrorsInJavaScript(); // Look for errors in our rather complex js. | 128 DetectErrorsInJavaScript(); // Look for errors in our rather complex js. |
129 } | 129 } |
130 | 130 |
131 void SetUpCommandLine(CommandLine* command_line) override { | 131 void SetUpCommandLine(base::CommandLine* command_line) override { |
132 EXPECT_FALSE(command_line->HasSwitch( | 132 EXPECT_FALSE(command_line->HasSwitch( |
133 switches::kUseFakeUIForMediaStream)); | 133 switches::kUseFakeUIForMediaStream)); |
134 | 134 |
135 // The WebAudio-based tests don't care what devices are available to | 135 // The WebAudio-based tests don't care what devices are available to |
136 // getUserMedia, and the getUserMedia-based tests will play back a file | 136 // getUserMedia, and the getUserMedia-based tests will play back a file |
137 // through the fake device using using --use-file-for-fake-audio-capture. | 137 // through the fake device using using --use-file-for-fake-audio-capture. |
138 command_line->AppendSwitch(switches::kUseFakeDeviceForMediaStream); | 138 command_line->AppendSwitch(switches::kUseFakeDeviceForMediaStream); |
139 } | 139 } |
140 | 140 |
141 void ConfigureFakeDeviceToPlayFile(const base::FilePath& wav_file_path) { | 141 void ConfigureFakeDeviceToPlayFile(const base::FilePath& wav_file_path) { |
142 CommandLine::ForCurrentProcess()->AppendSwitchPath( | 142 base::CommandLine::ForCurrentProcess()->AppendSwitchPath( |
143 switches::kUseFileForFakeAudioCapture, wav_file_path); | 143 switches::kUseFileForFakeAudioCapture, wav_file_path); |
144 } | 144 } |
145 | 145 |
146 void AddAudioFileToWebAudio(const std::string& input_file_relative_url, | 146 void AddAudioFileToWebAudio(const std::string& input_file_relative_url, |
147 content::WebContents* tab_contents) { | 147 content::WebContents* tab_contents) { |
148 // This calls into webaudio.js. | 148 // This calls into webaudio.js. |
149 EXPECT_EQ("ok-added", ExecuteJavascript( | 149 EXPECT_EQ("ok-added", ExecuteJavascript( |
150 "addAudioFile('" + input_file_relative_url + "')", tab_contents)); | 150 "addAudioFile('" + input_file_relative_url + "')", tab_contents)); |
151 } | 151 } |
152 | 152 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
185 // on success. We record in 44.1 kHz 16-bit format unless |record_cd| is | 185 // on success. We record in 44.1 kHz 16-bit format unless |record_cd| is |
186 // false, in which case we record in 48 kHz 16-bit format. We record in stereo | 186 // false, in which case we record in 48 kHz 16-bit format. We record in stereo |
187 // unless |mono| is true. | 187 // unless |mono| is true. |
188 // TODO(phoglund): make win and mac also support the record_cd parameter. Or, | 188 // TODO(phoglund): make win and mac also support the record_cd parameter. Or, |
189 // even better, make everybody use the CD format rather than DAT. | 189 // even better, make everybody use the CD format rather than DAT. |
190 bool StartRecording(int duration_sec, const base::FilePath& output_file, | 190 bool StartRecording(int duration_sec, const base::FilePath& output_file, |
191 bool mono, bool record_cd) { | 191 bool mono, bool record_cd) { |
192 EXPECT_FALSE(recording_application_.IsValid()) | 192 EXPECT_FALSE(recording_application_.IsValid()) |
193 << "Tried to record, but is already recording."; | 193 << "Tried to record, but is already recording."; |
194 | 194 |
195 CommandLine command_line(CommandLine::NO_PROGRAM); | 195 base::CommandLine command_line(base::CommandLine::NO_PROGRAM); |
196 #if defined(OS_WIN) | 196 #if defined(OS_WIN) |
197 // This disable is required to run SoundRecorder.exe on 64-bit Windows | 197 // This disable is required to run SoundRecorder.exe on 64-bit Windows |
198 // from a 32-bit binary. We need to load the wow64 disable function from | 198 // from a 32-bit binary. We need to load the wow64 disable function from |
199 // the DLL since it doesn't exist on Windows XP. | 199 // the DLL since it doesn't exist on Windows XP. |
200 // TODO(phoglund): find some cleaner solution than using SoundRecorder.exe. | 200 // TODO(phoglund): find some cleaner solution than using SoundRecorder.exe. |
201 base::ScopedNativeLibrary kernel32_lib(base::FilePath(L"kernel32")); | 201 base::ScopedNativeLibrary kernel32_lib(base::FilePath(L"kernel32")); |
202 if (kernel32_lib.is_valid()) { | 202 if (kernel32_lib.is_valid()) { |
203 typedef BOOL (WINAPI* Wow64DisableWow64FSRedirection)(PVOID*); | 203 typedef BOOL (WINAPI* Wow64DisableWow64FSRedirection)(PVOID*); |
204 Wow64DisableWow64FSRedirection wow_64_disable_wow_64_fs_redirection; | 204 Wow64DisableWow64FSRedirection wow_64_disable_wow_64_fs_redirection; |
205 wow_64_disable_wow_64_fs_redirection = | 205 wow_64_disable_wow_64_fs_redirection = |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
266 recording_application_.WaitForExit(&exit_code); | 266 recording_application_.WaitForExit(&exit_code); |
267 return exit_code == 0; | 267 return exit_code == 0; |
268 } | 268 } |
269 private: | 269 private: |
270 base::Process recording_application_; | 270 base::Process recording_application_; |
271 }; | 271 }; |
272 | 272 |
273 bool ForceMicrophoneVolumeTo100Percent() { | 273 bool ForceMicrophoneVolumeTo100Percent() { |
274 #if defined(OS_WIN) | 274 #if defined(OS_WIN) |
275 // Note: the force binary isn't in tools since it's one of our own. | 275 // Note: the force binary isn't in tools since it's one of our own. |
276 CommandLine command_line(test::GetReferenceFilesDir().Append( | 276 base::CommandLine command_line(test::GetReferenceFilesDir().Append( |
277 FILE_PATH_LITERAL("force_mic_volume_max.exe"))); | 277 FILE_PATH_LITERAL("force_mic_volume_max.exe"))); |
278 DVLOG(0) << "Running " << command_line.GetCommandLineString(); | 278 DVLOG(0) << "Running " << command_line.GetCommandLineString(); |
279 std::string result; | 279 std::string result; |
280 if (!base::GetAppOutput(command_line, &result)) { | 280 if (!base::GetAppOutput(command_line, &result)) { |
281 LOG(ERROR) << "Failed to set source volume: output was " << result; | 281 LOG(ERROR) << "Failed to set source volume: output was " << result; |
282 return false; | 282 return false; |
283 } | 283 } |
284 #elif defined(OS_MACOSX) | 284 #elif defined(OS_MACOSX) |
285 CommandLine command_line(base::FilePath(FILE_PATH_LITERAL("osascript"))); | 285 base::CommandLine command_line( |
| 286 base::FilePath(FILE_PATH_LITERAL("osascript"))); |
286 command_line.AppendArg("-e"); | 287 command_line.AppendArg("-e"); |
287 command_line.AppendArg("set volume input volume 100"); | 288 command_line.AppendArg("set volume input volume 100"); |
288 command_line.AppendArg("-e"); | 289 command_line.AppendArg("-e"); |
289 command_line.AppendArg("set volume output volume 100"); | 290 command_line.AppendArg("set volume output volume 100"); |
290 | 291 |
291 std::string result; | 292 std::string result; |
292 if (!base::GetAppOutput(command_line, &result)) { | 293 if (!base::GetAppOutput(command_line, &result)) { |
293 LOG(ERROR) << "Failed to set source volume: output was " << result; | 294 LOG(ERROR) << "Failed to set source volume: output was " << result; |
294 return false; | 295 return false; |
295 } | 296 } |
296 #else | 297 #else |
297 // Just force the volume of, say the first 5 devices. A machine will rarely | 298 // Just force the volume of, say the first 5 devices. A machine will rarely |
298 // have more input sources than that. This is way easier than finding the | 299 // have more input sources than that. This is way easier than finding the |
299 // input device we happen to be using. | 300 // input device we happen to be using. |
300 for (int device_index = 0; device_index < 5; ++device_index) { | 301 for (int device_index = 0; device_index < 5; ++device_index) { |
301 std::string result; | 302 std::string result; |
302 const std::string kHundredPercentVolume = "65536"; | 303 const std::string kHundredPercentVolume = "65536"; |
303 CommandLine command_line(base::FilePath(FILE_PATH_LITERAL("pacmd"))); | 304 base::CommandLine command_line(base::FilePath(FILE_PATH_LITERAL("pacmd"))); |
304 command_line.AppendArg("set-source-volume"); | 305 command_line.AppendArg("set-source-volume"); |
305 command_line.AppendArg(base::StringPrintf("%d", device_index)); | 306 command_line.AppendArg(base::StringPrintf("%d", device_index)); |
306 command_line.AppendArg(kHundredPercentVolume); | 307 command_line.AppendArg(kHundredPercentVolume); |
307 DVLOG(0) << "Running " << command_line.GetCommandLineString(); | 308 DVLOG(0) << "Running " << command_line.GetCommandLineString(); |
308 if (!base::GetAppOutput(command_line, &result)) { | 309 if (!base::GetAppOutput(command_line, &result)) { |
309 LOG(ERROR) << "Failed to set source volume: output was " << result; | 310 LOG(ERROR) << "Failed to set source volume: output was " << result; |
310 return false; | 311 return false; |
311 } | 312 } |
312 } | 313 } |
313 #endif | 314 #endif |
314 return true; | 315 return true; |
315 } | 316 } |
316 | 317 |
317 // Sox is the "Swiss army knife" of audio processing. We mainly use it for | 318 // Sox is the "Swiss army knife" of audio processing. We mainly use it for |
318 // silence trimming. See http://sox.sourceforge.net. | 319 // silence trimming. See http://sox.sourceforge.net. |
319 CommandLine MakeSoxCommandLine() { | 320 base::CommandLine MakeSoxCommandLine() { |
320 #if defined(OS_WIN) | 321 #if defined(OS_WIN) |
321 base::FilePath sox_path = test::GetReferenceFilesDir().Append( | 322 base::FilePath sox_path = test::GetReferenceFilesDir().Append( |
322 FILE_PATH_LITERAL("tools/sox.exe")); | 323 FILE_PATH_LITERAL("tools/sox.exe")); |
323 if (!base::PathExists(sox_path)) { | 324 if (!base::PathExists(sox_path)) { |
324 LOG(ERROR) << "Missing sox.exe binary in " << sox_path.value() | 325 LOG(ERROR) << "Missing sox.exe binary in " << sox_path.value() |
325 << "; you may have to provide this binary yourself."; | 326 << "; you may have to provide this binary yourself."; |
326 return CommandLine(CommandLine::NO_PROGRAM); | 327 return base::CommandLine(base::CommandLine::NO_PROGRAM); |
327 } | 328 } |
328 CommandLine command_line(sox_path); | 329 base::CommandLine command_line(sox_path); |
329 #else | 330 #else |
330 CommandLine command_line(base::FilePath(FILE_PATH_LITERAL("sox"))); | 331 base::CommandLine command_line(base::FilePath(FILE_PATH_LITERAL("sox"))); |
331 #endif | 332 #endif |
332 return command_line; | 333 return command_line; |
333 } | 334 } |
334 | 335 |
335 // Removes silence from beginning and end of the |input_audio_file| and writes | 336 // Removes silence from beginning and end of the |input_audio_file| and writes |
336 // the result to the |output_audio_file|. Returns true on success. | 337 // the result to the |output_audio_file|. Returns true on success. |
337 bool RemoveSilence(const base::FilePath& input_file, | 338 bool RemoveSilence(const base::FilePath& input_file, |
338 const base::FilePath& output_file) { | 339 const base::FilePath& output_file) { |
339 // SOX documentation for silence command: http://sox.sourceforge.net/sox.html | 340 // SOX documentation for silence command: http://sox.sourceforge.net/sox.html |
340 // To remove the silence from both beginning and end of the audio file, we | 341 // To remove the silence from both beginning and end of the audio file, we |
341 // call sox silence command twice: once on normal file and again on its | 342 // call sox silence command twice: once on normal file and again on its |
342 // reverse, then we reverse the final output. | 343 // reverse, then we reverse the final output. |
343 // Silence parameters are (in sequence): | 344 // Silence parameters are (in sequence): |
344 // ABOVE_PERIODS: The period for which silence occurs. Value 1 is used for | 345 // ABOVE_PERIODS: The period for which silence occurs. Value 1 is used for |
345 // silence at beginning of audio. | 346 // silence at beginning of audio. |
346 // DURATION: the amount of time in seconds that non-silence must be detected | 347 // DURATION: the amount of time in seconds that non-silence must be detected |
347 // before sox stops trimming audio. | 348 // before sox stops trimming audio. |
348 // THRESHOLD: value used to indicate what sample value is treats as silence. | 349 // THRESHOLD: value used to indicate what sample value is treats as silence. |
349 const char* kAbovePeriods = "1"; | 350 const char* kAbovePeriods = "1"; |
350 const char* kDuration = "2"; | 351 const char* kDuration = "2"; |
351 const char* kTreshold = "3%"; | 352 const char* kTreshold = "3%"; |
352 | 353 |
353 CommandLine command_line = MakeSoxCommandLine(); | 354 base::CommandLine command_line = MakeSoxCommandLine(); |
354 if (command_line.GetProgram().empty()) | 355 if (command_line.GetProgram().empty()) |
355 return false; | 356 return false; |
356 command_line.AppendArgPath(input_file); | 357 command_line.AppendArgPath(input_file); |
357 command_line.AppendArgPath(output_file); | 358 command_line.AppendArgPath(output_file); |
358 command_line.AppendArg("silence"); | 359 command_line.AppendArg("silence"); |
359 command_line.AppendArg(kAbovePeriods); | 360 command_line.AppendArg(kAbovePeriods); |
360 command_line.AppendArg(kDuration); | 361 command_line.AppendArg(kDuration); |
361 command_line.AppendArg(kTreshold); | 362 command_line.AppendArg(kTreshold); |
362 command_line.AppendArg("reverse"); | 363 command_line.AppendArg("reverse"); |
363 command_line.AppendArg("silence"); | 364 command_line.AppendArg("silence"); |
364 command_line.AppendArg(kAbovePeriods); | 365 command_line.AppendArg(kAbovePeriods); |
365 command_line.AppendArg(kDuration); | 366 command_line.AppendArg(kDuration); |
366 command_line.AppendArg(kTreshold); | 367 command_line.AppendArg(kTreshold); |
367 command_line.AppendArg("reverse"); | 368 command_line.AppendArg("reverse"); |
368 | 369 |
369 DVLOG(0) << "Running " << command_line.GetCommandLineString(); | 370 DVLOG(0) << "Running " << command_line.GetCommandLineString(); |
370 std::string result; | 371 std::string result; |
371 bool ok = base::GetAppOutput(command_line, &result); | 372 bool ok = base::GetAppOutput(command_line, &result); |
372 DVLOG(0) << "Output was:\n\n" << result; | 373 DVLOG(0) << "Output was:\n\n" << result; |
373 return ok; | 374 return ok; |
374 } | 375 } |
375 | 376 |
376 // Looks for 0.3-second silences (under 1% audio power) and splits the input | 377 // Looks for 0.3-second silences (under 1% audio power) and splits the input |
377 // file on those silences. Output files are written according to the output file | 378 // file on those silences. Output files are written according to the output file |
378 // template (e.g. /tmp/out.wav writes /tmp/out001.wav, /tmp/out002.wav, etc if | 379 // template (e.g. /tmp/out.wav writes /tmp/out001.wav, /tmp/out002.wav, etc if |
379 // there are two silence-padded regions in the file). The silences between | 380 // there are two silence-padded regions in the file). The silences between |
380 // speech segments must be at least 500 ms for this to be reliable. | 381 // speech segments must be at least 500 ms for this to be reliable. |
381 bool SplitFileOnSilence(const base::FilePath& input_file, | 382 bool SplitFileOnSilence(const base::FilePath& input_file, |
382 const base::FilePath& output_file_template) { | 383 const base::FilePath& output_file_template) { |
383 CommandLine command_line = MakeSoxCommandLine(); | 384 base::CommandLine command_line = MakeSoxCommandLine(); |
384 if (command_line.GetProgram().empty()) | 385 if (command_line.GetProgram().empty()) |
385 return false; | 386 return false; |
386 | 387 |
387 // These are experimentally determined and work on the files we use. | 388 // These are experimentally determined and work on the files we use. |
388 const char* kAbovePeriods = "1"; | 389 const char* kAbovePeriods = "1"; |
389 const char* kUnderPeriods = "1"; | 390 const char* kUnderPeriods = "1"; |
390 const char* kDuration = "0.3"; | 391 const char* kDuration = "0.3"; |
391 const char* kTreshold = "1%"; | 392 const char* kTreshold = "1%"; |
392 command_line.AppendArgPath(input_file); | 393 command_line.AppendArgPath(input_file); |
393 command_line.AppendArgPath(output_file_template); | 394 command_line.AppendArgPath(output_file_template); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
442 base::FilePath pesq_path = | 443 base::FilePath pesq_path = |
443 test::GetReferenceFilesDir().Append(FILE_PATH_LITERAL("tools/pesq")); | 444 test::GetReferenceFilesDir().Append(FILE_PATH_LITERAL("tools/pesq")); |
444 #endif | 445 #endif |
445 | 446 |
446 if (!base::PathExists(pesq_path)) { | 447 if (!base::PathExists(pesq_path)) { |
447 LOG(ERROR) << "Missing PESQ binary in " << pesq_path.value() | 448 LOG(ERROR) << "Missing PESQ binary in " << pesq_path.value() |
448 << "; you may have to provide this binary yourself."; | 449 << "; you may have to provide this binary yourself."; |
449 return false; | 450 return false; |
450 } | 451 } |
451 | 452 |
452 CommandLine command_line(pesq_path); | 453 base::CommandLine command_line(pesq_path); |
453 command_line.AppendArg(base::StringPrintf("+%d", sample_rate)); | 454 command_line.AppendArg(base::StringPrintf("+%d", sample_rate)); |
454 command_line.AppendArgPath(reference_file); | 455 command_line.AppendArgPath(reference_file); |
455 command_line.AppendArgPath(actual_file); | 456 command_line.AppendArgPath(actual_file); |
456 | 457 |
457 DVLOG(0) << "Running " << command_line.GetCommandLineString(); | 458 DVLOG(0) << "Running " << command_line.GetCommandLineString(); |
458 std::string result; | 459 std::string result; |
459 if (!base::GetAppOutput(command_line, &result)) { | 460 if (!base::GetAppOutput(command_line, &result)) { |
460 LOG(ERROR) << "Failed to run PESQ."; | 461 LOG(ERROR) << "Failed to run PESQ."; |
461 return false; | 462 return false; |
462 } | 463 } |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
751 | 752 |
752 // Since the AGC is off here there should be no gain at all. | 753 // Since the AGC is off here there should be no gain at all. |
753 IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcAudioQualityBrowserTest, | 754 IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcAudioQualityBrowserTest, |
754 MAYBE_MANUAL_TestComputeGainWithAudioProcessingOff) { | 755 MAYBE_MANUAL_TestComputeGainWithAudioProcessingOff) { |
755 const char* kAudioCallWithoutAudioProcessing = | 756 const char* kAudioCallWithoutAudioProcessing = |
756 "{audio: { mandatory: { echoCancellation: false } } }"; | 757 "{audio: { mandatory: { echoCancellation: false } } }"; |
757 ASSERT_NO_FATAL_FAILURE(TestAutoGainControl( | 758 ASSERT_NO_FATAL_FAILURE(TestAutoGainControl( |
758 kAgcTestReferenceFile, kAudioCallWithoutAudioProcessing, "_no_agc")); | 759 kAgcTestReferenceFile, kAudioCallWithoutAudioProcessing, "_no_agc")); |
759 } | 760 } |
760 | 761 |
OLD | NEW |