| 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" |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 45 static const size_t kFileDurationMs = 20000; | 45 static const size_t kFileDurationMs = 20000; |
| 46 static const size_t kNumFileSegments = 2; | 46 static const size_t kNumFileSegments = 2; |
| 47 static const int kBitsPerSample = 16; | 47 static const int kBitsPerSample = 16; |
| 48 static const size_t kMaxDeltaSamples = 1000; | 48 static const size_t kMaxDeltaSamples = 1000; |
| 49 static const char kDeltaTimeMsFileName[] = "delta_times_ms.txt"; | 49 static const char kDeltaTimeMsFileName[] = "delta_times_ms.txt"; |
| 50 | 50 |
| 51 MATCHER_P(HasValidDelay, value, "") { | 51 MATCHER_P(HasValidDelay, value, "") { |
| 52 // It is difficult to come up with a perfect test condition for the delay | 52 // It is difficult to come up with a perfect test condition for the delay |
| 53 // estimation. For now, verify that the produced output delay is always | 53 // estimation. For now, verify that the produced output delay is always |
| 54 // larger than the selected buffer size. | 54 // larger than the selected buffer size. |
| 55 return arg.hardware_delay_bytes >= value.hardware_delay_bytes; | 55 return arg >= value; |
| 56 } | 56 } |
| 57 | 57 |
| 58 // Used to terminate a loop from a different thread than the loop belongs to. | 58 // Used to terminate a loop from a different thread than the loop belongs to. |
| 59 // |loop| should be a MessageLoopProxy. | 59 // |loop| should be a MessageLoopProxy. |
| 60 ACTION_P(QuitLoop, loop) { | 60 ACTION_P(QuitLoop, loop) { |
| 61 loop->PostTask(FROM_HERE, base::MessageLoop::QuitClosure()); | 61 loop->PostTask(FROM_HERE, base::MessageLoop::QuitClosure()); |
| 62 } | 62 } |
| 63 | 63 |
| 64 // This audio source implementation should be used for manual tests only since | 64 // This audio source implementation should be used for manual tests only since |
| 65 // it takes about 20 seconds to play out a file. | 65 // it takes about 20 seconds to play out a file. |
| (...skipping 30 matching lines...) Expand all Loading... |
| 96 while (elements_written < elements_to_write_) { | 96 while (elements_written < elements_to_write_) { |
| 97 fprintf(text_file_, "%d\n", delta_times_[elements_written]); | 97 fprintf(text_file_, "%d\n", delta_times_[elements_written]); |
| 98 ++elements_written; | 98 ++elements_written; |
| 99 } | 99 } |
| 100 | 100 |
| 101 base::CloseFile(text_file_); | 101 base::CloseFile(text_file_); |
| 102 } | 102 } |
| 103 | 103 |
| 104 // AudioOutputStream::AudioSourceCallback implementation. | 104 // AudioOutputStream::AudioSourceCallback implementation. |
| 105 virtual int OnMoreData(AudioBus* audio_bus, | 105 virtual int OnMoreData(AudioBus* audio_bus, |
| 106 AudioBuffersState buffers_state) { | 106 int total_bytes_delay) { |
| 107 // Store time difference between two successive callbacks in an array. | 107 // Store time difference between two successive callbacks in an array. |
| 108 // These values will be written to a file in the destructor. | 108 // These values will be written to a file in the destructor. |
| 109 const base::TimeTicks now_time = base::TimeTicks::Now(); | 109 const base::TimeTicks now_time = base::TimeTicks::Now(); |
| 110 const int diff = (now_time - previous_call_time_).InMilliseconds(); | 110 const int diff = (now_time - previous_call_time_).InMilliseconds(); |
| 111 previous_call_time_ = now_time; | 111 previous_call_time_ = now_time; |
| 112 if (elements_to_write_ < kMaxDeltaSamples) { | 112 if (elements_to_write_ < kMaxDeltaSamples) { |
| 113 delta_times_[elements_to_write_] = diff; | 113 delta_times_[elements_to_write_] = diff; |
| 114 ++elements_to_write_; | 114 ++elements_to_write_; |
| 115 } | 115 } |
| 116 | 116 |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 389 base::MessageLoopForUI loop; | 389 base::MessageLoopForUI loop; |
| 390 MockAudioSourceCallback source; | 390 MockAudioSourceCallback source; |
| 391 | 391 |
| 392 // Create default WASAPI output stream which plays out in stereo using | 392 // Create default WASAPI output stream which plays out in stereo using |
| 393 // the shared mixing rate. The default buffer size is 10ms. | 393 // the shared mixing rate. The default buffer size is 10ms. |
| 394 AudioOutputStreamWrapper aosw(audio_manager.get()); | 394 AudioOutputStreamWrapper aosw(audio_manager.get()); |
| 395 AudioOutputStream* aos = aosw.Create(); | 395 AudioOutputStream* aos = aosw.Create(); |
| 396 EXPECT_TRUE(aos->Open()); | 396 EXPECT_TRUE(aos->Open()); |
| 397 | 397 |
| 398 // Derive the expected size in bytes of each packet. | 398 // Derive the expected size in bytes of each packet. |
| 399 uint32 bytes_per_packet = aosw.channels() * aosw.samples_per_packet() * | 399 int bytes_per_packet = aosw.channels() * aosw.samples_per_packet() * |
| 400 (aosw.bits_per_sample() / 8); | 400 (aosw.bits_per_sample() / 8); |
| 401 | |
| 402 // Set up expected minimum delay estimation. | |
| 403 AudioBuffersState state(0, bytes_per_packet); | |
| 404 | 401 |
| 405 // Wait for the first callback and verify its parameters. | 402 // Wait for the first callback and verify its parameters. |
| 406 EXPECT_CALL(source, OnMoreData(NotNull(), HasValidDelay(state))) | 403 EXPECT_CALL(source, OnMoreData(NotNull(), HasValidDelay(bytes_per_packet))) |
| 407 .WillOnce(DoAll( | 404 .WillOnce(DoAll( |
| 408 QuitLoop(loop.message_loop_proxy()), | 405 QuitLoop(loop.message_loop_proxy()), |
| 409 Return(aosw.samples_per_packet()))); | 406 Return(aosw.samples_per_packet()))); |
| 410 | 407 |
| 411 aos->Start(&source); | 408 aos->Start(&source); |
| 412 loop.PostDelayedTask(FROM_HERE, base::MessageLoop::QuitClosure(), | 409 loop.PostDelayedTask(FROM_HERE, base::MessageLoop::QuitClosure(), |
| 413 TestTimeouts::action_timeout()); | 410 TestTimeouts::action_timeout()); |
| 414 loop.Run(); | 411 loop.Run(); |
| 415 aos->Stop(); | 412 aos->Stop(); |
| 416 aos->Close(); | 413 aos->Close(); |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 593 base::MessageLoopForUI loop; | 590 base::MessageLoopForUI loop; |
| 594 MockAudioSourceCallback source; | 591 MockAudioSourceCallback source; |
| 595 | 592 |
| 596 // Create exclusive-mode WASAPI output stream which plays out in stereo | 593 // Create exclusive-mode WASAPI output stream which plays out in stereo |
| 597 // using the minimum buffer size at 48kHz sample rate. | 594 // using the minimum buffer size at 48kHz sample rate. |
| 598 AudioOutputStreamWrapper aosw(audio_manager.get()); | 595 AudioOutputStreamWrapper aosw(audio_manager.get()); |
| 599 AudioOutputStream* aos = aosw.Create(48000, 160); | 596 AudioOutputStream* aos = aosw.Create(48000, 160); |
| 600 EXPECT_TRUE(aos->Open()); | 597 EXPECT_TRUE(aos->Open()); |
| 601 | 598 |
| 602 // Derive the expected size in bytes of each packet. | 599 // Derive the expected size in bytes of each packet. |
| 603 uint32 bytes_per_packet = aosw.channels() * aosw.samples_per_packet() * | 600 int bytes_per_packet = aosw.channels() * aosw.samples_per_packet() * |
| 604 (aosw.bits_per_sample() / 8); | 601 (aosw.bits_per_sample() / 8); |
| 605 | 602 |
| 606 // Set up expected minimum delay estimation. | |
| 607 AudioBuffersState state(0, bytes_per_packet); | |
| 608 | |
| 609 // Wait for the first callback and verify its parameters. | 603 // Wait for the first callback and verify its parameters. |
| 610 EXPECT_CALL(source, OnMoreData(NotNull(), HasValidDelay(state))) | 604 EXPECT_CALL(source, OnMoreData(NotNull(), HasValidDelay(bytes_per_packet))) |
| 611 .WillOnce(DoAll( | 605 .WillOnce(DoAll( |
| 612 QuitLoop(loop.message_loop_proxy()), | 606 QuitLoop(loop.message_loop_proxy()), |
| 613 Return(aosw.samples_per_packet()))) | 607 Return(aosw.samples_per_packet()))) |
| 614 .WillRepeatedly(Return(aosw.samples_per_packet())); | 608 .WillRepeatedly(Return(aosw.samples_per_packet())); |
| 615 | 609 |
| 616 aos->Start(&source); | 610 aos->Start(&source); |
| 617 loop.PostDelayedTask(FROM_HERE, base::MessageLoop::QuitClosure(), | 611 loop.PostDelayedTask(FROM_HERE, base::MessageLoop::QuitClosure(), |
| 618 TestTimeouts::action_timeout()); | 612 TestTimeouts::action_timeout()); |
| 619 loop.Run(); | 613 loop.Run(); |
| 620 aos->Stop(); | 614 aos->Stop(); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 634 base::MessageLoopForUI loop; | 628 base::MessageLoopForUI loop; |
| 635 MockAudioSourceCallback source; | 629 MockAudioSourceCallback source; |
| 636 | 630 |
| 637 // Create exclusive-mode WASAPI output stream which plays out in stereo | 631 // Create exclusive-mode WASAPI output stream which plays out in stereo |
| 638 // using the minimum buffer size at 44.1kHz sample rate. | 632 // using the minimum buffer size at 44.1kHz sample rate. |
| 639 AudioOutputStreamWrapper aosw(audio_manager.get()); | 633 AudioOutputStreamWrapper aosw(audio_manager.get()); |
| 640 AudioOutputStream* aos = aosw.Create(44100, 160); | 634 AudioOutputStream* aos = aosw.Create(44100, 160); |
| 641 EXPECT_TRUE(aos->Open()); | 635 EXPECT_TRUE(aos->Open()); |
| 642 | 636 |
| 643 // Derive the expected size in bytes of each packet. | 637 // Derive the expected size in bytes of each packet. |
| 644 uint32 bytes_per_packet = aosw.channels() * aosw.samples_per_packet() * | 638 int bytes_per_packet = aosw.channels() * aosw.samples_per_packet() * |
| 645 (aosw.bits_per_sample() / 8); | 639 (aosw.bits_per_sample() / 8); |
| 646 | 640 |
| 647 // Set up expected minimum delay estimation. | |
| 648 AudioBuffersState state(0, bytes_per_packet); | |
| 649 | |
| 650 // Wait for the first callback and verify its parameters. | 641 // Wait for the first callback and verify its parameters. |
| 651 EXPECT_CALL(source, OnMoreData(NotNull(), HasValidDelay(state))) | 642 EXPECT_CALL(source, OnMoreData(NotNull(), HasValidDelay(bytes_per_packet))) |
| 652 .WillOnce(DoAll( | 643 .WillOnce(DoAll( |
| 653 QuitLoop(loop.message_loop_proxy()), | 644 QuitLoop(loop.message_loop_proxy()), |
| 654 Return(aosw.samples_per_packet()))) | 645 Return(aosw.samples_per_packet()))) |
| 655 .WillRepeatedly(Return(aosw.samples_per_packet())); | 646 .WillRepeatedly(Return(aosw.samples_per_packet())); |
| 656 | 647 |
| 657 aos->Start(&source); | 648 aos->Start(&source); |
| 658 loop.PostDelayedTask(FROM_HERE, base::MessageLoop::QuitClosure(), | 649 loop.PostDelayedTask(FROM_HERE, base::MessageLoop::QuitClosure(), |
| 659 TestTimeouts::action_timeout()); | 650 TestTimeouts::action_timeout()); |
| 660 loop.Run(); | 651 loop.Run(); |
| 661 aos->Stop(); | 652 aos->Stop(); |
| 662 aos->Close(); | 653 aos->Close(); |
| 663 } | 654 } |
| 664 | 655 |
| 665 } // namespace media | 656 } // namespace media |
| OLD | NEW |