Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(447)

Side by Side Diff: chrome/browser/media/chrome_webrtc_audio_quality_browsertest.cc

Issue 890893004: Removing silence trimming from WebRTC quality test. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 #define MAYBE_WebRtcAudioQualityBrowserTest WebRtcAudioQualityBrowserTest 47 #define MAYBE_WebRtcAudioQualityBrowserTest WebRtcAudioQualityBrowserTest
48 #else 48 #else
49 // Not implemented on Android, ChromeOS etc. 49 // Not implemented on Android, ChromeOS etc.
50 #define MAYBE_WebRtcAudioQualityBrowserTest DISABLED_WebRtcAudioQualityBrowserTe st 50 #define MAYBE_WebRtcAudioQualityBrowserTest DISABLED_WebRtcAudioQualityBrowserTe st
51 #endif 51 #endif
52 52
53 } // namespace 53 } // namespace
54 54
55 // Test we can set up a WebRTC call and play audio through it. 55 // Test we can set up a WebRTC call and play audio through it.
56 // 56 //
57 // WARNING: this test may mess with both output and input levels on your system
58 // and may cause audio to start blasting at full volume into your
59 // headphones.
60 //
57 // If you're not a googler and want to run this test, you need to provide a 61 // If you're not a googler and want to run this test, you need to provide a
58 // pesq binary for your platform (and sox.exe on windows). Read more on how 62 // pesq binary for your platform (and sox.exe on windows). Read more on how
59 // resources are managed in chrome/test/data/webrtc/resources/README. 63 // resources are managed in chrome/test/data/webrtc/resources/README.
60 // 64 //
61 // This test will only work on machines that have been configured to record 65 // This test will only work on machines that have been configured to record
62 // their own input. 66 // their own input.
63 // 67 //
64 // On Linux: 68 // On Linux:
65 // 1. # sudo apt-get install pavucontrol sox 69 // 1. # sudo apt-get install pavucontrol sox
66 // 2. For the user who will run the test: # pavucontrol 70 // 2. For the user who will run the test: # pavucontrol
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 // 1. Control panel > Sound > Manage audio devices. 103 // 1. Control panel > Sound > Manage audio devices.
100 // 2. In the recording tab, right-click in an empty space in the pane with the 104 // 2. In the recording tab, right-click in an empty space in the pane with the
101 // devices. Tick 'show disabled devices'. 105 // devices. Tick 'show disabled devices'.
102 // 3. You should see a 'stero mix' device - this is what your speakers output. 106 // 3. You should see a 'stero mix' device - this is what your speakers output.
103 // Right click > Properties. 107 // Right click > Properties.
104 // 4. In the Listen tab for the mix device, check the 'listen to this device' 108 // 4. In the Listen tab for the mix device, check the 'listen to this device'
105 // checkbox. Ensure the mix device is the default recording device. 109 // checkbox. Ensure the mix device is the default recording device.
106 // 5. Launch chrome and try playing a video with sound. You should see 110 // 5. Launch chrome and try playing a video with sound. You should see
107 // in the volume meter for the mix device. Configure the mix device to have 111 // in the volume meter for the mix device. Configure the mix device to have
108 // 50 / 100 in level. Also go into the playback tab, right-click Speakers, 112 // 50 / 100 in level. Also go into the playback tab, right-click Speakers,
109 // and set that level to 50 / 100. Otherwise you will get distortion in 113 // and set that level to 50 / 100. Otherwise you might get distortion in
110 // the recording. 114 // the recording.
111 class MAYBE_WebRtcAudioQualityBrowserTest : public WebRtcTestBase { 115 class MAYBE_WebRtcAudioQualityBrowserTest : public WebRtcTestBase {
112 public: 116 public:
113 MAYBE_WebRtcAudioQualityBrowserTest() {} 117 MAYBE_WebRtcAudioQualityBrowserTest() {}
114 void SetUpInProcessBrowserTestFixture() override { 118 void SetUpInProcessBrowserTestFixture() override {
115 DetectErrorsInJavaScript(); // Look for errors in our rather complex js. 119 DetectErrorsInJavaScript(); // Look for errors in our rather complex js.
116 } 120 }
117 121
118 void SetUpCommandLine(base::CommandLine* command_line) override { 122 void SetUpCommandLine(base::CommandLine* command_line) override {
119 EXPECT_FALSE(command_line->HasSwitch( 123 EXPECT_FALSE(command_line->HasSwitch(
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
242 // Joins the recording program. Returns true on success. 246 // Joins the recording program. Returns true on success.
243 bool WaitForRecordingToEnd() { 247 bool WaitForRecordingToEnd() {
244 int exit_code = -1; 248 int exit_code = -1;
245 recording_application_.WaitForExit(&exit_code); 249 recording_application_.WaitForExit(&exit_code);
246 return exit_code == 0; 250 return exit_code == 0;
247 } 251 }
248 private: 252 private:
249 base::Process recording_application_; 253 base::Process recording_application_;
250 }; 254 };
251 255
252 bool ForceMicrophoneVolumeTo100Percent() { 256 bool ForceMicrophoneLevelTo100Percent() {
253 #if defined(OS_WIN) 257 #if defined(OS_WIN)
254 // Note: the force binary isn't in tools since it's one of our own. 258 // Note: the force binary isn't in tools since it's one of our own.
255 base::CommandLine command_line(test::GetReferenceFilesDir().Append( 259 base::CommandLine command_line(test::GetReferenceFilesDir().Append(
256 FILE_PATH_LITERAL("force_mic_volume_max.exe"))); 260 FILE_PATH_LITERAL("force_mic_volume_max.exe")));
257 DVLOG(0) << "Running " << command_line.GetCommandLineString(); 261 DVLOG(0) << "Running " << command_line.GetCommandLineString();
258 std::string result; 262 std::string result;
259 if (!base::GetAppOutput(command_line, &result)) { 263 if (!base::GetAppOutput(command_line, &result)) {
260 LOG(ERROR) << "Failed to set source volume: output was " << result; 264 LOG(ERROR) << "Failed to set source volume: output was " << result;
261 return false; 265 return false;
262 } 266 }
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
480 } 484 }
481 485
482 // Splits |to_split| into sub-files based on silence. The file you use must have 486 // Splits |to_split| into sub-files based on silence. The file you use must have
483 // at least 500 ms periods of silence between speech segments for this to be 487 // at least 500 ms periods of silence between speech segments for this to be
484 // reliable. 488 // reliable.
485 void SplitFileOnSilenceIntoDir(const base::FilePath& to_split, 489 void SplitFileOnSilenceIntoDir(const base::FilePath& to_split,
486 const base::FilePath& workdir) { 490 const base::FilePath& workdir) {
487 // First trim beginning and end since they are tricky for the splitter. 491 // First trim beginning and end since they are tricky for the splitter.
488 base::FilePath trimmed_audio = CreateTemporaryWaveFile(); 492 base::FilePath trimmed_audio = CreateTemporaryWaveFile();
489 493
494 // TODO(phoglund): find smarter way to do this and get rid of RemoveSilence.
490 ASSERT_TRUE(RemoveSilence(to_split, trimmed_audio)); 495 ASSERT_TRUE(RemoveSilence(to_split, trimmed_audio));
491 DVLOG(0) << "Trimmed silence: " << trimmed_audio.value() << std::endl; 496 DVLOG(0) << "Trimmed silence: " << trimmed_audio.value() << std::endl;
492 497
493 ASSERT_TRUE(SplitFileOnSilence( 498 ASSERT_TRUE(SplitFileOnSilence(
494 trimmed_audio, workdir.Append(FILE_PATH_LITERAL("output.wav")))); 499 trimmed_audio, workdir.Append(FILE_PATH_LITERAL("output.wav"))));
495 ASSERT_TRUE(base::DeleteFile(trimmed_audio, false)); 500 ASSERT_TRUE(base::DeleteFile(trimmed_audio, false));
496 } 501 }
497 502
498 // Computes the difference between the actual and reference segment. A positive 503 // Computes the difference between the actual and reference segment. A positive
499 // number x means the actual file is x dB stronger than the reference. 504 // number x means the actual file is x dB stronger than the reference.
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
536 std::string trace_name = base::StringPrintf( 541 std::string trace_name = base::StringPrintf(
537 "%s_segment_%zu", reference_file.BaseName().value().c_str(), i); 542 "%s_segment_%zu", reference_file.BaseName().value().c_str(), i);
538 perf_test::PrintResult("agc_energy_diff", perf_modifier, trace_name, 543 perf_test::PrintResult("agc_energy_diff", perf_modifier, trace_name,
539 difference_in_decibel, "dB", false); 544 difference_in_decibel, "dB", false);
540 } 545 }
541 } 546 }
542 547
543 void ComputeAndPrintPesqResults(const base::FilePath& reference_file, 548 void ComputeAndPrintPesqResults(const base::FilePath& reference_file,
544 const base::FilePath& recording, 549 const base::FilePath& recording,
545 const std::string& perf_modifier) { 550 const std::string& perf_modifier) {
546 base::FilePath trimmed_reference = CreateTemporaryWaveFile();
547 base::FilePath trimmed_recording = CreateTemporaryWaveFile();
548
549 ASSERT_TRUE(RemoveSilence(reference_file, trimmed_reference));
550 ASSERT_TRUE(RemoveSilence(recording, trimmed_recording));
551
552 std::string raw_mos; 551 std::string raw_mos;
553 std::string mos_lqo; 552 std::string mos_lqo;
554 ASSERT_TRUE(RunPesq(trimmed_reference, trimmed_recording, 16000, 553 ASSERT_TRUE(RunPesq(reference_file, recording, 16000, &raw_mos, &mos_lqo));
555 &raw_mos, &mos_lqo));
556 554
557 perf_test::PrintResult( 555 perf_test::PrintResult(
558 "audio_pesq", perf_modifier, "raw_mos", raw_mos, "score", true); 556 "audio_pesq", perf_modifier, "raw_mos", raw_mos, "score", true);
559 perf_test::PrintResult( 557 perf_test::PrintResult(
560 "audio_pesq", perf_modifier, "mos_lqo", mos_lqo, "score", true); 558 "audio_pesq", perf_modifier, "mos_lqo", mos_lqo, "score", true);
561
562 EXPECT_TRUE(base::DeleteFile(trimmed_reference, false));
563 EXPECT_TRUE(base::DeleteFile(trimmed_recording, false));
564 } 559 }
565 560
566 } // namespace 561 } // namespace
567 562
568 // Sets up a one-way WebRTC call and records its output to |recording|, using 563 // Sets up a one-way WebRTC call and records its output to |recording|, using
569 // getUserMedia. 564 // getUserMedia.
570 // 565 //
571 // |reference_file| should have at least two seconds of silence in the 566 // |reference_file| should have at least two seconds of silence in the
572 // beginning: otherwise all the reference audio will not be picked up by the 567 // beginning: otherwise all the reference audio will not be picked up by the
573 // recording. Note that the reference file will start playing as soon as the 568 // recording. Note that the reference file will start playing as soon as the
574 // audio device is up following the getUserMedia call in the left tab. The time 569 // audio device is up following the getUserMedia call in the left tab. The time
575 // it takes to negotiate a call isn't deterministic, but two seconds should be 570 // it takes to negotiate a call isn't deterministic, but two seconds should be
576 // plenty of time. Similarly, the recording time should be enough to catch the 571 // plenty of time. Similarly, the recording time should be enough to catch the
577 // whole reference file. If you then silence-trim the reference file and actual 572 // whole reference file.
578 // file, you should end up with two time-synchronized files.
579 void MAYBE_WebRtcAudioQualityBrowserTest::SetupAndRecordAudioCall( 573 void MAYBE_WebRtcAudioQualityBrowserTest::SetupAndRecordAudioCall(
580 const base::FilePath& reference_file, 574 const base::FilePath& reference_file,
581 const base::FilePath& recording, 575 const base::FilePath& recording,
582 const std::string& constraints, 576 const std::string& constraints,
583 const base::TimeDelta recording_time) { 577 const base::TimeDelta recording_time) {
584 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); 578 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
585 ASSERT_TRUE(test::HasReferenceFilesInCheckout()); 579 ASSERT_TRUE(test::HasReferenceFilesInCheckout());
586 ASSERT_TRUE(ForceMicrophoneVolumeTo100Percent()); 580 ASSERT_TRUE(ForceMicrophoneLevelTo100Percent());
587 581
588 ConfigureFakeDeviceToPlayFile(reference_file); 582 ConfigureFakeDeviceToPlayFile(reference_file);
589 583
590 // Create a one-way call. 584 // Create a one-way call.
591 GURL test_page = embedded_test_server()->GetURL(kWebRtcAudioTestHtmlPage); 585 GURL test_page = embedded_test_server()->GetURL(kWebRtcAudioTestHtmlPage);
592 content::WebContents* left_tab = 586 content::WebContents* left_tab =
593 OpenPageAndGetUserMediaInNewTabWithConstraints(test_page, constraints); 587 OpenPageAndGetUserMediaInNewTabWithConstraints(test_page, constraints);
594 SetupPeerconnectionWithLocalStream(left_tab); 588 SetupPeerconnectionWithLocalStream(left_tab);
595 589
596 content::WebContents* right_tab = 590 content::WebContents* right_tab =
(...skipping 27 matching lines...) Expand all
624 return; 618 return;
625 } 619 }
626 620
627 base::FilePath reference_file = 621 base::FilePath reference_file =
628 test::GetReferenceFilesDir().Append(kReferenceFile); 622 test::GetReferenceFilesDir().Append(kReferenceFile);
629 base::FilePath recording = CreateTemporaryWaveFile(); 623 base::FilePath recording = CreateTemporaryWaveFile();
630 624
631 ASSERT_NO_FATAL_FAILURE(SetupAndRecordAudioCall( 625 ASSERT_NO_FATAL_FAILURE(SetupAndRecordAudioCall(
632 reference_file, recording, kAudioOnlyCallConstraints, 626 reference_file, recording, kAudioOnlyCallConstraints,
633 base::TimeDelta::FromSeconds(25))); 627 base::TimeDelta::FromSeconds(25)));
634 ComputeAndPrintPesqResults(reference_file, recording, "_getusermedia"); 628 ASSERT_NO_FATAL_FAILURE(ComputeAndPrintPesqResults(
629 reference_file, recording, "_getusermedia"));
635 630
636 EXPECT_TRUE(base::DeleteFile(recording, false)); 631 EXPECT_TRUE(base::DeleteFile(recording, false));
637 } 632 }
638 633
639 IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcAudioQualityBrowserTest, 634 IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcAudioQualityBrowserTest,
640 MANUAL_TestCallQualityWithAudioFromWebAudio) { 635 MANUAL_TestCallQualityWithAudioFromWebAudio) {
641 if (OnWinXp() || OnWin8()) { 636 if (OnWinXp() || OnWin8()) {
642 // http://crbug.com/379798. 637 // http://crbug.com/379798.
643 LOG(ERROR) << "This test is not implemented for Windows XP/Win8."; 638 LOG(ERROR) << "This test is not implemented for Windows XP/Win8.";
644 return; 639 return;
645 } 640 }
646 ASSERT_TRUE(test::HasReferenceFilesInCheckout()); 641 ASSERT_TRUE(test::HasReferenceFilesInCheckout());
647 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); 642 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
648 643
649 ASSERT_TRUE(ForceMicrophoneVolumeTo100Percent()); 644 ASSERT_TRUE(ForceMicrophoneLevelTo100Percent());
650 645
651 content::WebContents* left_tab = 646 content::WebContents* left_tab =
652 OpenPageWithoutGetUserMedia(kWebRtcAudioTestHtmlPage); 647 OpenPageWithoutGetUserMedia(kWebRtcAudioTestHtmlPage);
653 content::WebContents* right_tab = 648 content::WebContents* right_tab =
654 OpenPageWithoutGetUserMedia(kWebRtcAudioTestHtmlPage); 649 OpenPageWithoutGetUserMedia(kWebRtcAudioTestHtmlPage);
655 650
656 AddAudioFileToWebAudio(kReferenceFileRelativeUrl, left_tab); 651 AddAudioFileToWebAudio(kReferenceFileRelativeUrl, left_tab);
657 652
658 NegotiateCall(left_tab, right_tab); 653 NegotiateCall(left_tab, right_tab);
659 654
660 base::FilePath recording = CreateTemporaryWaveFile(); 655 base::FilePath recording = CreateTemporaryWaveFile();
661 656
662 // Note: the sound clip is about 13 seconds: record for 20 seconds to get some 657 // Note: the sound clip is about 13 seconds: record for 20 seconds to get some
663 // safety margins on each side. 658 // safety margins on each side.
664 AudioRecorder recorder; 659 AudioRecorder recorder;
665 ASSERT_TRUE(recorder.StartRecording(base::TimeDelta::FromSeconds(20), 660 ASSERT_TRUE(recorder.StartRecording(base::TimeDelta::FromSeconds(20),
666 recording)); 661 recording));
667 662
668 PlayAudioFileThroughWebAudio(left_tab); 663 PlayAudioFileThroughWebAudio(left_tab);
669 664
670 ASSERT_TRUE(recorder.WaitForRecordingToEnd()); 665 ASSERT_TRUE(recorder.WaitForRecordingToEnd());
671 DVLOG(0) << "Done recording to " << recording.value() << std::endl; 666 DVLOG(0) << "Done recording to " << recording.value() << std::endl;
672 667
673 HangUp(left_tab); 668 HangUp(left_tab);
674 669
675 // Compare with the reference file on disk (this is the same file we played 670 // Compare with the reference file on disk (this is the same file we played
676 // through WebAudio earlier). 671 // through WebAudio earlier).
677 base::FilePath reference_file = 672 base::FilePath reference_file =
678 test::GetReferenceFilesDir().Append(kReferenceFile); 673 test::GetReferenceFilesDir().Append(kReferenceFile);
679 ComputeAndPrintPesqResults(reference_file, recording, "_webaudio"); 674 ASSERT_NO_FATAL_FAILURE(ComputeAndPrintPesqResults(
675 reference_file, recording, "_webaudio"));
676 EXPECT_TRUE(base::DeleteFile(recording, false));
680 } 677 }
681 678
682 /** 679 /**
683 * The auto gain control test plays a file into the fake microphone. Then it 680 * The auto gain control test plays a file into the fake microphone. Then it
684 * sets up a one-way WebRTC call with audio only and records Chrome's output on 681 * sets up a one-way WebRTC call with audio only and records Chrome's output on
685 * the receiving side using the audio loopback provided by the quality test 682 * the receiving side using the audio loopback provided by the quality test
686 * (see the class comments for more details). 683 * (see the class comments for more details).
687 * 684 *
688 * Then both the recording and reference file are split on silence. This creates 685 * Then both the recording and reference file are split on silence. This creates
689 * a number of segments with speech in them. The reason for this is to provide 686 * a number of segments with speech in them. The reason for this is to provide
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
774 #endif 771 #endif
775 772
776 // Since the AGC is off here there should be no gain at all. 773 // Since the AGC is off here there should be no gain at all.
777 IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcAudioQualityBrowserTest, 774 IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcAudioQualityBrowserTest,
778 MAYBE_MANUAL_TestAutoGainIsOffWithAudioProcessingOff) { 775 MAYBE_MANUAL_TestAutoGainIsOffWithAudioProcessingOff) {
779 const char* kAudioCallWithoutAudioProcessing = 776 const char* kAudioCallWithoutAudioProcessing =
780 "{audio: { mandatory: { echoCancellation: false } } }"; 777 "{audio: { mandatory: { echoCancellation: false } } }";
781 ASSERT_NO_FATAL_FAILURE(TestAutoGainControl( 778 ASSERT_NO_FATAL_FAILURE(TestAutoGainControl(
782 kReferenceFile, kAudioCallWithoutAudioProcessing, "_no_agc")); 779 kReferenceFile, kAudioCallWithoutAudioProcessing, "_no_agc"));
783 } 780 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698