| 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(); | 249 int request_frames = output_parameters_.frames_per_buffer(); |
| 261 | 250 |
| 262 // Half fill won't be exactly half when resampling since the resampler | 251 // 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 | 252 // 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. | 253 // internal buffer and kernel size. So special case some of the checks. |
| 265 bool resampling = input_parameters_.sample_rate() | 254 bool resampling = input_parameters_.sample_rate() |
| 266 != output_parameters_.sample_rate(); | 255 != output_parameters_.sample_rate(); |
| 267 | 256 |
| 268 if (half_fill_) { | 257 if (half_fill_) { |
| 269 for (size_t i = 0; i < fake_callbacks_.size(); ++i) | 258 for (size_t i = 0; i < fake_callbacks_.size(); ++i) |
| 270 fake_callbacks_[i]->set_half_fill(true); | 259 fake_callbacks_[i]->set_half_fill(true); |
| 271 expected_callback_->set_half_fill(true); | 260 expected_callback_->set_half_fill(true); |
| 272 for (size_t i = 0; i < expected_audio_data_.size(); ++i) { | 261 expected_audio_bus_->Zero(); |
| 273 memset(expected_audio_data_[i], 0, | |
| 274 sizeof(*expected_audio_data_[i]) * request_frames); | |
| 275 } | |
| 276 } | 262 } |
| 277 | 263 |
| 278 // Render actual audio data. | 264 // Render actual audio data. |
| 279 int frames = mixer_callback_->Render(audio_data_, request_frames, 0); | 265 int frames = mixer_callback_->Render(audio_bus_.get(), request_frames, 0); |
| 280 if (frames != request_frames) | 266 if (frames != request_frames) |
| 281 return false; | 267 return false; |
| 282 | 268 |
| 283 // Render expected audio data (without scaling). | 269 // Render expected audio data (without scaling). |
| 284 expected_callback_->Render(expected_audio_data_, request_frames, 0); | 270 expected_callback_->Render(expected_audio_bus_.get(), request_frames, 0); |
| 285 | 271 |
| 286 if (half_fill_) { | 272 if (half_fill_) { |
| 287 // Verify first half of audio data for both resampling and non-resampling. | 273 // Verify first half of audio data for both resampling and non-resampling. |
| 288 if (!ValidateAudioData(0, frames / 2, scale)) | 274 if (!ValidateAudioData(0, frames / 2, scale)) |
| 289 return false; | 275 return false; |
| 290 // Verify silence in the second half if we're not resampling. | 276 // Verify silence in the second half if we're not resampling. |
| 291 if (!resampling) | 277 if (!resampling) |
| 292 return ValidateAudioData(frames / 2, frames, 0); | 278 return ValidateAudioData(frames / 2, frames, 0); |
| 293 return true; | 279 return true; |
| 294 } else { | 280 } else { |
| 295 return ValidateAudioData(0, frames, scale); | 281 return ValidateAudioData(0, frames, scale); |
| 296 } | 282 } |
| 297 } | 283 } |
| 298 | 284 |
| 299 // Fill |audio_data_| fully with |value|. | 285 // Fill |audio_bus_| fully with |value|. |
| 300 void FillAudioData(float value) { | 286 void FillAudioData(float value) { |
| 301 for (size_t i = 0; i < audio_data_.size(); ++i) | 287 for (int i = 0; i < audio_bus_->channels(); ++i) { |
| 302 std::fill(audio_data_[i], | 288 std::fill(audio_bus_->channel(i), |
| 303 audio_data_[i] + output_parameters_.frames_per_buffer(), value); | 289 audio_bus_->channel(i) + audio_bus_->frames(), value); |
| 290 } |
| 304 } | 291 } |
| 305 | 292 |
| 306 // Verify silence when mixer inputs are in pre-Start() and post-Start(). | 293 // Verify silence when mixer inputs are in pre-Start() and post-Start(). |
| 307 void StartTest(int inputs) { | 294 void StartTest(int inputs) { |
| 308 InitializeInputs(inputs); | 295 InitializeInputs(inputs); |
| 309 | 296 |
| 310 // Verify silence before any inputs have been started. Fill the buffer | 297 // Verify silence before any inputs have been started. Fill the buffer |
| 311 // before hand with non-zero data to ensure we get zeros back. | 298 // before hand with non-zero data to ensure we get zeros back. |
| 312 FillAudioData(1.0f); | 299 FillAudioData(1.0f); |
| 313 EXPECT_TRUE(RenderAndValidateAudioData(0.0f)); | 300 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. | 394 // Verify output when mixer inputs are in post-Stop() state. |
| 408 void StopTest(int inputs) { | 395 void StopTest(int inputs) { |
| 409 InitializeInputs(inputs); | 396 InitializeInputs(inputs); |
| 410 | 397 |
| 411 // Start() and Stop() all inputs. | 398 // Start() and Stop() all inputs. |
| 412 for (size_t i = 0; i < mixer_inputs_.size(); ++i) { | 399 for (size_t i = 0; i < mixer_inputs_.size(); ++i) { |
| 413 mixer_inputs_[i]->Start(); | 400 mixer_inputs_[i]->Start(); |
| 414 mixer_inputs_[i]->Stop(); | 401 mixer_inputs_[i]->Stop(); |
| 415 } | 402 } |
| 416 | 403 |
| 417 // Verify we get silence back; fill |audio_data_| before hand to be sure. | 404 // Verify we get silence back; fill |audio_bus_| before hand to be sure. |
| 418 FillAudioData(1.0f); | 405 FillAudioData(1.0f); |
| 419 EXPECT_TRUE(RenderAndValidateAudioData(0.0f)); | 406 EXPECT_TRUE(RenderAndValidateAudioData(0.0f)); |
| 420 } | 407 } |
| 421 | 408 |
| 422 protected: | 409 protected: |
| 423 virtual ~AudioRendererMixerTest() { | 410 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 | 411 |
| 430 scoped_refptr<MockAudioRendererSink> sink_; | 412 scoped_refptr<MockAudioRendererSink> sink_; |
| 431 scoped_ptr<AudioRendererMixer> mixer_; | 413 scoped_ptr<AudioRendererMixer> mixer_; |
| 432 AudioRendererSink::RenderCallback* mixer_callback_; | 414 AudioRendererSink::RenderCallback* mixer_callback_; |
| 433 AudioParameters input_parameters_; | 415 AudioParameters input_parameters_; |
| 434 AudioParameters output_parameters_; | 416 AudioParameters output_parameters_; |
| 435 std::vector<float*> audio_data_; | 417 scoped_ptr<AudioBus> audio_bus_; |
| 436 std::vector<float*> expected_audio_data_; | 418 scoped_ptr<AudioBus> expected_audio_bus_; |
| 437 std::vector< scoped_refptr<AudioRendererMixerInput> > mixer_inputs_; | 419 std::vector< scoped_refptr<AudioRendererMixerInput> > mixer_inputs_; |
| 438 ScopedVector<FakeAudioRenderCallback> fake_callbacks_; | 420 ScopedVector<FakeAudioRenderCallback> fake_callbacks_; |
| 439 scoped_ptr<FakeAudioRenderCallback> expected_callback_; | 421 scoped_ptr<FakeAudioRenderCallback> expected_callback_; |
| 440 double epsilon_; | 422 double epsilon_; |
| 441 bool half_fill_; | 423 bool half_fill_; |
| 442 | 424 |
| 443 DISALLOW_COPY_AND_ASSIGN(AudioRendererMixerTest); | 425 DISALLOW_COPY_AND_ASSIGN(AudioRendererMixerTest); |
| 444 }; | 426 }; |
| 445 | 427 |
| 446 // Verify a mixer with no inputs returns silence for all requested frames. | 428 // 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. | 529 // No resampling. |
| 548 std::tr1::make_tuple(44100, 44100, 0.00000048), | 530 std::tr1::make_tuple(44100, 44100, 0.00000048), |
| 549 | 531 |
| 550 // Upsampling. | 532 // Upsampling. |
| 551 std::tr1::make_tuple(44100, 48000, 0.033), | 533 std::tr1::make_tuple(44100, 48000, 0.033), |
| 552 | 534 |
| 553 // Downsampling. | 535 // Downsampling. |
| 554 std::tr1::make_tuple(48000, 41000, 0.042))); | 536 std::tr1::make_tuple(48000, 41000, 0.042))); |
| 555 | 537 |
| 556 } // namespace media | 538 } // namespace media |
| OLD | NEW |