Home | History | Annotate | Download | only in win
      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.
      4 
      5 #include <windows.h>
      6 #include <mmsystem.h>
      7 
      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/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/include/gmock/gmock.h"
     26 #include "testing/gmock_mutant.h"
     27 #include "testing/gtest/include/gtest/gtest.h"
     28 
     29 using ::testing::_;
     30 using ::testing::AnyNumber;
     31 using ::testing::AtLeast;
     32 using ::testing::Between;
     33 using ::testing::CreateFunctor;
     34 using ::testing::DoAll;
     35 using ::testing::Gt;
     36 using ::testing::InvokeWithoutArgs;
     37 using ::testing::NotNull;
     38 using ::testing::Return;
     39 using base::win::ScopedCOMInitializer;
     40 
     41 namespace media {
     42 
     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";
     50 
     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;
     56 }
     57 
     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, base::MessageLoop::QuitClosure());
     62 }
     63 
     64 class MockAudioSourceCallback : public AudioOutputStream::AudioSourceCallback {
     65  public:
     66   MOCK_METHOD2(OnMoreData, int(AudioBus* audio_bus,
     67                                AudioBuffersState buffers_state));
     68   MOCK_METHOD3(OnMoreIOData, int(AudioBus* source,
     69                                  AudioBus* dest,
     70                                  AudioBuffersState buffers_state));
     71   MOCK_METHOD1(OnError, void(AudioOutputStream* stream));
     72 };
     73 
     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 {
     77  public:
     78   explicit ReadFromFileAudioSource(const std::string& name)
     79     : pos_(0),
     80       previous_call_time_(base::TimeTicks::Now()),
     81       text_file_(NULL),
     82       elements_to_write_(0) {
     83     // Reads a test file from media/test/data directory.
     84     file_ = ReadTestDataFile(name);
     85 
     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]);
     91   }
     92 
     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);
     99 
    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.";
    103 
    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]);
    108       ++elements_written;
    109     }
    110 
    111     file_util::CloseFile(text_file_);
    112   }
    113 
    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     const base::TimeTicks now_time = base::TimeTicks::Now();
    120     const int diff = (now_time - previous_call_time_).InMilliseconds();
    121     previous_call_time_ = now_time;
    122     if (elements_to_write_ < kMaxDeltaSamples) {
    123       delta_times_[elements_to_write_] = diff;
    124       ++elements_to_write_;
    125     }
    126 
    127     int max_size =
    128         audio_bus->frames() * audio_bus->channels() * kBitsPerSample / 8;
    129 
    130     // Use samples read from a data file and fill up the audio buffer
    131     // provided to us in the callback.
    132     if (pos_ + static_cast<int>(max_size) > file_size())
    133       max_size = file_size() - pos_;
    134     int frames = max_size / (audio_bus->channels() * kBitsPerSample / 8);
    135     if (max_size) {
    136       audio_bus->FromInterleaved(
    137           file_->data() + pos_, frames, kBitsPerSample / 8);
    138       pos_ += max_size;
    139     }
    140     return frames;
    141   }
    142 
    143   virtual int OnMoreIOData(AudioBus* source,
    144                            AudioBus* dest,
    145                            AudioBuffersState buffers_state) OVERRIDE {
    146     NOTREACHED();
    147     return 0;
    148   }
    149 
    150   virtual void OnError(AudioOutputStream* stream) {}
    151 
    152   int file_size() { return file_->data_size(); }
    153 
    154  private:
    155   scoped_refptr<DecoderBuffer> file_;
    156   scoped_ptr<int[]> delta_times_;
    157   int pos_;
    158   base::TimeTicks previous_call_time_;
    159   FILE* text_file_;
    160   size_t elements_to_write_;
    161 };
    162 
    163 static bool ExclusiveModeIsEnabled() {
    164   return (WASAPIAudioOutputStream::GetShareMode() ==
    165           AUDCLNT_SHAREMODE_EXCLUSIVE);
    166 }
    167 
    168 // Convenience method which ensures that we are not running on the build
    169 // bots and that at least one valid output device can be found. We also
    170 // verify that we are not running on XP since the low-latency (WASAPI-
    171 // based) version requires Windows Vista or higher.
    172 static bool CanRunAudioTests(AudioManager* audio_man) {
    173   if (!CoreAudioUtil::IsSupported()) {
    174     LOG(WARNING) << "This test requires Windows Vista or higher.";
    175     return false;
    176   }
    177 
    178   // TODO(henrika): note that we use Wave today to query the number of
    179   // existing output devices.
    180   if (!audio_man->HasAudioOutputDevices()) {
    181     LOG(WARNING) << "No output devices detected.";
    182     return false;
    183   }
    184 
    185   return true;
    186 }
    187 
    188 // Convenience method which creates a default AudioOutputStream object but
    189 // also allows the user to modify the default settings.
    190 class AudioOutputStreamWrapper {
    191  public:
    192   explicit AudioOutputStreamWrapper(AudioManager* audio_manager)
    193       : audio_man_(audio_manager),
    194         format_(AudioParameters::AUDIO_PCM_LOW_LATENCY),
    195         bits_per_sample_(kBitsPerSample) {
    196     AudioParameters preferred_params;
    197     EXPECT_TRUE(SUCCEEDED(CoreAudioUtil::GetPreferredAudioParameters(
    198         eRender, eConsole, &preferred_params)));
    199     channel_layout_ = preferred_params.channel_layout();
    200     sample_rate_ = preferred_params.sample_rate();
    201     samples_per_packet_ = preferred_params.frames_per_buffer();
    202   }
    203 
    204   ~AudioOutputStreamWrapper() {}
    205 
    206   // Creates AudioOutputStream object using default parameters.
    207   AudioOutputStream* Create() {
    208     return CreateOutputStream();
    209   }
    210 
    211   // Creates AudioOutputStream object using non-default parameters where the
    212   // frame size is modified.
    213   AudioOutputStream* Create(int samples_per_packet) {
    214     samples_per_packet_ = samples_per_packet;
    215     return CreateOutputStream();
    216   }
    217 
    218   // Creates AudioOutputStream object using non-default parameters where the
    219   // sample rate and frame size are modified.
    220   AudioOutputStream* Create(int sample_rate, int samples_per_packet) {
    221     sample_rate_ = sample_rate;
    222     samples_per_packet_ = samples_per_packet;
    223     return CreateOutputStream();
    224   }
    225 
    226   AudioParameters::Format format() const { return format_; }
    227   int channels() const { return ChannelLayoutToChannelCount(channel_layout_); }
    228   int bits_per_sample() const { return bits_per_sample_; }
    229   int sample_rate() const { return sample_rate_; }
    230   int samples_per_packet() const { return samples_per_packet_; }
    231 
    232  private:
    233   AudioOutputStream* CreateOutputStream() {
    234     AudioOutputStream* aos = audio_man_->MakeAudioOutputStream(
    235         AudioParameters(format_, channel_layout_, sample_rate_,
    236                         bits_per_sample_, samples_per_packet_),
    237         std::string());
    238     EXPECT_TRUE(aos);
    239     return aos;
    240   }
    241 
    242   AudioManager* audio_man_;
    243   AudioParameters::Format format_;
    244   ChannelLayout channel_layout_;
    245   int bits_per_sample_;
    246   int sample_rate_;
    247   int samples_per_packet_;
    248 };
    249 
    250 // Convenience method which creates a default AudioOutputStream object.
    251 static AudioOutputStream* CreateDefaultAudioOutputStream(
    252     AudioManager* audio_manager) {
    253   AudioOutputStreamWrapper aosw(audio_manager);
    254   AudioOutputStream* aos = aosw.Create();
    255   return aos;
    256 }
    257 
    258 // Verify that we can retrieve the current hardware/mixing sample rate
    259 // for the default audio device.
    260 // TODO(henrika): modify this test when we support full device enumeration.
    261 TEST(WASAPIAudioOutputStreamTest, HardwareSampleRate) {
    262   // Skip this test in exclusive mode since the resulting rate is only utilized
    263   // for shared mode streams.
    264   scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
    265   if (!CanRunAudioTests(audio_manager.get()) || ExclusiveModeIsEnabled())
    266     return;
    267 
    268   // Default device intended for games, system notification sounds,
    269   // and voice commands.
    270   int fs = static_cast<int>(
    271       WASAPIAudioOutputStream::HardwareSampleRate());
    272   EXPECT_GE(fs, 0);
    273 }
    274 
    275 // Test Create(), Close() calling sequence.
    276 TEST(WASAPIAudioOutputStreamTest, CreateAndClose) {
    277   scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
    278   if (!CanRunAudioTests(audio_manager.get()))
    279     return;
    280   AudioOutputStream* aos = CreateDefaultAudioOutputStream(audio_manager.get());
    281   aos->Close();
    282 }
    283 
    284 // Test Open(), Close() calling sequence.
    285 TEST(WASAPIAudioOutputStreamTest, OpenAndClose) {
    286   scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
    287   if (!CanRunAudioTests(audio_manager.get()))
    288     return;
    289   AudioOutputStream* aos = CreateDefaultAudioOutputStream(audio_manager.get());
    290   EXPECT_TRUE(aos->Open());
    291   aos->Close();
    292 }
    293 
    294 // Test Open(), Start(), Close() calling sequence.
    295 TEST(WASAPIAudioOutputStreamTest, OpenStartAndClose) {
    296   scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
    297   if (!CanRunAudioTests(audio_manager.get()))
    298     return;
    299   AudioOutputStream* aos = CreateDefaultAudioOutputStream(audio_manager.get());
    300   EXPECT_TRUE(aos->Open());
    301   MockAudioSourceCallback source;
    302   EXPECT_CALL(source, OnError(aos))
    303       .Times(0);
    304   aos->Start(&source);
    305   aos->Close();
    306 }
    307 
    308 // Test Open(), Start(), Stop(), Close() calling sequence.
    309 TEST(WASAPIAudioOutputStreamTest, OpenStartStopAndClose) {
    310   scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
    311   if (!CanRunAudioTests(audio_manager.get()))
    312     return;
    313   AudioOutputStream* aos = CreateDefaultAudioOutputStream(audio_manager.get());
    314   EXPECT_TRUE(aos->Open());
    315   MockAudioSourceCallback source;
    316   EXPECT_CALL(source, OnError(aos))
    317       .Times(0);
    318   aos->Start(&source);
    319   aos->Stop();
    320   aos->Close();
    321 }
    322 
    323 // Test SetVolume(), GetVolume()
    324 TEST(WASAPIAudioOutputStreamTest, Volume) {
    325   scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
    326   if (!CanRunAudioTests(audio_manager.get()))
    327     return;
    328   AudioOutputStream* aos = CreateDefaultAudioOutputStream(audio_manager.get());
    329 
    330   // Initial volume should be full volume (1.0).
    331   double volume = 0.0;
    332   aos->GetVolume(&volume);
    333   EXPECT_EQ(1.0, volume);
    334 
    335   // Verify some valid volume settings.
    336   aos->SetVolume(0.0);
    337   aos->GetVolume(&volume);
    338   EXPECT_EQ(0.0, volume);
    339 
    340   aos->SetVolume(0.5);
    341   aos->GetVolume(&volume);
    342   EXPECT_EQ(0.5, volume);
    343 
    344   aos->SetVolume(1.0);
    345   aos->GetVolume(&volume);
    346   EXPECT_EQ(1.0, volume);
    347 
    348   // Ensure that invalid volume setting have no effect.
    349   aos->SetVolume(1.5);
    350   aos->GetVolume(&volume);
    351   EXPECT_EQ(1.0, volume);
    352 
    353   aos->SetVolume(-0.5);
    354   aos->GetVolume(&volume);
    355   EXPECT_EQ(1.0, volume);
    356 
    357   aos->Close();
    358 }
    359 
    360 // Test some additional calling sequences.
    361 TEST(WASAPIAudioOutputStreamTest, MiscCallingSequences) {
    362   scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
    363   if (!CanRunAudioTests(audio_manager.get()))
    364     return;
    365 
    366   AudioOutputStream* aos = CreateDefaultAudioOutputStream(audio_manager.get());
    367   WASAPIAudioOutputStream* waos = static_cast<WASAPIAudioOutputStream*>(aos);
    368 
    369   // Open(), Open() is a valid calling sequence (second call does nothing).
    370   EXPECT_TRUE(aos->Open());
    371   EXPECT_TRUE(aos->Open());
    372 
    373   MockAudioSourceCallback source;
    374 
    375   // Start(), Start() is a valid calling sequence (second call does nothing).
    376   aos->Start(&source);
    377   EXPECT_TRUE(waos->started());
    378   aos->Start(&source);
    379   EXPECT_TRUE(waos->started());
    380 
    381   // Stop(), Stop() is a valid calling sequence (second call does nothing).
    382   aos->Stop();
    383   EXPECT_FALSE(waos->started());
    384   aos->Stop();
    385   EXPECT_FALSE(waos->started());
    386 
    387   // Start(), Stop(), Start(), Stop().
    388   aos->Start(&source);
    389   EXPECT_TRUE(waos->started());
    390   aos->Stop();
    391   EXPECT_FALSE(waos->started());
    392   aos->Start(&source);
    393   EXPECT_TRUE(waos->started());
    394   aos->Stop();
    395   EXPECT_FALSE(waos->started());
    396 
    397   aos->Close();
    398 }
    399 
    400 // Use preferred packet size and verify that rendering starts.
    401 TEST(WASAPIAudioOutputStreamTest, ValidPacketSize) {
    402   scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
    403   if (!CanRunAudioTests(audio_manager.get()))
    404     return;
    405 
    406   base::MessageLoopForUI loop;
    407   MockAudioSourceCallback source;
    408 
    409   // Create default WASAPI output stream which plays out in stereo using
    410   // the shared mixing rate. The default buffer size is 10ms.
    411   AudioOutputStreamWrapper aosw(audio_manager.get());
    412   AudioOutputStream* aos = aosw.Create();
    413   EXPECT_TRUE(aos->Open());
    414 
    415   // Derive the expected size in bytes of each packet.
    416   uint32 bytes_per_packet = aosw.channels() * aosw.samples_per_packet() *
    417                            (aosw.bits_per_sample() / 8);
    418 
    419   // Set up expected minimum delay estimation.
    420   AudioBuffersState state(0, bytes_per_packet);
    421 
    422   // Wait for the first callback and verify its parameters.
    423   EXPECT_CALL(source, OnMoreData(NotNull(), HasValidDelay(state)))
    424       .WillOnce(DoAll(
    425           QuitLoop(loop.message_loop_proxy()),
    426           Return(aosw.samples_per_packet())));
    427 
    428   aos->Start(&source);
    429   loop.PostDelayedTask(FROM_HERE, base::MessageLoop::QuitClosure(),
    430                        TestTimeouts::action_timeout());
    431   loop.Run();
    432   aos->Stop();
    433   aos->Close();
    434 }
    435 
    436 // Use a non-preferred packet size and verify that Open() fails.
    437 TEST(WASAPIAudioOutputStreamTest, InvalidPacketSize) {
    438   scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
    439   if (!CanRunAudioTests(audio_manager.get()))
    440     return;
    441 
    442   if (ExclusiveModeIsEnabled())
    443     return;
    444 
    445   AudioParameters preferred_params;
    446   EXPECT_TRUE(SUCCEEDED(CoreAudioUtil::GetPreferredAudioParameters(
    447       eRender, eConsole, &preferred_params)));
    448   int too_large_packet_size = 2 * preferred_params.frames_per_buffer();
    449 
    450   AudioOutputStreamWrapper aosw(audio_manager.get());
    451   AudioOutputStream* aos = aosw.Create(too_large_packet_size);
    452   EXPECT_FALSE(aos->Open());
    453 
    454   aos->Close();
    455 }
    456 
    457 // This test is intended for manual tests and should only be enabled
    458 // when it is required to play out data from a local PCM file.
    459 // By default, GTest will print out YOU HAVE 1 DISABLED TEST.
    460 // To include disabled tests in test execution, just invoke the test program
    461 // with --gtest_also_run_disabled_tests or set the GTEST_ALSO_RUN_DISABLED_TESTS
    462 // environment variable to a value greater than 0.
    463 // The test files are approximately 20 seconds long.
    464 TEST(WASAPIAudioOutputStreamTest, DISABLED_ReadFromStereoFile) {
    465   scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
    466   if (!CanRunAudioTests(audio_manager.get()))
    467     return;
    468 
    469   AudioOutputStreamWrapper aosw(audio_manager.get());
    470   AudioOutputStream* aos = aosw.Create();
    471   EXPECT_TRUE(aos->Open());
    472 
    473   std::string file_name;
    474   if (aosw.sample_rate() == 48000) {
    475     file_name = kSpeechFile_16b_s_48k;
    476   } else if (aosw.sample_rate() == 44100) {
    477     file_name = kSpeechFile_16b_s_44k;
    478   } else if (aosw.sample_rate() == 96000) {
    479     // Use 48kHz file at 96kHz as well. Will sound like Donald Duck.
    480     file_name = kSpeechFile_16b_s_48k;
    481   } else {
    482     FAIL() << "This test supports 44.1, 48kHz and 96kHz only.";
    483     return;
    484   }
    485   ReadFromFileAudioSource file_source(file_name);
    486 
    487   LOG(INFO) << "File name      : " << file_name.c_str();
    488   LOG(INFO) << "Sample rate    : " << aosw.sample_rate();
    489   LOG(INFO) << "Bits per sample: " << aosw.bits_per_sample();
    490   LOG(INFO) << "#channels      : " << aosw.channels();
    491   LOG(INFO) << "File size      : " << file_source.file_size();
    492   LOG(INFO) << "#file segments : " << kNumFileSegments;
    493   LOG(INFO) << ">> Listen to the stereo file while playing...";
    494 
    495   for (int i = 0; i < kNumFileSegments; i++) {
    496     // Each segment will start with a short (~20ms) block of zeros, hence
    497     // some short glitches might be heard in this test if kNumFileSegments
    498     // is larger than one. The exact length of the silence period depends on
    499     // the selected sample rate.
    500     aos->Start(&file_source);
    501     base::PlatformThread::Sleep(
    502         base::TimeDelta::FromMilliseconds(kFileDurationMs / kNumFileSegments));
    503     aos->Stop();
    504   }
    505 
    506   LOG(INFO) << ">> Stereo file playout has stopped.";
    507   aos->Close();
    508 }
    509 
    510 // Verify that we can open the output stream in exclusive mode using a
    511 // certain set of audio parameters and a sample rate of 48kHz.
    512 // The expected outcomes of each setting in this test has been derived
    513 // manually using log outputs (--v=1).
    514 TEST(WASAPIAudioOutputStreamTest, ExclusiveModeBufferSizesAt48kHz) {
    515   if (!ExclusiveModeIsEnabled())
    516     return;
    517 
    518   scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
    519   if (!CanRunAudioTests(audio_manager.get()))
    520     return;
    521 
    522   AudioOutputStreamWrapper aosw(audio_manager.get());
    523 
    524   // 10ms @ 48kHz shall work.
    525   // Note that, this is the same size as we can use for shared-mode streaming
    526   // but here the endpoint buffer delay is only 10ms instead of 20ms.
    527   AudioOutputStream* aos = aosw.Create(48000, 480);
    528   EXPECT_TRUE(aos->Open());
    529   aos->Close();
    530 
    531   // 5ms @ 48kHz does not work due to misalignment.
    532   // This test will propose an aligned buffer size of 5.3333ms.
    533   // Note that we must call Close() even is Open() fails since Close() also
    534   // deletes the object and we want to create a new object in the next test.
    535   aos = aosw.Create(48000, 240);
    536   EXPECT_FALSE(aos->Open());
    537   aos->Close();
    538 
    539   // 5.3333ms @ 48kHz should work (see test above).
    540   aos = aosw.Create(48000, 256);
    541   EXPECT_TRUE(aos->Open());
    542   aos->Close();
    543 
    544   // 2.6667ms is smaller than the minimum supported size (=3ms).
    545   aos = aosw.Create(48000, 128);
    546   EXPECT_FALSE(aos->Open());
    547   aos->Close();
    548 
    549   // 3ms does not correspond to an aligned buffer size.
    550   // This test will propose an aligned buffer size of 3.3333ms.
    551   aos = aosw.Create(48000, 144);
    552   EXPECT_FALSE(aos->Open());
    553   aos->Close();
    554 
    555   // 3.3333ms @ 48kHz <=> smallest possible buffer size we can use.
    556   aos = aosw.Create(48000, 160);
    557   EXPECT_TRUE(aos->Open());
    558   aos->Close();
    559 }
    560 
    561 // Verify that we can open the output stream in exclusive mode using a
    562 // certain set of audio parameters and a sample rate of 44.1kHz.
    563 // The expected outcomes of each setting in this test has been derived
    564 // manually using log outputs (--v=1).
    565 TEST(WASAPIAudioOutputStreamTest, ExclusiveModeBufferSizesAt44kHz) {
    566   if (!ExclusiveModeIsEnabled())
    567     return;
    568 
    569   scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
    570   if (!CanRunAudioTests(audio_manager.get()))
    571     return;
    572 
    573   AudioOutputStreamWrapper aosw(audio_manager.get());
    574 
    575   // 10ms @ 44.1kHz does not work due to misalignment.
    576   // This test will propose an aligned buffer size of 10.1587ms.
    577   AudioOutputStream* aos = aosw.Create(44100, 441);
    578   EXPECT_FALSE(aos->Open());
    579   aos->Close();
    580 
    581   // 10.1587ms @ 44.1kHz shall work (see test above).
    582   aos = aosw.Create(44100, 448);
    583   EXPECT_TRUE(aos->Open());
    584   aos->Close();
    585 
    586   // 5.8050ms @ 44.1 should work.
    587   aos = aosw.Create(44100, 256);
    588   EXPECT_TRUE(aos->Open());
    589   aos->Close();
    590 
    591   // 4.9887ms @ 44.1kHz does not work to misalignment.
    592   // This test will propose an aligned buffer size of 5.0794ms.
    593   // Note that we must call Close() even is Open() fails since Close() also
    594   // deletes the object and we want to create a new object in the next test.
    595   aos = aosw.Create(44100, 220);
    596   EXPECT_FALSE(aos->Open());
    597   aos->Close();
    598 
    599   // 5.0794ms @ 44.1kHz shall work (see test above).
    600   aos = aosw.Create(44100, 224);
    601   EXPECT_TRUE(aos->Open());
    602   aos->Close();
    603 
    604   // 2.9025ms is smaller than the minimum supported size (=3ms).
    605   aos = aosw.Create(44100, 132);
    606   EXPECT_FALSE(aos->Open());
    607   aos->Close();
    608 
    609   // 3.01587ms is larger than the minimum size but is not aligned.
    610   // This test will propose an aligned buffer size of 3.6281ms.
    611   aos = aosw.Create(44100, 133);
    612   EXPECT_FALSE(aos->Open());
    613   aos->Close();
    614 
    615   // 3.6281ms @ 44.1kHz <=> smallest possible buffer size we can use.
    616   aos = aosw.Create(44100, 160);
    617   EXPECT_TRUE(aos->Open());
    618   aos->Close();
    619 }
    620 
    621 // Verify that we can open and start the output stream in exclusive mode at
    622 // the lowest possible delay at 48kHz.
    623 TEST(WASAPIAudioOutputStreamTest, ExclusiveModeMinBufferSizeAt48kHz) {
    624   if (!ExclusiveModeIsEnabled())
    625     return;
    626 
    627   scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
    628   if (!CanRunAudioTests(audio_manager.get()))
    629     return;
    630 
    631   base::MessageLoopForUI loop;
    632   MockAudioSourceCallback source;
    633 
    634   // Create exclusive-mode WASAPI output stream which plays out in stereo
    635   // using the minimum buffer size at 48kHz sample rate.
    636   AudioOutputStreamWrapper aosw(audio_manager.get());
    637   AudioOutputStream* aos = aosw.Create(48000, 160);
    638   EXPECT_TRUE(aos->Open());
    639 
    640   // Derive the expected size in bytes of each packet.
    641   uint32 bytes_per_packet = aosw.channels() * aosw.samples_per_packet() *
    642       (aosw.bits_per_sample() / 8);
    643 
    644   // Set up expected minimum delay estimation.
    645   AudioBuffersState state(0, bytes_per_packet);
    646 
    647  // Wait for the first callback and verify its parameters.
    648   EXPECT_CALL(source, OnMoreData(NotNull(), HasValidDelay(state)))
    649       .WillOnce(DoAll(
    650           QuitLoop(loop.message_loop_proxy()),
    651           Return(aosw.samples_per_packet())))
    652       .WillRepeatedly(Return(aosw.samples_per_packet()));
    653 
    654   aos->Start(&source);
    655   loop.PostDelayedTask(FROM_HERE, base::MessageLoop::QuitClosure(),
    656                        TestTimeouts::action_timeout());
    657   loop.Run();
    658   aos->Stop();
    659   aos->Close();
    660 }
    661 
    662 // Verify that we can open and start the output stream in exclusive mode at
    663 // the lowest possible delay at 44.1kHz.
    664 TEST(WASAPIAudioOutputStreamTest, ExclusiveModeMinBufferSizeAt44kHz) {
    665   if (!ExclusiveModeIsEnabled())
    666     return;
    667 
    668   scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
    669   if (!CanRunAudioTests(audio_manager.get()))
    670     return;
    671 
    672   base::MessageLoopForUI loop;
    673   MockAudioSourceCallback source;
    674 
    675   // Create exclusive-mode WASAPI output stream which plays out in stereo
    676   // using the minimum buffer size at 44.1kHz sample rate.
    677   AudioOutputStreamWrapper aosw(audio_manager.get());
    678   AudioOutputStream* aos = aosw.Create(44100, 160);
    679   EXPECT_TRUE(aos->Open());
    680 
    681   // Derive the expected size in bytes of each packet.
    682   uint32 bytes_per_packet = aosw.channels() * aosw.samples_per_packet() *
    683       (aosw.bits_per_sample() / 8);
    684 
    685   // Set up expected minimum delay estimation.
    686   AudioBuffersState state(0, bytes_per_packet);
    687 
    688   // Wait for the first callback and verify its parameters.
    689   EXPECT_CALL(source, OnMoreData(NotNull(), HasValidDelay(state)))
    690     .WillOnce(DoAll(
    691         QuitLoop(loop.message_loop_proxy()),
    692         Return(aosw.samples_per_packet())))
    693     .WillRepeatedly(Return(aosw.samples_per_packet()));
    694 
    695   aos->Start(&source);
    696   loop.PostDelayedTask(FROM_HERE, base::MessageLoop::QuitClosure(),
    697                         TestTimeouts::action_timeout());
    698   loop.Run();
    699   aos->Stop();
    700   aos->Close();
    701 }
    702 
    703 }  // namespace media
    704