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