Removed unused VideoCaptureCapability parameters.
[chromium-blink-merge.git] / media / audio / win / audio_low_latency_output_win_unittest.cc
blob42fca4d15a52ad3de0a8693d0c54b65e3c1b4e34
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/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/win/audio_low_latency_output_win.h"
20 #include "media/audio/win/core_audio_util_win.h"
21 #include "media/base/decoder_buffer.h"
22 #include "media/base/seekable_buffer.h"
23 #include "media/base/test_data_util.h"
24 #include "testing/gmock/include/gmock/gmock.h"
25 #include "testing/gmock_mutant.h"
26 #include "testing/gtest/include/gtest/gtest.h"
28 using ::testing::_;
29 using ::testing::AnyNumber;
30 using ::testing::AtLeast;
31 using ::testing::Between;
32 using ::testing::CreateFunctor;
33 using ::testing::DoAll;
34 using ::testing::Gt;
35 using ::testing::InvokeWithoutArgs;
36 using ::testing::NotNull;
37 using ::testing::Return;
38 using base::win::ScopedCOMInitializer;
40 namespace media {
42 static const char kSpeechFile_16b_s_48k[] = "speech_16b_stereo_48kHz.raw";
43 static const char kSpeechFile_16b_s_44k[] = "speech_16b_stereo_44kHz.raw";
44 static const size_t kFileDurationMs = 20000;
45 static const size_t kNumFileSegments = 2;
46 static const int kBitsPerSample = 16;
47 static const size_t kMaxDeltaSamples = 1000;
48 static const char kDeltaTimeMsFileName[] = "delta_times_ms.txt";
50 MATCHER_P(HasValidDelay, value, "") {
51 // It is difficult to come up with a perfect test condition for the delay
52 // estimation. For now, verify that the produced output delay is always
53 // larger than the selected buffer size.
54 return arg.hardware_delay_bytes >= value.hardware_delay_bytes;
57 // Used to terminate a loop from a different thread than the loop belongs to.
58 // |loop| should be a MessageLoopProxy.
59 ACTION_P(QuitLoop, loop) {
60 loop->PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
63 class MockAudioSourceCallback : public AudioOutputStream::AudioSourceCallback {
64 public:
65 MOCK_METHOD2(OnMoreData, int(AudioBus* audio_bus,
66 AudioBuffersState buffers_state));
67 MOCK_METHOD3(OnMoreIOData, int(AudioBus* source,
68 AudioBus* dest,
69 AudioBuffersState buffers_state));
70 MOCK_METHOD1(OnError, void(AudioOutputStream* stream));
73 // This audio source implementation should be used for manual tests only since
74 // it takes about 20 seconds to play out a file.
75 class ReadFromFileAudioSource : public AudioOutputStream::AudioSourceCallback {
76 public:
77 explicit ReadFromFileAudioSource(const std::string& name)
78 : pos_(0),
79 previous_call_time_(base::TimeTicks::Now()),
80 text_file_(NULL),
81 elements_to_write_(0) {
82 // Reads a test file from media/test/data directory.
83 file_ = ReadTestDataFile(name);
85 // Creates an array that will store delta times between callbacks.
86 // The content of this array will be written to a text file at
87 // destruction and can then be used for off-line analysis of the exact
88 // timing of callbacks. The text file will be stored in media/test/data.
89 delta_times_.reset(new int[kMaxDeltaSamples]);
92 virtual ~ReadFromFileAudioSource() {
93 // Get complete file path to output file in directory containing
94 // media_unittests.exe.
95 base::FilePath file_name;
96 EXPECT_TRUE(PathService::Get(base::DIR_EXE, &file_name));
97 file_name = file_name.AppendASCII(kDeltaTimeMsFileName);
99 EXPECT_TRUE(!text_file_);
100 text_file_ = file_util::OpenFile(file_name, "wt");
101 DLOG_IF(ERROR, !text_file_) << "Failed to open log file.";
103 // Write the array which contains delta times to a text file.
104 size_t elements_written = 0;
105 while (elements_written < elements_to_write_) {
106 fprintf(text_file_, "%d\n", delta_times_[elements_written]);
107 ++elements_written;
110 file_util::CloseFile(text_file_);
113 // AudioOutputStream::AudioSourceCallback implementation.
114 virtual int OnMoreData(AudioBus* audio_bus,
115 AudioBuffersState buffers_state) {
116 // Store time difference between two successive callbacks in an array.
117 // These values will be written to a file in the destructor.
118 const base::TimeTicks now_time = base::TimeTicks::Now();
119 const int diff = (now_time - previous_call_time_).InMilliseconds();
120 previous_call_time_ = now_time;
121 if (elements_to_write_ < kMaxDeltaSamples) {
122 delta_times_[elements_to_write_] = diff;
123 ++elements_to_write_;
126 int max_size =
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);
134 if (max_size) {
135 audio_bus->FromInterleaved(
136 file_->data() + pos_, frames, kBitsPerSample / 8);
137 pos_ += max_size;
139 return frames;
142 virtual int OnMoreIOData(AudioBus* source,
143 AudioBus* dest,
144 AudioBuffersState buffers_state) OVERRIDE {
145 NOTREACHED();
146 return 0;
149 virtual void OnError(AudioOutputStream* stream) {}
151 int file_size() { return file_->data_size(); }
153 private:
154 scoped_refptr<DecoderBuffer> file_;
155 scoped_ptr<int[]> delta_times_;
156 int pos_;
157 base::TimeTicks previous_call_time_;
158 FILE* text_file_;
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.";
174 return false;
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.";
181 return false;
184 return true;
187 // Convenience method which creates a default AudioOutputStream object but
188 // also allows the user to modify the default settings.
189 class AudioOutputStreamWrapper {
190 public:
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_; }
231 private:
232 AudioOutputStream* CreateOutputStream() {
233 AudioOutputStream* aos = audio_man_->MakeAudioOutputStream(
234 AudioParameters(format_, channel_layout_, sample_rate_,
235 bits_per_sample_, samples_per_packet_),
236 std::string(), std::string());
237 EXPECT_TRUE(aos);
238 return aos;
241 AudioManager* audio_man_;
242 AudioParameters::Format format_;
243 ChannelLayout channel_layout_;
244 int bits_per_sample_;
245 int sample_rate_;
246 int samples_per_packet_;
249 // Convenience method which creates a default AudioOutputStream object.
250 static AudioOutputStream* CreateDefaultAudioOutputStream(
251 AudioManager* audio_manager) {
252 AudioOutputStreamWrapper aosw(audio_manager);
253 AudioOutputStream* aos = aosw.Create();
254 return aos;
257 // Verify that we can retrieve the current hardware/mixing sample rate
258 // for the default audio device.
259 // TODO(henrika): modify this test when we support full device enumeration.
260 TEST(WASAPIAudioOutputStreamTest, HardwareSampleRate) {
261 // Skip this test in exclusive mode since the resulting rate is only utilized
262 // for shared mode streams.
263 scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
264 if (!CanRunAudioTests(audio_manager.get()) || ExclusiveModeIsEnabled())
265 return;
267 // Default device intended for games, system notification sounds,
268 // and voice commands.
269 int fs = static_cast<int>(
270 WASAPIAudioOutputStream::HardwareSampleRate(std::string()));
271 EXPECT_GE(fs, 0);
274 // Test Create(), Close() calling sequence.
275 TEST(WASAPIAudioOutputStreamTest, CreateAndClose) {
276 scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
277 if (!CanRunAudioTests(audio_manager.get()))
278 return;
279 AudioOutputStream* aos = CreateDefaultAudioOutputStream(audio_manager.get());
280 aos->Close();
283 // Test Open(), Close() calling sequence.
284 TEST(WASAPIAudioOutputStreamTest, OpenAndClose) {
285 scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
286 if (!CanRunAudioTests(audio_manager.get()))
287 return;
288 AudioOutputStream* aos = CreateDefaultAudioOutputStream(audio_manager.get());
289 EXPECT_TRUE(aos->Open());
290 aos->Close();
293 // Test Open(), Start(), Close() calling sequence.
294 TEST(WASAPIAudioOutputStreamTest, OpenStartAndClose) {
295 scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
296 if (!CanRunAudioTests(audio_manager.get()))
297 return;
298 AudioOutputStream* aos = CreateDefaultAudioOutputStream(audio_manager.get());
299 EXPECT_TRUE(aos->Open());
300 MockAudioSourceCallback source;
301 EXPECT_CALL(source, OnError(aos))
302 .Times(0);
303 aos->Start(&source);
304 aos->Close();
307 // Test Open(), Start(), Stop(), Close() calling sequence.
308 TEST(WASAPIAudioOutputStreamTest, OpenStartStopAndClose) {
309 scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
310 if (!CanRunAudioTests(audio_manager.get()))
311 return;
312 AudioOutputStream* aos = CreateDefaultAudioOutputStream(audio_manager.get());
313 EXPECT_TRUE(aos->Open());
314 MockAudioSourceCallback source;
315 EXPECT_CALL(source, OnError(aos))
316 .Times(0);
317 aos->Start(&source);
318 aos->Stop();
319 aos->Close();
322 // Test SetVolume(), GetVolume()
323 TEST(WASAPIAudioOutputStreamTest, Volume) {
324 scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
325 if (!CanRunAudioTests(audio_manager.get()))
326 return;
327 AudioOutputStream* aos = CreateDefaultAudioOutputStream(audio_manager.get());
329 // Initial volume should be full volume (1.0).
330 double volume = 0.0;
331 aos->GetVolume(&volume);
332 EXPECT_EQ(1.0, volume);
334 // Verify some valid volume settings.
335 aos->SetVolume(0.0);
336 aos->GetVolume(&volume);
337 EXPECT_EQ(0.0, volume);
339 aos->SetVolume(0.5);
340 aos->GetVolume(&volume);
341 EXPECT_EQ(0.5, volume);
343 aos->SetVolume(1.0);
344 aos->GetVolume(&volume);
345 EXPECT_EQ(1.0, volume);
347 // Ensure that invalid volume setting have no effect.
348 aos->SetVolume(1.5);
349 aos->GetVolume(&volume);
350 EXPECT_EQ(1.0, volume);
352 aos->SetVolume(-0.5);
353 aos->GetVolume(&volume);
354 EXPECT_EQ(1.0, volume);
356 aos->Close();
359 // Test some additional calling sequences.
360 TEST(WASAPIAudioOutputStreamTest, MiscCallingSequences) {
361 scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
362 if (!CanRunAudioTests(audio_manager.get()))
363 return;
365 AudioOutputStream* aos = CreateDefaultAudioOutputStream(audio_manager.get());
366 WASAPIAudioOutputStream* waos = static_cast<WASAPIAudioOutputStream*>(aos);
368 // Open(), Open() is a valid calling sequence (second call does nothing).
369 EXPECT_TRUE(aos->Open());
370 EXPECT_TRUE(aos->Open());
372 MockAudioSourceCallback source;
374 // Start(), Start() is a valid calling sequence (second call does nothing).
375 aos->Start(&source);
376 EXPECT_TRUE(waos->started());
377 aos->Start(&source);
378 EXPECT_TRUE(waos->started());
380 // Stop(), Stop() is a valid calling sequence (second call does nothing).
381 aos->Stop();
382 EXPECT_FALSE(waos->started());
383 aos->Stop();
384 EXPECT_FALSE(waos->started());
386 // Start(), Stop(), Start(), Stop().
387 aos->Start(&source);
388 EXPECT_TRUE(waos->started());
389 aos->Stop();
390 EXPECT_FALSE(waos->started());
391 aos->Start(&source);
392 EXPECT_TRUE(waos->started());
393 aos->Stop();
394 EXPECT_FALSE(waos->started());
396 aos->Close();
399 // Use preferred packet size and verify that rendering starts.
400 TEST(WASAPIAudioOutputStreamTest, ValidPacketSize) {
401 scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
402 if (!CanRunAudioTests(audio_manager.get()))
403 return;
405 base::MessageLoopForUI loop;
406 MockAudioSourceCallback source;
408 // Create default WASAPI output stream which plays out in stereo using
409 // the shared mixing rate. The default buffer size is 10ms.
410 AudioOutputStreamWrapper aosw(audio_manager.get());
411 AudioOutputStream* aos = aosw.Create();
412 EXPECT_TRUE(aos->Open());
414 // Derive the expected size in bytes of each packet.
415 uint32 bytes_per_packet = aosw.channels() * aosw.samples_per_packet() *
416 (aosw.bits_per_sample() / 8);
418 // Set up expected minimum delay estimation.
419 AudioBuffersState state(0, bytes_per_packet);
421 // Wait for the first callback and verify its parameters.
422 EXPECT_CALL(source, OnMoreData(NotNull(), HasValidDelay(state)))
423 .WillOnce(DoAll(
424 QuitLoop(loop.message_loop_proxy()),
425 Return(aosw.samples_per_packet())));
427 aos->Start(&source);
428 loop.PostDelayedTask(FROM_HERE, base::MessageLoop::QuitClosure(),
429 TestTimeouts::action_timeout());
430 loop.Run();
431 aos->Stop();
432 aos->Close();
435 // Use a non-preferred packet size and verify that Open() fails.
436 TEST(WASAPIAudioOutputStreamTest, InvalidPacketSize) {
437 scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
438 if (!CanRunAudioTests(audio_manager.get()))
439 return;
441 if (ExclusiveModeIsEnabled())
442 return;
444 AudioParameters preferred_params;
445 EXPECT_TRUE(SUCCEEDED(CoreAudioUtil::GetPreferredAudioParameters(
446 eRender, eConsole, &preferred_params)));
447 int too_large_packet_size = 2 * preferred_params.frames_per_buffer();
449 AudioOutputStreamWrapper aosw(audio_manager.get());
450 AudioOutputStream* aos = aosw.Create(too_large_packet_size);
451 EXPECT_FALSE(aos->Open());
453 aos->Close();
456 // This test is intended for manual tests and should only be enabled
457 // when it is required to play out data from a local PCM file.
458 // By default, GTest will print out YOU HAVE 1 DISABLED TEST.
459 // To include disabled tests in test execution, just invoke the test program
460 // with --gtest_also_run_disabled_tests or set the GTEST_ALSO_RUN_DISABLED_TESTS
461 // environment variable to a value greater than 0.
462 // The test files are approximately 20 seconds long.
463 TEST(WASAPIAudioOutputStreamTest, DISABLED_ReadFromStereoFile) {
464 scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
465 if (!CanRunAudioTests(audio_manager.get()))
466 return;
468 AudioOutputStreamWrapper aosw(audio_manager.get());
469 AudioOutputStream* aos = aosw.Create();
470 EXPECT_TRUE(aos->Open());
472 std::string file_name;
473 if (aosw.sample_rate() == 48000) {
474 file_name = kSpeechFile_16b_s_48k;
475 } else if (aosw.sample_rate() == 44100) {
476 file_name = kSpeechFile_16b_s_44k;
477 } else if (aosw.sample_rate() == 96000) {
478 // Use 48kHz file at 96kHz as well. Will sound like Donald Duck.
479 file_name = kSpeechFile_16b_s_48k;
480 } else {
481 FAIL() << "This test supports 44.1, 48kHz and 96kHz only.";
482 return;
484 ReadFromFileAudioSource file_source(file_name);
486 LOG(INFO) << "File name : " << file_name.c_str();
487 LOG(INFO) << "Sample rate : " << aosw.sample_rate();
488 LOG(INFO) << "Bits per sample: " << aosw.bits_per_sample();
489 LOG(INFO) << "#channels : " << aosw.channels();
490 LOG(INFO) << "File size : " << file_source.file_size();
491 LOG(INFO) << "#file segments : " << kNumFileSegments;
492 LOG(INFO) << ">> Listen to the stereo file while playing...";
494 for (int i = 0; i < kNumFileSegments; i++) {
495 // Each segment will start with a short (~20ms) block of zeros, hence
496 // some short glitches might be heard in this test if kNumFileSegments
497 // is larger than one. The exact length of the silence period depends on
498 // the selected sample rate.
499 aos->Start(&file_source);
500 base::PlatformThread::Sleep(
501 base::TimeDelta::FromMilliseconds(kFileDurationMs / kNumFileSegments));
502 aos->Stop();
505 LOG(INFO) << ">> Stereo file playout has stopped.";
506 aos->Close();
509 // Verify that we can open the output stream in exclusive mode using a
510 // certain set of audio parameters and a sample rate of 48kHz.
511 // The expected outcomes of each setting in this test has been derived
512 // manually using log outputs (--v=1).
513 TEST(WASAPIAudioOutputStreamTest, ExclusiveModeBufferSizesAt48kHz) {
514 if (!ExclusiveModeIsEnabled())
515 return;
517 scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
518 if (!CanRunAudioTests(audio_manager.get()))
519 return;
521 AudioOutputStreamWrapper aosw(audio_manager.get());
523 // 10ms @ 48kHz shall work.
524 // Note that, this is the same size as we can use for shared-mode streaming
525 // but here the endpoint buffer delay is only 10ms instead of 20ms.
526 AudioOutputStream* aos = aosw.Create(48000, 480);
527 EXPECT_TRUE(aos->Open());
528 aos->Close();
530 // 5ms @ 48kHz does not work due to misalignment.
531 // This test will propose an aligned buffer size of 5.3333ms.
532 // Note that we must call Close() even is Open() fails since Close() also
533 // deletes the object and we want to create a new object in the next test.
534 aos = aosw.Create(48000, 240);
535 EXPECT_FALSE(aos->Open());
536 aos->Close();
538 // 5.3333ms @ 48kHz should work (see test above).
539 aos = aosw.Create(48000, 256);
540 EXPECT_TRUE(aos->Open());
541 aos->Close();
543 // 2.6667ms is smaller than the minimum supported size (=3ms).
544 aos = aosw.Create(48000, 128);
545 EXPECT_FALSE(aos->Open());
546 aos->Close();
548 // 3ms does not correspond to an aligned buffer size.
549 // This test will propose an aligned buffer size of 3.3333ms.
550 aos = aosw.Create(48000, 144);
551 EXPECT_FALSE(aos->Open());
552 aos->Close();
554 // 3.3333ms @ 48kHz <=> smallest possible buffer size we can use.
555 aos = aosw.Create(48000, 160);
556 EXPECT_TRUE(aos->Open());
557 aos->Close();
560 // Verify that we can open the output stream in exclusive mode using a
561 // certain set of audio parameters and a sample rate of 44.1kHz.
562 // The expected outcomes of each setting in this test has been derived
563 // manually using log outputs (--v=1).
564 TEST(WASAPIAudioOutputStreamTest, ExclusiveModeBufferSizesAt44kHz) {
565 if (!ExclusiveModeIsEnabled())
566 return;
568 scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
569 if (!CanRunAudioTests(audio_manager.get()))
570 return;
572 AudioOutputStreamWrapper aosw(audio_manager.get());
574 // 10ms @ 44.1kHz does not work due to misalignment.
575 // This test will propose an aligned buffer size of 10.1587ms.
576 AudioOutputStream* aos = aosw.Create(44100, 441);
577 EXPECT_FALSE(aos->Open());
578 aos->Close();
580 // 10.1587ms @ 44.1kHz shall work (see test above).
581 aos = aosw.Create(44100, 448);
582 EXPECT_TRUE(aos->Open());
583 aos->Close();
585 // 5.8050ms @ 44.1 should work.
586 aos = aosw.Create(44100, 256);
587 EXPECT_TRUE(aos->Open());
588 aos->Close();
590 // 4.9887ms @ 44.1kHz does not work to misalignment.
591 // This test will propose an aligned buffer size of 5.0794ms.
592 // Note that we must call Close() even is Open() fails since Close() also
593 // deletes the object and we want to create a new object in the next test.
594 aos = aosw.Create(44100, 220);
595 EXPECT_FALSE(aos->Open());
596 aos->Close();
598 // 5.0794ms @ 44.1kHz shall work (see test above).
599 aos = aosw.Create(44100, 224);
600 EXPECT_TRUE(aos->Open());
601 aos->Close();
603 // 2.9025ms is smaller than the minimum supported size (=3ms).
604 aos = aosw.Create(44100, 132);
605 EXPECT_FALSE(aos->Open());
606 aos->Close();
608 // 3.01587ms is larger than the minimum size but is not aligned.
609 // This test will propose an aligned buffer size of 3.6281ms.
610 aos = aosw.Create(44100, 133);
611 EXPECT_FALSE(aos->Open());
612 aos->Close();
614 // 3.6281ms @ 44.1kHz <=> smallest possible buffer size we can use.
615 aos = aosw.Create(44100, 160);
616 EXPECT_TRUE(aos->Open());
617 aos->Close();
620 // Verify that we can open and start the output stream in exclusive mode at
621 // the lowest possible delay at 48kHz.
622 TEST(WASAPIAudioOutputStreamTest, ExclusiveModeMinBufferSizeAt48kHz) {
623 if (!ExclusiveModeIsEnabled())
624 return;
626 scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
627 if (!CanRunAudioTests(audio_manager.get()))
628 return;
630 base::MessageLoopForUI loop;
631 MockAudioSourceCallback source;
633 // Create exclusive-mode WASAPI output stream which plays out in stereo
634 // using the minimum buffer size at 48kHz sample rate.
635 AudioOutputStreamWrapper aosw(audio_manager.get());
636 AudioOutputStream* aos = aosw.Create(48000, 160);
637 EXPECT_TRUE(aos->Open());
639 // Derive the expected size in bytes of each packet.
640 uint32 bytes_per_packet = aosw.channels() * aosw.samples_per_packet() *
641 (aosw.bits_per_sample() / 8);
643 // Set up expected minimum delay estimation.
644 AudioBuffersState state(0, bytes_per_packet);
646 // Wait for the first callback and verify its parameters.
647 EXPECT_CALL(source, OnMoreData(NotNull(), HasValidDelay(state)))
648 .WillOnce(DoAll(
649 QuitLoop(loop.message_loop_proxy()),
650 Return(aosw.samples_per_packet())))
651 .WillRepeatedly(Return(aosw.samples_per_packet()));
653 aos->Start(&source);
654 loop.PostDelayedTask(FROM_HERE, base::MessageLoop::QuitClosure(),
655 TestTimeouts::action_timeout());
656 loop.Run();
657 aos->Stop();
658 aos->Close();
661 // Verify that we can open and start the output stream in exclusive mode at
662 // the lowest possible delay at 44.1kHz.
663 TEST(WASAPIAudioOutputStreamTest, ExclusiveModeMinBufferSizeAt44kHz) {
664 if (!ExclusiveModeIsEnabled())
665 return;
667 scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
668 if (!CanRunAudioTests(audio_manager.get()))
669 return;
671 base::MessageLoopForUI loop;
672 MockAudioSourceCallback source;
674 // Create exclusive-mode WASAPI output stream which plays out in stereo
675 // using the minimum buffer size at 44.1kHz sample rate.
676 AudioOutputStreamWrapper aosw(audio_manager.get());
677 AudioOutputStream* aos = aosw.Create(44100, 160);
678 EXPECT_TRUE(aos->Open());
680 // Derive the expected size in bytes of each packet.
681 uint32 bytes_per_packet = aosw.channels() * aosw.samples_per_packet() *
682 (aosw.bits_per_sample() / 8);
684 // Set up expected minimum delay estimation.
685 AudioBuffersState state(0, bytes_per_packet);
687 // Wait for the first callback and verify its parameters.
688 EXPECT_CALL(source, OnMoreData(NotNull(), HasValidDelay(state)))
689 .WillOnce(DoAll(
690 QuitLoop(loop.message_loop_proxy()),
691 Return(aosw.samples_per_packet())))
692 .WillRepeatedly(Return(aosw.samples_per_packet()));
694 aos->Start(&source);
695 loop.PostDelayedTask(FROM_HERE, base::MessageLoop::QuitClosure(),
696 TestTimeouts::action_timeout());
697 loop.Run();
698 aos->Stop();
699 aos->Close();
702 } // namespace media