| 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_utils.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 |