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