Home | History | Annotate | Download | only in cras
      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 <unistd.h>
      6 
      7 #include <string>
      8 
      9 #include "base/synchronization/waitable_event.h"
     10 #include "base/test/test_timeouts.h"
     11 #include "base/time/time.h"
     12 #include "media/audio/cras/audio_manager_cras.h"
     13 #include "media/audio/cras/cras_input.h"
     14 #include "testing/gmock/include/gmock/gmock.h"
     15 #include "testing/gtest/include/gtest/gtest.h"
     16 
     17 using testing::_;
     18 using testing::AtLeast;
     19 using testing::Ge;
     20 using testing::InvokeWithoutArgs;
     21 using testing::StrictMock;
     22 
     23 namespace media {
     24 
     25 class MockAudioInputCallback : public AudioInputStream::AudioInputCallback {
     26  public:
     27   MOCK_METHOD5(OnData, void(
     28       AudioInputStream*, const uint8*, uint32, uint32, double));
     29   MOCK_METHOD1(OnError, void(AudioInputStream*));
     30   MOCK_METHOD1(OnClose, void(AudioInputStream*));
     31 };
     32 
     33 class MockAudioManagerCrasInput : public AudioManagerCras {
     34  public:
     35   // We need to override this function in order to skip checking the number
     36   // of active output streams. It is because the number of active streams
     37   // is managed inside MakeAudioInputStream, and we don't use
     38   // MakeAudioInputStream to create the stream in the tests.
     39   virtual void ReleaseInputStream(AudioInputStream* stream) OVERRIDE {
     40     DCHECK(stream);
     41     delete stream;
     42   }
     43 };
     44 
     45 class CrasInputStreamTest : public testing::Test {
     46  protected:
     47   CrasInputStreamTest() {
     48     mock_manager_.reset(new StrictMock<MockAudioManagerCrasInput>());
     49   }
     50 
     51   virtual ~CrasInputStreamTest() {
     52   }
     53 
     54   CrasInputStream* CreateStream(ChannelLayout layout) {
     55     return CreateStream(layout, kTestFramesPerPacket);
     56   }
     57 
     58   CrasInputStream* CreateStream(ChannelLayout layout,
     59                                 int32 samples_per_packet) {
     60     AudioParameters params(kTestFormat,
     61                            layout,
     62                            kTestSampleRate,
     63                            kTestBitsPerSample,
     64                            samples_per_packet);
     65     return new CrasInputStream(params, mock_manager_.get(),
     66                                AudioManagerBase::kDefaultDeviceId);
     67   }
     68 
     69   void CaptureSomeFrames(const AudioParameters &params,
     70                          unsigned int duration_ms) {
     71     CrasInputStream* test_stream = new CrasInputStream(
     72         params, mock_manager_.get(), AudioManagerBase::kDefaultDeviceId);
     73 
     74     ASSERT_TRUE(test_stream->Open());
     75 
     76     // Allow 8 frames variance for SRC in the callback.  Different numbers of
     77     // samples can be provided when doing non-integer SRC.  For example
     78     // converting from 192k to 44.1k is a ratio of 4.35 to 1.
     79     MockAudioInputCallback mock_callback;
     80     unsigned int expected_size = (kTestFramesPerPacket - 8) *
     81                                  params.channels() *
     82                                  params.bits_per_sample() / 8;
     83 
     84     base::WaitableEvent event(false, false);
     85 
     86     EXPECT_CALL(mock_callback,
     87                 OnData(test_stream, _, Ge(expected_size), _, _))
     88         .WillOnce(InvokeWithoutArgs(&event, &base::WaitableEvent::Signal));
     89 
     90     test_stream->Start(&mock_callback);
     91 
     92     // Wait for samples to be captured.
     93     EXPECT_TRUE(event.TimedWait(TestTimeouts::action_timeout()));
     94 
     95     test_stream->Stop();
     96 
     97     EXPECT_CALL(mock_callback, OnClose(test_stream)).Times(1);
     98     test_stream->Close();
     99   }
    100 
    101   static const unsigned int kTestBitsPerSample;
    102   static const unsigned int kTestCaptureDurationMs;
    103   static const ChannelLayout kTestChannelLayout;
    104   static const AudioParameters::Format kTestFormat;
    105   static const uint32 kTestFramesPerPacket;
    106   static const int kTestSampleRate;
    107 
    108   scoped_ptr<StrictMock<MockAudioManagerCrasInput> > mock_manager_;
    109 
    110  private:
    111   DISALLOW_COPY_AND_ASSIGN(CrasInputStreamTest);
    112 };
    113 
    114 const unsigned int CrasInputStreamTest::kTestBitsPerSample = 16;
    115 const unsigned int CrasInputStreamTest::kTestCaptureDurationMs = 250;
    116 const ChannelLayout CrasInputStreamTest::kTestChannelLayout =
    117     CHANNEL_LAYOUT_STEREO;
    118 const AudioParameters::Format CrasInputStreamTest::kTestFormat =
    119     AudioParameters::AUDIO_PCM_LINEAR;
    120 const uint32 CrasInputStreamTest::kTestFramesPerPacket = 1000;
    121 const int CrasInputStreamTest::kTestSampleRate = 44100;
    122 
    123 TEST_F(CrasInputStreamTest, OpenMono) {
    124   CrasInputStream* test_stream = CreateStream(CHANNEL_LAYOUT_MONO);
    125   EXPECT_TRUE(test_stream->Open());
    126   test_stream->Close();
    127 }
    128 
    129 TEST_F(CrasInputStreamTest, OpenStereo) {
    130   CrasInputStream* test_stream = CreateStream(CHANNEL_LAYOUT_STEREO);
    131   EXPECT_TRUE(test_stream->Open());
    132   test_stream->Close();
    133 }
    134 
    135 TEST_F(CrasInputStreamTest, BadBitsPerSample) {
    136   AudioParameters bad_bps_params(kTestFormat,
    137                                  kTestChannelLayout,
    138                                  kTestSampleRate,
    139                                  kTestBitsPerSample - 1,
    140                                  kTestFramesPerPacket);
    141   CrasInputStream* test_stream = new CrasInputStream(
    142       bad_bps_params, mock_manager_.get(), AudioManagerBase::kDefaultDeviceId);
    143   EXPECT_FALSE(test_stream->Open());
    144   test_stream->Close();
    145 }
    146 
    147 TEST_F(CrasInputStreamTest, BadFormat) {
    148   AudioParameters bad_format_params(AudioParameters::AUDIO_LAST_FORMAT,
    149                                     kTestChannelLayout,
    150                                     kTestSampleRate,
    151                                     kTestBitsPerSample,
    152                                     kTestFramesPerPacket);
    153   CrasInputStream* test_stream = new CrasInputStream(
    154       bad_format_params, mock_manager_.get(),
    155       AudioManagerBase::kDefaultDeviceId);
    156   EXPECT_FALSE(test_stream->Open());
    157   test_stream->Close();
    158 }
    159 
    160 TEST_F(CrasInputStreamTest, BadSampleRate) {
    161   AudioParameters bad_rate_params(kTestFormat,
    162                                   kTestChannelLayout,
    163                                   0,
    164                                   kTestBitsPerSample,
    165                                   kTestFramesPerPacket);
    166   CrasInputStream* test_stream = new CrasInputStream(
    167       bad_rate_params, mock_manager_.get(), AudioManagerBase::kDefaultDeviceId);
    168   EXPECT_FALSE(test_stream->Open());
    169   test_stream->Close();
    170 }
    171 
    172 TEST_F(CrasInputStreamTest, SetGetVolume) {
    173   CrasInputStream* test_stream = CreateStream(CHANNEL_LAYOUT_MONO);
    174   EXPECT_TRUE(test_stream->Open());
    175 
    176   double max_volume = test_stream->GetMaxVolume();
    177   EXPECT_GE(max_volume, 1.0);
    178 
    179   test_stream->SetVolume(max_volume / 2);
    180 
    181   double new_volume = test_stream->GetVolume();
    182 
    183   EXPECT_GE(new_volume, 0.0);
    184   EXPECT_LE(new_volume, max_volume);
    185 
    186   test_stream->Close();
    187 }
    188 
    189 TEST_F(CrasInputStreamTest, CaptureFrames) {
    190   const unsigned int rates[] =
    191       {8000, 16000, 22050, 32000, 44100, 48000, 96000, 192000};
    192 
    193   for (unsigned int i = 0; i < ARRAY_SIZE(rates); i++) {
    194     SCOPED_TRACE(testing::Message() << "Mono " << rates[i] << "Hz");
    195     AudioParameters params_mono(kTestFormat,
    196                                 CHANNEL_LAYOUT_MONO,
    197                                 rates[i],
    198                                 kTestBitsPerSample,
    199                                 kTestFramesPerPacket);
    200     CaptureSomeFrames(params_mono, kTestCaptureDurationMs);
    201   }
    202 
    203   for (unsigned int i = 0; i < ARRAY_SIZE(rates); i++) {
    204     SCOPED_TRACE(testing::Message() << "Stereo " << rates[i] << "Hz");
    205     AudioParameters params_stereo(kTestFormat,
    206                                   CHANNEL_LAYOUT_STEREO,
    207                                   rates[i],
    208                                   kTestBitsPerSample,
    209                                   kTestFramesPerPacket);
    210     CaptureSomeFrames(params_stereo, kTestCaptureDurationMs);
    211   }
    212 }
    213 
    214 }  // namespace media
    215