OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 <windows.h> | 5 #include <windows.h> |
6 #include <mmsystem.h> | 6 #include <mmsystem.h> |
7 | 7 |
8 #include "base/basictypes.h" | 8 #include "base/basictypes.h" |
9 #include "base/environment.h" | 9 #include "base/environment.h" |
10 #include "base/files/file_util.h" | 10 #include "base/files/file_util.h" |
11 #include "base/memory/scoped_ptr.h" | 11 #include "base/memory/scoped_ptr.h" |
12 #include "base/message_loop/message_loop.h" | 12 #include "base/message_loop/message_loop.h" |
13 #include "base/path_service.h" | 13 #include "base/path_service.h" |
14 #include "base/test/test_timeouts.h" | 14 #include "base/test/test_timeouts.h" |
15 #include "base/win/scoped_com_initializer.h" | 15 #include "base/win/scoped_com_initializer.h" |
16 #include "media/audio/audio_io.h" | 16 #include "media/audio/audio_io.h" |
17 #include "media/audio/audio_manager_base.h" | 17 #include "media/audio/audio_manager_base.h" |
| 18 #include "media/audio/audio_unittest_util.h" |
18 #include "media/audio/win/audio_low_latency_input_win.h" | 19 #include "media/audio/win/audio_low_latency_input_win.h" |
19 #include "media/audio/win/core_audio_util_win.h" | 20 #include "media/audio/win/core_audio_util_win.h" |
20 #include "media/base/seekable_buffer.h" | 21 #include "media/base/seekable_buffer.h" |
21 #include "testing/gmock/include/gmock/gmock.h" | 22 #include "testing/gmock/include/gmock/gmock.h" |
22 #include "testing/gtest/include/gtest/gtest.h" | 23 #include "testing/gtest/include/gtest/gtest.h" |
23 | 24 |
24 using base::win::ScopedCOMInitializer; | 25 using base::win::ScopedCOMInitializer; |
25 using ::testing::_; | 26 using ::testing::_; |
26 using ::testing::AnyNumber; | 27 using ::testing::AnyNumber; |
27 using ::testing::AtLeast; | 28 using ::testing::AtLeast; |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 | 144 |
144 virtual void OnError(AudioInputStream* stream) {} | 145 virtual void OnError(AudioInputStream* stream) {} |
145 | 146 |
146 private: | 147 private: |
147 int bits_per_sample_; | 148 int bits_per_sample_; |
148 media::SeekableBuffer buffer_; | 149 media::SeekableBuffer buffer_; |
149 FILE* binary_file_; | 150 FILE* binary_file_; |
150 size_t bytes_to_write_; | 151 size_t bytes_to_write_; |
151 }; | 152 }; |
152 | 153 |
153 // Convenience method which ensures that we are not running on the build | 154 static bool HasCoreAudioAndInputDevices(AudioManager* audio_man) { |
154 // bots and that at least one valid input device can be found. We also | 155 // The low-latency (WASAPI-based) version requires Windows Vista or higher. |
155 // verify that we are not running on XP since the low-latency (WASAPI- | |
156 // based) version requires Windows Vista or higher. | |
157 static bool CanRunAudioTests(AudioManager* audio_man) { | |
158 if (!CoreAudioUtil::IsSupported()) { | |
159 LOG(WARNING) << "This tests requires Windows Vista or higher."; | |
160 return false; | |
161 } | |
162 // TODO(henrika): note that we use Wave today to query the number of | 156 // TODO(henrika): note that we use Wave today to query the number of |
163 // existing input devices. | 157 // existing input devices. |
164 bool input = audio_man->HasAudioInputDevices(); | 158 return CoreAudioUtil::IsSupported() && audio_man->HasAudioInputDevices(); |
165 LOG_IF(WARNING, !input) << "No input device detected."; | |
166 return input; | |
167 } | 159 } |
168 | 160 |
169 // Convenience method which creates a default AudioInputStream object but | 161 // Convenience method which creates a default AudioInputStream object but |
170 // also allows the user to modify the default settings. | 162 // also allows the user to modify the default settings. |
171 class AudioInputStreamWrapper { | 163 class AudioInputStreamWrapper { |
172 public: | 164 public: |
173 explicit AudioInputStreamWrapper(AudioManager* audio_manager) | 165 explicit AudioInputStreamWrapper(AudioManager* audio_manager) |
174 : com_init_(ScopedCOMInitializer::kMTA), | 166 : com_init_(ScopedCOMInitializer::kMTA), |
175 audio_man_(audio_manager), | 167 audio_man_(audio_manager), |
176 default_params_( | 168 default_params_( |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
259 private: | 251 private: |
260 AudioInputStream* stream_; | 252 AudioInputStream* stream_; |
261 | 253 |
262 DISALLOW_COPY_AND_ASSIGN(ScopedAudioInputStream); | 254 DISALLOW_COPY_AND_ASSIGN(ScopedAudioInputStream); |
263 }; | 255 }; |
264 | 256 |
265 // Verify that we can retrieve the current hardware/mixing sample rate | 257 // Verify that we can retrieve the current hardware/mixing sample rate |
266 // for all available input devices. | 258 // for all available input devices. |
267 TEST(WinAudioInputTest, WASAPIAudioInputStreamHardwareSampleRate) { | 259 TEST(WinAudioInputTest, WASAPIAudioInputStreamHardwareSampleRate) { |
268 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting()); | 260 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting()); |
269 if (!CanRunAudioTests(audio_manager.get())) | 261 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager.get())); |
270 return; | |
271 | 262 |
272 ScopedCOMInitializer com_init(ScopedCOMInitializer::kMTA); | 263 ScopedCOMInitializer com_init(ScopedCOMInitializer::kMTA); |
273 | 264 |
274 // Retrieve a list of all available input devices. | 265 // Retrieve a list of all available input devices. |
275 media::AudioDeviceNames device_names; | 266 media::AudioDeviceNames device_names; |
276 audio_manager->GetAudioInputDeviceNames(&device_names); | 267 audio_manager->GetAudioInputDeviceNames(&device_names); |
277 | 268 |
278 // Scan all available input devices and repeat the same test for all of them. | 269 // Scan all available input devices and repeat the same test for all of them. |
279 for (media::AudioDeviceNames::const_iterator it = device_names.begin(); | 270 for (media::AudioDeviceNames::const_iterator it = device_names.begin(); |
280 it != device_names.end(); ++it) { | 271 it != device_names.end(); ++it) { |
281 // Retrieve the hardware sample rate given a specified audio input device. | 272 // Retrieve the hardware sample rate given a specified audio input device. |
282 AudioParameters params = WASAPIAudioInputStream::GetInputStreamParameters( | 273 AudioParameters params = WASAPIAudioInputStream::GetInputStreamParameters( |
283 it->unique_id); | 274 it->unique_id); |
284 EXPECT_GE(params.sample_rate(), 0); | 275 EXPECT_GE(params.sample_rate(), 0); |
285 } | 276 } |
286 } | 277 } |
287 | 278 |
288 // Test Create(), Close() calling sequence. | 279 // Test Create(), Close() calling sequence. |
289 TEST(WinAudioInputTest, WASAPIAudioInputStreamCreateAndClose) { | 280 TEST(WinAudioInputTest, WASAPIAudioInputStreamCreateAndClose) { |
290 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting()); | 281 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting()); |
291 if (!CanRunAudioTests(audio_manager.get())) | 282 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager.get())); |
292 return; | |
293 ScopedAudioInputStream ais( | 283 ScopedAudioInputStream ais( |
294 CreateDefaultAudioInputStream(audio_manager.get())); | 284 CreateDefaultAudioInputStream(audio_manager.get())); |
295 ais.Close(); | 285 ais.Close(); |
296 } | 286 } |
297 | 287 |
298 // Test Open(), Close() calling sequence. | 288 // Test Open(), Close() calling sequence. |
299 TEST(WinAudioInputTest, WASAPIAudioInputStreamOpenAndClose) { | 289 TEST(WinAudioInputTest, WASAPIAudioInputStreamOpenAndClose) { |
300 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting()); | 290 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting()); |
301 if (!CanRunAudioTests(audio_manager.get())) | 291 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager.get())); |
302 return; | |
303 ScopedAudioInputStream ais( | 292 ScopedAudioInputStream ais( |
304 CreateDefaultAudioInputStream(audio_manager.get())); | 293 CreateDefaultAudioInputStream(audio_manager.get())); |
305 EXPECT_TRUE(ais->Open()); | 294 EXPECT_TRUE(ais->Open()); |
306 ais.Close(); | 295 ais.Close(); |
307 } | 296 } |
308 | 297 |
309 // Test Open(), Start(), Close() calling sequence. | 298 // Test Open(), Start(), Close() calling sequence. |
310 TEST(WinAudioInputTest, WASAPIAudioInputStreamOpenStartAndClose) { | 299 TEST(WinAudioInputTest, WASAPIAudioInputStreamOpenStartAndClose) { |
311 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting()); | 300 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting()); |
312 if (!CanRunAudioTests(audio_manager.get())) | 301 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager.get())); |
313 return; | |
314 ScopedAudioInputStream ais( | 302 ScopedAudioInputStream ais( |
315 CreateDefaultAudioInputStream(audio_manager.get())); | 303 CreateDefaultAudioInputStream(audio_manager.get())); |
316 EXPECT_TRUE(ais->Open()); | 304 EXPECT_TRUE(ais->Open()); |
317 MockAudioInputCallback sink; | 305 MockAudioInputCallback sink; |
318 ais->Start(&sink); | 306 ais->Start(&sink); |
319 ais.Close(); | 307 ais.Close(); |
320 } | 308 } |
321 | 309 |
322 // Test Open(), Start(), Stop(), Close() calling sequence. | 310 // Test Open(), Start(), Stop(), Close() calling sequence. |
323 TEST(WinAudioInputTest, WASAPIAudioInputStreamOpenStartStopAndClose) { | 311 TEST(WinAudioInputTest, WASAPIAudioInputStreamOpenStartStopAndClose) { |
324 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting()); | 312 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting()); |
325 if (!CanRunAudioTests(audio_manager.get())) | 313 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager.get())); |
326 return; | |
327 ScopedAudioInputStream ais( | 314 ScopedAudioInputStream ais( |
328 CreateDefaultAudioInputStream(audio_manager.get())); | 315 CreateDefaultAudioInputStream(audio_manager.get())); |
329 EXPECT_TRUE(ais->Open()); | 316 EXPECT_TRUE(ais->Open()); |
330 MockAudioInputCallback sink; | 317 MockAudioInputCallback sink; |
331 ais->Start(&sink); | 318 ais->Start(&sink); |
332 ais->Stop(); | 319 ais->Stop(); |
333 ais.Close(); | 320 ais.Close(); |
334 } | 321 } |
335 | 322 |
336 // Test some additional calling sequences. | 323 // Test some additional calling sequences. |
337 TEST(WinAudioInputTest, WASAPIAudioInputStreamMiscCallingSequences) { | 324 TEST(WinAudioInputTest, WASAPIAudioInputStreamMiscCallingSequences) { |
338 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting()); | 325 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting()); |
339 if (!CanRunAudioTests(audio_manager.get())) | 326 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager.get())); |
340 return; | |
341 ScopedAudioInputStream ais( | 327 ScopedAudioInputStream ais( |
342 CreateDefaultAudioInputStream(audio_manager.get())); | 328 CreateDefaultAudioInputStream(audio_manager.get())); |
343 WASAPIAudioInputStream* wais = | 329 WASAPIAudioInputStream* wais = |
344 static_cast<WASAPIAudioInputStream*>(ais.get()); | 330 static_cast<WASAPIAudioInputStream*>(ais.get()); |
345 | 331 |
346 // Open(), Open() should fail the second time. | 332 // Open(), Open() should fail the second time. |
347 EXPECT_TRUE(ais->Open()); | 333 EXPECT_TRUE(ais->Open()); |
348 EXPECT_FALSE(ais->Open()); | 334 EXPECT_FALSE(ais->Open()); |
349 | 335 |
350 MockAudioInputCallback sink; | 336 MockAudioInputCallback sink; |
351 | 337 |
352 // Start(), Start() is a valid calling sequence (second call does nothing). | 338 // Start(), Start() is a valid calling sequence (second call does nothing). |
353 ais->Start(&sink); | 339 ais->Start(&sink); |
354 EXPECT_TRUE(wais->started()); | 340 EXPECT_TRUE(wais->started()); |
355 ais->Start(&sink); | 341 ais->Start(&sink); |
356 EXPECT_TRUE(wais->started()); | 342 EXPECT_TRUE(wais->started()); |
357 | 343 |
358 // Stop(), Stop() is a valid calling sequence (second call does nothing). | 344 // Stop(), Stop() is a valid calling sequence (second call does nothing). |
359 ais->Stop(); | 345 ais->Stop(); |
360 EXPECT_FALSE(wais->started()); | 346 EXPECT_FALSE(wais->started()); |
361 ais->Stop(); | 347 ais->Stop(); |
362 EXPECT_FALSE(wais->started()); | 348 EXPECT_FALSE(wais->started()); |
363 ais.Close(); | 349 ais.Close(); |
364 } | 350 } |
365 | 351 |
366 TEST(WinAudioInputTest, WASAPIAudioInputStreamTestPacketSizes) { | 352 TEST(WinAudioInputTest, WASAPIAudioInputStreamTestPacketSizes) { |
367 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting()); | 353 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting()); |
368 if (!CanRunAudioTests(audio_manager.get())) | 354 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager.get())); |
369 return; | |
370 | 355 |
371 int count = 0; | 356 int count = 0; |
372 base::MessageLoopForUI loop; | 357 base::MessageLoopForUI loop; |
373 | 358 |
374 // 10 ms packet size. | 359 // 10 ms packet size. |
375 | 360 |
376 // Create default WASAPI input stream which records in stereo using | 361 // Create default WASAPI input stream which records in stereo using |
377 // the shared mixing rate. The default buffer size is 10ms. | 362 // the shared mixing rate. The default buffer size is 10ms. |
378 AudioInputStreamWrapper aisw(audio_manager.get()); | 363 AudioInputStreamWrapper aisw(audio_manager.get()); |
379 ScopedAudioInputStream ais(aisw.Create()); | 364 ScopedAudioInputStream ais(aisw.Create()); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
429 .WillRepeatedly(CheckCountAndPostQuitTask(&count, 10, &loop)); | 414 .WillRepeatedly(CheckCountAndPostQuitTask(&count, 10, &loop)); |
430 ais->Start(&sink); | 415 ais->Start(&sink); |
431 loop.Run(); | 416 loop.Run(); |
432 ais->Stop(); | 417 ais->Stop(); |
433 ais.Close(); | 418 ais.Close(); |
434 } | 419 } |
435 | 420 |
436 // Test that we can capture a stream in loopback. | 421 // Test that we can capture a stream in loopback. |
437 TEST(WinAudioInputTest, WASAPIAudioInputStreamLoopback) { | 422 TEST(WinAudioInputTest, WASAPIAudioInputStreamLoopback) { |
438 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting()); | 423 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting()); |
439 if (!audio_manager->HasAudioOutputDevices() || !CoreAudioUtil::IsSupported()) | 424 ABORT_AUDIO_TEST_IF_NOT(audio_manager->HasAudioOutputDevices() && |
440 return; | 425 CoreAudioUtil::IsSupported()); |
441 | 426 |
442 AudioParameters params = audio_manager->GetInputStreamParameters( | 427 AudioParameters params = audio_manager->GetInputStreamParameters( |
443 AudioManagerBase::kLoopbackInputDeviceId); | 428 AudioManagerBase::kLoopbackInputDeviceId); |
444 EXPECT_EQ(params.effects(), 0); | 429 EXPECT_EQ(params.effects(), 0); |
445 | 430 |
446 AudioParameters output_params = | 431 AudioParameters output_params = |
447 audio_manager->GetOutputStreamParameters(std::string()); | 432 audio_manager->GetOutputStreamParameters(std::string()); |
448 EXPECT_EQ(params.sample_rate(), output_params.sample_rate()); | 433 EXPECT_EQ(params.sample_rate(), output_params.sample_rate()); |
449 EXPECT_EQ(params.channel_layout(), output_params.channel_layout()); | 434 EXPECT_EQ(params.channel_layout(), output_params.channel_layout()); |
450 | 435 |
(...skipping 12 matching lines...) Expand all Loading... |
463 } | 448 } |
464 | 449 |
465 // This test is intended for manual tests and should only be enabled | 450 // This test is intended for manual tests and should only be enabled |
466 // when it is required to store the captured data on a local file. | 451 // when it is required to store the captured data on a local file. |
467 // By default, GTest will print out YOU HAVE 1 DISABLED TEST. | 452 // By default, GTest will print out YOU HAVE 1 DISABLED TEST. |
468 // To include disabled tests in test execution, just invoke the test program | 453 // To include disabled tests in test execution, just invoke the test program |
469 // with --gtest_also_run_disabled_tests or set the GTEST_ALSO_RUN_DISABLED_TESTS | 454 // with --gtest_also_run_disabled_tests or set the GTEST_ALSO_RUN_DISABLED_TESTS |
470 // environment variable to a value greater than 0. | 455 // environment variable to a value greater than 0. |
471 TEST(WinAudioInputTest, DISABLED_WASAPIAudioInputStreamRecordToFile) { | 456 TEST(WinAudioInputTest, DISABLED_WASAPIAudioInputStreamRecordToFile) { |
472 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting()); | 457 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting()); |
473 if (!CanRunAudioTests(audio_manager.get())) | 458 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager.get())); |
474 return; | |
475 | 459 |
476 // Name of the output PCM file containing captured data. The output file | 460 // Name of the output PCM file containing captured data. The output file |
477 // will be stored in the directory containing 'media_unittests.exe'. | 461 // will be stored in the directory containing 'media_unittests.exe'. |
478 // Example of full name: \src\build\Debug\out_stereo_10sec.pcm. | 462 // Example of full name: \src\build\Debug\out_stereo_10sec.pcm. |
479 const char* file_name = "out_stereo_10sec.pcm"; | 463 const char* file_name = "out_stereo_10sec.pcm"; |
480 | 464 |
481 AudioInputStreamWrapper aisw(audio_manager.get()); | 465 AudioInputStreamWrapper aisw(audio_manager.get()); |
482 ScopedAudioInputStream ais(aisw.Create()); | 466 ScopedAudioInputStream ais(aisw.Create()); |
483 EXPECT_TRUE(ais->Open()); | 467 EXPECT_TRUE(ais->Open()); |
484 | 468 |
485 VLOG(0) << ">> Sample rate: " << aisw.sample_rate() << " [Hz]"; | 469 VLOG(0) << ">> Sample rate: " << aisw.sample_rate() << " [Hz]"; |
486 WriteToFileAudioSink file_sink(file_name, aisw.bits_per_sample()); | 470 WriteToFileAudioSink file_sink(file_name, aisw.bits_per_sample()); |
487 VLOG(0) << ">> Speak into the default microphone while recording."; | 471 VLOG(0) << ">> Speak into the default microphone while recording."; |
488 ais->Start(&file_sink); | 472 ais->Start(&file_sink); |
489 base::PlatformThread::Sleep(TestTimeouts::action_timeout()); | 473 base::PlatformThread::Sleep(TestTimeouts::action_timeout()); |
490 ais->Stop(); | 474 ais->Stop(); |
491 VLOG(0) << ">> Recording has stopped."; | 475 VLOG(0) << ">> Recording has stopped."; |
492 ais.Close(); | 476 ais.Close(); |
493 } | 477 } |
494 | 478 |
495 } // namespace media | 479 } // namespace media |
OLD | NEW |