Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(366)

Side by Side Diff: media/audio/audio_input_unittest.cc

Issue 131503006: Initialization of audio manager for Android is now done on the audio thread (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: now compiles Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « media/audio/android/audio_manager_android.cc ('k') | media/audio/audio_manager_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/basictypes.h" 5 #include "base/basictypes.h"
6 #include "base/environment.h" 6 #include "base/environment.h"
7 #include "base/memory/scoped_ptr.h" 7 #include "base/memory/scoped_ptr.h"
8 #include "base/message_loop/message_loop.h" 8 #include "base/message_loop/message_loop.h"
9 #include "base/synchronization/waitable_event.h"
9 #include "base/threading/platform_thread.h" 10 #include "base/threading/platform_thread.h"
10 #include "media/audio/audio_io.h" 11 #include "media/audio/audio_io.h"
11 #include "media/audio/audio_manager_base.h" 12 #include "media/audio/audio_manager_base.h"
12 #include "testing/gtest/include/gtest/gtest.h" 13 #include "testing/gtest/include/gtest/gtest.h"
13 14
14 namespace media { 15 namespace media {
15 16
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 17 // This class allows to find out if the callbacks are occurring as
20 // expected and if any error has been reported. 18 // expected and if any error has been reported.
21 class TestInputCallback : public AudioInputStream::AudioInputCallback { 19 class TestInputCallback : public AudioInputStream::AudioInputCallback {
22 public: 20 public:
23 explicit TestInputCallback(int max_data_bytes) 21 explicit TestInputCallback()
24 : callback_count_(0), 22 : callback_count_(0),
25 had_error_(0), 23 had_error_(0) {
26 max_data_bytes_(max_data_bytes) {
27 } 24 }
28 virtual void OnData(AudioInputStream* stream, 25 virtual void OnData(AudioInputStream* stream,
29 const uint8* data, 26 const uint8* data,
30 uint32 size, 27 uint32 size,
31 uint32 hardware_delay_bytes, 28 uint32 hardware_delay_bytes,
32 double volume) OVERRIDE { 29 double volume) OVERRIDE {
33 ++callback_count_; 30 ++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 } 31 }
41 virtual void OnError(AudioInputStream* stream) OVERRIDE { 32 virtual void OnError(AudioInputStream* stream) OVERRIDE {
42 ++had_error_; 33 ++had_error_;
43 } 34 }
44 // Returns how many times OnData() has been called. 35 // Returns how many times OnData() has been called.
45 int callback_count() const { 36 int callback_count() const {
46 return callback_count_; 37 return callback_count_;
47 } 38 }
48 // Returns how many times the OnError callback was called. 39 // Returns how many times the OnError callback was called.
49 int had_error() const { 40 int had_error() const {
50 return had_error_; 41 return had_error_;
51 } 42 }
52 43
53 private: 44 private:
54 int callback_count_; 45 int callback_count_;
55 int had_error_; 46 int had_error_;
56 int max_data_bytes_;
57 }; 47 };
58 48
59 static bool CanRunAudioTests(AudioManager* audio_man) { 49 class AudioInputTest : public testing::Test {
60 bool has_input = audio_man->HasAudioInputDevices(); 50 public:
51 AudioInputTest() :
52 message_loop_(base::MessageLoop::TYPE_UI),
53 audio_manager_(AudioManager::CreateForTesting()),
54 audio_input_stream_(NULL) {
55 }
61 56
62 if (!has_input) 57 virtual ~AudioInputTest() {}
63 LOG(WARNING) << "No input devices detected";
64 58
65 return has_input; 59 protected:
66 } 60 AudioManager* audio_manager() { return audio_manager_.get(); }
67 61
68 static AudioInputStream* CreateTestAudioInputStream(AudioManager* audio_man) { 62 bool CanRunAudioTests() {
69 AudioInputStream* ais = audio_man->MakeAudioInputStream( 63 bool has_input = audio_manager()->HasAudioInputDevices();
70 AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_STEREO, 64 LOG_IF(WARNING, !has_input) << "No input devices detected";
71 kSamplingRate, 16, kSamplesPerPacket), 65 return has_input;
72 AudioManagerBase::kDefaultDeviceId); 66 }
73 EXPECT_TRUE(NULL != ais);
74 return ais;
75 }
76 67
77 // Test that AudioInputStream rejects out of range parameters. 68 void MakeAudioInputStreamOnAudioThread() {
78 TEST(AudioInputTest, SanityOnMakeParams) { 69 RunOnAudioThread(
79 scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting()); 70 base::Bind(&AudioInputTest::MakeAudioInputStream,
80 if (!CanRunAudioTests(audio_man.get())) 71 base::Unretained(this)));
81 return; 72 }
82 73
83 AudioParameters::Format fmt = AudioParameters::AUDIO_PCM_LINEAR; 74 void CloseAudioInputStreamOnAudioThread() {
84 EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream( 75 RunOnAudioThread(
85 AudioParameters(fmt, CHANNEL_LAYOUT_7_1, 8000, 16, 76 base::Bind(&AudioInputStream::Close,
86 kSamplesPerPacket), AudioManagerBase::kDefaultDeviceId)); 77 base::Unretained(audio_input_stream_)));
87 EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream( 78 audio_input_stream_ = NULL;
88 AudioParameters(fmt, CHANNEL_LAYOUT_MONO, 1024 * 1024, 16, 79 }
89 kSamplesPerPacket), AudioManagerBase::kDefaultDeviceId)); 80
90 EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream( 81 void OpenAndCloseAudioInputStreamOnAudioThread() {
91 AudioParameters(fmt, CHANNEL_LAYOUT_STEREO, 8000, 80, 82 RunOnAudioThread(
92 kSamplesPerPacket), AudioManagerBase::kDefaultDeviceId)); 83 base::Bind(&AudioInputTest::OpenAndClose,
93 EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream( 84 base::Unretained(this)));
94 AudioParameters(fmt, CHANNEL_LAYOUT_STEREO, 8000, 80, 85 }
95 1000 * kSamplesPerPacket), 86
96 AudioManagerBase::kDefaultDeviceId)); 87 void OpenStopAndCloseAudioInputStreamOnAudioThread() {
97 EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream( 88 RunOnAudioThread(
98 AudioParameters(fmt, CHANNEL_LAYOUT_UNSUPPORTED, 8000, 16, 89 base::Bind(&AudioInputTest::OpenStopAndClose,
99 kSamplesPerPacket), AudioManagerBase::kDefaultDeviceId)); 90 base::Unretained(this)));
100 EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream( 91 }
101 AudioParameters(fmt, CHANNEL_LAYOUT_STEREO, -8000, 16, 92
102 kSamplesPerPacket), AudioManagerBase::kDefaultDeviceId)); 93 void OpenAndStartAudioInputStreamOnAudioThread(
103 EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream( 94 AudioInputStream::AudioInputCallback* sink) {
104 AudioParameters(fmt, CHANNEL_LAYOUT_STEREO, 8000, -16, 95 RunOnAudioThread(
105 kSamplesPerPacket), AudioManagerBase::kDefaultDeviceId)); 96 base::Bind(&AudioInputTest::OpenAndStart,
106 EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream( 97 base::Unretained(this),
107 AudioParameters(fmt, CHANNEL_LAYOUT_STEREO, 8000, 16, -1024), 98 sink));
108 AudioManagerBase::kDefaultDeviceId)); 99 }
109 } 100
101 void StopAndCloseAudioInputStreamOnAudioThread() {
102 RunOnAudioThread(
103 base::Bind(&AudioInputTest::StopAndClose,
104 base::Unretained(this)));
105 }
106
107 void MakeAudioInputStream() {
108 DCHECK(audio_manager()->GetTaskRunner()->BelongsToCurrentThread());
109 AudioParameters params = audio_manager()->GetInputStreamParameters(
110 AudioManagerBase::kDefaultDeviceId);
111 audio_input_stream_ = audio_manager()->MakeAudioInputStream(params,
112 AudioManagerBase::kDefaultDeviceId);
113 EXPECT_TRUE(audio_input_stream_);
114 }
115
116 void OpenAndClose() {
117 DCHECK(audio_manager()->GetTaskRunner()->BelongsToCurrentThread());
118 EXPECT_TRUE(audio_input_stream_->Open());
119 audio_input_stream_->Close();
120 audio_input_stream_ = NULL;
121 }
122
123 void OpenAndStart(AudioInputStream::AudioInputCallback* sink) {
124 DCHECK(audio_manager()->GetTaskRunner()->BelongsToCurrentThread());
125 EXPECT_TRUE(audio_input_stream_->Open());
126 audio_input_stream_->Start(sink);
127 }
128
129 void OpenStopAndClose() {
130 DCHECK(audio_manager()->GetTaskRunner()->BelongsToCurrentThread());
131 EXPECT_TRUE(audio_input_stream_->Open());
132 audio_input_stream_->Stop();
133 audio_input_stream_->Close();
134 audio_input_stream_ = NULL;
135 }
136
137 void StopAndClose() {
138 DCHECK(audio_manager()->GetTaskRunner()->BelongsToCurrentThread());
139 audio_input_stream_->Stop();
140 audio_input_stream_->Close();
141 audio_input_stream_ = NULL;
142 }
143
144 // Synchronously runs the provided callback/closure on the audio thread.
145 void RunOnAudioThread(const base::Closure& closure) {
146 if (!audio_manager()->GetTaskRunner()->BelongsToCurrentThread()) {
147 base::WaitableEvent event(false, false);
148 audio_manager()->GetTaskRunner()->PostTask(
149 FROM_HERE,
150 base::Bind(&AudioInputTest::RunOnAudioThreadImpl,
151 base::Unretained(this),
152 closure,
153 &event));
154 event.Wait();
155 } else {
156 closure.Run();
157 }
158 }
159
160 void RunOnAudioThreadImpl(const base::Closure& closure,
161 base::WaitableEvent* event) {
162 DCHECK(audio_manager()->GetTaskRunner()->BelongsToCurrentThread());
163 closure.Run();
164 event->Signal();
165 }
166
167 base::MessageLoop message_loop_;
168 scoped_ptr<AudioManager> audio_manager_;
169 AudioInputStream* audio_input_stream_;
170
171 private:
172 DISALLOW_COPY_AND_ASSIGN(AudioInputTest);
173 };
110 174
111 // Test create and close of an AudioInputStream without recording audio. 175 // Test create and close of an AudioInputStream without recording audio.
112 TEST(AudioInputTest, CreateAndClose) { 176 TEST_F(AudioInputTest, CreateAndClose) {
113 scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting()); 177 if (!CanRunAudioTests())
114 if (!CanRunAudioTests(audio_man.get()))
115 return; 178 return;
116 AudioInputStream* ais = CreateTestAudioInputStream(audio_man.get()); 179 MakeAudioInputStreamOnAudioThread();
117 ais->Close(); 180 CloseAudioInputStreamOnAudioThread();
118 } 181 }
119 182
120 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY) 183 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
121 // This test is failing on ARM linux: http://crbug.com/238490 184 // This test is failing on ARM linux: http://crbug.com/238490
122 #define MAYBE_OpenAndClose DISABLED_OpenAndClose 185 #define MAYBE_OpenAndClose DISABLED_OpenAndClose
123 #else 186 #else
124 #define MAYBE_OpenAndClose OpenAndClose 187 #define MAYBE_OpenAndClose OpenAndClose
125 #endif 188 #endif
126 // Test create, open and close of an AudioInputStream without recording audio. 189 // Test create, open and close of an AudioInputStream without recording audio.
127 TEST(AudioInputTest, MAYBE_OpenAndClose) { 190 TEST_F(AudioInputTest, MAYBE_OpenAndClose) {
128 scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting()); 191 if (!CanRunAudioTests())
129 if (!CanRunAudioTests(audio_man.get()))
130 return; 192 return;
131 AudioInputStream* ais = CreateTestAudioInputStream(audio_man.get()); 193 MakeAudioInputStreamOnAudioThread();
132 EXPECT_TRUE(ais->Open()); 194 OpenAndCloseAudioInputStreamOnAudioThread();
133 ais->Close();
134 } 195 }
135 196
136 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY) 197 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
137 // This test is failing on ARM linux: http://crbug.com/238490 198 // This test is failing on ARM linux: http://crbug.com/238490
138 #define MAYBE_OpenStopAndClose DISABLED_OpenStopAndClose 199 #define MAYBE_OpenStopAndClose DISABLED_OpenStopAndClose
139 #else 200 #else
140 #define MAYBE_OpenStopAndClose OpenStopAndClose 201 #define MAYBE_OpenStopAndClose OpenStopAndClose
141 #endif 202 #endif
142 // Test create, open, stop and close of an AudioInputStream without recording. 203 // Test create, open, stop and close of an AudioInputStream without recording.
143 TEST(AudioInputTest, MAYBE_OpenStopAndClose) { 204 TEST_F(AudioInputTest, MAYBE_OpenStopAndClose) {
144 scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting()); 205 if (!CanRunAudioTests())
145 if (!CanRunAudioTests(audio_man.get()))
146 return; 206 return;
147 AudioInputStream* ais = CreateTestAudioInputStream(audio_man.get()); 207 MakeAudioInputStreamOnAudioThread();
148 EXPECT_TRUE(ais->Open()); 208 OpenStopAndCloseAudioInputStreamOnAudioThread();
149 ais->Stop();
150 ais->Close();
151 } 209 }
152 210
153 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY) 211 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
154 // This test is failing on ARM linux: http://crbug.com/238490 212 // This test is failing on ARM linux: http://crbug.com/238490
155 #define MAYBE_Record DISABLED_Record 213 #define MAYBE_Record DISABLED_Record
156 #else 214 #else
157 #define MAYBE_Record Record 215 #define MAYBE_Record Record
158 #endif 216 #endif
159 // Test a normal recording sequence using an AudioInputStream. 217 // Test a normal recording sequence using an AudioInputStream.
160 TEST(AudioInputTest, MAYBE_Record) { 218 // Very simple test which starts capturing during half a second and verifies
161 scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting()); 219 // that recording starts.
162 if (!CanRunAudioTests(audio_man.get())) 220 TEST_F(AudioInputTest, MAYBE_Record) {
221 if (!CanRunAudioTests())
163 return; 222 return;
164 base::MessageLoop message_loop; 223 MakeAudioInputStreamOnAudioThread();
165 AudioInputStream* ais = CreateTestAudioInputStream(audio_man.get());
166 EXPECT_TRUE(ais->Open());
167 224
168 TestInputCallback test_callback(kSamplesPerPacket * 4); 225 TestInputCallback test_callback;
169 ais->Start(&test_callback); 226 OpenAndStartAudioInputStreamOnAudioThread(&test_callback);
170 // Verify at least 500ms worth of audio was recorded, after giving sufficient 227
171 // extra time. 228 message_loop_.PostDelayedTask(
172 message_loop.PostDelayedTask(
173 FROM_HERE, 229 FROM_HERE,
174 base::MessageLoop::QuitClosure(), 230 base::MessageLoop::QuitClosure(),
175 base::TimeDelta::FromMilliseconds(690)); 231 base::TimeDelta::FromMilliseconds(500));
176 message_loop.Run(); 232 message_loop_.Run();
177 EXPECT_GE(test_callback.callback_count(), 1); 233 EXPECT_GE(test_callback.callback_count(), 2);
178 EXPECT_FALSE(test_callback.had_error()); 234 EXPECT_FALSE(test_callback.had_error());
179 235
180 ais->Stop(); 236 StopAndCloseAudioInputStreamOnAudioThread();
181 ais->Close();
182 } 237 }
183 238
184 } // namespace media 239 } // namespace media
OLDNEW
« no previous file with comments | « media/audio/android/audio_manager_android.cc ('k') | media/audio/audio_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698