OLD | NEW |
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 // MSVC++ requires this to be set before any other includes to get M_PI. | 5 // MSVC++ requires this to be set before any other includes to get M_PI. |
6 #define _USE_MATH_DEFINES | 6 #define _USE_MATH_DEFINES |
7 #include <cmath> | 7 #include <cmath> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
184 std::tr1::get<1>(GetParam()), 16, kLowLatencyBufferSize); | 184 std::tr1::get<1>(GetParam()), 16, kLowLatencyBufferSize); |
185 | 185 |
186 sink_ = new MockAudioRendererSink(); | 186 sink_ = new MockAudioRendererSink(); |
187 EXPECT_CALL(*sink_, Start()); | 187 EXPECT_CALL(*sink_, Start()); |
188 EXPECT_CALL(*sink_, Stop()); | 188 EXPECT_CALL(*sink_, Stop()); |
189 | 189 |
190 mixer_.reset(new AudioRendererMixer( | 190 mixer_.reset(new AudioRendererMixer( |
191 input_parameters_, output_parameters_, sink_)); | 191 input_parameters_, output_parameters_, sink_)); |
192 mixer_callback_ = sink_->callback(); | 192 mixer_callback_ = sink_->callback(); |
193 | 193 |
194 // TODO(dalecurtis): If we switch to AVX/SSE optimization, we'll need to | 194 audio_bus_ = AudioBus::Create(output_parameters_); |
195 // allocate these on 32-byte boundaries and ensure they're sized % 32 bytes. | 195 expected_audio_bus_ = AudioBus::Create(output_parameters_); |
196 audio_data_.reserve(output_parameters_.channels()); | |
197 for (int i = 0; i < output_parameters_.channels(); ++i) | |
198 audio_data_.push_back(new float[output_parameters_.frames_per_buffer()]); | |
199 | |
200 // TODO(dalecurtis): If we switch to AVX/SSE optimization, we'll need to | |
201 // allocate these on 32-byte boundaries and ensure they're sized % 32 bytes. | |
202 expected_audio_data_.reserve(output_parameters_.channels()); | |
203 for (int i = 0; i < output_parameters_.channels(); ++i) { | |
204 expected_audio_data_.push_back( | |
205 new float[output_parameters_.frames_per_buffer()]); | |
206 } | |
207 | 196 |
208 // Allocate one callback for generating expected results. | 197 // Allocate one callback for generating expected results. |
209 double step = kSineCycles / static_cast<double>( | 198 double step = kSineCycles / static_cast<double>( |
210 output_parameters_.frames_per_buffer()); | 199 output_parameters_.frames_per_buffer()); |
211 expected_callback_.reset(new FakeAudioRenderCallback(step)); | 200 expected_callback_.reset(new FakeAudioRenderCallback(step)); |
212 } | 201 } |
213 | 202 |
214 AudioRendererMixer* GetMixer(const AudioParameters& params) { | 203 AudioRendererMixer* GetMixer(const AudioParameters& params) { |
215 return mixer_.get(); | 204 return mixer_.get(); |
216 } | 205 } |
(...skipping 17 matching lines...) Expand all Loading... |
234 base::Unretained(this)), | 223 base::Unretained(this)), |
235 base::Bind(&AudioRendererMixerTest::RemoveMixer, | 224 base::Bind(&AudioRendererMixerTest::RemoveMixer, |
236 base::Unretained(this)))); | 225 base::Unretained(this)))); |
237 mixer_inputs_[i]->Initialize(input_parameters_, fake_callbacks_[i]); | 226 mixer_inputs_[i]->Initialize(input_parameters_, fake_callbacks_[i]); |
238 mixer_inputs_[i]->SetVolume(1.0f); | 227 mixer_inputs_[i]->SetVolume(1.0f); |
239 } | 228 } |
240 EXPECT_CALL(*this, RemoveMixer(testing::_)).Times(count); | 229 EXPECT_CALL(*this, RemoveMixer(testing::_)).Times(count); |
241 } | 230 } |
242 | 231 |
243 bool ValidateAudioData(int index, int frames, float scale) { | 232 bool ValidateAudioData(int index, int frames, float scale) { |
244 for (size_t i = 0; i < audio_data_.size(); ++i) { | 233 for (int i = 0; i < audio_bus_->channels(); ++i) { |
245 for (int j = index; j < frames; j++) { | 234 for (int j = index; j < frames; j++) { |
246 double error = fabs( | 235 double error = fabs(audio_bus_->channel(i)[j] - |
247 audio_data_[i][j] - expected_audio_data_[i][j] * scale); | 236 expected_audio_bus_->channel(i)[j] * scale); |
248 if (error > epsilon_) { | 237 if (error > epsilon_) { |
249 EXPECT_NEAR( | 238 EXPECT_NEAR(expected_audio_bus_->channel(i)[j] * scale, |
250 expected_audio_data_[i][j] * scale, audio_data_[i][j], epsilon_) | 239 audio_bus_->channel(i)[j], epsilon_) |
251 << " i=" << i << ", j=" << j; | 240 << " i=" << i << ", j=" << j; |
252 return false; | 241 return false; |
253 } | 242 } |
254 } | 243 } |
255 } | 244 } |
256 return true; | 245 return true; |
257 } | 246 } |
258 | 247 |
259 bool RenderAndValidateAudioData(float scale) { | 248 bool RenderAndValidateAudioData(float scale) { |
260 int request_frames = output_parameters_.frames_per_buffer(); | |
261 | |
262 // Half fill won't be exactly half when resampling since the resampler | 249 // Half fill won't be exactly half when resampling since the resampler |
263 // will have enough data to fill out more of the buffer based on its | 250 // will have enough data to fill out more of the buffer based on its |
264 // internal buffer and kernel size. So special case some of the checks. | 251 // internal buffer and kernel size. So special case some of the checks. |
265 bool resampling = input_parameters_.sample_rate() | 252 bool resampling = input_parameters_.sample_rate() |
266 != output_parameters_.sample_rate(); | 253 != output_parameters_.sample_rate(); |
267 | 254 |
268 if (half_fill_) { | 255 if (half_fill_) { |
269 for (size_t i = 0; i < fake_callbacks_.size(); ++i) | 256 for (size_t i = 0; i < fake_callbacks_.size(); ++i) |
270 fake_callbacks_[i]->set_half_fill(true); | 257 fake_callbacks_[i]->set_half_fill(true); |
271 expected_callback_->set_half_fill(true); | 258 expected_callback_->set_half_fill(true); |
272 for (size_t i = 0; i < expected_audio_data_.size(); ++i) { | 259 expected_audio_bus_->Zero(); |
273 memset(expected_audio_data_[i], 0, | |
274 sizeof(*expected_audio_data_[i]) * request_frames); | |
275 } | |
276 } | 260 } |
277 | 261 |
278 // Render actual audio data. | 262 // Render actual audio data. |
279 int frames = mixer_callback_->Render(audio_data_, request_frames, 0); | 263 int frames = mixer_callback_->Render(audio_bus_.get(), 0); |
280 if (frames != request_frames) | 264 if (frames != audio_bus_->frames()) |
281 return false; | 265 return false; |
282 | 266 |
283 // Render expected audio data (without scaling). | 267 // Render expected audio data (without scaling). |
284 expected_callback_->Render(expected_audio_data_, request_frames, 0); | 268 expected_callback_->Render(expected_audio_bus_.get(), 0); |
285 | 269 |
286 if (half_fill_) { | 270 if (half_fill_) { |
287 // Verify first half of audio data for both resampling and non-resampling. | 271 // Verify first half of audio data for both resampling and non-resampling. |
288 if (!ValidateAudioData(0, frames / 2, scale)) | 272 if (!ValidateAudioData(0, frames / 2, scale)) |
289 return false; | 273 return false; |
290 // Verify silence in the second half if we're not resampling. | 274 // Verify silence in the second half if we're not resampling. |
291 if (!resampling) | 275 if (!resampling) |
292 return ValidateAudioData(frames / 2, frames, 0); | 276 return ValidateAudioData(frames / 2, frames, 0); |
293 return true; | 277 return true; |
294 } else { | 278 } else { |
295 return ValidateAudioData(0, frames, scale); | 279 return ValidateAudioData(0, frames, scale); |
296 } | 280 } |
297 } | 281 } |
298 | 282 |
299 // Fill |audio_data_| fully with |value|. | 283 // Fill |audio_bus_| fully with |value|. |
300 void FillAudioData(float value) { | 284 void FillAudioData(float value) { |
301 for (size_t i = 0; i < audio_data_.size(); ++i) | 285 for (int i = 0; i < audio_bus_->channels(); ++i) { |
302 std::fill(audio_data_[i], | 286 std::fill(audio_bus_->channel(i), |
303 audio_data_[i] + output_parameters_.frames_per_buffer(), value); | 287 audio_bus_->channel(i) + audio_bus_->frames(), value); |
| 288 } |
304 } | 289 } |
305 | 290 |
306 // Verify silence when mixer inputs are in pre-Start() and post-Start(). | 291 // Verify silence when mixer inputs are in pre-Start() and post-Start(). |
307 void StartTest(int inputs) { | 292 void StartTest(int inputs) { |
308 InitializeInputs(inputs); | 293 InitializeInputs(inputs); |
309 | 294 |
310 // Verify silence before any inputs have been started. Fill the buffer | 295 // Verify silence before any inputs have been started. Fill the buffer |
311 // before hand with non-zero data to ensure we get zeros back. | 296 // before hand with non-zero data to ensure we get zeros back. |
312 FillAudioData(1.0f); | 297 FillAudioData(1.0f); |
313 EXPECT_TRUE(RenderAndValidateAudioData(0.0f)); | 298 EXPECT_TRUE(RenderAndValidateAudioData(0.0f)); |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
407 // Verify output when mixer inputs are in post-Stop() state. | 392 // Verify output when mixer inputs are in post-Stop() state. |
408 void StopTest(int inputs) { | 393 void StopTest(int inputs) { |
409 InitializeInputs(inputs); | 394 InitializeInputs(inputs); |
410 | 395 |
411 // Start() and Stop() all inputs. | 396 // Start() and Stop() all inputs. |
412 for (size_t i = 0; i < mixer_inputs_.size(); ++i) { | 397 for (size_t i = 0; i < mixer_inputs_.size(); ++i) { |
413 mixer_inputs_[i]->Start(); | 398 mixer_inputs_[i]->Start(); |
414 mixer_inputs_[i]->Stop(); | 399 mixer_inputs_[i]->Stop(); |
415 } | 400 } |
416 | 401 |
417 // Verify we get silence back; fill |audio_data_| before hand to be sure. | 402 // Verify we get silence back; fill |audio_bus_| before hand to be sure. |
418 FillAudioData(1.0f); | 403 FillAudioData(1.0f); |
419 EXPECT_TRUE(RenderAndValidateAudioData(0.0f)); | 404 EXPECT_TRUE(RenderAndValidateAudioData(0.0f)); |
420 } | 405 } |
421 | 406 |
422 protected: | 407 protected: |
423 virtual ~AudioRendererMixerTest() { | 408 virtual ~AudioRendererMixerTest() {} |
424 for (size_t i = 0; i < audio_data_.size(); ++i) | |
425 delete [] audio_data_[i]; | |
426 for (size_t i = 0; i < expected_audio_data_.size(); ++i) | |
427 delete [] expected_audio_data_[i]; | |
428 } | |
429 | 409 |
430 scoped_refptr<MockAudioRendererSink> sink_; | 410 scoped_refptr<MockAudioRendererSink> sink_; |
431 scoped_ptr<AudioRendererMixer> mixer_; | 411 scoped_ptr<AudioRendererMixer> mixer_; |
432 AudioRendererSink::RenderCallback* mixer_callback_; | 412 AudioRendererSink::RenderCallback* mixer_callback_; |
433 AudioParameters input_parameters_; | 413 AudioParameters input_parameters_; |
434 AudioParameters output_parameters_; | 414 AudioParameters output_parameters_; |
435 std::vector<float*> audio_data_; | 415 scoped_ptr<AudioBus> audio_bus_; |
436 std::vector<float*> expected_audio_data_; | 416 scoped_ptr<AudioBus> expected_audio_bus_; |
437 std::vector< scoped_refptr<AudioRendererMixerInput> > mixer_inputs_; | 417 std::vector< scoped_refptr<AudioRendererMixerInput> > mixer_inputs_; |
438 ScopedVector<FakeAudioRenderCallback> fake_callbacks_; | 418 ScopedVector<FakeAudioRenderCallback> fake_callbacks_; |
439 scoped_ptr<FakeAudioRenderCallback> expected_callback_; | 419 scoped_ptr<FakeAudioRenderCallback> expected_callback_; |
440 double epsilon_; | 420 double epsilon_; |
441 bool half_fill_; | 421 bool half_fill_; |
442 | 422 |
443 DISALLOW_COPY_AND_ASSIGN(AudioRendererMixerTest); | 423 DISALLOW_COPY_AND_ASSIGN(AudioRendererMixerTest); |
444 }; | 424 }; |
445 | 425 |
446 // Verify a mixer with no inputs returns silence for all requested frames. | 426 // Verify a mixer with no inputs returns silence for all requested frames. |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
547 // No resampling. | 527 // No resampling. |
548 std::tr1::make_tuple(44100, 44100, 0.00000048), | 528 std::tr1::make_tuple(44100, 44100, 0.00000048), |
549 | 529 |
550 // Upsampling. | 530 // Upsampling. |
551 std::tr1::make_tuple(44100, 48000, 0.033), | 531 std::tr1::make_tuple(44100, 48000, 0.033), |
552 | 532 |
553 // Downsampling. | 533 // Downsampling. |
554 std::tr1::make_tuple(48000, 41000, 0.042))); | 534 std::tr1::make_tuple(48000, 41000, 0.042))); |
555 | 535 |
556 } // namespace media | 536 } // namespace media |
OLD | NEW |