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_util.h" | 8 #include "base/files/file_util.h" |
9 #include "base/path_service.h" | 9 #include "base/path_service.h" |
10 #include "base/process/launch.h" | 10 #include "base/process/launch.h" |
(...skipping 11 matching lines...) Expand all Loading... |
22 #include "content/public/test/browser_test_utils.h" | 22 #include "content/public/test/browser_test_utils.h" |
23 #include "media/base/media_switches.h" | 23 #include "media/base/media_switches.h" |
24 #include "net/test/embedded_test_server/embedded_test_server.h" | 24 #include "net/test/embedded_test_server/embedded_test_server.h" |
25 #include "testing/perf/perf_test.h" | 25 #include "testing/perf/perf_test.h" |
26 | 26 |
27 // These are relative to the reference file dir defined by | 27 // These are relative to the reference file dir defined by |
28 // webrtc_browsertest_common.h (i.e. chrome/test/data/webrtc/resources). | 28 // webrtc_browsertest_common.h (i.e. chrome/test/data/webrtc/resources). |
29 static const base::FilePath::CharType kReferenceFile[] = | 29 static const base::FilePath::CharType kReferenceFile[] = |
30 #if defined (OS_WIN) | 30 #if defined (OS_WIN) |
31 FILE_PATH_LITERAL("human-voice-win.wav"); | 31 FILE_PATH_LITERAL("human-voice-win.wav"); |
| 32 #elif defined (OS_MACOSX) |
| 33 FILE_PATH_LITERAL("human-voice-mac.wav"); |
32 #else | 34 #else |
33 FILE_PATH_LITERAL("human-voice-linux.wav"); | 35 FILE_PATH_LITERAL("human-voice-linux.wav"); |
34 #endif | 36 #endif |
35 | 37 |
36 // The javascript will load the reference file relative to its location, | 38 // The javascript will load the reference file relative to its location, |
37 // which is in /webrtc on the web server. The files we are looking for are in | 39 // which is in /webrtc on the web server. The files we are looking for are in |
38 // webrtc/resources in the chrome/test/data folder. | 40 // webrtc/resources in the chrome/test/data folder. |
39 static const char kReferenceFileRelativeUrl[] = | 41 static const char kReferenceFileRelativeUrl[] = |
40 #if defined (OS_WIN) | 42 #if defined (OS_WIN) |
41 "resources/human-voice-win.wav"; | 43 "resources/human-voice-win.wav"; |
| 44 #elif defined (OS_MACOSX) |
| 45 "resources/human-voice-mac.wav"; |
42 #else | 46 #else |
43 "resources/human-voice-linux.wav"; | 47 "resources/human-voice-linux.wav"; |
44 #endif | 48 #endif |
45 | 49 |
46 static const char kMainWebrtcTestHtmlPage[] = | 50 static const char kMainWebrtcTestHtmlPage[] = |
47 "/webrtc/webrtc_audio_quality_test.html"; | 51 "/webrtc/webrtc_audio_quality_test.html"; |
48 | 52 |
49 // Test we can set up a WebRTC call and play audio through it. | 53 // Test we can set up a WebRTC call and play audio through it. |
50 // | 54 // |
51 // If you're not a googler and want to run this test, you need to provide a | 55 // If you're not a googler and want to run this test, you need to provide a |
(...skipping 11 matching lines...) Expand all Loading... |
63 // 5. For the ALSA plug-in [aplay]: ALSA Capture from, change from <x> to | 67 // 5. For the ALSA plug-in [aplay]: ALSA Capture from, change from <x> to |
64 // <Monitor of x>, where x is whatever your primary sound device is called. | 68 // <Monitor of x>, where x is whatever your primary sound device is called. |
65 // 6. Try launching chrome as the target user on the target machine, try | 69 // 6. Try launching chrome as the target user on the target machine, try |
66 // playing, say, a YouTube video, and record with # arecord -f dat tmp.dat. | 70 // playing, say, a YouTube video, and record with # arecord -f dat tmp.dat. |
67 // Verify the recording with aplay (should have recorded what you played | 71 // Verify the recording with aplay (should have recorded what you played |
68 // from chrome). | 72 // from chrome). |
69 // | 73 // |
70 // Note: the volume for ALL your input devices will be forced to 100% by | 74 // Note: the volume for ALL your input devices will be forced to 100% by |
71 // running this test on Linux. | 75 // running this test on Linux. |
72 // | 76 // |
| 77 // On Mac: |
| 78 // 1. Get SoundFlower: http://rogueamoeba.com/freebies/soundflower/download.php |
| 79 // 2. Install it + reboot. |
| 80 // 3. Install MacPorts (http://www.macports.org/). |
| 81 // 4. Install sox: sudo port install sox. |
| 82 // 5. In Sound Preferences, set both input and output to Soundflower (2ch). |
| 83 // Note: You will no longer hear audio on this machine, and it will no |
| 84 // longer use any built-in mics. |
| 85 // 6. Ensure the output volume is max and the input volume at about 20%. |
| 86 // 7. Try launching chrome as the target user on the target machine, try |
| 87 // playing, say, a YouTube video, and record with 'rec test.wav trim 0 5'. |
| 88 // Stop the video in chrome and try playing back the file; you should hear |
| 89 // a recording of the video (note; if you play back on the target machine |
| 90 // you must revert the changes in step 3 first). |
| 91 // |
73 // On Windows 7: | 92 // On Windows 7: |
74 // 1. Control panel > Sound > Manage audio devices. | 93 // 1. Control panel > Sound > Manage audio devices. |
75 // 2. In the recording tab, right-click in an empty space in the pane with the | 94 // 2. In the recording tab, right-click in an empty space in the pane with the |
76 // devices. Tick 'show disabled devices'. | 95 // devices. Tick 'show disabled devices'. |
77 // 3. You should see a 'stero mix' device - this is what your speakers output. | 96 // 3. You should see a 'stero mix' device - this is what your speakers output. |
78 // Right click > Properties. | 97 // Right click > Properties. |
79 // 4. In the Listen tab for the mix device, check the 'listen to this device' | 98 // 4. In the Listen tab for the mix device, check the 'listen to this device' |
80 // checkbox. Ensure the mix device is the default recording device. | 99 // checkbox. Ensure the mix device is the default recording device. |
81 // 5. Launch chrome and try playing a video with sound. You should see | 100 // 5. Launch chrome and try playing a video with sound. You should see |
82 // in the volume meter for the mix device. Configure the mix device to have | 101 // in the volume meter for the mix device. Configure the mix device to have |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 duration_tm.tm_sec = duration_sec; | 175 duration_tm.tm_sec = duration_sec; |
157 EXPECT_NE(0u, strftime(duration_in_hms, arraysize(duration_in_hms), | 176 EXPECT_NE(0u, strftime(duration_in_hms, arraysize(duration_in_hms), |
158 "%H:%M:%S", &duration_tm)); | 177 "%H:%M:%S", &duration_tm)); |
159 | 178 |
160 command_line.SetProgram( | 179 command_line.SetProgram( |
161 base::FilePath(FILE_PATH_LITERAL("SoundRecorder.exe"))); | 180 base::FilePath(FILE_PATH_LITERAL("SoundRecorder.exe"))); |
162 command_line.AppendArg("/FILE"); | 181 command_line.AppendArg("/FILE"); |
163 command_line.AppendArgPath(output_file); | 182 command_line.AppendArgPath(output_file); |
164 command_line.AppendArg("/DURATION"); | 183 command_line.AppendArg("/DURATION"); |
165 command_line.AppendArg(duration_in_hms); | 184 command_line.AppendArg(duration_in_hms); |
| 185 #elif defined(OS_MACOSX) |
| 186 command_line.SetProgram(base::FilePath("rec")); |
| 187 command_line.AppendArg("-b"); |
| 188 command_line.AppendArg("16"); |
| 189 command_line.AppendArg("-q"); |
| 190 command_line.AppendArgPath(output_file); |
| 191 command_line.AppendArg("trim"); |
| 192 command_line.AppendArg("0"); |
| 193 command_line.AppendArg(base::StringPrintf("%d", duration_sec)); |
| 194 command_line.AppendArg("rate"); |
| 195 command_line.AppendArg("16k"); |
| 196 if (mono) { |
| 197 command_line.AppendArg("remix"); |
| 198 command_line.AppendArg("-"); |
| 199 } |
166 #else | 200 #else |
167 int num_channels = mono ? 1 : 2; | 201 int num_channels = mono ? 1 : 2; |
168 command_line.SetProgram(base::FilePath("arecord")); | 202 command_line.SetProgram(base::FilePath("arecord")); |
169 command_line.AppendArg("-d"); | 203 command_line.AppendArg("-d"); |
170 command_line.AppendArg(base::StringPrintf("%d", duration_sec)); | 204 command_line.AppendArg(base::StringPrintf("%d", duration_sec)); |
171 command_line.AppendArg("-f"); | 205 command_line.AppendArg("-f"); |
172 command_line.AppendArg("dat"); | 206 command_line.AppendArg("dat"); |
173 command_line.AppendArg("-c"); | 207 command_line.AppendArg("-c"); |
174 command_line.AppendArg(base::StringPrintf("%d", num_channels)); | 208 command_line.AppendArg(base::StringPrintf("%d", num_channels)); |
175 command_line.AppendArgPath(output_file); | 209 command_line.AppendArgPath(output_file); |
(...skipping 18 matching lines...) Expand all Loading... |
194 #if defined(OS_WIN) | 228 #if defined(OS_WIN) |
195 // Note: the force binary isn't in tools since it's one of our own. | 229 // Note: the force binary isn't in tools since it's one of our own. |
196 CommandLine command_line(test::GetReferenceFilesDir().Append( | 230 CommandLine command_line(test::GetReferenceFilesDir().Append( |
197 FILE_PATH_LITERAL("force_mic_volume_max.exe"))); | 231 FILE_PATH_LITERAL("force_mic_volume_max.exe"))); |
198 VLOG(0) << "Running " << command_line.GetCommandLineString(); | 232 VLOG(0) << "Running " << command_line.GetCommandLineString(); |
199 std::string result; | 233 std::string result; |
200 if (!base::GetAppOutput(command_line, &result)) { | 234 if (!base::GetAppOutput(command_line, &result)) { |
201 LOG(ERROR) << "Failed to set source volume: output was " << result; | 235 LOG(ERROR) << "Failed to set source volume: output was " << result; |
202 return false; | 236 return false; |
203 } | 237 } |
| 238 #elif defined(OS_MACOSX) |
| 239 // TODO(phoglund): implement. |
204 #else | 240 #else |
205 // Just force the volume of, say the first 5 devices. A machine will rarely | 241 // 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 | 242 // have more input sources than that. This is way easier than finding the |
207 // input device we happen to be using. | 243 // input device we happen to be using. |
208 for (int device_index = 0; device_index < 5; ++device_index) { | 244 for (int device_index = 0; device_index < 5; ++device_index) { |
209 std::string result; | 245 std::string result; |
210 const std::string kHundredPercentVolume = "65536"; | 246 const std::string kHundredPercentVolume = "65536"; |
211 CommandLine command_line(base::FilePath(FILE_PATH_LITERAL("pacmd"))); | 247 CommandLine command_line(base::FilePath(FILE_PATH_LITERAL("pacmd"))); |
212 command_line.AppendArg("set-source-volume"); | 248 command_line.AppendArg("set-source-volume"); |
213 command_line.AppendArg(base::StringPrintf("%d", device_index)); | 249 command_line.AppendArg(base::StringPrintf("%d", device_index)); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
290 bool RunPesq(const base::FilePath& reference_file, | 326 bool RunPesq(const base::FilePath& reference_file, |
291 const base::FilePath& actual_file, | 327 const base::FilePath& actual_file, |
292 int sample_rate, std::string* raw_mos, std::string* mos_lqo) { | 328 int sample_rate, std::string* raw_mos, std::string* mos_lqo) { |
293 // PESQ will break if the paths are too long (!). | 329 // PESQ will break if the paths are too long (!). |
294 EXPECT_LT(reference_file.value().length(), 128u); | 330 EXPECT_LT(reference_file.value().length(), 128u); |
295 EXPECT_LT(actual_file.value().length(), 128u); | 331 EXPECT_LT(actual_file.value().length(), 128u); |
296 | 332 |
297 #if defined(OS_WIN) | 333 #if defined(OS_WIN) |
298 base::FilePath pesq_path = | 334 base::FilePath pesq_path = |
299 test::GetReferenceFilesDir().Append(FILE_PATH_LITERAL("tools/pesq.exe")); | 335 test::GetReferenceFilesDir().Append(FILE_PATH_LITERAL("tools/pesq.exe")); |
| 336 #elif defined(OS_MACOSX) |
| 337 base::FilePath pesq_path = |
| 338 test::GetReferenceFilesDir().Append(FILE_PATH_LITERAL("tools/pesq_mac")); |
300 #else | 339 #else |
301 base::FilePath pesq_path = | 340 base::FilePath pesq_path = |
302 test::GetReferenceFilesDir().Append(FILE_PATH_LITERAL("tools/pesq")); | 341 test::GetReferenceFilesDir().Append(FILE_PATH_LITERAL("tools/pesq")); |
303 #endif | 342 #endif |
304 | 343 |
305 if (!base::PathExists(pesq_path)) { | 344 if (!base::PathExists(pesq_path)) { |
306 LOG(ERROR) << "Missing PESQ binary in " << pesq_path.value() | 345 LOG(ERROR) << "Missing PESQ binary in " << pesq_path.value() |
307 << "; you may have to provide this binary yourself."; | 346 << "; you may have to provide this binary yourself."; |
308 return false; | 347 return false; |
309 } | 348 } |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
416 test::GetReferenceFilesDir().Append(kReferenceFile); | 455 test::GetReferenceFilesDir().Append(kReferenceFile); |
417 ASSERT_TRUE(RunPesq(reference_file_in_test_dir, trimmed_recording, 16000, | 456 ASSERT_TRUE(RunPesq(reference_file_in_test_dir, trimmed_recording, 16000, |
418 &raw_mos, &mos_lqo)); | 457 &raw_mos, &mos_lqo)); |
419 | 458 |
420 perf_test::PrintResult("audio_pesq", "", "raw_mos", raw_mos, "score", true); | 459 perf_test::PrintResult("audio_pesq", "", "raw_mos", raw_mos, "score", true); |
421 perf_test::PrintResult("audio_pesq", "", "mos_lqo", mos_lqo, "score", true); | 460 perf_test::PrintResult("audio_pesq", "", "mos_lqo", mos_lqo, "score", true); |
422 | 461 |
423 EXPECT_TRUE(base::DeleteFile(recording, false)); | 462 EXPECT_TRUE(base::DeleteFile(recording, false)); |
424 EXPECT_TRUE(base::DeleteFile(trimmed_recording, false)); | 463 EXPECT_TRUE(base::DeleteFile(trimmed_recording, false)); |
425 } | 464 } |
OLD | NEW |