OLD | NEW |
---|---|
(Empty) | |
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 <vector> | |
6 | |
7 #include "base/message_loop.h" | |
8 #include "base/synchronization/waitable_event.h" | |
9 #include "media/audio/audio_manager.h" | |
10 #include "media/audio/simple_sources.h" | |
11 #include "media/audio/virtual_audio_input_stream.h" | |
12 #include "testing/gtest/include/gtest/gtest.h" | |
13 | |
14 namespace media { | |
15 | |
16 class MockInputCallback : public AudioInputStream::AudioInputCallback { | |
17 public: | |
18 MockInputCallback() {} | |
19 virtual void OnData(AudioInputStream* stream, const uint8* data, | |
20 uint32 size, uint32 hardware_delay_bytes, | |
21 double volume) {} | |
22 virtual void OnClose(AudioInputStream* stream) {} | |
23 virtual void OnError(AudioInputStream* stream, int code) {} | |
24 | |
25 private: | |
26 DISALLOW_COPY_AND_ASSIGN(MockInputCallback); | |
27 }; | |
28 | |
29 class VirtualAudioInputStreamTest : public testing::Test { | |
30 public: | |
31 VirtualAudioInputStreamTest() | |
32 : audio_manager_(AudioManager::Create()), | |
33 params_(AudioParameters::AUDIO_VIRTUAL, | |
DaleCurtis
2012/12/03 19:27:28
Bad indent.
justinlin
2012/12/03 21:18:42
Done.
| |
34 CHANNEL_LAYOUT_MONO, 8000, 8, 128), | |
35 output_params_(AudioParameters::AUDIO_PCM_LINEAR, | |
36 CHANNEL_LAYOUT_MONO, 8000, 8, 128), | |
DaleCurtis
2012/12/03 19:27:28
Ditto.
justinlin
2012/12/03 21:18:42
Done.
| |
37 stream_(NULL), | |
38 source_(CHANNEL_LAYOUT_STEREO, 200.0, 128), | |
39 done_(false, false) { | |
40 } | |
41 | |
42 void StartStreamAndRunTestsOnAudioThread(int num_output_streams, | |
43 int num_callback_iterations, | |
44 int num_streams_removed_per_round, | |
45 int num_expected_source_callbacks) { | |
46 ASSERT_TRUE(audio_manager_->GetMessageLoop()->BelongsToCurrentThread()); | |
47 stream_->Open(); | |
48 stream_->Start(&input_callback_); | |
49 AddStreamsAndDoCallbacks(num_output_streams, | |
50 num_callback_iterations, | |
51 num_streams_removed_per_round, | |
52 num_expected_source_callbacks); | |
53 } | |
54 | |
55 void AddStreamsAndDoCallbacks(int num_output_streams, | |
56 int num_callback_iterations, | |
57 int num_streams_removed_per_round, | |
58 int num_expected_source_callbacks) { | |
59 ASSERT_TRUE(audio_manager_->GetMessageLoop()->BelongsToCurrentThread()); | |
60 | |
61 for (int i = 0; i < num_output_streams; ++i) { | |
62 AudioOutputStream* output_stream = | |
63 audio_manager_->MakeAudioOutputStream(output_params_); | |
64 DCHECK(output_stream); | |
65 output_streams_.push_back(output_stream); | |
66 | |
67 output_stream->Open(); | |
68 output_stream->Start(&source_); | |
69 } | |
70 | |
71 if (num_streams_removed_per_round > 0) { | |
DaleCurtis
2012/12/03 19:27:28
Do you really want to remove streams on round 0?
justinlin
2012/12/03 21:18:42
Done.
| |
72 AudioOutputStream* output_stream = output_streams_.back(); | |
73 output_streams_.pop_back(); | |
74 output_stream->Stop(); | |
75 output_stream->Close(); | |
76 } | |
77 | |
78 if (num_callback_iterations > 0) { | |
79 // Force the next callback to be immediate. | |
80 stream_->buffer_duration_ms_ = base::TimeDelta::FromMilliseconds(0); | |
DaleCurtis
2012/12/03 19:27:28
Just base::TimeDelta().
justinlin
2012/12/03 21:18:42
Done.
| |
81 audio_manager_->GetMessageLoop()->PostTask(FROM_HERE, base::Bind( | |
82 &VirtualAudioInputStreamTest::AddStreamsAndDoCallbacks, | |
83 base::Unretained(this), 0, --num_callback_iterations, | |
84 num_streams_removed_per_round, num_expected_source_callbacks)); | |
85 } else { | |
86 // Finish the test. | |
87 EXPECT_EQ(num_expected_source_callbacks, source_.callbacks()); | |
88 EXPECT_EQ(0, source_.errors()); | |
89 | |
90 for (std::vector<AudioOutputStream*>::iterator it = | |
91 output_streams_.begin(); it != output_streams_.end(); ++it) { | |
92 (*it)->Stop(); | |
93 } | |
94 | |
95 stream_->Stop(); | |
96 | |
97 audio_manager_->GetMessageLoop()->PostTask(FROM_HERE, | |
98 base::Bind(&VirtualAudioInputStreamTest::EndTest, | |
99 base::Unretained(this))); | |
DaleCurtis
2012/12/03 19:27:28
Bad indent.
justinlin
2012/12/03 21:18:42
Done.
| |
100 } | |
101 } | |
102 | |
103 void OpenAndCloseOnAudioThread() { | |
104 ASSERT_TRUE(audio_manager_->GetMessageLoop()->BelongsToCurrentThread()); | |
105 stream_->Open(); | |
106 | |
107 for (int i = 0; i < 2; ++i) { | |
DaleCurtis
2012/12/03 19:27:28
Explanation + constify?
justinlin
2012/12/03 21:18:42
Done.
| |
108 AudioOutputStream* output_stream = | |
109 audio_manager_->MakeAudioOutputStream(output_params_); | |
110 DCHECK(output_stream); | |
111 output_streams_.push_back(output_stream); | |
112 | |
113 output_stream->Open(); | |
114 } | |
115 | |
116 audio_manager_->GetMessageLoop()->PostTask(FROM_HERE, | |
117 base::Bind(&VirtualAudioInputStreamTest::EndTest, | |
DaleCurtis
2012/12/03 19:27:28
Bad indent.
justinlin
2012/12/03 21:18:42
Done.
| |
118 base::Unretained(this))); | |
119 } | |
120 | |
121 void StartStopOnAudioThread(int num_output_streams, | |
122 int num_callback_iterations, int num_expected_source_callbacks) { | |
DaleCurtis
2012/12/03 19:27:28
Ditto.
justinlin
2012/12/03 21:18:42
Done.
| |
123 ASSERT_TRUE(audio_manager_->GetMessageLoop()->BelongsToCurrentThread()); | |
124 stream_->Open(); | |
125 stream_->Start(&input_callback_); | |
126 StartStopCallback(true, num_output_streams, num_callback_iterations, | |
127 num_expected_source_callbacks); | |
128 } | |
129 | |
130 void StartStopCallback(int init, int num_output_streams, | |
DaleCurtis
2012/12/03 19:27:28
bool init?
justinlin
2012/12/03 21:18:42
Done.
| |
131 int num_callback_iterations, int num_expected_source_callbacks) { | |
DaleCurtis
2012/12/03 19:27:28
Ditto.
justinlin
2012/12/03 21:18:42
Done.
| |
132 ASSERT_TRUE(audio_manager_->GetMessageLoop()->BelongsToCurrentThread()); | |
133 | |
134 if (init) { | |
135 for (int i = 0; i < num_output_streams; ++i) { | |
136 AudioOutputStream* output_stream = | |
137 audio_manager_->MakeAudioOutputStream(output_params_); | |
138 DCHECK(output_stream); | |
139 output_streams_.push_back(output_stream); | |
140 | |
141 output_stream->Open(); | |
142 output_stream->Start(&source_); | |
143 } | |
144 | |
145 // Start with an odd iteration number so we call Stop() first below. | |
146 DCHECK_NE(0, num_callback_iterations % 2); | |
147 } | |
148 | |
149 // Start or stop half the streams. | |
150 for (int i = 0; i < num_output_streams / 2; ++i) { | |
DaleCurtis
2012/12/03 19:27:28
Nothing happens if num_output_streams = 1.
justinlin
2012/12/03 21:18:42
I think that's OK since it's only used by 1 test w
| |
151 if (num_callback_iterations % 2 != 0) | |
152 output_streams_[i]->Stop(); | |
153 else | |
154 output_streams_[i]->Start(&source_); | |
155 } | |
156 | |
157 if (num_callback_iterations > 0) { | |
158 // Force the next callback to be immediate. | |
159 stream_->buffer_duration_ms_ = base::TimeDelta::FromMilliseconds(0); | |
DaleCurtis
2012/12/03 19:27:28
base::TimeDelta()
justinlin
2012/12/03 21:18:42
Done.
| |
160 audio_manager_->GetMessageLoop()->PostTask(FROM_HERE, | |
161 base::Bind(&VirtualAudioInputStreamTest::StartStopCallback, | |
DaleCurtis
2012/12/03 19:27:28
Bad indent. These are everywhere, fix them all ov
justinlin
2012/12/03 21:18:42
Done.
| |
162 base::Unretained(this), false, num_output_streams, | |
163 --num_callback_iterations, num_expected_source_callbacks)); | |
164 } else { | |
165 // Finish the test. | |
166 EXPECT_EQ(num_expected_source_callbacks, source_.callbacks()); | |
167 EXPECT_EQ(0, source_.errors()); | |
168 | |
169 for (std::vector<AudioOutputStream*>::iterator it = | |
170 output_streams_.begin(); it != output_streams_.end(); ++it) { | |
171 (*it)->Stop(); | |
172 } | |
173 | |
174 stream_->Stop(); | |
175 | |
176 audio_manager_->GetMessageLoop()->PostTask(FROM_HERE, | |
177 base::Bind(&VirtualAudioInputStreamTest::EndTest, | |
178 base::Unretained(this))); | |
179 } | |
180 } | |
181 | |
182 void EndTest() { | |
183 for (std::vector<AudioOutputStream*>::iterator it = | |
184 output_streams_.begin(); it != output_streams_.end(); ++it) { | |
185 (*it)->Close(); | |
186 } | |
187 | |
188 stream_->Close(); | |
189 | |
190 done_.Signal(); | |
191 } | |
192 | |
193 protected: | |
194 scoped_ptr<AudioManager> audio_manager_; | |
195 AudioParameters params_; | |
196 AudioParameters output_params_; | |
197 VirtualAudioInputStream* stream_; | |
198 MockInputCallback input_callback_; | |
199 std::vector<AudioOutputStream*> output_streams_; | |
200 SineWaveAudioSource source_; | |
201 base::WaitableEvent done_; | |
202 | |
203 private: | |
204 DISALLOW_COPY_AND_ASSIGN(VirtualAudioInputStreamTest); | |
205 }; | |
206 | |
207 TEST_F(VirtualAudioInputStreamTest, AttachAndDriveSingleStream) { | |
208 stream_ = static_cast<VirtualAudioInputStream*>( | |
209 audio_manager_->MakeAudioInputStream(params_, "1")); | |
210 DCHECK(stream_); | |
211 | |
212 const int num_output_streams = 1; | |
213 const int num_callback_iterations = 1; | |
214 const int num_streams_removed_per_round = 0; | |
215 const int num_expected_source_callbacks = 1; | |
216 | |
217 audio_manager_->GetMessageLoop()->PostTask(FROM_HERE, base::Bind( | |
218 &VirtualAudioInputStreamTest::StartStreamAndRunTestsOnAudioThread, | |
219 base::Unretained(this), | |
220 num_output_streams, num_callback_iterations, | |
221 num_streams_removed_per_round, | |
222 num_expected_source_callbacks)); | |
223 | |
224 done_.Wait(); | |
225 } | |
226 | |
227 TEST_F(VirtualAudioInputStreamTest, AttachAndDriveMultipleStreams) { | |
228 stream_ = static_cast<VirtualAudioInputStream*>( | |
229 audio_manager_->MakeAudioInputStream(params_, "1")); | |
230 DCHECK(stream_); | |
231 | |
232 const int num_output_streams = 5; | |
233 const int num_callback_iterations = 5; | |
234 const int num_streams_removed_per_round = 0; | |
235 const int num_expected_source_callbacks = 25; | |
236 | |
237 audio_manager_->GetMessageLoop()->PostTask(FROM_HERE, base::Bind( | |
238 &VirtualAudioInputStreamTest::StartStreamAndRunTestsOnAudioThread, | |
239 base::Unretained(this), | |
240 num_output_streams, num_callback_iterations, | |
241 num_streams_removed_per_round, | |
242 num_expected_source_callbacks)); | |
243 | |
244 done_.Wait(); | |
245 } | |
246 | |
247 TEST_F(VirtualAudioInputStreamTest, AttachAndRemoveStreams) { | |
248 stream_ = static_cast<VirtualAudioInputStream*>( | |
249 audio_manager_->MakeAudioInputStream(params_, "1")); | |
250 DCHECK(stream_); | |
251 | |
252 const int num_output_streams = 8; | |
253 const int num_callback_iterations = 5; | |
254 const int num_streams_removed_per_round = 1; | |
255 const int num_expected_source_callbacks = 7 + 6 + 5 + 4 + 3; | |
256 | |
257 audio_manager_->GetMessageLoop()->PostTask(FROM_HERE, base::Bind( | |
258 &VirtualAudioInputStreamTest::StartStreamAndRunTestsOnAudioThread, | |
259 base::Unretained(this), | |
260 num_output_streams, num_callback_iterations, | |
261 num_streams_removed_per_round, | |
262 num_expected_source_callbacks)); | |
263 | |
264 done_.Wait(); | |
265 } | |
266 | |
267 // Opens/closes a VirtualAudioInputStream and a number of attached | |
268 // VirtualAudioOutputStreams without calling Start()/Stop(). | |
269 TEST_F(VirtualAudioInputStreamTest, OpenAndClose) { | |
270 stream_ = static_cast<VirtualAudioInputStream*>( | |
271 audio_manager_->MakeAudioInputStream(params_, "1")); | |
272 DCHECK(stream_); | |
273 | |
274 audio_manager_->GetMessageLoop()->PostTask(FROM_HERE, base::Bind( | |
275 &VirtualAudioInputStreamTest::OpenAndCloseOnAudioThread, | |
276 base::Unretained(this))); | |
277 | |
278 done_.Wait(); | |
279 } | |
280 | |
281 // Creates and closes and VirtualAudioInputStream. | |
282 TEST_F(VirtualAudioInputStreamTest, CreateAndClose) { | |
283 stream_ = static_cast<VirtualAudioInputStream*>( | |
284 audio_manager_->MakeAudioInputStream(params_, "1")); | |
285 DCHECK(stream_); | |
286 | |
287 audio_manager_->GetMessageLoop()->PostTask(FROM_HERE, base::Bind( | |
288 &VirtualAudioInputStreamTest::EndTest, | |
289 base::Unretained(this))); | |
290 | |
291 done_.Wait(); | |
292 } | |
293 | |
294 // Starts and stops VirtualAudioOutputStreams while attached to a | |
295 // VirtualAudioInputStream. | |
296 TEST_F(VirtualAudioInputStreamTest, AttachAndStartStopStreams) { | |
297 stream_ = static_cast<VirtualAudioInputStream*>( | |
298 audio_manager_->MakeAudioInputStream(params_, "1")); | |
299 DCHECK(stream_); | |
300 | |
301 const int num_output_streams = 4; | |
302 const int num_callback_iterations = 5; | |
303 const int num_expected_source_callbacks = 2 + 4 + 2 + 4 + 2; | |
304 | |
305 audio_manager_->GetMessageLoop()->PostTask(FROM_HERE, base::Bind( | |
306 &VirtualAudioInputStreamTest::StartStopOnAudioThread, | |
307 base::Unretained(this), num_output_streams, num_callback_iterations, | |
308 num_expected_source_callbacks)); | |
309 | |
310 done_.Wait(); | |
311 } | |
312 | |
313 } // namespace media | |
OLD | NEW |