1 // Copyright (c) 2011 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.
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"
14 static const int kSamplingRate
= 8000;
15 static const int kSamplesPerPacket
= kSamplingRate
/ 20;
17 // This class allows to find out if the callbacks are occurring as
18 // expected and if any error has been reported.
19 class TestInputCallback
: public AudioInputStream::AudioInputCallback
{
21 explicit TestInputCallback(int max_data_bytes
)
25 max_data_bytes_(max_data_bytes
) {
27 virtual void OnData(AudioInputStream
* stream
, const uint8
* data
,
28 uint32 size
, uint32 hardware_delay_bytes
) {
30 // Read the first byte to make sure memory is good.
32 ASSERT_LE(static_cast<int>(size
), max_data_bytes_
);
37 virtual void OnClose(AudioInputStream
* stream
) {
40 virtual void OnError(AudioInputStream
* stream
, int code
) {
43 // Returns how many times OnData() has been called.
44 int callback_count() const {
45 return callback_count_
;
47 // Returns how many times the OnError callback was called.
48 int had_error() const {
52 void set_error(bool error
) {
53 had_error_
+= error
? 1 : 0;
55 // Returns how many times the OnClose callback was called.
56 int was_closed() const {
67 // Specializes TestInputCallback to simulate a sink that blocks for some time
68 // in the OnData callback.
69 class TestInputCallbackBlocking
: public TestInputCallback
{
71 TestInputCallbackBlocking(int max_data_bytes
, int block_after_callback
,
73 : TestInputCallback(max_data_bytes
),
74 block_after_callback_(block_after_callback
),
75 block_for_ms_(block_for_ms
) {
77 virtual void OnData(AudioInputStream
* stream
, const uint8
* data
,
78 uint32 size
, uint32 hardware_delay_bytes
) {
79 // Call the base, which increments the callback_count_.
80 TestInputCallback::OnData(stream
, data
, size
, hardware_delay_bytes
);
81 if (callback_count() > block_after_callback_
)
82 base::PlatformThread::Sleep(block_for_ms_
);
86 int block_after_callback_
;
90 static bool CanRunAudioTests(AudioManager
* audio_man
) {
91 bool has_input
= audio_man
->HasAudioInputDevices();
94 LOG(WARNING
) << "No input devices detected";
99 static AudioInputStream
* CreateTestAudioInputStream(AudioManager
* audio_man
) {
100 AudioInputStream
* ais
= audio_man
->MakeAudioInputStream(
101 AudioParameters(AudioParameters::AUDIO_PCM_LINEAR
, CHANNEL_LAYOUT_STEREO
,
102 kSamplingRate
, 16, kSamplesPerPacket
),
103 AudioManagerBase::kDefaultDeviceId
);
104 EXPECT_TRUE(NULL
!= ais
);
108 // Test that AudioInputStream rejects out of range parameters.
109 TEST(AudioInputTest
, SanityOnMakeParams
) {
110 scoped_refptr
<AudioManager
> audio_man(AudioManager::Create());
111 if (!CanRunAudioTests(audio_man
.get()))
114 AudioParameters::Format fmt
= AudioParameters::AUDIO_PCM_LINEAR
;
115 EXPECT_TRUE(NULL
== audio_man
->MakeAudioInputStream(
116 AudioParameters(fmt
, CHANNEL_LAYOUT_7POINT1
, 8000, 16,
117 kSamplesPerPacket
), AudioManagerBase::kDefaultDeviceId
));
118 EXPECT_TRUE(NULL
== audio_man
->MakeAudioInputStream(
119 AudioParameters(fmt
, CHANNEL_LAYOUT_MONO
, 1024 * 1024, 16,
120 kSamplesPerPacket
), AudioManagerBase::kDefaultDeviceId
));
121 EXPECT_TRUE(NULL
== audio_man
->MakeAudioInputStream(
122 AudioParameters(fmt
, CHANNEL_LAYOUT_STEREO
, 8000, 80,
123 kSamplesPerPacket
), AudioManagerBase::kDefaultDeviceId
));
124 EXPECT_TRUE(NULL
== audio_man
->MakeAudioInputStream(
125 AudioParameters(fmt
, CHANNEL_LAYOUT_STEREO
, 8000, 80,
126 1000 * kSamplesPerPacket
),
127 AudioManagerBase::kDefaultDeviceId
));
128 EXPECT_TRUE(NULL
== audio_man
->MakeAudioInputStream(
129 AudioParameters(fmt
, CHANNEL_LAYOUT_UNSUPPORTED
, 8000, 16,
130 kSamplesPerPacket
), AudioManagerBase::kDefaultDeviceId
));
131 EXPECT_TRUE(NULL
== audio_man
->MakeAudioInputStream(
132 AudioParameters(fmt
, CHANNEL_LAYOUT_STEREO
, -8000, 16,
133 kSamplesPerPacket
), AudioManagerBase::kDefaultDeviceId
));
134 EXPECT_TRUE(NULL
== audio_man
->MakeAudioInputStream(
135 AudioParameters(fmt
, CHANNEL_LAYOUT_STEREO
, 8000, -16,
136 kSamplesPerPacket
), AudioManagerBase::kDefaultDeviceId
));
137 EXPECT_TRUE(NULL
== audio_man
->MakeAudioInputStream(
138 AudioParameters(fmt
, CHANNEL_LAYOUT_STEREO
, 8000, 16, -1024),
139 AudioManagerBase::kDefaultDeviceId
));
142 // Test create and close of an AudioInputStream without recording audio.
143 TEST(AudioInputTest
, CreateAndClose
) {
144 scoped_refptr
<AudioManager
> audio_man(AudioManager::Create());
145 if (!CanRunAudioTests(audio_man
.get()))
147 AudioInputStream
* ais
= CreateTestAudioInputStream(audio_man
.get());
151 // Test create, open and close of an AudioInputStream without recording audio.
152 TEST(AudioInputTest
, OpenAndClose
) {
153 scoped_refptr
<AudioManager
> audio_man(AudioManager::Create());
154 if (!CanRunAudioTests(audio_man
.get()))
156 AudioInputStream
* ais
= CreateTestAudioInputStream(audio_man
.get());
157 EXPECT_TRUE(ais
->Open());
161 // Test create, open, stop and close of an AudioInputStream without recording.
162 TEST(AudioInputTest
, OpenStopAndClose
) {
163 scoped_refptr
<AudioManager
> audio_man(AudioManager::Create());
164 if (!CanRunAudioTests(audio_man
.get()))
166 AudioInputStream
* ais
= CreateTestAudioInputStream(audio_man
.get());
167 EXPECT_TRUE(ais
->Open());
172 // Test a normal recording sequence using an AudioInputStream.
173 TEST(AudioInputTest
, Record
) {
174 scoped_refptr
<AudioManager
> audio_man(AudioManager::Create());
175 if (!CanRunAudioTests(audio_man
.get()))
177 MessageLoop
message_loop(MessageLoop::TYPE_DEFAULT
);
178 AudioInputStream
* ais
= CreateTestAudioInputStream(audio_man
.get());
179 EXPECT_TRUE(ais
->Open());
181 TestInputCallback
test_callback(kSamplesPerPacket
* 4);
182 ais
->Start(&test_callback
);
183 // Verify at least 500ms worth of audio was recorded, after giving sufficient
185 message_loop
.PostDelayedTask(FROM_HERE
, MessageLoop::QuitClosure(), 590);
187 EXPECT_GE(test_callback
.callback_count(), 10);
188 EXPECT_FALSE(test_callback
.had_error());