Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / media / audio / win / audio_low_latency_output_win_unittest.cc
blob348543ce9328f506d0d327ec65efc02a4c554b99
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.
5 #include <windows.h>
6 #include <mmsystem.h>
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"
30 using ::testing::_;
31 using ::testing::AnyNumber;
32 using ::testing::AtLeast;
33 using ::testing::Between;
34 using ::testing::CreateFunctor;
35 using ::testing::DoAll;
36 using ::testing::Gt;
37 using ::testing::InvokeWithoutArgs;
38 using ::testing::NotNull;
39 using ::testing::Return;
41 namespace media {
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 >= value;
58 // Used to terminate a loop from a different thread than the loop belongs to.
59 // |task_runner| should be a SingleThreadTaskRunner.
60 ACTION_P(QuitLoop, task_runner) {
61 task_runner->PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
64 // This audio source implementation should be used for manual tests only since
65 // it takes about 20 seconds to play out a file.
66 class ReadFromFileAudioSource : public AudioOutputStream::AudioSourceCallback {
67 public:
68 explicit ReadFromFileAudioSource(const std::string& name)
69 : pos_(0),
70 previous_call_time_(base::TimeTicks::Now()),
71 text_file_(NULL),
72 elements_to_write_(0) {
73 // Reads a test file from media/test/data directory.
74 file_ = ReadTestDataFile(name);
76 // Creates an array that will store delta times between callbacks.
77 // The content of this array will be written to a text file at
78 // destruction and can then be used for off-line analysis of the exact
79 // timing of callbacks. The text file will be stored in media/test/data.
80 delta_times_.reset(new int[kMaxDeltaSamples]);
83 ~ReadFromFileAudioSource() override {
84 // Get complete file path to output file in directory containing
85 // media_unittests.exe.
86 base::FilePath file_name;
87 EXPECT_TRUE(PathService::Get(base::DIR_EXE, &file_name));
88 file_name = file_name.AppendASCII(kDeltaTimeMsFileName);
90 EXPECT_TRUE(!text_file_);
91 text_file_ = base::OpenFile(file_name, "wt");
92 DLOG_IF(ERROR, !text_file_) << "Failed to open log file.";
94 // Write the array which contains delta times to a text file.
95 size_t elements_written = 0;
96 while (elements_written < elements_to_write_) {
97 fprintf(text_file_, "%d\n", delta_times_[elements_written]);
98 ++elements_written;
101 base::CloseFile(text_file_);
104 // AudioOutputStream::AudioSourceCallback implementation.
105 int OnMoreData(AudioBus* audio_bus, uint32 total_bytes_delay) override {
106 // Store time difference between two successive callbacks in an array.
107 // These values will be written to a file in the destructor.
108 const base::TimeTicks now_time = base::TimeTicks::Now();
109 const int diff = (now_time - previous_call_time_).InMilliseconds();
110 previous_call_time_ = now_time;
111 if (elements_to_write_ < kMaxDeltaSamples) {
112 delta_times_[elements_to_write_] = diff;
113 ++elements_to_write_;
116 int max_size =
117 audio_bus->frames() * audio_bus->channels() * kBitsPerSample / 8;
119 // Use samples read from a data file and fill up the audio buffer
120 // provided to us in the callback.
121 if (pos_ + static_cast<int>(max_size) > file_size())
122 max_size = file_size() - pos_;
123 int frames = max_size / (audio_bus->channels() * kBitsPerSample / 8);
124 if (max_size) {
125 audio_bus->FromInterleaved(
126 file_->data() + pos_, frames, kBitsPerSample / 8);
127 pos_ += max_size;
129 return frames;
132 void OnError(AudioOutputStream* stream) override {}
134 int file_size() { return file_->data_size(); }
136 private:
137 scoped_refptr<DecoderBuffer> file_;
138 scoped_ptr<int[]> delta_times_;
139 int pos_;
140 base::TimeTicks previous_call_time_;
141 FILE* text_file_;
142 size_t elements_to_write_;
145 static bool ExclusiveModeIsEnabled() {
146 return (WASAPIAudioOutputStream::GetShareMode() ==
147 AUDCLNT_SHAREMODE_EXCLUSIVE);
150 static bool HasCoreAudioAndOutputDevices(AudioManager* audio_man) {
151 // The low-latency (WASAPI-based) version requires Windows Vista or higher.
152 // TODO(henrika): note that we use Wave today to query the number of
153 // existing output devices.
154 return CoreAudioUtil::IsSupported() && audio_man->HasAudioOutputDevices();
157 // Convenience method which creates a default AudioOutputStream object but
158 // also allows the user to modify the default settings.
159 class AudioOutputStreamWrapper {
160 public:
161 explicit AudioOutputStreamWrapper(AudioManager* audio_manager)
162 : audio_man_(audio_manager),
163 format_(AudioParameters::AUDIO_PCM_LOW_LATENCY),
164 bits_per_sample_(kBitsPerSample) {
165 AudioParameters preferred_params;
166 EXPECT_TRUE(SUCCEEDED(CoreAudioUtil::GetPreferredAudioParameters(
167 eRender, eConsole, &preferred_params)));
168 channel_layout_ = preferred_params.channel_layout();
169 sample_rate_ = preferred_params.sample_rate();
170 samples_per_packet_ = preferred_params.frames_per_buffer();
173 ~AudioOutputStreamWrapper() {}
175 // Creates AudioOutputStream object using default parameters.
176 AudioOutputStream* Create() {
177 return CreateOutputStream();
180 // Creates AudioOutputStream object using non-default parameters where the
181 // frame size is modified.
182 AudioOutputStream* Create(int samples_per_packet) {
183 samples_per_packet_ = samples_per_packet;
184 return CreateOutputStream();
187 // Creates AudioOutputStream object using non-default parameters where the
188 // sample rate and frame size are modified.
189 AudioOutputStream* Create(int sample_rate, int samples_per_packet) {
190 sample_rate_ = sample_rate;
191 samples_per_packet_ = samples_per_packet;
192 return CreateOutputStream();
195 AudioParameters::Format format() const { return format_; }
196 int channels() const { return ChannelLayoutToChannelCount(channel_layout_); }
197 int bits_per_sample() const { return bits_per_sample_; }
198 int sample_rate() const { return sample_rate_; }
199 int samples_per_packet() const { return samples_per_packet_; }
201 private:
202 AudioOutputStream* CreateOutputStream() {
203 AudioOutputStream* aos = audio_man_->MakeAudioOutputStream(
204 AudioParameters(format_, channel_layout_, sample_rate_,
205 bits_per_sample_, samples_per_packet_),
206 std::string());
207 EXPECT_TRUE(aos);
208 return aos;
211 AudioManager* audio_man_;
212 AudioParameters::Format format_;
213 ChannelLayout channel_layout_;
214 int bits_per_sample_;
215 int sample_rate_;
216 int samples_per_packet_;
219 // Convenience method which creates a default AudioOutputStream object.
220 static AudioOutputStream* CreateDefaultAudioOutputStream(
221 AudioManager* audio_manager) {
222 AudioOutputStreamWrapper aosw(audio_manager);
223 AudioOutputStream* aos = aosw.Create();
224 return aos;
227 // Verify that we can retrieve the current hardware/mixing sample rate
228 // for the default audio device.
229 // TODO(henrika): modify this test when we support full device enumeration.
230 TEST(WASAPIAudioOutputStreamTest, HardwareSampleRate) {
231 // Skip this test in exclusive mode since the resulting rate is only utilized
232 // for shared mode streams.
233 if (ExclusiveModeIsEnabled())
234 return;
235 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
236 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager.get()));
238 // Default device intended for games, system notification sounds,
239 // and voice commands.
240 int fs = static_cast<int>(
241 WASAPIAudioOutputStream::HardwareSampleRate(std::string()));
242 EXPECT_GE(fs, 0);
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());
250 aos->Close();
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());
259 aos->Close();
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))
270 .Times(0);
271 aos->Start(&source);
272 aos->Close();
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))
283 .Times(0);
284 aos->Start(&source);
285 aos->Stop();
286 aos->Close();
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).
296 double volume = 0.0;
297 aos->GetVolume(&volume);
298 EXPECT_EQ(1.0, volume);
300 // Verify some valid volume settings.
301 aos->SetVolume(0.0);
302 aos->GetVolume(&volume);
303 EXPECT_EQ(0.0, volume);
305 aos->SetVolume(0.5);
306 aos->GetVolume(&volume);
307 EXPECT_EQ(0.5, volume);
309 aos->SetVolume(1.0);
310 aos->GetVolume(&volume);
311 EXPECT_EQ(1.0, volume);
313 // Ensure that invalid volume setting have no effect.
314 aos->SetVolume(1.5);
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);
322 aos->Close();
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).
340 aos->Start(&source);
341 EXPECT_TRUE(waos->started());
342 aos->Start(&source);
343 EXPECT_TRUE(waos->started());
345 // Stop(), Stop() is a valid calling sequence (second call does nothing).
346 aos->Stop();
347 EXPECT_FALSE(waos->started());
348 aos->Stop();
349 EXPECT_FALSE(waos->started());
351 // Start(), Stop(), Start(), Stop().
352 aos->Start(&source);
353 EXPECT_TRUE(waos->started());
354 aos->Stop();
355 EXPECT_FALSE(waos->started());
356 aos->Start(&source);
357 EXPECT_TRUE(waos->started());
358 aos->Stop();
359 EXPECT_FALSE(waos->started());
361 aos->Close();
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)))
384 .WillOnce(DoAll(QuitLoop(loop.task_runner()),
385 Return(aosw.samples_per_packet())));
387 aos->Start(&source);
388 loop.PostDelayedTask(FROM_HERE, base::MessageLoop::QuitClosure(),
389 TestTimeouts::action_timeout());
390 loop.Run();
391 aos->Stop();
392 aos->Close();
395 // This test is intended for manual tests and should only be enabled
396 // when it is required to play out data from a local PCM file.
397 // By default, GTest will print out YOU HAVE 1 DISABLED TEST.
398 // To include disabled tests in test execution, just invoke the test program
399 // with --gtest_also_run_disabled_tests or set the GTEST_ALSO_RUN_DISABLED_TESTS
400 // environment variable to a value greater than 0.
401 // The test files are approximately 20 seconds long.
402 TEST(WASAPIAudioOutputStreamTest, DISABLED_ReadFromStereoFile) {
403 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
404 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager.get()));
406 AudioOutputStreamWrapper aosw(audio_manager.get());
407 AudioOutputStream* aos = aosw.Create();
408 EXPECT_TRUE(aos->Open());
410 std::string file_name;
411 if (aosw.sample_rate() == 48000) {
412 file_name = kSpeechFile_16b_s_48k;
413 } else if (aosw.sample_rate() == 44100) {
414 file_name = kSpeechFile_16b_s_44k;
415 } else if (aosw.sample_rate() == 96000) {
416 // Use 48kHz file at 96kHz as well. Will sound like Donald Duck.
417 file_name = kSpeechFile_16b_s_48k;
418 } else {
419 FAIL() << "This test supports 44.1, 48kHz and 96kHz only.";
420 return;
422 ReadFromFileAudioSource file_source(file_name);
424 DVLOG(0) << "File name : " << file_name.c_str();
425 DVLOG(0) << "Sample rate : " << aosw.sample_rate();
426 DVLOG(0) << "Bits per sample: " << aosw.bits_per_sample();
427 DVLOG(0) << "#channels : " << aosw.channels();
428 DVLOG(0) << "File size : " << file_source.file_size();
429 DVLOG(0) << "#file segments : " << kNumFileSegments;
430 DVLOG(0) << ">> Listen to the stereo file while playing...";
432 for (int i = 0; i < kNumFileSegments; i++) {
433 // Each segment will start with a short (~20ms) block of zeros, hence
434 // some short glitches might be heard in this test if kNumFileSegments
435 // is larger than one. The exact length of the silence period depends on
436 // the selected sample rate.
437 aos->Start(&file_source);
438 base::PlatformThread::Sleep(
439 base::TimeDelta::FromMilliseconds(kFileDurationMs / kNumFileSegments));
440 aos->Stop();
443 DVLOG(0) << ">> Stereo file playout has stopped.";
444 aos->Close();
447 // Verify that we can open the output stream in exclusive mode using a
448 // certain set of audio parameters and a sample rate of 48kHz.
449 // The expected outcomes of each setting in this test has been derived
450 // manually using log outputs (--v=1).
451 // It's disabled by default because a flag is required to enable exclusive mode.
452 TEST(WASAPIAudioOutputStreamTest, DISABLED_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());
464 aos->Close();
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());
472 aos->Close();
474 // 5.3333ms @ 48kHz should work (see test above).
475 aos = aosw.Create(48000, 256);
476 EXPECT_TRUE(aos->Open());
477 aos->Close();
479 // 2.6667ms is smaller than the minimum supported size (=3ms).
480 aos = aosw.Create(48000, 128);
481 EXPECT_FALSE(aos->Open());
482 aos->Close();
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());
488 aos->Close();
490 // 3.3333ms @ 48kHz <=> smallest possible buffer size we can use.
491 aos = aosw.Create(48000, 160);
492 EXPECT_TRUE(aos->Open());
493 aos->Close();
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 // It's disabled by default because a flag is required to enable exclusive mode.
501 TEST(WASAPIAudioOutputStreamTest, DISABLED_ExclusiveModeBufferSizesAt44kHz) {
502 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
503 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager.get()) &&
504 ExclusiveModeIsEnabled());
506 AudioOutputStreamWrapper aosw(audio_manager.get());
508 // 10ms @ 44.1kHz does not work due to misalignment.
509 // This test will propose an aligned buffer size of 10.1587ms.
510 AudioOutputStream* aos = aosw.Create(44100, 441);
511 EXPECT_FALSE(aos->Open());
512 aos->Close();
514 // 10.1587ms @ 44.1kHz shall work (see test above).
515 aos = aosw.Create(44100, 448);
516 EXPECT_TRUE(aos->Open());
517 aos->Close();
519 // 5.8050ms @ 44.1 should work.
520 aos = aosw.Create(44100, 256);
521 EXPECT_TRUE(aos->Open());
522 aos->Close();
524 // 4.9887ms @ 44.1kHz does not work to misalignment.
525 // This test will propose an aligned buffer size of 5.0794ms.
526 // Note that we must call Close() even is Open() fails since Close() also
527 // deletes the object and we want to create a new object in the next test.
528 aos = aosw.Create(44100, 220);
529 EXPECT_FALSE(aos->Open());
530 aos->Close();
532 // 5.0794ms @ 44.1kHz shall work (see test above).
533 aos = aosw.Create(44100, 224);
534 EXPECT_TRUE(aos->Open());
535 aos->Close();
537 // 2.9025ms is smaller than the minimum supported size (=3ms).
538 aos = aosw.Create(44100, 132);
539 EXPECT_FALSE(aos->Open());
540 aos->Close();
542 // 3.01587ms is larger than the minimum size but is not aligned.
543 // This test will propose an aligned buffer size of 3.6281ms.
544 aos = aosw.Create(44100, 133);
545 EXPECT_FALSE(aos->Open());
546 aos->Close();
548 // 3.6281ms @ 44.1kHz <=> smallest possible buffer size we can use.
549 aos = aosw.Create(44100, 160);
550 EXPECT_TRUE(aos->Open());
551 aos->Close();
554 // Verify that we can open and start the output stream in exclusive mode at
555 // the lowest possible delay at 48kHz.
556 // It's disabled by default because a flag is required to enable exclusive mode.
557 TEST(WASAPIAudioOutputStreamTest, DISABLED_ExclusiveModeMinBufferSizeAt48kHz) {
558 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
559 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager.get()) &&
560 ExclusiveModeIsEnabled());
562 base::MessageLoopForUI loop;
563 MockAudioSourceCallback source;
565 // Create exclusive-mode WASAPI output stream which plays out in stereo
566 // using the minimum buffer size at 48kHz sample rate.
567 AudioOutputStreamWrapper aosw(audio_manager.get());
568 AudioOutputStream* aos = aosw.Create(48000, 160);
569 EXPECT_TRUE(aos->Open());
571 // Derive the expected size in bytes of each packet.
572 uint32 bytes_per_packet = aosw.channels() * aosw.samples_per_packet() *
573 (aosw.bits_per_sample() / 8);
575 // Wait for the first callback and verify its parameters.
576 EXPECT_CALL(source, OnMoreData(NotNull(), HasValidDelay(bytes_per_packet)))
577 .WillOnce(DoAll(QuitLoop(loop.task_runner()),
578 Return(aosw.samples_per_packet())))
579 .WillRepeatedly(Return(aosw.samples_per_packet()));
581 aos->Start(&source);
582 loop.PostDelayedTask(FROM_HERE, base::MessageLoop::QuitClosure(),
583 TestTimeouts::action_timeout());
584 loop.Run();
585 aos->Stop();
586 aos->Close();
589 // Verify that we can open and start the output stream in exclusive mode at
590 // the lowest possible delay at 44.1kHz.
591 // It's disabled by default because a flag is required to enable exclusive mode.
592 TEST(WASAPIAudioOutputStreamTest, DISABLED_ExclusiveModeMinBufferSizeAt44kHz) {
593 ABORT_AUDIO_TEST_IF_NOT(ExclusiveModeIsEnabled());
594 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
596 base::MessageLoopForUI loop;
597 MockAudioSourceCallback source;
599 // Create exclusive-mode WASAPI output stream which plays out in stereo
600 // using the minimum buffer size at 44.1kHz sample rate.
601 AudioOutputStreamWrapper aosw(audio_manager.get());
602 AudioOutputStream* aos = aosw.Create(44100, 160);
603 EXPECT_TRUE(aos->Open());
605 // Derive the expected size in bytes of each packet.
606 uint32 bytes_per_packet = aosw.channels() * aosw.samples_per_packet() *
607 (aosw.bits_per_sample() / 8);
609 // Wait for the first callback and verify its parameters.
610 EXPECT_CALL(source, OnMoreData(NotNull(), HasValidDelay(bytes_per_packet)))
611 .WillOnce(DoAll(QuitLoop(loop.task_runner()),
612 Return(aosw.samples_per_packet())))
613 .WillRepeatedly(Return(aosw.samples_per_packet()));
615 aos->Start(&source);
616 loop.PostDelayedTask(FROM_HERE, base::MessageLoop::QuitClosure(),
617 TestTimeouts::action_timeout());
618 loop.Run();
619 aos->Stop();
620 aos->Close();
623 } // namespace media