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

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: Minor changes proposed by Andrew Created 8 years, 4 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
« no previous file with comments | « media/audio/win/audio_low_latency_output_win.cc ('k') | media/base/media_switches.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/environment.h" 9 #include "base/environment.h"
10 #include "base/file_util.h" 10 #include "base/file_util.h"
(...skipping 23 matching lines...) Expand all
34 using ::testing::InvokeWithoutArgs; 34 using ::testing::InvokeWithoutArgs;
35 using ::testing::NotNull; 35 using ::testing::NotNull;
36 using ::testing::Return; 36 using ::testing::Return;
37 using base::win::ScopedCOMInitializer; 37 using base::win::ScopedCOMInitializer;
38 38
39 namespace media { 39 namespace media {
40 40
41 static const char kSpeechFile_16b_s_48k[] = "speech_16b_stereo_48kHz.raw"; 41 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"; 42 static const char kSpeechFile_16b_s_44k[] = "speech_16b_stereo_44kHz.raw";
43 static const size_t kFileDurationMs = 20000; 43 static const size_t kFileDurationMs = 20000;
44 static const size_t kNumFileSegments = 1; 44 static const size_t kNumFileSegments = 2;
45 45
46 static const size_t kMaxDeltaSamples = 1000; 46 static const size_t kMaxDeltaSamples = 1000;
47 static const char* kDeltaTimeMsFileName = "delta_times_ms.txt"; 47 static const char* kDeltaTimeMsFileName = "delta_times_ms.txt";
48 48
49 MATCHER_P(HasValidDelay, value, "") { 49 MATCHER_P(HasValidDelay, value, "") {
50 // It is difficult to come up with a perfect test condition for the delay 50 // 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 51 // estimation. For now, verify that the produced output delay is always
52 // larger than the selected buffer size. 52 // larger than the selected buffer size.
53 return arg.hardware_delay_bytes > value.hardware_delay_bytes; 53 return arg.hardware_delay_bytes > value.hardware_delay_bytes;
54 } 54 }
55 55
56 // Used to terminate a loop from a different thread than the loop belongs to.
57 // |loop| should be a MessageLoopProxy.
58 ACTION_P(QuitLoop, loop) {
59 loop->PostTask(FROM_HERE, MessageLoop::QuitClosure());
60 }
61
56 class MockAudioSourceCallback : public AudioOutputStream::AudioSourceCallback { 62 class MockAudioSourceCallback : public AudioOutputStream::AudioSourceCallback {
57 public: 63 public:
58 MOCK_METHOD3(OnMoreData, uint32(uint8* dest, 64 MOCK_METHOD3(OnMoreData, uint32(uint8* dest,
59 uint32 max_size, 65 uint32 max_size,
60 AudioBuffersState buffers_state)); 66 AudioBuffersState buffers_state));
61 MOCK_METHOD2(OnError, void(AudioOutputStream* stream, int code)); 67 MOCK_METHOD2(OnError, void(AudioOutputStream* stream, int code));
62 }; 68 };
63 69
64 // This audio source implementation should be used for manual tests only since 70 // This audio source implementation should be used for manual tests only since
65 // it takes about 20 seconds to play out a file. 71 // it takes about 20 seconds to play out a file.
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 137
132 private: 138 private:
133 scoped_refptr<DecoderBuffer> file_; 139 scoped_refptr<DecoderBuffer> file_;
134 scoped_array<int> delta_times_; 140 scoped_array<int> delta_times_;
135 int pos_; 141 int pos_;
136 base::Time previous_call_time_; 142 base::Time previous_call_time_;
137 FILE* text_file_; 143 FILE* text_file_;
138 size_t elements_to_write_; 144 size_t elements_to_write_;
139 }; 145 };
140 146
147 static bool ExclusiveModeIsEnabled() {
148 return (WASAPIAudioOutputStream::GetShareMode() ==
149 AUDCLNT_SHAREMODE_EXCLUSIVE);
150 }
151
141 // Convenience method which ensures that we are not running on the build 152 // 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 153 // 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- 154 // verify that we are not running on XP since the low-latency (WASAPI-
144 // based) version requires Windows Vista or higher. 155 // based) version requires Windows Vista or higher.
145 static bool CanRunAudioTests(AudioManager* audio_man) { 156 static bool CanRunAudioTests(AudioManager* audio_man) {
146 if (!media::IsWASAPISupported()) { 157 if (!media::IsWASAPISupported()) {
147 LOG(WARNING) << "This tests requires Windows Vista or higher."; 158 LOG(WARNING) << "This tests requires Windows Vista or higher.";
148 return false; 159 return false;
149 } 160 }
150 // TODO(henrika): note that we use Wave today to query the number of 161 // TODO(henrika): note that we use Wave today to query the number of
(...skipping 28 matching lines...) Expand all
179 } 190 }
180 191
181 // Creates AudioOutputStream object using non-default parameters where the 192 // Creates AudioOutputStream object using non-default parameters where the
182 // frame size is modified. 193 // frame size is modified.
183 AudioOutputStream* Create(int samples_per_packet) { 194 AudioOutputStream* Create(int samples_per_packet) {
184 samples_per_packet_ = samples_per_packet; 195 samples_per_packet_ = samples_per_packet;
185 return CreateOutputStream(); 196 return CreateOutputStream();
186 } 197 }
187 198
188 // Creates AudioOutputStream object using non-default parameters where the 199 // Creates AudioOutputStream object using non-default parameters where the
200 // sample rate and frame size are modified.
201 AudioOutputStream* Create(int sample_rate, int samples_per_packet) {
202 sample_rate_ = sample_rate;
203 samples_per_packet_ = samples_per_packet;
204 return CreateOutputStream();
205 }
206
207 // Creates AudioOutputStream object using non-default parameters where the
189 // channel layout is modified. 208 // channel layout is modified.
190 AudioOutputStream* Create(ChannelLayout channel_layout) { 209 AudioOutputStream* Create(ChannelLayout channel_layout) {
191 channel_layout_ = channel_layout; 210 channel_layout_ = channel_layout;
192 return CreateOutputStream(); 211 return CreateOutputStream();
193 } 212 }
194 213
195 AudioParameters::Format format() const { return format_; } 214 AudioParameters::Format format() const { return format_; }
196 int channels() const { return ChannelLayoutToChannelCount(channel_layout_); } 215 int channels() const { return ChannelLayoutToChannelCount(channel_layout_); }
197 int bits_per_sample() const { return bits_per_sample_; } 216 int bits_per_sample() const { return bits_per_sample_; }
198 int sample_rate() const { return sample_rate_; } 217 int sample_rate() const { return sample_rate_; }
(...skipping 18 matching lines...) Expand all
217 }; 236 };
218 237
219 // Convenience method which creates a default AudioOutputStream object. 238 // Convenience method which creates a default AudioOutputStream object.
220 static AudioOutputStream* CreateDefaultAudioOutputStream( 239 static AudioOutputStream* CreateDefaultAudioOutputStream(
221 AudioManager* audio_manager) { 240 AudioManager* audio_manager) {
222 AudioOutputStreamWrapper aosw(audio_manager); 241 AudioOutputStreamWrapper aosw(audio_manager);
223 AudioOutputStream* aos = aosw.Create(); 242 AudioOutputStream* aos = aosw.Create();
224 return aos; 243 return aos;
225 } 244 }
226 245
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 246 // Verify that we can retrieve the current hardware/mixing sample rate
232 // for all supported device roles. The ERole enumeration defines constants 247 // for all supported device roles. The ERole enumeration defines constants
233 // that indicate the role that the system/user has assigned to an audio 248 // that indicate the role that the system/user has assigned to an audio
234 // endpoint device. 249 // endpoint device.
235 // TODO(henrika): modify this test when we support full device enumeration. 250 // TODO(henrika): modify this test when we support full device enumeration.
236 TEST(WinAudioOutputTest, WASAPIAudioOutputStreamTestHardwareSampleRate) { 251 TEST(WinAudioOutputTest, WASAPIAudioOutputStreamTestHardwareSampleRate) {
252 // Skip this test in exclusive mode since the resulting rate is only utilized
253 // for shared mode streams.
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()) || ExclusiveModeIsEnabled())
239 return; 256 return;
240 257
241 ScopedCOMInitializer com_init(ScopedCOMInitializer::kMTA); 258 ScopedCOMInitializer com_init(ScopedCOMInitializer::kMTA);
242 259
243 // Default device intended for games, system notification sounds, 260 // Default device intended for games, system notification sounds,
244 // and voice commands. 261 // and voice commands.
245 int fs = static_cast<int>( 262 int fs = static_cast<int>(
246 WASAPIAudioOutputStream::HardwareSampleRate(eConsole)); 263 WASAPIAudioOutputStream::HardwareSampleRate(eConsole));
247 EXPECT_GE(fs, 0); 264 EXPECT_GE(fs, 0);
248 265
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 aos->Close(); 399 aos->Close();
383 } 400 }
384 401
385 // Use default packet size (10ms) and verify that rendering starts. 402 // Use default packet size (10ms) and verify that rendering starts.
386 TEST(WinAudioOutputTest, WASAPIAudioOutputStreamTestPacketSizeInMilliseconds) { 403 TEST(WinAudioOutputTest, WASAPIAudioOutputStreamTestPacketSizeInMilliseconds) {
387 scoped_ptr<AudioManager> audio_manager(AudioManager::Create()); 404 scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
388 if (!CanRunAudioTests(audio_manager.get())) 405 if (!CanRunAudioTests(audio_manager.get()))
389 return; 406 return;
390 407
391 MessageLoopForUI loop; 408 MessageLoopForUI loop;
392 scoped_refptr<base::MessageLoopProxy> proxy(loop.message_loop_proxy());
393
394 MockAudioSourceCallback source; 409 MockAudioSourceCallback source;
395 410
396 // Create default WASAPI output stream which plays out in stereo using 411 // Create default WASAPI output stream which plays out in stereo using
397 // the shared mixing rate. The default buffer size is 10ms. 412 // the shared mixing rate. The default buffer size is 10ms.
398 AudioOutputStreamWrapper aosw(audio_manager.get()); 413 AudioOutputStreamWrapper aosw(audio_manager.get());
399 AudioOutputStream* aos = aosw.Create(); 414 AudioOutputStream* aos = aosw.Create();
400 EXPECT_TRUE(aos->Open()); 415 EXPECT_TRUE(aos->Open());
401 416
402 // Derive the expected size in bytes of each packet. 417 // Derive the expected size in bytes of each packet.
403 uint32 bytes_per_packet = aosw.channels() * aosw.samples_per_packet() * 418 uint32 bytes_per_packet = aosw.channels() * aosw.samples_per_packet() *
404 (aosw.bits_per_sample() / 8); 419 (aosw.bits_per_sample() / 8);
405 420
406 // Set up expected minimum delay estimation. 421 // Set up expected minimum delay estimation.
407 AudioBuffersState state(0, bytes_per_packet); 422 AudioBuffersState state(0, bytes_per_packet);
408 423
409 // Wait for the first callback and verify its parameters. 424 // Wait for the first callback and verify its parameters.
410 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_per_packet, 425 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_per_packet,
411 HasValidDelay(state))) 426 HasValidDelay(state)))
412 .WillOnce( 427 .WillOnce(DoAll(
413 DoAll( 428 QuitLoop(loop.message_loop_proxy()),
414 InvokeWithoutArgs( 429 Return(bytes_per_packet)));
415 CreateFunctor(&QuitMessageLoop, proxy.get())),
416 Return(bytes_per_packet)));
417 430
418 aos->Start(&source); 431 aos->Start(&source);
419 loop.PostDelayedTask(FROM_HERE, MessageLoop::QuitClosure(), 432 loop.PostDelayedTask(FROM_HERE, MessageLoop::QuitClosure(),
420 TestTimeouts::action_timeout()); 433 TestTimeouts::action_timeout());
421 loop.Run(); 434 loop.Run();
422 aos->Stop(); 435 aos->Stop();
423 aos->Close(); 436 aos->Close();
424 } 437 }
425 438
426 // Use a fixed packets size (independent of sample rate) and verify 439 // Use a fixed packets size (independent of sample rate) and verify
427 // that rendering starts. 440 // that rendering starts.
428 TEST(WinAudioOutputTest, WASAPIAudioOutputStreamTestPacketSizeInSamples) { 441 TEST(WinAudioOutputTest, WASAPIAudioOutputStreamTestPacketSizeInSamples) {
429 scoped_ptr<AudioManager> audio_manager(AudioManager::Create()); 442 scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
430 if (!CanRunAudioTests(audio_manager.get())) 443 if (!CanRunAudioTests(audio_manager.get()))
431 return; 444 return;
432 445
433 MessageLoopForUI loop; 446 MessageLoopForUI loop;
434 scoped_refptr<base::MessageLoopProxy> proxy(loop.message_loop_proxy());
435
436 MockAudioSourceCallback source; 447 MockAudioSourceCallback source;
437 448
438 // Create default WASAPI output stream which plays out in stereo using 449 // Create default WASAPI output stream which plays out in stereo using
439 // the shared mixing rate. The buffer size is set to 1024 samples. 450 // the shared mixing rate. The buffer size is set to 1024 samples.
440 AudioOutputStreamWrapper aosw(audio_manager.get()); 451 AudioOutputStreamWrapper aosw(audio_manager.get());
441 AudioOutputStream* aos = aosw.Create(1024); 452 AudioOutputStream* aos = aosw.Create(1024);
442 EXPECT_TRUE(aos->Open()); 453 EXPECT_TRUE(aos->Open());
443 454
444 // Derive the expected size in bytes of each packet. 455 // Derive the expected size in bytes of each packet.
445 uint32 bytes_per_packet = aosw.channels() * aosw.samples_per_packet() * 456 uint32 bytes_per_packet = aosw.channels() * aosw.samples_per_packet() *
446 (aosw.bits_per_sample() / 8); 457 (aosw.bits_per_sample() / 8);
447 458
448 // Set up expected minimum delay estimation. 459 // Set up expected minimum delay estimation.
449 AudioBuffersState state(0, bytes_per_packet); 460 AudioBuffersState state(0, bytes_per_packet);
450 461
451 // Wait for the first callback and verify its parameters. 462 // Ensure that callbacks start correctly.
452 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_per_packet, 463 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_per_packet,
453 HasValidDelay(state))) 464 HasValidDelay(state)))
454 .WillOnce( 465 .WillOnce(DoAll(
455 DoAll( 466 QuitLoop(loop.message_loop_proxy()),
456 InvokeWithoutArgs( 467 Return(bytes_per_packet)))
457 CreateFunctor(&QuitMessageLoop, proxy.get())), 468 .WillRepeatedly(Return(bytes_per_packet));
458 Return(bytes_per_packet)));
459 469
460 aos->Start(&source); 470 aos->Start(&source);
461 loop.PostDelayedTask(FROM_HERE, MessageLoop::QuitClosure(), 471 loop.PostDelayedTask(FROM_HERE, MessageLoop::QuitClosure(),
462 TestTimeouts::action_timeout()); 472 TestTimeouts::action_timeout());
463 loop.Run(); 473 loop.Run();
464 aos->Stop(); 474 aos->Stop();
465 aos->Close(); 475 aos->Close();
466 } 476 }
467 477
468 TEST(WinAudioOutputTest, WASAPIAudioOutputStreamTestMono) { 478 TEST(WinAudioOutputTest, WASAPIAudioOutputStreamTestMono) {
469 scoped_ptr<AudioManager> audio_manager(AudioManager::Create()); 479 scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
470 if (!CanRunAudioTests(audio_manager.get())) 480 if (!CanRunAudioTests(audio_manager.get()))
471 return; 481 return;
472 482
473 MessageLoopForUI loop; 483 MessageLoopForUI loop;
474 scoped_refptr<base::MessageLoopProxy> proxy(loop.message_loop_proxy());
475
476 MockAudioSourceCallback source; 484 MockAudioSourceCallback source;
477 485
478 // Create default WASAPI output stream which plays out in *mono* using 486 // Create default WASAPI output stream which plays out in *mono* using
479 // the shared mixing rate. The default buffer size is 10ms. 487 // the shared mixing rate. The default buffer size is 10ms.
480 AudioOutputStreamWrapper aosw(audio_manager.get()); 488 AudioOutputStreamWrapper aosw(audio_manager.get());
481 AudioOutputStream* aos = aosw.Create(CHANNEL_LAYOUT_MONO); 489 AudioOutputStream* aos = aosw.Create(CHANNEL_LAYOUT_MONO);
482 490
483 bool opened = aos->Open(); 491 bool opened = aos->Open();
484 if (!opened) { 492 if (!opened) {
485 // It was not possible to open this audio device in mono. 493 // It was not possible to open this audio device in mono.
486 // No point in continuing the test so let's break here. 494 // No point in continuing the test so let's break here.
487 LOG(WARNING) << "Mono is not supported. Skipping test."; 495 LOG(WARNING) << "Mono is not supported. Skipping test.";
488 aos->Close(); 496 aos->Close();
489 return; 497 return;
490 } 498 }
491 // Derive the expected size in bytes of each packet. 499 // Derive the expected size in bytes of each packet.
492 uint32 bytes_per_packet = aosw.channels() * aosw.samples_per_packet() * 500 uint32 bytes_per_packet = aosw.channels() * aosw.samples_per_packet() *
493 (aosw.bits_per_sample() / 8); 501 (aosw.bits_per_sample() / 8);
494 502
495 // Set up expected minimum delay estimation. 503 // Set up expected minimum delay estimation.
496 AudioBuffersState state(0, bytes_per_packet); 504 AudioBuffersState state(0, bytes_per_packet);
497 505
498 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_per_packet, 506 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_per_packet,
499 HasValidDelay(state))) 507 HasValidDelay(state)))
500 .WillOnce( 508 .WillOnce(DoAll(
501 DoAll( 509 QuitLoop(loop.message_loop_proxy()),
502 InvokeWithoutArgs( 510 Return(bytes_per_packet)))
503 CreateFunctor(&QuitMessageLoop, proxy.get())), 511 .WillRepeatedly(Return(bytes_per_packet));
504 Return(bytes_per_packet)));
505 512
506 aos->Start(&source); 513 aos->Start(&source);
507 loop.PostDelayedTask(FROM_HERE, MessageLoop::QuitClosure(), 514 loop.PostDelayedTask(FROM_HERE, MessageLoop::QuitClosure(),
508 TestTimeouts::action_timeout()); 515 TestTimeouts::action_timeout());
509 loop.Run(); 516 loop.Run();
510 aos->Stop(); 517 aos->Stop();
511 aos->Close(); 518 aos->Close();
512 } 519 }
513 520
514 // This test is intended for manual tests and should only be enabled 521 // 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); 562 aos->Start(&file_source);
556 base::PlatformThread::Sleep( 563 base::PlatformThread::Sleep(
557 base::TimeDelta::FromMilliseconds(kFileDurationMs / kNumFileSegments)); 564 base::TimeDelta::FromMilliseconds(kFileDurationMs / kNumFileSegments));
558 aos->Stop(); 565 aos->Stop();
559 } 566 }
560 567
561 LOG(INFO) << ">> File playout has stopped."; 568 LOG(INFO) << ">> File playout has stopped.";
562 aos->Close(); 569 aos->Close();
563 } 570 }
564 571
572 // Verify that we can open the output stream in exclusive mode using a
573 // certain set of audio parameters and a sample rate of 48kHz.
574 // The expected outcomes of each setting in this test has been derived
575 // manually using log outputs (--v=1).
576 TEST(WinAudioOutputTest, WASAPIExclusiveModeBufferSizesAt48kHz) {
577 if (!ExclusiveModeIsEnabled())
578 return;
579
580 scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
581 if (!CanRunAudioTests(audio_manager.get()))
582 return;
583
584 AudioOutputStreamWrapper aosw(audio_manager.get());
585
586 // 10ms @ 48kHz shall work.
587 // Note that, this is the same size as we can use for shared-mode streaming
588 // but here the endpoint buffer delay is only 10ms instead of 20ms.
589 AudioOutputStream* aos = aosw.Create(48000, 480);
590 EXPECT_TRUE(aos->Open());
591 aos->Close();
592
593 // 5ms @ 48kHz does not work due to misalignment.
594 // This test will propose an aligned buffer size of 5.3333ms.
595 // Note that we must call Close() even is Open() fails since Close() also
596 // deletes the object and we want to create a new object in the next test.
597 aos = aosw.Create(48000, 240);
598 EXPECT_FALSE(aos->Open());
599 aos->Close();
600
601 // 5.3333ms @ 48kHz should work (see test above).
602 aos = aosw.Create(48000, 256);
603 EXPECT_TRUE(aos->Open());
604 aos->Close();
605
606 // 2.6667ms is smaller than the minimum supported size (=3ms).
607 aos = aosw.Create(48000, 128);
608 EXPECT_FALSE(aos->Open());
609 aos->Close();
610
611 // 3ms does not correspond to an aligned buffer size.
612 // This test will propose an aligned buffer size of 3.3333ms.
613 aos = aosw.Create(48000, 144);
614 EXPECT_FALSE(aos->Open());
615 aos->Close();
616
617 // 3.3333ms @ 48kHz <=> smallest possible buffer size we can use.
618 aos = aosw.Create(48000, 160);
619 EXPECT_TRUE(aos->Open());
620 aos->Close();
621 }
622
623 // Verify that we can open the output stream in exclusive mode using a
624 // certain set of audio parameters and a sample rate of 44.1kHz.
625 // The expected outcomes of each setting in this test has been derived
626 // manually using log outputs (--v=1).
627 TEST(WinAudioOutputTest, WASAPIExclusiveModeBufferSizesAt44kHz) {
628 if (!ExclusiveModeIsEnabled())
629 return;
630
631 scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
632 if (!CanRunAudioTests(audio_manager.get()))
633 return;
634
635 AudioOutputStreamWrapper aosw(audio_manager.get());
636
637 // 10ms @ 44.1kHz does not work due to misalignment.
638 // This test will propose an aligned buffer size of 10.1587ms.
639 AudioOutputStream* aos = aosw.Create(44100, 441);
640 EXPECT_FALSE(aos->Open());
641 aos->Close();
642
643 // 10.1587ms @ 44.1kHz shall work (see test above).
644 aos = aosw.Create(44100, 448);
645 EXPECT_TRUE(aos->Open());
646 aos->Close();
647
648 // 5.8050ms @ 44.1 should work.
649 aos = aosw.Create(44100, 256);
650 EXPECT_TRUE(aos->Open());
651 aos->Close();
652
653 // 4.9887ms @ 44.1kHz does not work to misalignment.
654 // This test will propose an aligned buffer size of 5.0794ms.
655 // Note that we must call Close() even is Open() fails since Close() also
656 // deletes the object and we want to create a new object in the next test.
657 aos = aosw.Create(44100, 220);
658 EXPECT_FALSE(aos->Open());
659 aos->Close();
660
661 // 5.0794ms @ 44.1kHz shall work (see test above).
662 aos = aosw.Create(44100, 224);
663 EXPECT_TRUE(aos->Open());
664 aos->Close();
665
666 // 2.9025ms is smaller than the minimum supported size (=3ms).
667 aos = aosw.Create(44100, 132);
668 EXPECT_FALSE(aos->Open());
669 aos->Close();
670
671 // 3.01587ms is larger than the minimum size but is not aligned.
672 // This test will propose an aligned buffer size of 3.6281ms.
673 aos = aosw.Create(44100, 133);
674 EXPECT_FALSE(aos->Open());
675 aos->Close();
676
677 // 3.6281ms @ 44.1kHz <=> smallest possible buffer size we can use.
678 aos = aosw.Create(44100, 160);
679 EXPECT_TRUE(aos->Open());
680 aos->Close();
681 }
682
683 // Verify that we can open and start the output stream in exclusive mode at
684 // the lowest possible delay at 48kHz.
685 TEST(WinAudioOutputTest, WASAPIExclusiveModeMinBufferSizeAt48kHz) {
686 if (!ExclusiveModeIsEnabled())
687 return;
688
689 scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
690 if (!CanRunAudioTests(audio_manager.get()))
691 return;
692
693 MessageLoopForUI loop;
694 MockAudioSourceCallback source;
695
696 // Create exclusive-mode WASAPI output stream which plays out in stereo
697 // using the minimum buffer size at 48kHz sample rate.
698 AudioOutputStreamWrapper aosw(audio_manager.get());
699 AudioOutputStream* aos = aosw.Create(48000, 160);
700 EXPECT_TRUE(aos->Open());
701
702 // Derive the expected size in bytes of each packet.
703 uint32 bytes_per_packet = aosw.channels() * aosw.samples_per_packet() *
704 (aosw.bits_per_sample() / 8);
705
706 // Set up expected minimum delay estimation.
707 AudioBuffersState state(0, bytes_per_packet);
708
709 // Wait for the first callback and verify its parameters.
710 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_per_packet,
711 HasValidDelay(state)))
712 .WillOnce(DoAll(
713 QuitLoop(loop.message_loop_proxy()),
714 Return(bytes_per_packet)))
715 .WillRepeatedly(Return(bytes_per_packet));
716
717 aos->Start(&source);
718 loop.PostDelayedTask(FROM_HERE, MessageLoop::QuitClosure(),
719 TestTimeouts::action_timeout());
720 loop.Run();
721 aos->Stop();
722 aos->Close();
723 }
724
725 // Verify that we can open and start the output stream in exclusive mode at
726 // the lowest possible delay at 44.1kHz.
727 TEST(WinAudioOutputTest, WASAPIExclusiveModeMinBufferSizeAt44kHz) {
728 if (!ExclusiveModeIsEnabled())
729 return;
730
731 scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
732 if (!CanRunAudioTests(audio_manager.get()))
733 return;
734
735 MessageLoopForUI loop;
736 MockAudioSourceCallback source;
737
738 // Create exclusive-mode WASAPI output stream which plays out in stereo
739 // using the minimum buffer size at 44.1kHz sample rate.
740 AudioOutputStreamWrapper aosw(audio_manager.get());
741 AudioOutputStream* aos = aosw.Create(44100, 160);
742 EXPECT_TRUE(aos->Open());
743
744 // Derive the expected size in bytes of each packet.
745 uint32 bytes_per_packet = aosw.channels() * aosw.samples_per_packet() *
746 (aosw.bits_per_sample() / 8);
747
748 // Set up expected minimum delay estimation.
749 AudioBuffersState state(0, bytes_per_packet);
750
751 // Wait for the first callback and verify its parameters.
752 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_per_packet,
753 HasValidDelay(state)))
754 .WillOnce(DoAll(
755 QuitLoop(loop.message_loop_proxy()),
756 Return(bytes_per_packet)))
757 .WillRepeatedly(Return(bytes_per_packet));
758
759 aos->Start(&source);
760 loop.PostDelayedTask(FROM_HERE, MessageLoop::QuitClosure(),
761 TestTimeouts::action_timeout());
762 loop.Run();
763 aos->Stop();
764 aos->Close();
765 }
766
565 } // namespace media 767 } // namespace media
OLDNEW
« no previous file with comments | « media/audio/win/audio_low_latency_output_win.cc ('k') | media/base/media_switches.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698