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 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include "base/environment.h" | 10 #include "base/environment.h" |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
243 Close(); | 243 Close(); |
244 stream_ = new_stream; | 244 stream_ = new_stream; |
245 } | 245 } |
246 | 246 |
247 private: | 247 private: |
248 AudioInputStream* stream_; | 248 AudioInputStream* stream_; |
249 | 249 |
250 DISALLOW_COPY_AND_ASSIGN(ScopedAudioInputStream); | 250 DISALLOW_COPY_AND_ASSIGN(ScopedAudioInputStream); |
251 }; | 251 }; |
252 | 252 |
| 253 class WinAudioInputTest : public ::testing::Test { |
| 254 public: |
| 255 WinAudioInputTest() { |
| 256 audio_manager_ = |
| 257 AudioManager::CreateForTesting(message_loop_.task_runner()); |
| 258 message_loop_.RunUntilIdle(); |
| 259 } |
| 260 ~WinAudioInputTest() override { |
| 261 audio_manager_.reset(); |
| 262 message_loop_.RunUntilIdle(); |
| 263 } |
| 264 |
| 265 protected: |
| 266 base::MessageLoop message_loop_; |
| 267 ScopedAudioManagerPtr audio_manager_; |
| 268 }; |
| 269 |
253 // Verify that we can retrieve the current hardware/mixing sample rate | 270 // Verify that we can retrieve the current hardware/mixing sample rate |
254 // for all available input devices. | 271 // for all available input devices. |
255 TEST(WinAudioInputTest, WASAPIAudioInputStreamHardwareSampleRate) { | 272 TEST_F(WinAudioInputTest, WASAPIAudioInputStreamHardwareSampleRate) { |
256 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting()); | 273 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager_.get())); |
257 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager.get())); | |
258 | 274 |
259 // Retrieve a list of all available input devices. | 275 // Retrieve a list of all available input devices. |
260 media::AudioDeviceNames device_names; | 276 media::AudioDeviceNames device_names; |
261 audio_manager->GetAudioInputDeviceNames(&device_names); | 277 audio_manager_->GetAudioInputDeviceNames(&device_names); |
262 | 278 |
263 // Scan all available input devices and repeat the same test for all of them. | 279 // Scan all available input devices and repeat the same test for all of them. |
264 for (media::AudioDeviceNames::const_iterator it = device_names.begin(); | 280 for (media::AudioDeviceNames::const_iterator it = device_names.begin(); |
265 it != device_names.end(); ++it) { | 281 it != device_names.end(); ++it) { |
266 // Retrieve the hardware sample rate given a specified audio input device. | 282 // Retrieve the hardware sample rate given a specified audio input device. |
267 AudioParameters params; | 283 AudioParameters params; |
268 ASSERT_TRUE(SUCCEEDED(CoreAudioUtil::GetPreferredAudioParameters( | 284 ASSERT_TRUE(SUCCEEDED(CoreAudioUtil::GetPreferredAudioParameters( |
269 it->unique_id, false, ¶ms))); | 285 it->unique_id, false, ¶ms))); |
270 EXPECT_GE(params.sample_rate(), 0); | 286 EXPECT_GE(params.sample_rate(), 0); |
271 } | 287 } |
272 } | 288 } |
273 | 289 |
274 // Test Create(), Close() calling sequence. | 290 // Test Create(), Close() calling sequence. |
275 TEST(WinAudioInputTest, WASAPIAudioInputStreamCreateAndClose) { | 291 TEST_F(WinAudioInputTest, WASAPIAudioInputStreamCreateAndClose) { |
276 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting()); | 292 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager_.get())); |
277 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager.get())); | |
278 ScopedAudioInputStream ais( | 293 ScopedAudioInputStream ais( |
279 CreateDefaultAudioInputStream(audio_manager.get())); | 294 CreateDefaultAudioInputStream(audio_manager_.get())); |
280 ais.Close(); | 295 ais.Close(); |
281 } | 296 } |
282 | 297 |
283 // Test Open(), Close() calling sequence. | 298 // Test Open(), Close() calling sequence. |
284 TEST(WinAudioInputTest, WASAPIAudioInputStreamOpenAndClose) { | 299 TEST_F(WinAudioInputTest, WASAPIAudioInputStreamOpenAndClose) { |
285 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting()); | 300 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager_.get())); |
286 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager.get())); | |
287 ScopedAudioInputStream ais( | 301 ScopedAudioInputStream ais( |
288 CreateDefaultAudioInputStream(audio_manager.get())); | 302 CreateDefaultAudioInputStream(audio_manager_.get())); |
289 EXPECT_TRUE(ais->Open()); | 303 EXPECT_TRUE(ais->Open()); |
290 ais.Close(); | 304 ais.Close(); |
291 } | 305 } |
292 | 306 |
293 // Test Open(), Start(), Close() calling sequence. | 307 // Test Open(), Start(), Close() calling sequence. |
294 TEST(WinAudioInputTest, WASAPIAudioInputStreamOpenStartAndClose) { | 308 TEST_F(WinAudioInputTest, WASAPIAudioInputStreamOpenStartAndClose) { |
295 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting()); | 309 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager_.get())); |
296 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager.get())); | |
297 ScopedAudioInputStream ais( | 310 ScopedAudioInputStream ais( |
298 CreateDefaultAudioInputStream(audio_manager.get())); | 311 CreateDefaultAudioInputStream(audio_manager_.get())); |
299 EXPECT_TRUE(ais->Open()); | 312 EXPECT_TRUE(ais->Open()); |
300 MockAudioInputCallback sink; | 313 MockAudioInputCallback sink; |
301 ais->Start(&sink); | 314 ais->Start(&sink); |
302 ais.Close(); | 315 ais.Close(); |
303 } | 316 } |
304 | 317 |
305 // Test Open(), Start(), Stop(), Close() calling sequence. | 318 // Test Open(), Start(), Stop(), Close() calling sequence. |
306 TEST(WinAudioInputTest, WASAPIAudioInputStreamOpenStartStopAndClose) { | 319 TEST_F(WinAudioInputTest, WASAPIAudioInputStreamOpenStartStopAndClose) { |
307 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting()); | 320 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager_.get())); |
308 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager.get())); | |
309 ScopedAudioInputStream ais( | 321 ScopedAudioInputStream ais( |
310 CreateDefaultAudioInputStream(audio_manager.get())); | 322 CreateDefaultAudioInputStream(audio_manager_.get())); |
311 EXPECT_TRUE(ais->Open()); | 323 EXPECT_TRUE(ais->Open()); |
312 MockAudioInputCallback sink; | 324 MockAudioInputCallback sink; |
313 ais->Start(&sink); | 325 ais->Start(&sink); |
314 ais->Stop(); | 326 ais->Stop(); |
315 ais.Close(); | 327 ais.Close(); |
316 } | 328 } |
317 | 329 |
318 // Test some additional calling sequences. | 330 // Test some additional calling sequences. |
319 TEST(WinAudioInputTest, WASAPIAudioInputStreamMiscCallingSequences) { | 331 TEST_F(WinAudioInputTest, WASAPIAudioInputStreamMiscCallingSequences) { |
320 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting()); | 332 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager_.get())); |
321 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager.get())); | |
322 ScopedAudioInputStream ais( | 333 ScopedAudioInputStream ais( |
323 CreateDefaultAudioInputStream(audio_manager.get())); | 334 CreateDefaultAudioInputStream(audio_manager_.get())); |
324 WASAPIAudioInputStream* wais = | 335 WASAPIAudioInputStream* wais = |
325 static_cast<WASAPIAudioInputStream*>(ais.get()); | 336 static_cast<WASAPIAudioInputStream*>(ais.get()); |
326 | 337 |
327 // Open(), Open() should fail the second time. | 338 // Open(), Open() should fail the second time. |
328 EXPECT_TRUE(ais->Open()); | 339 EXPECT_TRUE(ais->Open()); |
329 EXPECT_FALSE(ais->Open()); | 340 EXPECT_FALSE(ais->Open()); |
330 | 341 |
331 MockAudioInputCallback sink; | 342 MockAudioInputCallback sink; |
332 | 343 |
333 // Start(), Start() is a valid calling sequence (second call does nothing). | 344 // Start(), Start() is a valid calling sequence (second call does nothing). |
334 ais->Start(&sink); | 345 ais->Start(&sink); |
335 EXPECT_TRUE(wais->started()); | 346 EXPECT_TRUE(wais->started()); |
336 ais->Start(&sink); | 347 ais->Start(&sink); |
337 EXPECT_TRUE(wais->started()); | 348 EXPECT_TRUE(wais->started()); |
338 | 349 |
339 // Stop(), Stop() is a valid calling sequence (second call does nothing). | 350 // Stop(), Stop() is a valid calling sequence (second call does nothing). |
340 ais->Stop(); | 351 ais->Stop(); |
341 EXPECT_FALSE(wais->started()); | 352 EXPECT_FALSE(wais->started()); |
342 ais->Stop(); | 353 ais->Stop(); |
343 EXPECT_FALSE(wais->started()); | 354 EXPECT_FALSE(wais->started()); |
344 ais.Close(); | 355 ais.Close(); |
345 } | 356 } |
346 | 357 |
347 TEST(WinAudioInputTest, WASAPIAudioInputStreamTestPacketSizes) { | 358 TEST_F(WinAudioInputTest, WASAPIAudioInputStreamTestPacketSizes) { |
348 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting()); | 359 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager_.get())); |
349 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager.get())); | |
350 | 360 |
351 int count = 0; | 361 int count = 0; |
352 base::MessageLoopForUI loop; | |
353 | 362 |
354 // 10 ms packet size. | 363 // 10 ms packet size. |
355 | 364 |
356 // Create default WASAPI input stream which records in stereo using | 365 // Create default WASAPI input stream which records in stereo using |
357 // the shared mixing rate. The default buffer size is 10ms. | 366 // the shared mixing rate. The default buffer size is 10ms. |
358 AudioInputStreamWrapper aisw(audio_manager.get()); | 367 AudioInputStreamWrapper aisw(audio_manager_.get()); |
359 ScopedAudioInputStream ais(aisw.Create()); | 368 ScopedAudioInputStream ais(aisw.Create()); |
360 EXPECT_TRUE(ais->Open()); | 369 EXPECT_TRUE(ais->Open()); |
361 | 370 |
362 MockAudioInputCallback sink; | 371 MockAudioInputCallback sink; |
363 | 372 |
364 // Derive the expected size in bytes of each recorded packet. | 373 // Derive the expected size in bytes of each recorded packet. |
365 uint32_t bytes_per_packet = | 374 uint32_t bytes_per_packet = |
366 aisw.channels() * aisw.frames_per_buffer() * (aisw.bits_per_sample() / 8); | 375 aisw.channels() * aisw.frames_per_buffer() * (aisw.bits_per_sample() / 8); |
367 | 376 |
368 // We use 10ms packets and will run the test until ten packets are received. | 377 // We use 10ms packets and will run the test until ten packets are received. |
369 // All should contain valid packets of the same size and a valid delay | 378 // All should contain valid packets of the same size and a valid delay |
370 // estimate. | 379 // estimate. |
371 EXPECT_CALL(sink, OnData(ais.get(), NotNull(), _, _)) | 380 EXPECT_CALL(sink, OnData(ais.get(), NotNull(), _, _)) |
372 .Times(AtLeast(10)) | 381 .Times(AtLeast(10)) |
373 .WillRepeatedly(CheckCountAndPostQuitTask(&count, 10, &loop)); | 382 .WillRepeatedly(CheckCountAndPostQuitTask(&count, 10, &message_loop_)); |
374 ais->Start(&sink); | 383 ais->Start(&sink); |
375 loop.Run(); | 384 message_loop_.Run(); |
376 ais->Stop(); | 385 ais->Stop(); |
377 | 386 |
378 // Store current packet size (to be used in the subsequent tests). | 387 // Store current packet size (to be used in the subsequent tests). |
379 int frames_per_buffer_10ms = aisw.frames_per_buffer(); | 388 int frames_per_buffer_10ms = aisw.frames_per_buffer(); |
380 | 389 |
381 ais.Close(); | 390 ais.Close(); |
382 | 391 |
383 // 20 ms packet size. | 392 // 20 ms packet size. |
384 | 393 |
385 count = 0; | 394 count = 0; |
386 ais.Reset(aisw.Create(2 * frames_per_buffer_10ms)); | 395 ais.Reset(aisw.Create(2 * frames_per_buffer_10ms)); |
387 EXPECT_TRUE(ais->Open()); | 396 EXPECT_TRUE(ais->Open()); |
388 bytes_per_packet = aisw.channels() * aisw.frames_per_buffer() * | 397 bytes_per_packet = aisw.channels() * aisw.frames_per_buffer() * |
389 (aisw.bits_per_sample() / 8); | 398 (aisw.bits_per_sample() / 8); |
390 | 399 |
391 EXPECT_CALL(sink, OnData(ais.get(), NotNull(), _, _)) | 400 EXPECT_CALL(sink, OnData(ais.get(), NotNull(), _, _)) |
392 .Times(AtLeast(10)) | 401 .Times(AtLeast(10)) |
393 .WillRepeatedly(CheckCountAndPostQuitTask(&count, 10, &loop)); | 402 .WillRepeatedly(CheckCountAndPostQuitTask(&count, 10, &message_loop_)); |
394 ais->Start(&sink); | 403 ais->Start(&sink); |
395 loop.Run(); | 404 message_loop_.Run(); |
396 ais->Stop(); | 405 ais->Stop(); |
397 ais.Close(); | 406 ais.Close(); |
398 | 407 |
399 // 5 ms packet size. | 408 // 5 ms packet size. |
400 | 409 |
401 count = 0; | 410 count = 0; |
402 ais.Reset(aisw.Create(frames_per_buffer_10ms / 2)); | 411 ais.Reset(aisw.Create(frames_per_buffer_10ms / 2)); |
403 EXPECT_TRUE(ais->Open()); | 412 EXPECT_TRUE(ais->Open()); |
404 bytes_per_packet = aisw.channels() * aisw.frames_per_buffer() * | 413 bytes_per_packet = aisw.channels() * aisw.frames_per_buffer() * |
405 (aisw.bits_per_sample() / 8); | 414 (aisw.bits_per_sample() / 8); |
406 | 415 |
407 EXPECT_CALL(sink, OnData(ais.get(), NotNull(), _, _)) | 416 EXPECT_CALL(sink, OnData(ais.get(), NotNull(), _, _)) |
408 .Times(AtLeast(10)) | 417 .Times(AtLeast(10)) |
409 .WillRepeatedly(CheckCountAndPostQuitTask(&count, 10, &loop)); | 418 .WillRepeatedly(CheckCountAndPostQuitTask(&count, 10, &message_loop_)); |
410 ais->Start(&sink); | 419 ais->Start(&sink); |
411 loop.Run(); | 420 message_loop_.Run(); |
412 ais->Stop(); | 421 ais->Stop(); |
413 ais.Close(); | 422 ais.Close(); |
414 } | 423 } |
415 | 424 |
416 // Test that we can capture a stream in loopback. | 425 // Test that we can capture a stream in loopback. |
417 TEST(WinAudioInputTest, WASAPIAudioInputStreamLoopback) { | 426 TEST_F(WinAudioInputTest, WASAPIAudioInputStreamLoopback) { |
418 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting()); | 427 ABORT_AUDIO_TEST_IF_NOT(audio_manager_->HasAudioOutputDevices() && |
419 ABORT_AUDIO_TEST_IF_NOT(audio_manager->HasAudioOutputDevices() && | |
420 CoreAudioUtil::IsSupported()); | 428 CoreAudioUtil::IsSupported()); |
421 | 429 |
422 AudioParameters params = audio_manager->GetInputStreamParameters( | 430 AudioParameters params = audio_manager_->GetInputStreamParameters( |
423 AudioManagerBase::kLoopbackInputDeviceId); | 431 AudioManagerBase::kLoopbackInputDeviceId); |
424 EXPECT_EQ(params.effects(), 0); | 432 EXPECT_EQ(params.effects(), 0); |
425 | 433 |
426 AudioParameters output_params = | 434 AudioParameters output_params = |
427 audio_manager->GetOutputStreamParameters(std::string()); | 435 audio_manager_->GetOutputStreamParameters(std::string()); |
428 EXPECT_EQ(params.sample_rate(), output_params.sample_rate()); | 436 EXPECT_EQ(params.sample_rate(), output_params.sample_rate()); |
429 EXPECT_EQ(params.channel_layout(), output_params.channel_layout()); | 437 EXPECT_EQ(params.channel_layout(), output_params.channel_layout()); |
430 | 438 |
431 ScopedAudioInputStream stream(audio_manager->MakeAudioInputStream( | 439 ScopedAudioInputStream stream(audio_manager_->MakeAudioInputStream( |
432 params, AudioManagerBase::kLoopbackInputDeviceId)); | 440 params, AudioManagerBase::kLoopbackInputDeviceId)); |
433 ASSERT_TRUE(stream->Open()); | 441 ASSERT_TRUE(stream->Open()); |
434 FakeAudioInputCallback sink; | 442 FakeAudioInputCallback sink; |
435 stream->Start(&sink); | 443 stream->Start(&sink); |
436 ASSERT_FALSE(sink.error()); | 444 ASSERT_FALSE(sink.error()); |
437 | 445 |
438 sink.WaitForData(); | 446 sink.WaitForData(); |
439 stream.Close(); | 447 stream.Close(); |
440 | 448 |
441 EXPECT_GT(sink.num_received_audio_frames(), 0); | 449 EXPECT_GT(sink.num_received_audio_frames(), 0); |
442 EXPECT_FALSE(sink.error()); | 450 EXPECT_FALSE(sink.error()); |
443 } | 451 } |
444 | 452 |
445 // This test is intended for manual tests and should only be enabled | 453 // This test is intended for manual tests and should only be enabled |
446 // when it is required to store the captured data on a local file. | 454 // when it is required to store the captured data on a local file. |
447 // By default, GTest will print out YOU HAVE 1 DISABLED TEST. | 455 // By default, GTest will print out YOU HAVE 1 DISABLED TEST. |
448 // To include disabled tests in test execution, just invoke the test program | 456 // To include disabled tests in test execution, just invoke the test program |
449 // with --gtest_also_run_disabled_tests or set the GTEST_ALSO_RUN_DISABLED_TESTS | 457 // with --gtest_also_run_disabled_tests or set the GTEST_ALSO_RUN_DISABLED_TESTS |
450 // environment variable to a value greater than 0. | 458 // environment variable to a value greater than 0. |
451 TEST(WinAudioInputTest, DISABLED_WASAPIAudioInputStreamRecordToFile) { | 459 TEST_F(WinAudioInputTest, DISABLED_WASAPIAudioInputStreamRecordToFile) { |
452 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting()); | 460 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager_.get())); |
453 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager.get())); | |
454 | 461 |
455 // Name of the output PCM file containing captured data. The output file | 462 // Name of the output PCM file containing captured data. The output file |
456 // will be stored in the directory containing 'media_unittests.exe'. | 463 // will be stored in the directory containing 'media_unittests.exe'. |
457 // Example of full name: \src\build\Debug\out_stereo_10sec.pcm. | 464 // Example of full name: \src\build\Debug\out_stereo_10sec.pcm. |
458 const char* file_name = "out_stereo_10sec.pcm"; | 465 const char* file_name = "out_stereo_10sec.pcm"; |
459 | 466 |
460 AudioInputStreamWrapper aisw(audio_manager.get()); | 467 AudioInputStreamWrapper aisw(audio_manager_.get()); |
461 ScopedAudioInputStream ais(aisw.Create()); | 468 ScopedAudioInputStream ais(aisw.Create()); |
462 EXPECT_TRUE(ais->Open()); | 469 EXPECT_TRUE(ais->Open()); |
463 | 470 |
464 VLOG(0) << ">> Sample rate: " << aisw.sample_rate() << " [Hz]"; | 471 VLOG(0) << ">> Sample rate: " << aisw.sample_rate() << " [Hz]"; |
465 WriteToFileAudioSink file_sink(file_name, aisw.bits_per_sample()); | 472 WriteToFileAudioSink file_sink(file_name, aisw.bits_per_sample()); |
466 VLOG(0) << ">> Speak into the default microphone while recording."; | 473 VLOG(0) << ">> Speak into the default microphone while recording."; |
467 ais->Start(&file_sink); | 474 ais->Start(&file_sink); |
468 base::PlatformThread::Sleep(TestTimeouts::action_timeout()); | 475 base::PlatformThread::Sleep(TestTimeouts::action_timeout()); |
469 ais->Stop(); | 476 ais->Stop(); |
470 VLOG(0) << ">> Recording has stopped."; | 477 VLOG(0) << ">> Recording has stopped."; |
471 ais.Close(); | 478 ais.Close(); |
472 } | 479 } |
473 | 480 |
474 } // namespace media | 481 } // namespace media |
OLD | NEW |