Chromium Code Reviews| Index: media/audio/win/audio_low_latency_output_win_unittest.cc |
| diff --git a/media/audio/win/audio_low_latency_output_win_unittest.cc b/media/audio/win/audio_low_latency_output_win_unittest.cc |
| index f764834571199c012b7fe65aad362ae2f742dbb9..f6170c4542079e6018dae45e4935a0ddcd43d670 100644 |
| --- a/media/audio/win/audio_low_latency_output_win_unittest.cc |
| +++ b/media/audio/win/audio_low_latency_output_win_unittest.cc |
| @@ -6,8 +6,10 @@ |
| #include <mmsystem.h> |
| #include "base/basictypes.h" |
| +#include "base/command_line.h" |
| #include "base/environment.h" |
| #include "base/file_util.h" |
| +#include "media/base/media_switches.h" |
| #include "base/memory/scoped_ptr.h" |
| #include "base/message_loop.h" |
| #include "base/test/test_timeouts.h" |
| @@ -41,7 +43,7 @@ namespace media { |
| static const char kSpeechFile_16b_s_48k[] = "speech_16b_stereo_48kHz.raw"; |
| static const char kSpeechFile_16b_s_44k[] = "speech_16b_stereo_44kHz.raw"; |
| static const size_t kFileDurationMs = 20000; |
| -static const size_t kNumFileSegments = 1; |
| +static const size_t kNumFileSegments = 2; |
| static const size_t kMaxDeltaSamples = 1000; |
| static const char* kDeltaTimeMsFileName = "delta_times_ms.txt"; |
| @@ -138,6 +140,11 @@ class ReadFromFileAudioSource : public AudioOutputStream::AudioSourceCallback { |
| size_t elements_to_write_; |
| }; |
| +static bool ExclusiveModeIsEnabled() { |
| + const CommandLine* cmd_line = CommandLine::ForCurrentProcess(); |
| + return (cmd_line->HasSwitch(switches::kEnableExclusiveMode)); |
| +} |
| + |
| // Convenience method which ensures that we are not running on the build |
| // bots and that at least one valid output device can be found. We also |
| // verify that we are not running on XP since the low-latency (WASAPI- |
| @@ -186,6 +193,14 @@ class AudioOutputStreamWrapper { |
| } |
| // Creates AudioOutputStream object using non-default parameters where the |
| + // sample rate and frame size are modified. |
| + AudioOutputStream* Create(int sample_rate, int samples_per_packet) { |
| + sample_rate_ = sample_rate; |
| + samples_per_packet_ = samples_per_packet; |
| + return CreateOutputStream(); |
| + } |
| + |
| + // Creates AudioOutputStream object using non-default parameters where the |
| // channel layout is modified. |
| AudioOutputStream* Create(ChannelLayout channel_layout) { |
| channel_layout_ = channel_layout; |
| @@ -562,4 +577,205 @@ TEST(WinAudioOutputTest, DISABLED_WASAPIAudioOutputStreamReadFromFile) { |
| aos->Close(); |
| } |
| +// Verify that we can open the output stream in exclusive mode using a |
| +// certain set of audio parameters and a sample rate of 48kHz. |
| +// The expected outcomes of each setting in this test has been derived |
| +// manually using log outputs (--v=1). |
| +TEST(WinAudioOutputTest, |
| + WASAPIAudioOutputStreamTestExclusiveModeBufferSizesAt48kHzSampleRate) { |
| + if (!ExclusiveModeIsEnabled()) |
| + return; |
| + |
| + scoped_ptr<AudioManager> audio_manager(AudioManager::Create()); |
| + if (!CanRunAudioTests(audio_manager.get())) |
| + return; |
| + |
| + AudioOutputStreamWrapper aosw(audio_manager.get()); |
| + |
| + // 10ms @ 48kHz shall work. |
| + // Note that, this is the same size as we can use for shared-mode streaming |
| + // but here the endpoint buffer delay is only 10ms instead of 20ms. |
| + AudioOutputStream* aos = aosw.Create(48000, 480); |
| + EXPECT_TRUE(aos->Open()); |
| + aos->Close(); |
| + |
| + // 5ms @ 48kHz does not work to misalignment. |
|
tommi (sloooow) - chröme
2012/07/25 11:49:40
rephrase "does not work to misaligment"
henrika (OOO until Aug 14)
2012/07/25 15:26:30
Done.
|
| + // This test will propose an aligned buffer size of 5.3333ms. |
| + aos = aosw.Create(48000, 240); |
| + EXPECT_FALSE(aos->Open()); |
| + aos->Close(); |
| + |
| + // 5.3333ms @ 48kHz shall work (see test above). |
|
tommi (sloooow) - chröme
2012/07/25 11:49:40
nit: s/shall/should (and below)
henrika (OOO until Aug 14)
2012/07/25 15:26:30
Done.
|
| + aos = aosw.Create(48000, 256); |
| + EXPECT_TRUE(aos->Open()); |
| + aos->Close(); |
| + |
| + // 2.6667ms is smaller than the minimum supported size (=3ms). |
| + aos = aosw.Create(48000, 128); |
| + EXPECT_FALSE(aos->Open()); |
| + aos->Close(); |
|
tommi (sloooow) - chröme
2012/07/25 11:49:40
it's a bit strange to see that Open() is expected
henrika (OOO until Aug 14)
2012/07/25 15:26:30
Added comment. Thanks.
|
| + |
| + // 3ms does not correspond to an aligned buffer size. |
| + // This test will propose an aligned buffer size of 3.3333ms. |
| + aos = aosw.Create(48000, 144); |
| + EXPECT_FALSE(aos->Open()); |
| + aos->Close(); |
| + |
| + // 3.3333ms @ 48kHz <=> smallest possible buffer size we can use. |
| + aos = aosw.Create(48000, 160); |
| + EXPECT_TRUE(aos->Open()); |
| + aos->Close(); |
| +} |
| + |
| +// Verify that we can open the output stream in exclusive mode using a |
| +// certain set of audio parameters and a sample rate of 44.1kHz. |
| +// The expected outcomes of each setting in this test has been derived |
| +// manually using log outputs (--v=1). |
| +TEST(WinAudioOutputTest, |
| + WASAPIAudioOutputStreamTestExclusiveModeBufferSizesAt44kHzSampleRate) { |
| + if (!ExclusiveModeIsEnabled()) |
| + return; |
| + |
| + scoped_ptr<AudioManager> audio_manager(AudioManager::Create()); |
| + if (!CanRunAudioTests(audio_manager.get())) |
| + return; |
| + |
| + AudioOutputStreamWrapper aosw(audio_manager.get()); |
| + |
| + // 10ms @ 44.1kHz does not work due to misalignment. |
| + // This test will propose an aligned buffer size of 10.1587ms. |
| + AudioOutputStream* aos = aosw.Create(44100, 441); |
| + EXPECT_FALSE(aos->Open()); |
| + aos->Close(); |
| + |
| + // 10.1587ms @ 44.1kHz shall work (see test above). |
| + aos = aosw.Create(44100, 448); |
| + EXPECT_TRUE(aos->Open()); |
| + aos->Close(); |
| + |
| + // 5.8050ms @ 44.1 shall work. |
| + aos = aosw.Create(44100, 256); |
| + EXPECT_TRUE(aos->Open()); |
| + aos->Close(); |
| + |
| + // 4.9887ms @ 44.1kHz does not work to misalignment. |
| + // This test will propose an aligned buffer size of 5.0794ms. |
| + aos = aosw.Create(44100, 220); |
| + EXPECT_FALSE(aos->Open()); |
| + aos->Close(); |
| + |
| + // 5.0794ms @ 44.1kHz shall work (see test above). |
| + aos = aosw.Create(44100, 224); |
| + EXPECT_TRUE(aos->Open()); |
| + aos->Close(); |
| + |
| + // 2.9025ms is smaller than the minimum supported size (=3ms). |
| + aos = aosw.Create(44100, 132); |
| + EXPECT_FALSE(aos->Open()); |
| + aos->Close(); |
| + |
| + // 3.01587ms is larger than the minimum size but is not aligned. |
| + // This test will propose an aligned buffer size of 3.6281ms. |
| + aos = aosw.Create(44100, 133); |
| + EXPECT_FALSE(aos->Open()); |
| + aos->Close(); |
| + |
| + // 3.6281ms @ 44.1kHz <=> smallest possible buffer size we can use. |
| + aos = aosw.Create(44100, 160); |
| + EXPECT_TRUE(aos->Open()); |
| + aos->Close(); |
| +} |
| + |
| +// Verify that we can open and start the output stream in exclusive mode at |
| +// the lowest possible delay at 48kHz. |
| +TEST(WinAudioOutputTest, |
| + WASAPIAudioOutputStreamTestExclusiveModeMinBufferSizeAt48kHzSampleRate) { |
| + if (!ExclusiveModeIsEnabled()) |
| + return; |
| + |
| + scoped_ptr<AudioManager> audio_manager(AudioManager::Create()); |
| + if (!CanRunAudioTests(audio_manager.get())) |
| + return; |
| + |
| + MessageLoopForUI loop; |
| + scoped_refptr<base::MessageLoopProxy> proxy(loop.message_loop_proxy()); |
| + |
| + MockAudioSourceCallback source; |
| + |
| + // Create exclusive-mode WASAPI output stream which plays out in stereo |
| + // using the minimum buffer size at 48kHz sample rate. |
| + AudioOutputStreamWrapper aosw(audio_manager.get()); |
| + AudioOutputStream* aos = aosw.Create(48000, 160); |
| + EXPECT_TRUE(aos->Open()); |
| + |
| + // Derive the expected size in bytes of each packet. |
| + uint32 bytes_per_packet = aosw.channels() * aosw.samples_per_packet() * |
| + (aosw.bits_per_sample() / 8); |
| + |
| + // Set up expected minimum delay estimation. |
| + AudioBuffersState state(0, bytes_per_packet); |
| + |
| + // Wait for the first callback and verify its parameters. |
| + EXPECT_CALL(source, OnMoreData(NotNull(), bytes_per_packet, |
| + HasValidDelay(state))) |
| + .WillOnce( |
| + DoAll( |
| + InvokeWithoutArgs( |
| + CreateFunctor(&QuitMessageLoop, proxy.get())), |
|
tommi (sloooow) - chröme
2012/07/25 11:49:40
ACTION instead of CreateFunctor?
henrika (OOO until Aug 14)
2012/07/25 15:26:30
Done.
|
| + Return(bytes_per_packet))); |
| + |
| + aos->Start(&source); |
| + loop.PostDelayedTask(FROM_HERE, MessageLoop::QuitClosure(), |
| + TestTimeouts::action_timeout()); |
| + loop.Run(); |
| + aos->Stop(); |
| + aos->Close(); |
| +} |
| + |
| +// Verify that we can open and start the output stream in exclusive mode at |
| +// the lowest possible delay at 44.1kHz. |
| +TEST(WinAudioOutputTest, |
| + WASAPIAudioOutputStreamTestExclusiveModeMinBufferSizeAt44kHzSampleRate) { |
| + if (!ExclusiveModeIsEnabled()) |
| + return; |
| + |
| + scoped_ptr<AudioManager> audio_manager(AudioManager::Create()); |
| + if (!CanRunAudioTests(audio_manager.get())) |
| + return; |
| + |
| + MessageLoopForUI loop; |
| + scoped_refptr<base::MessageLoopProxy> proxy(loop.message_loop_proxy()); |
| + |
| + MockAudioSourceCallback source; |
| + |
| + // Create exclusive-mode WASAPI output stream which plays out in stereo |
| + // using the minimum buffer size at 48kHz sample rate. |
| + AudioOutputStreamWrapper aosw(audio_manager.get()); |
| + AudioOutputStream* aos = aosw.Create(44100, 160); |
| + EXPECT_TRUE(aos->Open()); |
| + |
| + // Derive the expected size in bytes of each packet. |
| + uint32 bytes_per_packet = aosw.channels() * aosw.samples_per_packet() * |
| + (aosw.bits_per_sample() / 8); |
| + |
| + // Set up expected minimum delay estimation. |
| + AudioBuffersState state(0, bytes_per_packet); |
| + |
| + // Wait for the first callback and verify its parameters. |
| + EXPECT_CALL(source, OnMoreData(NotNull(), bytes_per_packet, |
| + HasValidDelay(state))) |
| + .WillOnce( |
| + DoAll( |
| + InvokeWithoutArgs( |
| + CreateFunctor(&QuitMessageLoop, proxy.get())), |
|
tommi (sloooow) - chröme
2012/07/25 11:49:40
ACTION instead of CreateFunctor?
henrika (OOO until Aug 14)
2012/07/25 15:26:30
Done.
|
| + Return(bytes_per_packet))); |
| + |
| + aos->Start(&source); |
| + loop.PostDelayedTask(FROM_HERE, MessageLoop::QuitClosure(), |
| + TestTimeouts::action_timeout()); |
| + loop.Run(); |
| + aos->Stop(); |
| + aos->Close(); |
| +} |
| + |
| } // namespace media |