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