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/files/file_util.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/path_service.h"
14 #include "base/test/test_timeouts.h"
15 #include "base/time/time.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_unittest_util.h"
20 #include "media/audio/mock_audio_source_callback.h"
21 #include "media/audio/win/audio_low_latency_output_win.h"
22 #include "media/audio/win/core_audio_util_win.h"
23 #include "media/base/decoder_buffer.h"
24 #include "media/base/seekable_buffer.h"
25 #include "media/base/test_data_util.h"
26 #include "testing/gmock/include/gmock/gmock.h"
27 #include "testing/gmock_mutant.h"
28 #include "testing/gtest/include/gtest/gtest.h"
31 using ::testing::AnyNumber
;
32 using ::testing::AtLeast
;
33 using ::testing::Between
;
34 using ::testing::CreateFunctor
;
35 using ::testing::DoAll
;
37 using ::testing::InvokeWithoutArgs
;
38 using ::testing::NotNull
;
39 using ::testing::Return
;
40 using base::win::ScopedCOMInitializer
;
44 static const char kSpeechFile_16b_s_48k
[] = "speech_16b_stereo_48kHz.raw";
45 static const char kSpeechFile_16b_s_44k
[] = "speech_16b_stereo_44kHz.raw";
46 static const size_t kFileDurationMs
= 20000;
47 static const size_t kNumFileSegments
= 2;
48 static const int kBitsPerSample
= 16;
49 static const size_t kMaxDeltaSamples
= 1000;
50 static const char kDeltaTimeMsFileName
[] = "delta_times_ms.txt";
52 MATCHER_P(HasValidDelay
, value
, "") {
53 // It is difficult to come up with a perfect test condition for the delay
54 // estimation. For now, verify that the produced output delay is always
55 // larger than the selected buffer size.
59 // Used to terminate a loop from a different thread than the loop belongs to.
60 // |loop| should be a MessageLoopProxy.
61 ACTION_P(QuitLoop
, loop
) {
62 loop
->PostTask(FROM_HERE
, base::MessageLoop::QuitClosure());
65 // This audio source implementation should be used for manual tests only since
66 // it takes about 20 seconds to play out a file.
67 class ReadFromFileAudioSource
: public AudioOutputStream::AudioSourceCallback
{
69 explicit ReadFromFileAudioSource(const std::string
& name
)
71 previous_call_time_(base::TimeTicks::Now()),
73 elements_to_write_(0) {
74 // Reads a test file from media/test/data directory.
75 file_
= ReadTestDataFile(name
);
77 // Creates an array that will store delta times between callbacks.
78 // The content of this array will be written to a text file at
79 // destruction and can then be used for off-line analysis of the exact
80 // timing of callbacks. The text file will be stored in media/test/data.
81 delta_times_
.reset(new int[kMaxDeltaSamples
]);
84 ~ReadFromFileAudioSource() override
{
85 // Get complete file path to output file in directory containing
86 // media_unittests.exe.
87 base::FilePath file_name
;
88 EXPECT_TRUE(PathService::Get(base::DIR_EXE
, &file_name
));
89 file_name
= file_name
.AppendASCII(kDeltaTimeMsFileName
);
91 EXPECT_TRUE(!text_file_
);
92 text_file_
= base::OpenFile(file_name
, "wt");
93 DLOG_IF(ERROR
, !text_file_
) << "Failed to open log file.";
95 // Write the array which contains delta times to a text file.
96 size_t elements_written
= 0;
97 while (elements_written
< elements_to_write_
) {
98 fprintf(text_file_
, "%d\n", delta_times_
[elements_written
]);
102 base::CloseFile(text_file_
);
105 // AudioOutputStream::AudioSourceCallback implementation.
106 int OnMoreData(AudioBus
* audio_bus
, uint32 total_bytes_delay
) override
{
107 // Store time difference between two successive callbacks in an array.
108 // These values will be written to a file in the destructor.
109 const base::TimeTicks now_time
= base::TimeTicks::Now();
110 const int diff
= (now_time
- previous_call_time_
).InMilliseconds();
111 previous_call_time_
= now_time
;
112 if (elements_to_write_
< kMaxDeltaSamples
) {
113 delta_times_
[elements_to_write_
] = diff
;
114 ++elements_to_write_
;
118 audio_bus
->frames() * audio_bus
->channels() * kBitsPerSample
/ 8;
120 // Use samples read from a data file and fill up the audio buffer
121 // provided to us in the callback.
122 if (pos_
+ static_cast<int>(max_size
) > file_size())
123 max_size
= file_size() - pos_
;
124 int frames
= max_size
/ (audio_bus
->channels() * kBitsPerSample
/ 8);
126 audio_bus
->FromInterleaved(
127 file_
->data() + pos_
, frames
, kBitsPerSample
/ 8);
133 void OnError(AudioOutputStream
* stream
) override
{}
135 int file_size() { return file_
->data_size(); }
138 scoped_refptr
<DecoderBuffer
> file_
;
139 scoped_ptr
<int[]> delta_times_
;
141 base::TimeTicks previous_call_time_
;
143 size_t elements_to_write_
;
146 static bool ExclusiveModeIsEnabled() {
147 return (WASAPIAudioOutputStream::GetShareMode() ==
148 AUDCLNT_SHAREMODE_EXCLUSIVE
);
151 static bool HasCoreAudioAndOutputDevices(AudioManager
* audio_man
) {
152 // The low-latency (WASAPI-based) version requires Windows Vista or higher.
153 // TODO(henrika): note that we use Wave today to query the number of
154 // existing output devices.
155 return CoreAudioUtil::IsSupported() && audio_man
->HasAudioOutputDevices();
158 // Convenience method which creates a default AudioOutputStream object but
159 // also allows the user to modify the default settings.
160 class AudioOutputStreamWrapper
{
162 explicit AudioOutputStreamWrapper(AudioManager
* audio_manager
)
163 : audio_man_(audio_manager
),
164 format_(AudioParameters::AUDIO_PCM_LOW_LATENCY
),
165 bits_per_sample_(kBitsPerSample
) {
166 AudioParameters preferred_params
;
167 EXPECT_TRUE(SUCCEEDED(CoreAudioUtil::GetPreferredAudioParameters(
168 eRender
, eConsole
, &preferred_params
)));
169 channel_layout_
= preferred_params
.channel_layout();
170 sample_rate_
= preferred_params
.sample_rate();
171 samples_per_packet_
= preferred_params
.frames_per_buffer();
174 ~AudioOutputStreamWrapper() {}
176 // Creates AudioOutputStream object using default parameters.
177 AudioOutputStream
* Create() {
178 return CreateOutputStream();
181 // Creates AudioOutputStream object using non-default parameters where the
182 // frame size is modified.
183 AudioOutputStream
* Create(int samples_per_packet
) {
184 samples_per_packet_
= samples_per_packet
;
185 return CreateOutputStream();
188 // Creates AudioOutputStream object using non-default parameters where the
189 // sample rate and frame size are modified.
190 AudioOutputStream
* Create(int sample_rate
, int samples_per_packet
) {
191 sample_rate_
= sample_rate
;
192 samples_per_packet_
= samples_per_packet
;
193 return CreateOutputStream();
196 AudioParameters::Format
format() const { return format_
; }
197 int channels() const { return ChannelLayoutToChannelCount(channel_layout_
); }
198 int bits_per_sample() const { return bits_per_sample_
; }
199 int sample_rate() const { return sample_rate_
; }
200 int samples_per_packet() const { return samples_per_packet_
; }
203 AudioOutputStream
* CreateOutputStream() {
204 AudioOutputStream
* aos
= audio_man_
->MakeAudioOutputStream(
205 AudioParameters(format_
, channel_layout_
, sample_rate_
,
206 bits_per_sample_
, samples_per_packet_
),
212 AudioManager
* audio_man_
;
213 AudioParameters::Format format_
;
214 ChannelLayout channel_layout_
;
215 int bits_per_sample_
;
217 int samples_per_packet_
;
220 // Convenience method which creates a default AudioOutputStream object.
221 static AudioOutputStream
* CreateDefaultAudioOutputStream(
222 AudioManager
* audio_manager
) {
223 AudioOutputStreamWrapper
aosw(audio_manager
);
224 AudioOutputStream
* aos
= aosw
.Create();
228 // Verify that we can retrieve the current hardware/mixing sample rate
229 // for the default audio device.
230 // TODO(henrika): modify this test when we support full device enumeration.
231 TEST(WASAPIAudioOutputStreamTest
, HardwareSampleRate
) {
232 // Skip this test in exclusive mode since the resulting rate is only utilized
233 // for shared mode streams.
234 scoped_ptr
<AudioManager
> audio_manager(AudioManager::CreateForTesting());
235 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager
.get()) &&
236 ExclusiveModeIsEnabled());
238 // Default device intended for games, system notification sounds,
239 // and voice commands.
240 int fs
= static_cast<int>(
241 WASAPIAudioOutputStream::HardwareSampleRate(std::string()));
245 // Test Create(), Close() calling sequence.
246 TEST(WASAPIAudioOutputStreamTest
, CreateAndClose
) {
247 scoped_ptr
<AudioManager
> audio_manager(AudioManager::CreateForTesting());
248 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager
.get()));
249 AudioOutputStream
* aos
= CreateDefaultAudioOutputStream(audio_manager
.get());
253 // Test Open(), Close() calling sequence.
254 TEST(WASAPIAudioOutputStreamTest
, OpenAndClose
) {
255 scoped_ptr
<AudioManager
> audio_manager(AudioManager::CreateForTesting());
256 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager
.get()));
257 AudioOutputStream
* aos
= CreateDefaultAudioOutputStream(audio_manager
.get());
258 EXPECT_TRUE(aos
->Open());
262 // Test Open(), Start(), Close() calling sequence.
263 TEST(WASAPIAudioOutputStreamTest
, OpenStartAndClose
) {
264 scoped_ptr
<AudioManager
> audio_manager(AudioManager::CreateForTesting());
265 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager
.get()));
266 AudioOutputStream
* aos
= CreateDefaultAudioOutputStream(audio_manager
.get());
267 EXPECT_TRUE(aos
->Open());
268 MockAudioSourceCallback source
;
269 EXPECT_CALL(source
, OnError(aos
))
275 // Test Open(), Start(), Stop(), Close() calling sequence.
276 TEST(WASAPIAudioOutputStreamTest
, OpenStartStopAndClose
) {
277 scoped_ptr
<AudioManager
> audio_manager(AudioManager::CreateForTesting());
278 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager
.get()));
279 AudioOutputStream
* aos
= CreateDefaultAudioOutputStream(audio_manager
.get());
280 EXPECT_TRUE(aos
->Open());
281 MockAudioSourceCallback source
;
282 EXPECT_CALL(source
, OnError(aos
))
289 // Test SetVolume(), GetVolume()
290 TEST(WASAPIAudioOutputStreamTest
, Volume
) {
291 scoped_ptr
<AudioManager
> audio_manager(AudioManager::CreateForTesting());
292 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager
.get()));
293 AudioOutputStream
* aos
= CreateDefaultAudioOutputStream(audio_manager
.get());
295 // Initial volume should be full volume (1.0).
297 aos
->GetVolume(&volume
);
298 EXPECT_EQ(1.0, volume
);
300 // Verify some valid volume settings.
302 aos
->GetVolume(&volume
);
303 EXPECT_EQ(0.0, volume
);
306 aos
->GetVolume(&volume
);
307 EXPECT_EQ(0.5, volume
);
310 aos
->GetVolume(&volume
);
311 EXPECT_EQ(1.0, volume
);
313 // Ensure that invalid volume setting have no effect.
315 aos
->GetVolume(&volume
);
316 EXPECT_EQ(1.0, volume
);
318 aos
->SetVolume(-0.5);
319 aos
->GetVolume(&volume
);
320 EXPECT_EQ(1.0, volume
);
325 // Test some additional calling sequences.
326 TEST(WASAPIAudioOutputStreamTest
, MiscCallingSequences
) {
327 scoped_ptr
<AudioManager
> audio_manager(AudioManager::CreateForTesting());
328 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager
.get()));
330 AudioOutputStream
* aos
= CreateDefaultAudioOutputStream(audio_manager
.get());
331 WASAPIAudioOutputStream
* waos
= static_cast<WASAPIAudioOutputStream
*>(aos
);
333 // Open(), Open() is a valid calling sequence (second call does nothing).
334 EXPECT_TRUE(aos
->Open());
335 EXPECT_TRUE(aos
->Open());
337 MockAudioSourceCallback source
;
339 // Start(), Start() is a valid calling sequence (second call does nothing).
341 EXPECT_TRUE(waos
->started());
343 EXPECT_TRUE(waos
->started());
345 // Stop(), Stop() is a valid calling sequence (second call does nothing).
347 EXPECT_FALSE(waos
->started());
349 EXPECT_FALSE(waos
->started());
351 // Start(), Stop(), Start(), Stop().
353 EXPECT_TRUE(waos
->started());
355 EXPECT_FALSE(waos
->started());
357 EXPECT_TRUE(waos
->started());
359 EXPECT_FALSE(waos
->started());
364 // Use preferred packet size and verify that rendering starts.
365 TEST(WASAPIAudioOutputStreamTest
, ValidPacketSize
) {
366 scoped_ptr
<AudioManager
> audio_manager(AudioManager::CreateForTesting());
367 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager
.get()));
369 base::MessageLoopForUI loop
;
370 MockAudioSourceCallback source
;
372 // Create default WASAPI output stream which plays out in stereo using
373 // the shared mixing rate. The default buffer size is 10ms.
374 AudioOutputStreamWrapper
aosw(audio_manager
.get());
375 AudioOutputStream
* aos
= aosw
.Create();
376 EXPECT_TRUE(aos
->Open());
378 // Derive the expected size in bytes of each packet.
379 uint32 bytes_per_packet
= aosw
.channels() * aosw
.samples_per_packet() *
380 (aosw
.bits_per_sample() / 8);
382 // Wait for the first callback and verify its parameters.
383 EXPECT_CALL(source
, OnMoreData(NotNull(), HasValidDelay(bytes_per_packet
)))
385 QuitLoop(loop
.message_loop_proxy()),
386 Return(aosw
.samples_per_packet())));
389 loop
.PostDelayedTask(FROM_HERE
, base::MessageLoop::QuitClosure(),
390 TestTimeouts::action_timeout());
396 // This test is intended for manual tests and should only be enabled
397 // when it is required to play out data from a local PCM file.
398 // By default, GTest will print out YOU HAVE 1 DISABLED TEST.
399 // To include disabled tests in test execution, just invoke the test program
400 // with --gtest_also_run_disabled_tests or set the GTEST_ALSO_RUN_DISABLED_TESTS
401 // environment variable to a value greater than 0.
402 // The test files are approximately 20 seconds long.
403 TEST(WASAPIAudioOutputStreamTest
, DISABLED_ReadFromStereoFile
) {
404 scoped_ptr
<AudioManager
> audio_manager(AudioManager::CreateForTesting());
405 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager
.get()));
407 AudioOutputStreamWrapper
aosw(audio_manager
.get());
408 AudioOutputStream
* aos
= aosw
.Create();
409 EXPECT_TRUE(aos
->Open());
411 std::string file_name
;
412 if (aosw
.sample_rate() == 48000) {
413 file_name
= kSpeechFile_16b_s_48k
;
414 } else if (aosw
.sample_rate() == 44100) {
415 file_name
= kSpeechFile_16b_s_44k
;
416 } else if (aosw
.sample_rate() == 96000) {
417 // Use 48kHz file at 96kHz as well. Will sound like Donald Duck.
418 file_name
= kSpeechFile_16b_s_48k
;
420 FAIL() << "This test supports 44.1, 48kHz and 96kHz only.";
423 ReadFromFileAudioSource
file_source(file_name
);
425 DVLOG(0) << "File name : " << file_name
.c_str();
426 DVLOG(0) << "Sample rate : " << aosw
.sample_rate();
427 DVLOG(0) << "Bits per sample: " << aosw
.bits_per_sample();
428 DVLOG(0) << "#channels : " << aosw
.channels();
429 DVLOG(0) << "File size : " << file_source
.file_size();
430 DVLOG(0) << "#file segments : " << kNumFileSegments
;
431 DVLOG(0) << ">> Listen to the stereo file while playing...";
433 for (int i
= 0; i
< kNumFileSegments
; i
++) {
434 // Each segment will start with a short (~20ms) block of zeros, hence
435 // some short glitches might be heard in this test if kNumFileSegments
436 // is larger than one. The exact length of the silence period depends on
437 // the selected sample rate.
438 aos
->Start(&file_source
);
439 base::PlatformThread::Sleep(
440 base::TimeDelta::FromMilliseconds(kFileDurationMs
/ kNumFileSegments
));
444 DVLOG(0) << ">> Stereo file playout has stopped.";
448 // Verify that we can open the output stream in exclusive mode using a
449 // certain set of audio parameters and a sample rate of 48kHz.
450 // The expected outcomes of each setting in this test has been derived
451 // manually using log outputs (--v=1).
452 TEST(WASAPIAudioOutputStreamTest
, ExclusiveModeBufferSizesAt48kHz
) {
453 scoped_ptr
<AudioManager
> audio_manager(AudioManager::CreateForTesting());
454 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager
.get()) &&
455 ExclusiveModeIsEnabled());
457 AudioOutputStreamWrapper
aosw(audio_manager
.get());
459 // 10ms @ 48kHz shall work.
460 // Note that, this is the same size as we can use for shared-mode streaming
461 // but here the endpoint buffer delay is only 10ms instead of 20ms.
462 AudioOutputStream
* aos
= aosw
.Create(48000, 480);
463 EXPECT_TRUE(aos
->Open());
466 // 5ms @ 48kHz does not work due to misalignment.
467 // This test will propose an aligned buffer size of 5.3333ms.
468 // Note that we must call Close() even is Open() fails since Close() also
469 // deletes the object and we want to create a new object in the next test.
470 aos
= aosw
.Create(48000, 240);
471 EXPECT_FALSE(aos
->Open());
474 // 5.3333ms @ 48kHz should work (see test above).
475 aos
= aosw
.Create(48000, 256);
476 EXPECT_TRUE(aos
->Open());
479 // 2.6667ms is smaller than the minimum supported size (=3ms).
480 aos
= aosw
.Create(48000, 128);
481 EXPECT_FALSE(aos
->Open());
484 // 3ms does not correspond to an aligned buffer size.
485 // This test will propose an aligned buffer size of 3.3333ms.
486 aos
= aosw
.Create(48000, 144);
487 EXPECT_FALSE(aos
->Open());
490 // 3.3333ms @ 48kHz <=> smallest possible buffer size we can use.
491 aos
= aosw
.Create(48000, 160);
492 EXPECT_TRUE(aos
->Open());
496 // Verify that we can open the output stream in exclusive mode using a
497 // certain set of audio parameters and a sample rate of 44.1kHz.
498 // The expected outcomes of each setting in this test has been derived
499 // manually using log outputs (--v=1).
500 TEST(WASAPIAudioOutputStreamTest
, ExclusiveModeBufferSizesAt44kHz
) {
501 scoped_ptr
<AudioManager
> audio_manager(AudioManager::CreateForTesting());
502 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager
.get()) &&
503 ExclusiveModeIsEnabled());
505 AudioOutputStreamWrapper
aosw(audio_manager
.get());
507 // 10ms @ 44.1kHz does not work due to misalignment.
508 // This test will propose an aligned buffer size of 10.1587ms.
509 AudioOutputStream
* aos
= aosw
.Create(44100, 441);
510 EXPECT_FALSE(aos
->Open());
513 // 10.1587ms @ 44.1kHz shall work (see test above).
514 aos
= aosw
.Create(44100, 448);
515 EXPECT_TRUE(aos
->Open());
518 // 5.8050ms @ 44.1 should work.
519 aos
= aosw
.Create(44100, 256);
520 EXPECT_TRUE(aos
->Open());
523 // 4.9887ms @ 44.1kHz does not work to misalignment.
524 // This test will propose an aligned buffer size of 5.0794ms.
525 // Note that we must call Close() even is Open() fails since Close() also
526 // deletes the object and we want to create a new object in the next test.
527 aos
= aosw
.Create(44100, 220);
528 EXPECT_FALSE(aos
->Open());
531 // 5.0794ms @ 44.1kHz shall work (see test above).
532 aos
= aosw
.Create(44100, 224);
533 EXPECT_TRUE(aos
->Open());
536 // 2.9025ms is smaller than the minimum supported size (=3ms).
537 aos
= aosw
.Create(44100, 132);
538 EXPECT_FALSE(aos
->Open());
541 // 3.01587ms is larger than the minimum size but is not aligned.
542 // This test will propose an aligned buffer size of 3.6281ms.
543 aos
= aosw
.Create(44100, 133);
544 EXPECT_FALSE(aos
->Open());
547 // 3.6281ms @ 44.1kHz <=> smallest possible buffer size we can use.
548 aos
= aosw
.Create(44100, 160);
549 EXPECT_TRUE(aos
->Open());
553 // Verify that we can open and start the output stream in exclusive mode at
554 // the lowest possible delay at 48kHz.
555 TEST(WASAPIAudioOutputStreamTest
, ExclusiveModeMinBufferSizeAt48kHz
) {
556 scoped_ptr
<AudioManager
> audio_manager(AudioManager::CreateForTesting());
557 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager
.get()) &&
558 ExclusiveModeIsEnabled());
560 base::MessageLoopForUI loop
;
561 MockAudioSourceCallback source
;
563 // Create exclusive-mode WASAPI output stream which plays out in stereo
564 // using the minimum buffer size at 48kHz sample rate.
565 AudioOutputStreamWrapper
aosw(audio_manager
.get());
566 AudioOutputStream
* aos
= aosw
.Create(48000, 160);
567 EXPECT_TRUE(aos
->Open());
569 // Derive the expected size in bytes of each packet.
570 uint32 bytes_per_packet
= aosw
.channels() * aosw
.samples_per_packet() *
571 (aosw
.bits_per_sample() / 8);
573 // Wait for the first callback and verify its parameters.
574 EXPECT_CALL(source
, OnMoreData(NotNull(), HasValidDelay(bytes_per_packet
)))
576 QuitLoop(loop
.message_loop_proxy()),
577 Return(aosw
.samples_per_packet())))
578 .WillRepeatedly(Return(aosw
.samples_per_packet()));
581 loop
.PostDelayedTask(FROM_HERE
, base::MessageLoop::QuitClosure(),
582 TestTimeouts::action_timeout());
588 // Verify that we can open and start the output stream in exclusive mode at
589 // the lowest possible delay at 44.1kHz.
590 TEST(WASAPIAudioOutputStreamTest
, ExclusiveModeMinBufferSizeAt44kHz
) {
591 ABORT_AUDIO_TEST_IF_NOT(ExclusiveModeIsEnabled());
592 scoped_ptr
<AudioManager
> audio_manager(AudioManager::CreateForTesting());
594 base::MessageLoopForUI loop
;
595 MockAudioSourceCallback source
;
597 // Create exclusive-mode WASAPI output stream which plays out in stereo
598 // using the minimum buffer size at 44.1kHz sample rate.
599 AudioOutputStreamWrapper
aosw(audio_manager
.get());
600 AudioOutputStream
* aos
= aosw
.Create(44100, 160);
601 EXPECT_TRUE(aos
->Open());
603 // Derive the expected size in bytes of each packet.
604 uint32 bytes_per_packet
= aosw
.channels() * aosw
.samples_per_packet() *
605 (aosw
.bits_per_sample() / 8);
607 // Wait for the first callback and verify its parameters.
608 EXPECT_CALL(source
, OnMoreData(NotNull(), HasValidDelay(bytes_per_packet
)))
610 QuitLoop(loop
.message_loop_proxy()),
611 Return(aosw
.samples_per_packet())))
612 .WillRepeatedly(Return(aosw
.samples_per_packet()));
615 loop
.PostDelayedTask(FROM_HERE
, base::MessageLoop::QuitClosure(),
616 TestTimeouts::action_timeout());