Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(54)

Side by Side Diff: media/audio/win/audio_low_latency_output_win_unittest.cc

Issue 10575017: Adding experimental exclusive-mode streaming to WASAPIAudioOutputStream (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: nit Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/command_line.h"
9 #include "base/environment.h" 10 #include "base/environment.h"
10 #include "base/file_util.h" 11 #include "base/file_util.h"
12 #include "media/base/media_switches.h"
11 #include "base/memory/scoped_ptr.h" 13 #include "base/memory/scoped_ptr.h"
12 #include "base/message_loop.h" 14 #include "base/message_loop.h"
13 #include "base/test/test_timeouts.h" 15 #include "base/test/test_timeouts.h"
14 #include "base/time.h" 16 #include "base/time.h"
15 #include "base/path_service.h" 17 #include "base/path_service.h"
16 #include "base/win/scoped_com_initializer.h" 18 #include "base/win/scoped_com_initializer.h"
17 #include "media/audio/audio_io.h" 19 #include "media/audio/audio_io.h"
18 #include "media/audio/audio_manager.h" 20 #include "media/audio/audio_manager.h"
19 #include "media/audio/audio_util.h" 21 #include "media/audio/audio_util.h"
20 #include "media/audio/win/audio_low_latency_output_win.h" 22 #include "media/audio/win/audio_low_latency_output_win.h"
(...skipping 13 matching lines...) Expand all
34 using ::testing::InvokeWithoutArgs; 36 using ::testing::InvokeWithoutArgs;
35 using ::testing::NotNull; 37 using ::testing::NotNull;
36 using ::testing::Return; 38 using ::testing::Return;
37 using base::win::ScopedCOMInitializer; 39 using base::win::ScopedCOMInitializer;
38 40
39 namespace media { 41 namespace media {
40 42
41 static const char kSpeechFile_16b_s_48k[] = "speech_16b_stereo_48kHz.raw"; 43 static const char kSpeechFile_16b_s_48k[] = "speech_16b_stereo_48kHz.raw";
42 static const char kSpeechFile_16b_s_44k[] = "speech_16b_stereo_44kHz.raw"; 44 static const char kSpeechFile_16b_s_44k[] = "speech_16b_stereo_44kHz.raw";
43 static const size_t kFileDurationMs = 20000; 45 static const size_t kFileDurationMs = 20000;
44 static const size_t kNumFileSegments = 1; 46 static const size_t kNumFileSegments = 2;
45 47
46 static const size_t kMaxDeltaSamples = 1000; 48 static const size_t kMaxDeltaSamples = 1000;
47 static const char* kDeltaTimeMsFileName = "delta_times_ms.txt"; 49 static const char* kDeltaTimeMsFileName = "delta_times_ms.txt";
48 50
49 MATCHER_P(HasValidDelay, value, "") { 51 MATCHER_P(HasValidDelay, value, "") {
50 // 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
51 // estimation. For now, verify that the produced output delay is always 53 // estimation. For now, verify that the produced output delay is always
52 // larger than the selected buffer size. 54 // larger than the selected buffer size.
53 return arg.hardware_delay_bytes > value.hardware_delay_bytes; 55 return arg.hardware_delay_bytes > value.hardware_delay_bytes;
54 } 56 }
55 57
58 // Used to terminate a loop from a different thread than the loop belongs to.
59 // |loop| should be a MessageLoopProxy.
60 ACTION_P(QuitLoop, loop) {
61 loop->PostTask(FROM_HERE, MessageLoop::QuitClosure());
62 }
63
56 class MockAudioSourceCallback : public AudioOutputStream::AudioSourceCallback { 64 class MockAudioSourceCallback : public AudioOutputStream::AudioSourceCallback {
57 public: 65 public:
58 MOCK_METHOD3(OnMoreData, uint32(uint8* dest, 66 MOCK_METHOD3(OnMoreData, uint32(uint8* dest,
59 uint32 max_size, 67 uint32 max_size,
60 AudioBuffersState buffers_state)); 68 AudioBuffersState buffers_state));
61 MOCK_METHOD2(OnError, void(AudioOutputStream* stream, int code)); 69 MOCK_METHOD2(OnError, void(AudioOutputStream* stream, int code));
62 }; 70 };
63 71
64 // This audio source implementation should be used for manual tests only since 72 // This audio source implementation should be used for manual tests only since
65 // it takes about 20 seconds to play out a file. 73 // it takes about 20 seconds to play out a file.
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 139
132 private: 140 private:
133 scoped_refptr<DecoderBuffer> file_; 141 scoped_refptr<DecoderBuffer> file_;
134 scoped_array<int> delta_times_; 142 scoped_array<int> delta_times_;
135 int pos_; 143 int pos_;
136 base::Time previous_call_time_; 144 base::Time previous_call_time_;
137 FILE* text_file_; 145 FILE* text_file_;
138 size_t elements_to_write_; 146 size_t elements_to_write_;
139 }; 147 };
140 148
149 static bool ExclusiveModeIsEnabled() {
150 const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
151 return (cmd_line->HasSwitch(switches::kEnableExclusiveMode));
152 }
153
141 // Convenience method which ensures that we are not running on the build 154 // Convenience method which ensures that we are not running on the build
142 // bots and that at least one valid output device can be found. We also 155 // bots and that at least one valid output device can be found. We also
143 // verify that we are not running on XP since the low-latency (WASAPI- 156 // verify that we are not running on XP since the low-latency (WASAPI-
144 // based) version requires Windows Vista or higher. 157 // based) version requires Windows Vista or higher.
145 static bool CanRunAudioTests(AudioManager* audio_man) { 158 static bool CanRunAudioTests(AudioManager* audio_man) {
146 if (!media::IsWASAPISupported()) { 159 if (!media::IsWASAPISupported()) {
147 LOG(WARNING) << "This tests requires Windows Vista or higher."; 160 LOG(WARNING) << "This tests requires Windows Vista or higher.";
148 return false; 161 return false;
149 } 162 }
150 // TODO(henrika): note that we use Wave today to query the number of 163 // TODO(henrika): note that we use Wave today to query the number of
(...skipping 28 matching lines...) Expand all
179 } 192 }
180 193
181 // Creates AudioOutputStream object using non-default parameters where the 194 // Creates AudioOutputStream object using non-default parameters where the
182 // frame size is modified. 195 // frame size is modified.
183 AudioOutputStream* Create(int samples_per_packet) { 196 AudioOutputStream* Create(int samples_per_packet) {
184 samples_per_packet_ = samples_per_packet; 197 samples_per_packet_ = samples_per_packet;
185 return CreateOutputStream(); 198 return CreateOutputStream();
186 } 199 }
187 200
188 // Creates AudioOutputStream object using non-default parameters where the 201 // Creates AudioOutputStream object using non-default parameters where the
202 // sample rate and frame size are modified.
203 AudioOutputStream* Create(int sample_rate, int samples_per_packet) {
204 sample_rate_ = sample_rate;
205 samples_per_packet_ = samples_per_packet;
206 return CreateOutputStream();
207 }
208
209 // Creates AudioOutputStream object using non-default parameters where the
189 // channel layout is modified. 210 // channel layout is modified.
190 AudioOutputStream* Create(ChannelLayout channel_layout) { 211 AudioOutputStream* Create(ChannelLayout channel_layout) {
191 channel_layout_ = channel_layout; 212 channel_layout_ = channel_layout;
192 return CreateOutputStream(); 213 return CreateOutputStream();
193 } 214 }
194 215
195 AudioParameters::Format format() const { return format_; } 216 AudioParameters::Format format() const { return format_; }
196 int channels() const { return ChannelLayoutToChannelCount(channel_layout_); } 217 int channels() const { return ChannelLayoutToChannelCount(channel_layout_); }
197 int bits_per_sample() const { return bits_per_sample_; } 218 int bits_per_sample() const { return bits_per_sample_; }
198 int sample_rate() const { return sample_rate_; } 219 int sample_rate() const { return sample_rate_; }
(...skipping 18 matching lines...) Expand all
217 }; 238 };
218 239
219 // Convenience method which creates a default AudioOutputStream object. 240 // Convenience method which creates a default AudioOutputStream object.
220 static AudioOutputStream* CreateDefaultAudioOutputStream( 241 static AudioOutputStream* CreateDefaultAudioOutputStream(
221 AudioManager* audio_manager) { 242 AudioManager* audio_manager) {
222 AudioOutputStreamWrapper aosw(audio_manager); 243 AudioOutputStreamWrapper aosw(audio_manager);
223 AudioOutputStream* aos = aosw.Create(); 244 AudioOutputStream* aos = aosw.Create();
224 return aos; 245 return aos;
225 } 246 }
226 247
227 static void QuitMessageLoop(base::MessageLoopProxy* proxy) {
228 proxy->PostTask(FROM_HERE, MessageLoop::QuitClosure());
229 }
230
231 // Verify that we can retrieve the current hardware/mixing sample rate 248 // Verify that we can retrieve the current hardware/mixing sample rate
232 // for all supported device roles. The ERole enumeration defines constants 249 // for all supported device roles. The ERole enumeration defines constants
233 // that indicate the role that the system/user has assigned to an audio 250 // that indicate the role that the system/user has assigned to an audio
234 // endpoint device. 251 // endpoint device.
235 // TODO(henrika): modify this test when we support full device enumeration. 252 // TODO(henrika): modify this test when we support full device enumeration.
236 TEST(WinAudioOutputTest, WASAPIAudioOutputStreamTestHardwareSampleRate) { 253 TEST(WinAudioOutputTest, WASAPIAudioOutputStreamTestHardwareSampleRate) {
237 scoped_ptr<AudioManager> audio_manager(AudioManager::Create()); 254 scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
238 if (!CanRunAudioTests(audio_manager.get())) 255 if (!CanRunAudioTests(audio_manager.get()))
239 return; 256 return;
240 257
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 // Derive the expected size in bytes of each packet. 419 // Derive the expected size in bytes of each packet.
403 uint32 bytes_per_packet = aosw.channels() * aosw.samples_per_packet() * 420 uint32 bytes_per_packet = aosw.channels() * aosw.samples_per_packet() *
404 (aosw.bits_per_sample() / 8); 421 (aosw.bits_per_sample() / 8);
405 422
406 // Set up expected minimum delay estimation. 423 // Set up expected minimum delay estimation.
407 AudioBuffersState state(0, bytes_per_packet); 424 AudioBuffersState state(0, bytes_per_packet);
408 425
409 // Wait for the first callback and verify its parameters. 426 // Wait for the first callback and verify its parameters.
410 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_per_packet, 427 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_per_packet,
411 HasValidDelay(state))) 428 HasValidDelay(state)))
412 .WillOnce( 429 .WillOnce(DoAll(
413 DoAll( 430 QuitLoop(proxy.get()),
414 InvokeWithoutArgs( 431 Return(bytes_per_packet)));
415 CreateFunctor(&QuitMessageLoop, proxy.get())),
416 Return(bytes_per_packet)));
417 432
418 aos->Start(&source); 433 aos->Start(&source);
419 loop.PostDelayedTask(FROM_HERE, MessageLoop::QuitClosure(), 434 loop.PostDelayedTask(FROM_HERE, MessageLoop::QuitClosure(),
420 TestTimeouts::action_timeout()); 435 TestTimeouts::action_timeout());
421 loop.Run(); 436 loop.Run();
422 aos->Stop(); 437 aos->Stop();
423 aos->Close(); 438 aos->Close();
424 } 439 }
425 440
426 // Use a fixed packets size (independent of sample rate) and verify 441 // Use a fixed packets size (independent of sample rate) and verify
(...skipping 17 matching lines...) Expand all
444 // Derive the expected size in bytes of each packet. 459 // Derive the expected size in bytes of each packet.
445 uint32 bytes_per_packet = aosw.channels() * aosw.samples_per_packet() * 460 uint32 bytes_per_packet = aosw.channels() * aosw.samples_per_packet() *
446 (aosw.bits_per_sample() / 8); 461 (aosw.bits_per_sample() / 8);
447 462
448 // Set up expected minimum delay estimation. 463 // Set up expected minimum delay estimation.
449 AudioBuffersState state(0, bytes_per_packet); 464 AudioBuffersState state(0, bytes_per_packet);
450 465
451 // Wait for the first callback and verify its parameters. 466 // Wait for the first callback and verify its parameters.
452 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_per_packet, 467 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_per_packet,
453 HasValidDelay(state))) 468 HasValidDelay(state)))
454 .WillOnce( 469 .WillOnce(DoAll(
455 DoAll( 470 QuitLoop(proxy.get()),
456 InvokeWithoutArgs( 471 Return(bytes_per_packet)));
457 CreateFunctor(&QuitMessageLoop, proxy.get())),
458 Return(bytes_per_packet)));
459 472
460 aos->Start(&source); 473 aos->Start(&source);
461 loop.PostDelayedTask(FROM_HERE, MessageLoop::QuitClosure(), 474 loop.PostDelayedTask(FROM_HERE, MessageLoop::QuitClosure(),
462 TestTimeouts::action_timeout()); 475 TestTimeouts::action_timeout());
463 loop.Run(); 476 loop.Run();
464 aos->Stop(); 477 aos->Stop();
465 aos->Close(); 478 aos->Close();
466 } 479 }
467 480
468 TEST(WinAudioOutputTest, WASAPIAudioOutputStreamTestMono) { 481 TEST(WinAudioOutputTest, WASAPIAudioOutputStreamTestMono) {
(...skipping 21 matching lines...) Expand all
490 } 503 }
491 // Derive the expected size in bytes of each packet. 504 // Derive the expected size in bytes of each packet.
492 uint32 bytes_per_packet = aosw.channels() * aosw.samples_per_packet() * 505 uint32 bytes_per_packet = aosw.channels() * aosw.samples_per_packet() *
493 (aosw.bits_per_sample() / 8); 506 (aosw.bits_per_sample() / 8);
494 507
495 // Set up expected minimum delay estimation. 508 // Set up expected minimum delay estimation.
496 AudioBuffersState state(0, bytes_per_packet); 509 AudioBuffersState state(0, bytes_per_packet);
497 510
498 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_per_packet, 511 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_per_packet,
499 HasValidDelay(state))) 512 HasValidDelay(state)))
500 .WillOnce( 513 .WillOnce(DoAll(
501 DoAll( 514 QuitLoop(proxy.get()),
502 InvokeWithoutArgs( 515 Return(bytes_per_packet)));
503 CreateFunctor(&QuitMessageLoop, proxy.get())),
504 Return(bytes_per_packet)));
505 516
506 aos->Start(&source); 517 aos->Start(&source);
507 loop.PostDelayedTask(FROM_HERE, MessageLoop::QuitClosure(), 518 loop.PostDelayedTask(FROM_HERE, MessageLoop::QuitClosure(),
508 TestTimeouts::action_timeout()); 519 TestTimeouts::action_timeout());
509 loop.Run(); 520 loop.Run();
510 aos->Stop(); 521 aos->Stop();
511 aos->Close(); 522 aos->Close();
512 } 523 }
513 524
514 // This test is intended for manual tests and should only be enabled 525 // This test is intended for manual tests and should only be enabled
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
555 aos->Start(&file_source); 566 aos->Start(&file_source);
556 base::PlatformThread::Sleep( 567 base::PlatformThread::Sleep(
557 base::TimeDelta::FromMilliseconds(kFileDurationMs / kNumFileSegments)); 568 base::TimeDelta::FromMilliseconds(kFileDurationMs / kNumFileSegments));
558 aos->Stop(); 569 aos->Stop();
559 } 570 }
560 571
561 LOG(INFO) << ">> File playout has stopped."; 572 LOG(INFO) << ">> File playout has stopped.";
562 aos->Close(); 573 aos->Close();
563 } 574 }
564 575
576 // Verify that we can open the output stream in exclusive mode using a
577 // certain set of audio parameters and a sample rate of 48kHz.
578 // The expected outcomes of each setting in this test has been derived
579 // manually using log outputs (--v=1).
580 TEST(WinAudioOutputTest,
581 WASAPIAudioOutputStreamTestExclusiveModeBufferSizesAt48kHzSampleRate) {
scherkus (not reviewing) 2012/07/25 23:44:44 considering the tests already contain "WinAudioOut
henrika (OOO until Aug 14) 2012/07/26 08:31:11 Done.
582 if (!ExclusiveModeIsEnabled())
583 return;
584
585 scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
586 if (!CanRunAudioTests(audio_manager.get()))
587 return;
588
589 AudioOutputStreamWrapper aosw(audio_manager.get());
590
591 // 10ms @ 48kHz shall work.
592 // Note that, this is the same size as we can use for shared-mode streaming
593 // but here the endpoint buffer delay is only 10ms instead of 20ms.
594 AudioOutputStream* aos = aosw.Create(48000, 480);
595 EXPECT_TRUE(aos->Open());
596 aos->Close();
597
598 // 5ms @ 48kHz does not work due to misalignment.
599 // This test will propose an aligned buffer size of 5.3333ms.
600 // Note that we must call Close() even is Open() fails since Close() also
601 // deletes the object and we want to create a new object in the next test.
602 aos = aosw.Create(48000, 240);
603 EXPECT_FALSE(aos->Open());
604 aos->Close();
605
606 // 5.3333ms @ 48kHz should work (see test above).
607 aos = aosw.Create(48000, 256);
608 EXPECT_TRUE(aos->Open());
609 aos->Close();
610
611 // 2.6667ms is smaller than the minimum supported size (=3ms).
612 aos = aosw.Create(48000, 128);
613 EXPECT_FALSE(aos->Open());
614 aos->Close();
615
616 // 3ms does not correspond to an aligned buffer size.
617 // This test will propose an aligned buffer size of 3.3333ms.
618 aos = aosw.Create(48000, 144);
619 EXPECT_FALSE(aos->Open());
620 aos->Close();
621
622 // 3.3333ms @ 48kHz <=> smallest possible buffer size we can use.
623 aos = aosw.Create(48000, 160);
624 EXPECT_TRUE(aos->Open());
625 aos->Close();
626 }
627
628 // Verify that we can open the output stream in exclusive mode using a
629 // certain set of audio parameters and a sample rate of 44.1kHz.
630 // The expected outcomes of each setting in this test has been derived
631 // manually using log outputs (--v=1).
632 TEST(WinAudioOutputTest,
633 WASAPIAudioOutputStreamTestExclusiveModeBufferSizesAt44kHzSampleRate) {
634 if (!ExclusiveModeIsEnabled())
635 return;
636
637 scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
638 if (!CanRunAudioTests(audio_manager.get()))
639 return;
640
641 AudioOutputStreamWrapper aosw(audio_manager.get());
642
643 // 10ms @ 44.1kHz does not work due to misalignment.
644 // This test will propose an aligned buffer size of 10.1587ms.
645 AudioOutputStream* aos = aosw.Create(44100, 441);
646 EXPECT_FALSE(aos->Open());
647 aos->Close();
648
649 // 10.1587ms @ 44.1kHz shall work (see test above).
650 aos = aosw.Create(44100, 448);
651 EXPECT_TRUE(aos->Open());
652 aos->Close();
653
654 // 5.8050ms @ 44.1 should work.
655 aos = aosw.Create(44100, 256);
656 EXPECT_TRUE(aos->Open());
657 aos->Close();
658
659 // 4.9887ms @ 44.1kHz does not work to misalignment.
660 // This test will propose an aligned buffer size of 5.0794ms.
661 // Note that we must call Close() even is Open() fails since Close() also
662 // deletes the object and we want to create a new object in the next test.
663 aos = aosw.Create(44100, 220);
664 EXPECT_FALSE(aos->Open());
665 aos->Close();
666
667 // 5.0794ms @ 44.1kHz shall work (see test above).
668 aos = aosw.Create(44100, 224);
669 EXPECT_TRUE(aos->Open());
670 aos->Close();
671
672 // 2.9025ms is smaller than the minimum supported size (=3ms).
673 aos = aosw.Create(44100, 132);
674 EXPECT_FALSE(aos->Open());
675 aos->Close();
676
677 // 3.01587ms is larger than the minimum size but is not aligned.
678 // This test will propose an aligned buffer size of 3.6281ms.
679 aos = aosw.Create(44100, 133);
680 EXPECT_FALSE(aos->Open());
681 aos->Close();
682
683 // 3.6281ms @ 44.1kHz <=> smallest possible buffer size we can use.
684 aos = aosw.Create(44100, 160);
685 EXPECT_TRUE(aos->Open());
686 aos->Close();
687 }
688
689 // Verify that we can open and start the output stream in exclusive mode at
690 // the lowest possible delay at 48kHz.
691 TEST(WinAudioOutputTest,
692 WASAPIAudioOutputStreamTestExclusiveModeMinBufferSizeAt48kHzSampleRate) {
693 if (!ExclusiveModeIsEnabled())
694 return;
695
696 scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
697 if (!CanRunAudioTests(audio_manager.get()))
698 return;
699
700 MessageLoopForUI loop;
701 scoped_refptr<base::MessageLoopProxy> proxy(loop.message_loop_proxy());
702
703 MockAudioSourceCallback source;
704
705 // Create exclusive-mode WASAPI output stream which plays out in stereo
706 // using the minimum buffer size at 48kHz sample rate.
707 AudioOutputStreamWrapper aosw(audio_manager.get());
708 AudioOutputStream* aos = aosw.Create(48000, 160);
709 EXPECT_TRUE(aos->Open());
710
711 // Derive the expected size in bytes of each packet.
712 uint32 bytes_per_packet = aosw.channels() * aosw.samples_per_packet() *
713 (aosw.bits_per_sample() / 8);
714
715 // Set up expected minimum delay estimation.
716 AudioBuffersState state(0, bytes_per_packet);
717
718 // Wait for the first callback and verify its parameters.
719 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_per_packet,
720 HasValidDelay(state)))
721 .WillOnce(DoAll(
722 QuitLoop(proxy.get()),
723 Return(bytes_per_packet)));
724
725 aos->Start(&source);
726 loop.PostDelayedTask(FROM_HERE, MessageLoop::QuitClosure(),
727 TestTimeouts::action_timeout());
728 loop.Run();
729 aos->Stop();
730 aos->Close();
731 }
732
733 // Verify that we can open and start the output stream in exclusive mode at
734 // the lowest possible delay at 44.1kHz.
735 TEST(WinAudioOutputTest,
736 WASAPIAudioOutputStreamTestExclusiveModeMinBufferSizeAt44kHzSampleRate) {
737 if (!ExclusiveModeIsEnabled())
738 return;
739
740 scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
741 if (!CanRunAudioTests(audio_manager.get()))
742 return;
743
744 MessageLoopForUI loop;
745 scoped_refptr<base::MessageLoopProxy> proxy(loop.message_loop_proxy());
746
747 MockAudioSourceCallback source;
748
749 // Create exclusive-mode WASAPI output stream which plays out in stereo
750 // using the minimum buffer size at 48kHz sample rate.
751 AudioOutputStreamWrapper aosw(audio_manager.get());
752 AudioOutputStream* aos = aosw.Create(44100, 160);
753 EXPECT_TRUE(aos->Open());
754
755 // Derive the expected size in bytes of each packet.
756 uint32 bytes_per_packet = aosw.channels() * aosw.samples_per_packet() *
757 (aosw.bits_per_sample() / 8);
758
759 // Set up expected minimum delay estimation.
760 AudioBuffersState state(0, bytes_per_packet);
761
762 // Wait for the first callback and verify its parameters.
763 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_per_packet,
764 HasValidDelay(state)))
765 .WillOnce(DoAll(
766 QuitLoop(proxy.get()),
767 Return(bytes_per_packet)));
768
769 aos->Start(&source);
770 loop.PostDelayedTask(FROM_HERE, MessageLoop::QuitClosure(),
771 TestTimeouts::action_timeout());
772 loop.Run();
773 aos->Stop();
774 aos->Close();
775 }
776
565 } // namespace media 777 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698