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
3 // found in the LICENSE file.
8 #include "base/basictypes.h"
9 #include "base/environment.h"
10 #include "base/file_util.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/message_loop.h"
13 #include "base/test/test_timeouts.h"
14 #include "base/time.h"
15 #include "base/path_service.h"
16 #include "base/win/scoped_com_initializer.h"
17 #include "media/audio/audio_io.h"
18 #include "media/audio/audio_manager.h"
19 #include "media/audio/audio_util.h"
20 #include "media/audio/win/audio_low_latency_output_win.h"
21 #include "media/audio/win/core_audio_util_win.h"
22 #include "media/base/decoder_buffer.h"
23 #include "media/base/seekable_buffer.h"
24 #include "media/base/test_data_util.h"
25 #include "testing/gmock_mutant.h"
26 #include "testing/gmock/include/gmock/gmock.h"
27 #include "testing/gtest/include/gtest/gtest.h"
30 using ::testing::AnyNumber
;
31 using ::testing::AtLeast
;
32 using ::testing::Between
;
33 using ::testing::CreateFunctor
;
34 using ::testing::DoAll
;
36 using ::testing::InvokeWithoutArgs
;
37 using ::testing::NotNull
;
38 using ::testing::Return
;
39 using base::win::ScopedCOMInitializer
;
43 static const char kSpeechFile_16b_s_48k
[] = "speech_16b_stereo_48kHz.raw";
44 static const char kSpeechFile_16b_s_44k
[] = "speech_16b_stereo_44kHz.raw";
45 static const size_t kFileDurationMs
= 20000;
46 static const size_t kNumFileSegments
= 2;
47 static const int kBitsPerSample
= 16;
48 static const size_t kMaxDeltaSamples
= 1000;
49 static const char kDeltaTimeMsFileName
[] = "delta_times_ms.txt";
51 MATCHER_P(HasValidDelay
, value
, "") {
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
54 // larger than the selected buffer size.
55 return arg
.hardware_delay_bytes
>= value
.hardware_delay_bytes
;
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());
64 class MockAudioSourceCallback
: public AudioOutputStream::AudioSourceCallback
{
66 MOCK_METHOD2(OnMoreData
, int(AudioBus
* audio_bus
,
67 AudioBuffersState buffers_state
));
68 MOCK_METHOD3(OnMoreIOData
, int(AudioBus
* source
,
70 AudioBuffersState buffers_state
));
71 MOCK_METHOD1(OnError
, void(AudioOutputStream
* stream
));
74 // This audio source implementation should be used for manual tests only since
75 // it takes about 20 seconds to play out a file.
76 class ReadFromFileAudioSource
: public AudioOutputStream::AudioSourceCallback
{
78 explicit ReadFromFileAudioSource(const std::string
& name
)
80 previous_call_time_(base::Time::Now()),
82 elements_to_write_(0) {
83 // Reads a test file from media/test/data directory.
84 file_
= ReadTestDataFile(name
);
86 // Creates an array that will store delta times between callbacks.
87 // The content of this array will be written to a text file at
88 // destruction and can then be used for off-line analysis of the exact
89 // timing of callbacks. The text file will be stored in media/test/data.
90 delta_times_
.reset(new int[kMaxDeltaSamples
]);
93 virtual ~ReadFromFileAudioSource() {
94 // Get complete file path to output file in directory containing
95 // media_unittests.exe.
96 base::FilePath file_name
;
97 EXPECT_TRUE(PathService::Get(base::DIR_EXE
, &file_name
));
98 file_name
= file_name
.AppendASCII(kDeltaTimeMsFileName
);
100 EXPECT_TRUE(!text_file_
);
101 text_file_
= file_util::OpenFile(file_name
, "wt");
102 DLOG_IF(ERROR
, !text_file_
) << "Failed to open log file.";
104 // Write the array which contains delta times to a text file.
105 size_t elements_written
= 0;
106 while (elements_written
< elements_to_write_
) {
107 fprintf(text_file_
, "%d\n", delta_times_
[elements_written
]);
111 file_util::CloseFile(text_file_
);
114 // AudioOutputStream::AudioSourceCallback implementation.
115 virtual int OnMoreData(AudioBus
* audio_bus
,
116 AudioBuffersState buffers_state
) {
117 // Store time difference between two successive callbacks in an array.
118 // These values will be written to a file in the destructor.
119 int diff
= (base::Time::Now() - previous_call_time_
).InMilliseconds();
120 previous_call_time_
= base::Time::Now();
121 if (elements_to_write_
< kMaxDeltaSamples
) {
122 delta_times_
[elements_to_write_
] = diff
;
123 ++elements_to_write_
;
127 audio_bus
->frames() * audio_bus
->channels() * kBitsPerSample
/ 8;
129 // Use samples read from a data file and fill up the audio buffer
130 // provided to us in the callback.
131 if (pos_
+ static_cast<int>(max_size
) > file_size())
132 max_size
= file_size() - pos_
;
133 int frames
= max_size
/ (audio_bus
->channels() * kBitsPerSample
/ 8);
135 audio_bus
->FromInterleaved(
136 file_
->GetData() + pos_
, frames
, kBitsPerSample
/ 8);
142 virtual int OnMoreIOData(AudioBus
* source
,
144 AudioBuffersState buffers_state
) OVERRIDE
{
149 virtual void OnError(AudioOutputStream
* stream
) {}
151 int file_size() { return file_
->GetDataSize(); }
154 scoped_refptr
<DecoderBuffer
> file_
;
155 scoped_array
<int> delta_times_
;
157 base::Time previous_call_time_
;
159 size_t elements_to_write_
;
162 static bool ExclusiveModeIsEnabled() {
163 return (WASAPIAudioOutputStream::GetShareMode() ==
164 AUDCLNT_SHAREMODE_EXCLUSIVE
);
167 // Convenience method which ensures that we are not running on the build
168 // bots and that at least one valid output device can be found. We also
169 // verify that we are not running on XP since the low-latency (WASAPI-
170 // based) version requires Windows Vista or higher.
171 static bool CanRunAudioTests(AudioManager
* audio_man
) {
172 if (!CoreAudioUtil::IsSupported()) {
173 LOG(WARNING
) << "This test requires Windows Vista or higher.";
177 // TODO(henrika): note that we use Wave today to query the number of
178 // existing output devices.
179 if (!audio_man
->HasAudioOutputDevices()) {
180 LOG(WARNING
) << "No output devices detected.";
187 // Convenience method which creates a default AudioOutputStream object but
188 // also allows the user to modify the default settings.
189 class AudioOutputStreamWrapper
{
191 explicit AudioOutputStreamWrapper(AudioManager
* audio_manager
)
192 : audio_man_(audio_manager
),
193 format_(AudioParameters::AUDIO_PCM_LOW_LATENCY
),
194 bits_per_sample_(kBitsPerSample
) {
195 AudioParameters preferred_params
;
196 EXPECT_TRUE(SUCCEEDED(CoreAudioUtil::GetPreferredAudioParameters(
197 eRender
, eConsole
, &preferred_params
)));
198 channel_layout_
= preferred_params
.channel_layout();
199 sample_rate_
= preferred_params
.sample_rate();
200 samples_per_packet_
= preferred_params
.frames_per_buffer();
203 ~AudioOutputStreamWrapper() {}
205 // Creates AudioOutputStream object using default parameters.
206 AudioOutputStream
* Create() {
207 return CreateOutputStream();
210 // Creates AudioOutputStream object using non-default parameters where the
211 // frame size is modified.
212 AudioOutputStream
* Create(int samples_per_packet
) {
213 samples_per_packet_
= samples_per_packet
;
214 return CreateOutputStream();
217 // Creates AudioOutputStream object using non-default parameters where the
218 // sample rate and frame size are modified.
219 AudioOutputStream
* Create(int sample_rate
, int samples_per_packet
) {
220 sample_rate_
= sample_rate
;
221 samples_per_packet_
= samples_per_packet
;
222 return CreateOutputStream();
225 AudioParameters::Format
format() const { return format_
; }
226 int channels() const { return ChannelLayoutToChannelCount(channel_layout_
); }
227 int bits_per_sample() const { return bits_per_sample_
; }
228 int sample_rate() const { return sample_rate_
; }
229 int samples_per_packet() const { return samples_per_packet_
; }
232 AudioOutputStream
* CreateOutputStream() {
233 AudioOutputStream
* aos
= audio_man_
->MakeAudioOutputStream(
234 AudioParameters(format_
, channel_layout_
, sample_rate_
,
235 bits_per_sample_
, samples_per_packet_
));
240 AudioManager
* audio_man_
;
241 AudioParameters::Format format_
;
242 ChannelLayout channel_layout_
;
243 int bits_per_sample_
;
245 int samples_per_packet_
;
248 // Convenience method which creates a default AudioOutputStream object.
249 static AudioOutputStream
* CreateDefaultAudioOutputStream(
250 AudioManager
* audio_manager
) {
251 AudioOutputStreamWrapper
aosw(audio_manager
);
252 AudioOutputStream
* aos
= aosw
.Create();
256 // Verify that we can retrieve the current hardware/mixing sample rate
257 // for the default audio device.
258 // TODO(henrika): modify this test when we support full device enumeration.
259 TEST(WASAPIAudioOutputStreamTest
, HardwareSampleRate
) {
260 // Skip this test in exclusive mode since the resulting rate is only utilized
261 // for shared mode streams.
262 scoped_ptr
<AudioManager
> audio_manager(AudioManager::Create());
263 if (!CanRunAudioTests(audio_manager
.get()) || ExclusiveModeIsEnabled())
266 // Default device intended for games, system notification sounds,
267 // and voice commands.
268 int fs
= static_cast<int>(
269 WASAPIAudioOutputStream::HardwareSampleRate());
273 // Test Create(), Close() calling sequence.
274 TEST(WASAPIAudioOutputStreamTest
, CreateAndClose
) {
275 scoped_ptr
<AudioManager
> audio_manager(AudioManager::Create());
276 if (!CanRunAudioTests(audio_manager
.get()))
278 AudioOutputStream
* aos
= CreateDefaultAudioOutputStream(audio_manager
.get());
282 // Test Open(), Close() calling sequence.
283 TEST(WASAPIAudioOutputStreamTest
, OpenAndClose
) {
284 scoped_ptr
<AudioManager
> audio_manager(AudioManager::Create());
285 if (!CanRunAudioTests(audio_manager
.get()))
287 AudioOutputStream
* aos
= CreateDefaultAudioOutputStream(audio_manager
.get());
288 EXPECT_TRUE(aos
->Open());
292 // Test Open(), Start(), Close() calling sequence.
293 TEST(WASAPIAudioOutputStreamTest
, OpenStartAndClose
) {
294 scoped_ptr
<AudioManager
> audio_manager(AudioManager::Create());
295 if (!CanRunAudioTests(audio_manager
.get()))
297 AudioOutputStream
* aos
= CreateDefaultAudioOutputStream(audio_manager
.get());
298 EXPECT_TRUE(aos
->Open());
299 MockAudioSourceCallback source
;
300 EXPECT_CALL(source
, OnError(aos
))
306 // Test Open(), Start(), Stop(), Close() calling sequence.
307 TEST(WASAPIAudioOutputStreamTest
, OpenStartStopAndClose
) {
308 scoped_ptr
<AudioManager
> audio_manager(AudioManager::Create());
309 if (!CanRunAudioTests(audio_manager
.get()))
311 AudioOutputStream
* aos
= CreateDefaultAudioOutputStream(audio_manager
.get());
312 EXPECT_TRUE(aos
->Open());
313 MockAudioSourceCallback source
;
314 EXPECT_CALL(source
, OnError(aos
))
321 // Test SetVolume(), GetVolume()
322 TEST(WASAPIAudioOutputStreamTest
, Volume
) {
323 scoped_ptr
<AudioManager
> audio_manager(AudioManager::Create());
324 if (!CanRunAudioTests(audio_manager
.get()))
326 AudioOutputStream
* aos
= CreateDefaultAudioOutputStream(audio_manager
.get());
328 // Initial volume should be full volume (1.0).
330 aos
->GetVolume(&volume
);
331 EXPECT_EQ(1.0, volume
);
333 // Verify some valid volume settings.
335 aos
->GetVolume(&volume
);
336 EXPECT_EQ(0.0, volume
);
339 aos
->GetVolume(&volume
);
340 EXPECT_EQ(0.5, volume
);
343 aos
->GetVolume(&volume
);
344 EXPECT_EQ(1.0, volume
);
346 // Ensure that invalid volume setting have no effect.
348 aos
->GetVolume(&volume
);
349 EXPECT_EQ(1.0, volume
);
351 aos
->SetVolume(-0.5);
352 aos
->GetVolume(&volume
);
353 EXPECT_EQ(1.0, volume
);
358 // Test some additional calling sequences.
359 TEST(WASAPIAudioOutputStreamTest
, MiscCallingSequences
) {
360 scoped_ptr
<AudioManager
> audio_manager(AudioManager::Create());
361 if (!CanRunAudioTests(audio_manager
.get()))
364 AudioOutputStream
* aos
= CreateDefaultAudioOutputStream(audio_manager
.get());
365 WASAPIAudioOutputStream
* waos
= static_cast<WASAPIAudioOutputStream
*>(aos
);
367 // Open(), Open() is a valid calling sequence (second call does nothing).
368 EXPECT_TRUE(aos
->Open());
369 EXPECT_TRUE(aos
->Open());
371 MockAudioSourceCallback source
;
373 // Start(), Start() is a valid calling sequence (second call does nothing).
375 EXPECT_TRUE(waos
->started());
377 EXPECT_TRUE(waos
->started());
379 // Stop(), Stop() is a valid calling sequence (second call does nothing).
381 EXPECT_FALSE(waos
->started());
383 EXPECT_FALSE(waos
->started());
385 // Start(), Stop(), Start(), Stop().
387 EXPECT_TRUE(waos
->started());
389 EXPECT_FALSE(waos
->started());
391 EXPECT_TRUE(waos
->started());
393 EXPECT_FALSE(waos
->started());
398 // Use preferred packet size and verify that rendering starts.
399 TEST(WASAPIAudioOutputStreamTest
, ValidPacketSize
) {
400 scoped_ptr
<AudioManager
> audio_manager(AudioManager::Create());
401 if (!CanRunAudioTests(audio_manager
.get()))
404 MessageLoopForUI loop
;
405 MockAudioSourceCallback source
;
407 // Create default WASAPI output stream which plays out in stereo using
408 // the shared mixing rate. The default buffer size is 10ms.
409 AudioOutputStreamWrapper
aosw(audio_manager
.get());
410 AudioOutputStream
* aos
= aosw
.Create();
411 EXPECT_TRUE(aos
->Open());
413 // Derive the expected size in bytes of each packet.
414 uint32 bytes_per_packet
= aosw
.channels() * aosw
.samples_per_packet() *
415 (aosw
.bits_per_sample() / 8);
417 // Set up expected minimum delay estimation.
418 AudioBuffersState
state(0, bytes_per_packet
);
420 // Wait for the first callback and verify its parameters.
421 EXPECT_CALL(source
, OnMoreData(NotNull(), HasValidDelay(state
)))
423 QuitLoop(loop
.message_loop_proxy()),
424 Return(aosw
.samples_per_packet())));
427 loop
.PostDelayedTask(FROM_HERE
, MessageLoop::QuitClosure(),
428 TestTimeouts::action_timeout());
434 // Use a non-preferred packet size and verify that Open() fails.
435 TEST(WASAPIAudioOutputStreamTest
, InvalidPacketSize
) {
436 scoped_ptr
<AudioManager
> audio_manager(AudioManager::Create());
437 if (!CanRunAudioTests(audio_manager
.get()))
440 if (ExclusiveModeIsEnabled())
443 AudioParameters preferred_params
;
444 EXPECT_TRUE(SUCCEEDED(CoreAudioUtil::GetPreferredAudioParameters(
445 eRender
, eConsole
, &preferred_params
)));
446 int too_large_packet_size
= 2 * preferred_params
.frames_per_buffer();
448 AudioOutputStreamWrapper
aosw(audio_manager
.get());
449 AudioOutputStream
* aos
= aosw
.Create(too_large_packet_size
);
450 EXPECT_FALSE(aos
->Open());
455 // This test is intended for manual tests and should only be enabled
456 // when it is required to play out data from a local PCM file.
457 // By default, GTest will print out YOU HAVE 1 DISABLED TEST.
458 // To include disabled tests in test execution, just invoke the test program
459 // with --gtest_also_run_disabled_tests or set the GTEST_ALSO_RUN_DISABLED_TESTS
460 // environment variable to a value greater than 0.
461 // The test files are approximately 20 seconds long.
462 TEST(WASAPIAudioOutputStreamTest
, DISABLED_ReadFromStereoFile
) {
463 scoped_ptr
<AudioManager
> audio_manager(AudioManager::Create());
464 if (!CanRunAudioTests(audio_manager
.get()))
467 AudioOutputStreamWrapper
aosw(audio_manager
.get());
468 AudioOutputStream
* aos
= aosw
.Create();
469 EXPECT_TRUE(aos
->Open());
471 std::string file_name
;
472 if (aosw
.sample_rate() == 48000) {
473 file_name
= kSpeechFile_16b_s_48k
;
474 } else if (aosw
.sample_rate() == 44100) {
475 file_name
= kSpeechFile_16b_s_44k
;
476 } else if (aosw
.sample_rate() == 96000) {
477 // Use 48kHz file at 96kHz as well. Will sound like Donald Duck.
478 file_name
= kSpeechFile_16b_s_48k
;
480 FAIL() << "This test supports 44.1, 48kHz and 96kHz only.";
483 ReadFromFileAudioSource
file_source(file_name
);
485 LOG(INFO
) << "File name : " << file_name
.c_str();
486 LOG(INFO
) << "Sample rate : " << aosw
.sample_rate();
487 LOG(INFO
) << "Bits per sample: " << aosw
.bits_per_sample();
488 LOG(INFO
) << "#channels : " << aosw
.channels();
489 LOG(INFO
) << "File size : " << file_source
.file_size();
490 LOG(INFO
) << "#file segments : " << kNumFileSegments
;
491 LOG(INFO
) << ">> Listen to the stereo file while playing...";
493 for (int i
= 0; i
< kNumFileSegments
; i
++) {
494 // Each segment will start with a short (~20ms) block of zeros, hence
495 // some short glitches might be heard in this test if kNumFileSegments
496 // is larger than one. The exact length of the silence period depends on
497 // the selected sample rate.
498 aos
->Start(&file_source
);
499 base::PlatformThread::Sleep(
500 base::TimeDelta::FromMilliseconds(kFileDurationMs
/ kNumFileSegments
));
504 LOG(INFO
) << ">> Stereo file playout has stopped.";
508 // Verify that we can open the output stream in exclusive mode using a
509 // certain set of audio parameters and a sample rate of 48kHz.
510 // The expected outcomes of each setting in this test has been derived
511 // manually using log outputs (--v=1).
512 TEST(WASAPIAudioOutputStreamTest
, ExclusiveModeBufferSizesAt48kHz
) {
513 if (!ExclusiveModeIsEnabled())
516 scoped_ptr
<AudioManager
> audio_manager(AudioManager::Create());
517 if (!CanRunAudioTests(audio_manager
.get()))
520 AudioOutputStreamWrapper
aosw(audio_manager
.get());
522 // 10ms @ 48kHz shall work.
523 // Note that, this is the same size as we can use for shared-mode streaming
524 // but here the endpoint buffer delay is only 10ms instead of 20ms.
525 AudioOutputStream
* aos
= aosw
.Create(48000, 480);
526 EXPECT_TRUE(aos
->Open());
529 // 5ms @ 48kHz does not work due to misalignment.
530 // This test will propose an aligned buffer size of 5.3333ms.
531 // Note that we must call Close() even is Open() fails since Close() also
532 // deletes the object and we want to create a new object in the next test.
533 aos
= aosw
.Create(48000, 240);
534 EXPECT_FALSE(aos
->Open());
537 // 5.3333ms @ 48kHz should work (see test above).
538 aos
= aosw
.Create(48000, 256);
539 EXPECT_TRUE(aos
->Open());
542 // 2.6667ms is smaller than the minimum supported size (=3ms).
543 aos
= aosw
.Create(48000, 128);
544 EXPECT_FALSE(aos
->Open());
547 // 3ms does not correspond to an aligned buffer size.
548 // This test will propose an aligned buffer size of 3.3333ms.
549 aos
= aosw
.Create(48000, 144);
550 EXPECT_FALSE(aos
->Open());
553 // 3.3333ms @ 48kHz <=> smallest possible buffer size we can use.
554 aos
= aosw
.Create(48000, 160);
555 EXPECT_TRUE(aos
->Open());
559 // Verify that we can open the output stream in exclusive mode using a
560 // certain set of audio parameters and a sample rate of 44.1kHz.
561 // The expected outcomes of each setting in this test has been derived
562 // manually using log outputs (--v=1).
563 TEST(WASAPIAudioOutputStreamTest
, ExclusiveModeBufferSizesAt44kHz
) {
564 if (!ExclusiveModeIsEnabled())
567 scoped_ptr
<AudioManager
> audio_manager(AudioManager::Create());
568 if (!CanRunAudioTests(audio_manager
.get()))
571 AudioOutputStreamWrapper
aosw(audio_manager
.get());
573 // 10ms @ 44.1kHz does not work due to misalignment.
574 // This test will propose an aligned buffer size of 10.1587ms.
575 AudioOutputStream
* aos
= aosw
.Create(44100, 441);
576 EXPECT_FALSE(aos
->Open());
579 // 10.1587ms @ 44.1kHz shall work (see test above).
580 aos
= aosw
.Create(44100, 448);
581 EXPECT_TRUE(aos
->Open());
584 // 5.8050ms @ 44.1 should work.
585 aos
= aosw
.Create(44100, 256);
586 EXPECT_TRUE(aos
->Open());
589 // 4.9887ms @ 44.1kHz does not work to misalignment.
590 // This test will propose an aligned buffer size of 5.0794ms.
591 // Note that we must call Close() even is Open() fails since Close() also
592 // deletes the object and we want to create a new object in the next test.
593 aos
= aosw
.Create(44100, 220);
594 EXPECT_FALSE(aos
->Open());
597 // 5.0794ms @ 44.1kHz shall work (see test above).
598 aos
= aosw
.Create(44100, 224);
599 EXPECT_TRUE(aos
->Open());
602 // 2.9025ms is smaller than the minimum supported size (=3ms).
603 aos
= aosw
.Create(44100, 132);
604 EXPECT_FALSE(aos
->Open());
607 // 3.01587ms is larger than the minimum size but is not aligned.
608 // This test will propose an aligned buffer size of 3.6281ms.
609 aos
= aosw
.Create(44100, 133);
610 EXPECT_FALSE(aos
->Open());
613 // 3.6281ms @ 44.1kHz <=> smallest possible buffer size we can use.
614 aos
= aosw
.Create(44100, 160);
615 EXPECT_TRUE(aos
->Open());
619 // Verify that we can open and start the output stream in exclusive mode at
620 // the lowest possible delay at 48kHz.
621 TEST(WASAPIAudioOutputStreamTest
, ExclusiveModeMinBufferSizeAt48kHz
) {
622 if (!ExclusiveModeIsEnabled())
625 scoped_ptr
<AudioManager
> audio_manager(AudioManager::Create());
626 if (!CanRunAudioTests(audio_manager
.get()))
629 MessageLoopForUI loop
;
630 MockAudioSourceCallback source
;
632 // Create exclusive-mode WASAPI output stream which plays out in stereo
633 // using the minimum buffer size at 48kHz sample rate.
634 AudioOutputStreamWrapper
aosw(audio_manager
.get());
635 AudioOutputStream
* aos
= aosw
.Create(48000, 160);
636 EXPECT_TRUE(aos
->Open());
638 // Derive the expected size in bytes of each packet.
639 uint32 bytes_per_packet
= aosw
.channels() * aosw
.samples_per_packet() *
640 (aosw
.bits_per_sample() / 8);
642 // Set up expected minimum delay estimation.
643 AudioBuffersState
state(0, bytes_per_packet
);
645 // Wait for the first callback and verify its parameters.
646 EXPECT_CALL(source
, OnMoreData(NotNull(), HasValidDelay(state
)))
648 QuitLoop(loop
.message_loop_proxy()),
649 Return(aosw
.samples_per_packet())))
650 .WillRepeatedly(Return(aosw
.samples_per_packet()));
653 loop
.PostDelayedTask(FROM_HERE
, MessageLoop::QuitClosure(),
654 TestTimeouts::action_timeout());
660 // Verify that we can open and start the output stream in exclusive mode at
661 // the lowest possible delay at 44.1kHz.
662 TEST(WASAPIAudioOutputStreamTest
, ExclusiveModeMinBufferSizeAt44kHz
) {
663 if (!ExclusiveModeIsEnabled())
666 scoped_ptr
<AudioManager
> audio_manager(AudioManager::Create());
667 if (!CanRunAudioTests(audio_manager
.get()))
670 MessageLoopForUI loop
;
671 MockAudioSourceCallback source
;
673 // Create exclusive-mode WASAPI output stream which plays out in stereo
674 // using the minimum buffer size at 44.1kHz sample rate.
675 AudioOutputStreamWrapper
aosw(audio_manager
.get());
676 AudioOutputStream
* aos
= aosw
.Create(44100, 160);
677 EXPECT_TRUE(aos
->Open());
679 // Derive the expected size in bytes of each packet.
680 uint32 bytes_per_packet
= aosw
.channels() * aosw
.samples_per_packet() *
681 (aosw
.bits_per_sample() / 8);
683 // Set up expected minimum delay estimation.
684 AudioBuffersState
state(0, bytes_per_packet
);
686 // Wait for the first callback and verify its parameters.
687 EXPECT_CALL(source
, OnMoreData(NotNull(), HasValidDelay(state
)))
689 QuitLoop(loop
.message_loop_proxy()),
690 Return(aosw
.samples_per_packet())))
691 .WillRepeatedly(Return(aosw
.samples_per_packet()));
694 loop
.PostDelayedTask(FROM_HERE
, MessageLoop::QuitClosure(),
695 TestTimeouts::action_timeout());