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/basictypes.h"
      6 #include "base/environment.h"
      7 #include "base/memory/scoped_ptr.h"
      8 #include "base/message_loop/message_loop.h"
      9 #include "base/threading/platform_thread.h"
     10 #include "media/audio/audio_io.h"
     11 #include "media/audio/audio_manager_base.h"
     12 #include "testing/gtest/include/gtest/gtest.h"
     13 
     14 namespace media {
     15 
     16 static const int kSamplingRate = 8000;
     17 static const int kSamplesPerPacket = kSamplingRate / 20;
     18 
     19 // This class allows to find out if the callbacks are occurring as
     20 // expected and if any error has been reported.
     21 class TestInputCallback : public AudioInputStream::AudioInputCallback {
     22  public:
     23   explicit TestInputCallback(int max_data_bytes)
     24       : callback_count_(0),
     25         had_error_(0),
     26         max_data_bytes_(max_data_bytes) {
     27   }
     28   virtual void OnData(AudioInputStream* stream,
     29                       const uint8* data,
     30                       uint32 size,
     31                       uint32 hardware_delay_bytes,
     32                       double volume) OVERRIDE {
     33     ++callback_count_;
     34     // Read the first byte to make sure memory is good.
     35     if (size) {
     36       ASSERT_LE(static_cast<int>(size), max_data_bytes_);
     37       int value = data[0];
     38       EXPECT_GE(value, 0);
     39     }
     40   }
     41   virtual void OnClose(AudioInputStream* stream) OVERRIDE {}
     42   virtual void OnError(AudioInputStream* stream) OVERRIDE {
     43     ++had_error_;
     44   }
     45   // Returns how many times OnData() has been called.
     46   int callback_count() const {
     47     return callback_count_;
     48   }
     49   // Returns how many times the OnError callback was called.
     50   int had_error() const {
     51     return had_error_;
     52   }
     53 
     54  private:
     55   int callback_count_;
     56   int had_error_;
     57   int max_data_bytes_;
     58 };
     59 
     60 static bool CanRunAudioTests(AudioManager* audio_man) {
     61   bool has_input = audio_man->HasAudioInputDevices();
     62 
     63   if (!has_input)
     64     LOG(WARNING) << "No input devices detected";
     65 
     66   return has_input;
     67 }
     68 
     69 static AudioInputStream* CreateTestAudioInputStream(AudioManager* audio_man) {
     70   AudioInputStream* ais = audio_man->MakeAudioInputStream(
     71       AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_STEREO,
     72                       kSamplingRate, 16, kSamplesPerPacket),
     73                       AudioManagerBase::kDefaultDeviceId);
     74   EXPECT_TRUE(NULL != ais);
     75   return ais;
     76 }
     77 
     78 // Test that AudioInputStream rejects out of range parameters.
     79 TEST(AudioInputTest, SanityOnMakeParams) {
     80   scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting());
     81   if (!CanRunAudioTests(audio_man.get()))
     82     return;
     83 
     84   AudioParameters::Format fmt = AudioParameters::AUDIO_PCM_LINEAR;
     85   EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(
     86       AudioParameters(fmt, CHANNEL_LAYOUT_7_1, 8000, 16,
     87                       kSamplesPerPacket), AudioManagerBase::kDefaultDeviceId));
     88   EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(
     89       AudioParameters(fmt, CHANNEL_LAYOUT_MONO, 1024 * 1024, 16,
     90                       kSamplesPerPacket), AudioManagerBase::kDefaultDeviceId));
     91   EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(
     92       AudioParameters(fmt, CHANNEL_LAYOUT_STEREO, 8000, 80,
     93                       kSamplesPerPacket), AudioManagerBase::kDefaultDeviceId));
     94   EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(
     95       AudioParameters(fmt, CHANNEL_LAYOUT_STEREO, 8000, 80,
     96                       1000 * kSamplesPerPacket),
     97                       AudioManagerBase::kDefaultDeviceId));
     98   EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(
     99       AudioParameters(fmt, CHANNEL_LAYOUT_UNSUPPORTED, 8000, 16,
    100                       kSamplesPerPacket), AudioManagerBase::kDefaultDeviceId));
    101   EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(
    102       AudioParameters(fmt, CHANNEL_LAYOUT_STEREO, -8000, 16,
    103                       kSamplesPerPacket), AudioManagerBase::kDefaultDeviceId));
    104   EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(
    105       AudioParameters(fmt, CHANNEL_LAYOUT_STEREO, 8000, -16,
    106                       kSamplesPerPacket), AudioManagerBase::kDefaultDeviceId));
    107   EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(
    108       AudioParameters(fmt, CHANNEL_LAYOUT_STEREO, 8000, 16, -1024),
    109       AudioManagerBase::kDefaultDeviceId));
    110 }
    111 
    112 // Test create and close of an AudioInputStream without recording audio.
    113 TEST(AudioInputTest, CreateAndClose) {
    114   scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting());
    115   if (!CanRunAudioTests(audio_man.get()))
    116     return;
    117   AudioInputStream* ais = CreateTestAudioInputStream(audio_man.get());
    118   ais->Close();
    119 }
    120 
    121 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
    122 // This test is failing on ARM linux: http://crbug.com/238490
    123 #define MAYBE_OpenAndClose DISABLED_OpenAndClose
    124 #else
    125 #define MAYBE_OpenAndClose OpenAndClose
    126 #endif
    127 // Test create, open and close of an AudioInputStream without recording audio.
    128 TEST(AudioInputTest, MAYBE_OpenAndClose) {
    129   scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting());
    130   if (!CanRunAudioTests(audio_man.get()))
    131     return;
    132   AudioInputStream* ais = CreateTestAudioInputStream(audio_man.get());
    133   EXPECT_TRUE(ais->Open());
    134   ais->Close();
    135 }
    136 
    137 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
    138 // This test is failing on ARM linux: http://crbug.com/238490
    139 #define MAYBE_OpenStopAndClose DISABLED_OpenStopAndClose
    140 #else
    141 #define MAYBE_OpenStopAndClose OpenStopAndClose
    142 #endif
    143 // Test create, open, stop and close of an AudioInputStream without recording.
    144 TEST(AudioInputTest, MAYBE_OpenStopAndClose) {
    145   scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting());
    146   if (!CanRunAudioTests(audio_man.get()))
    147     return;
    148   AudioInputStream* ais = CreateTestAudioInputStream(audio_man.get());
    149   EXPECT_TRUE(ais->Open());
    150   ais->Stop();
    151   ais->Close();
    152 }
    153 
    154 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
    155 // This test is failing on ARM linux: http://crbug.com/238490
    156 #define MAYBE_Record DISABLED_Record
    157 #else
    158 #define MAYBE_Record Record
    159 #endif
    160 // Test a normal recording sequence using an AudioInputStream.
    161 TEST(AudioInputTest, MAYBE_Record) {
    162   scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting());
    163   if (!CanRunAudioTests(audio_man.get()))
    164     return;
    165   base::MessageLoop message_loop(base::MessageLoop::TYPE_DEFAULT);
    166   AudioInputStream* ais = CreateTestAudioInputStream(audio_man.get());
    167   EXPECT_TRUE(ais->Open());
    168 
    169   TestInputCallback test_callback(kSamplesPerPacket * 4);
    170   ais->Start(&test_callback);
    171   // Verify at least 500ms worth of audio was recorded, after giving sufficient
    172   // extra time.
    173   message_loop.PostDelayedTask(
    174       FROM_HERE,
    175       base::MessageLoop::QuitClosure(),
    176       base::TimeDelta::FromMilliseconds(690));
    177   message_loop.Run();
    178   EXPECT_GE(test_callback.callback_count(), 1);
    179   EXPECT_FALSE(test_callback.had_error());
    180 
    181   ais->Stop();
    182   ais->Close();
    183 }
    184 
    185 }  // namespace media
    186