Home | History | Annotate | Download | only in audio
      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 "base/bind.h"
      6 #include "base/bind_helpers.h"
      7 #include "base/message_loop/message_loop.h"
      8 #include "base/message_loop/message_loop_proxy.h"
      9 #include "base/synchronization/waitable_event.h"
     10 #include "base/threading/thread.h"
     11 #include "media/audio/audio_manager.h"
     12 #include "media/audio/simple_sources.h"
     13 #include "media/audio/virtual_audio_input_stream.h"
     14 #include "media/audio/virtual_audio_output_stream.h"
     15 #include "testing/gmock/include/gmock/gmock.h"
     16 #include "testing/gtest/include/gtest/gtest.h"
     17 
     18 using ::testing::_;
     19 
     20 namespace media {
     21 
     22 namespace {
     23 const AudioParameters kParams(
     24     AudioParameters::AUDIO_PCM_LOW_LATENCY, CHANNEL_LAYOUT_MONO, 8000, 8, 128);
     25 }
     26 
     27 class MockVirtualAudioInputStream : public VirtualAudioInputStream {
     28  public:
     29   explicit MockVirtualAudioInputStream(
     30       const scoped_refptr<base::MessageLoopProxy>& worker_loop)
     31       : VirtualAudioInputStream(
     32             kParams,
     33             worker_loop,
     34             base::Bind(&base::DeletePointer<VirtualAudioInputStream>)) {}
     35   ~MockVirtualAudioInputStream() {}
     36 
     37   MOCK_METHOD2(AddOutputStream, void(VirtualAudioOutputStream* stream,
     38                                      const AudioParameters& output_params));
     39   MOCK_METHOD2(RemoveOutputStream, void(VirtualAudioOutputStream* stream,
     40                                         const AudioParameters& output_params));
     41 
     42  private:
     43   DISALLOW_COPY_AND_ASSIGN(MockVirtualAudioInputStream);
     44 };
     45 
     46 class MockAudioDeviceListener : public AudioManager::AudioDeviceListener {
     47  public:
     48   MOCK_METHOD0(OnDeviceChange, void());
     49 };
     50 
     51 class VirtualAudioOutputStreamTest : public testing::Test {
     52  public:
     53   VirtualAudioOutputStreamTest()
     54       : audio_thread_(new base::Thread("AudioThread")) {
     55     audio_thread_->Start();
     56     audio_message_loop_ = audio_thread_->message_loop_proxy();
     57   }
     58 
     59   const scoped_refptr<base::MessageLoopProxy>& audio_message_loop() const {
     60     return audio_message_loop_;
     61   }
     62 
     63   void SyncWithAudioThread() {
     64     base::WaitableEvent done(false, false);
     65     audio_message_loop()->PostTask(
     66         FROM_HERE, base::Bind(&base::WaitableEvent::Signal,
     67                               base::Unretained(&done)));
     68     done.Wait();
     69   }
     70 
     71  private:
     72   scoped_ptr<base::Thread> audio_thread_;
     73   scoped_refptr<base::MessageLoopProxy> audio_message_loop_;
     74 
     75   DISALLOW_COPY_AND_ASSIGN(VirtualAudioOutputStreamTest);
     76 };
     77 
     78 TEST_F(VirtualAudioOutputStreamTest, StartStopStartStop) {
     79   static const int kCycles = 3;
     80 
     81   MockVirtualAudioInputStream* const input_stream =
     82       new MockVirtualAudioInputStream(audio_message_loop());
     83   audio_message_loop()->PostTask(
     84       FROM_HERE, base::Bind(
     85           base::IgnoreResult(&MockVirtualAudioInputStream::Open),
     86           base::Unretained(input_stream)));
     87 
     88   VirtualAudioOutputStream* const output_stream = new VirtualAudioOutputStream(
     89       kParams,
     90       input_stream,
     91       base::Bind(&base::DeletePointer<VirtualAudioOutputStream>));
     92 
     93   EXPECT_CALL(*input_stream, AddOutputStream(output_stream, _))
     94       .Times(kCycles);
     95   EXPECT_CALL(*input_stream, RemoveOutputStream(output_stream, _))
     96       .Times(kCycles);
     97 
     98   audio_message_loop()->PostTask(
     99       FROM_HERE, base::Bind(base::IgnoreResult(&VirtualAudioOutputStream::Open),
    100                             base::Unretained(output_stream)));
    101   SineWaveAudioSource source(CHANNEL_LAYOUT_STEREO, 200.0, 128);
    102   for (int i = 0; i < kCycles; ++i) {
    103     audio_message_loop()->PostTask(
    104         FROM_HERE, base::Bind(&VirtualAudioOutputStream::Start,
    105                               base::Unretained(output_stream),
    106                               &source));
    107     audio_message_loop()->PostTask(
    108         FROM_HERE, base::Bind(&VirtualAudioOutputStream::Stop,
    109                               base::Unretained(output_stream)));
    110   }
    111   audio_message_loop()->PostTask(
    112       FROM_HERE, base::Bind(&VirtualAudioOutputStream::Close,
    113                             base::Unretained(output_stream)));
    114 
    115   audio_message_loop()->PostTask(
    116       FROM_HERE, base::Bind(&MockVirtualAudioInputStream::Close,
    117                             base::Unretained(input_stream)));
    118 
    119   SyncWithAudioThread();
    120 }
    121 
    122 }  // namespace media
    123