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.
5 // MSVC++ requires this to be set before any other includes to get M_PI.
6 #define _USE_MATH_DEFINES
10 #include "base/bind_helpers.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/memory/scoped_vector.h"
13 #include "base/synchronization/waitable_event.h"
14 #include "base/threading/platform_thread.h"
15 #include "media/base/audio_renderer_mixer.h"
16 #include "media/base/audio_renderer_mixer_input.h"
17 #include "media/base/fake_audio_render_callback.h"
18 #include "media/base/mock_audio_renderer_sink.h"
19 #include "testing/gmock/include/gmock/gmock.h"
20 #include "testing/gtest/include/gtest/gtest.h"
24 // Parameters which control the many input case tests.
25 const int kMixerInputs
= 8;
26 const int kMixerCycles
= 3;
28 // Parameters used for testing.
29 const int kBitsPerChannel
= 32;
30 const ChannelLayout kChannelLayout
= CHANNEL_LAYOUT_STEREO
;
31 const int kHighLatencyBufferSize
= 8192;
32 const int kLowLatencyBufferSize
= 256;
34 // Number of full sine wave cycles for each Render() call.
35 const int kSineCycles
= 4;
37 // Tuple of <input sampling rate, output sampling rate, epsilon>.
38 typedef std::tr1::tuple
<int, int, double> AudioRendererMixerTestData
;
39 class AudioRendererMixerTest
40 : public testing::TestWithParam
<AudioRendererMixerTestData
> {
42 AudioRendererMixerTest()
43 : epsilon_(std::tr1::get
<2>(GetParam())),
45 // Create input and output parameters based on test parameters.
46 input_parameters_
= AudioParameters(
47 AudioParameters::AUDIO_PCM_LINEAR
, kChannelLayout
,
48 std::tr1::get
<0>(GetParam()), kBitsPerChannel
, kHighLatencyBufferSize
);
49 output_parameters_
= AudioParameters(
50 AudioParameters::AUDIO_PCM_LOW_LATENCY
, kChannelLayout
,
51 std::tr1::get
<1>(GetParam()), 16, kLowLatencyBufferSize
);
53 sink_
= new MockAudioRendererSink();
54 EXPECT_CALL(*sink_
.get(), Start());
55 EXPECT_CALL(*sink_
.get(), Stop());
57 mixer_
.reset(new AudioRendererMixer(
58 input_parameters_
, output_parameters_
, sink_
));
59 mixer_callback_
= sink_
->callback();
61 audio_bus_
= AudioBus::Create(output_parameters_
);
62 expected_audio_bus_
= AudioBus::Create(output_parameters_
);
64 // Allocate one callback for generating expected results.
65 double step
= kSineCycles
/ static_cast<double>(
66 output_parameters_
.frames_per_buffer());
67 expected_callback_
.reset(new FakeAudioRenderCallback(step
));
70 AudioRendererMixer
* GetMixer(const AudioParameters
& params
) {
74 MOCK_METHOD1(RemoveMixer
, void(const AudioParameters
&));
76 void InitializeInputs(int count
) {
77 mixer_inputs_
.reserve(count
);
78 fake_callbacks_
.reserve(count
);
80 // Setup FakeAudioRenderCallback step to compensate for resampling.
81 double scale_factor
= input_parameters_
.sample_rate() /
82 static_cast<double>(output_parameters_
.sample_rate());
83 double step
= kSineCycles
/ (scale_factor
*
84 static_cast<double>(output_parameters_
.frames_per_buffer()));
86 for (int i
= 0; i
< count
; ++i
) {
87 fake_callbacks_
.push_back(new FakeAudioRenderCallback(step
));
88 mixer_inputs_
.push_back(new AudioRendererMixerInput(
89 base::Bind(&AudioRendererMixerTest::GetMixer
,
90 base::Unretained(this)),
91 base::Bind(&AudioRendererMixerTest::RemoveMixer
,
92 base::Unretained(this))));
93 mixer_inputs_
[i
]->Initialize(input_parameters_
, fake_callbacks_
[i
]);
94 mixer_inputs_
[i
]->SetVolume(1.0f
);
96 EXPECT_CALL(*this, RemoveMixer(testing::_
)).Times(count
);
99 bool ValidateAudioData(int index
, int frames
, float scale
, double epsilon
) {
100 for (int i
= 0; i
< audio_bus_
->channels(); ++i
) {
101 for (int j
= index
; j
< frames
; j
++) {
102 double error
= fabs(audio_bus_
->channel(i
)[j
] -
103 expected_audio_bus_
->channel(i
)[j
] * scale
);
104 if (error
> epsilon
) {
105 EXPECT_NEAR(expected_audio_bus_
->channel(i
)[j
] * scale
,
106 audio_bus_
->channel(i
)[j
], epsilon
)
107 << " i=" << i
<< ", j=" << j
;
115 bool ValidateAudioData(int index
, int frames
, float scale
) {
116 return ValidateAudioData(index
, frames
, scale
, epsilon_
);
119 bool RenderAndValidateAudioData(float scale
) {
121 for (size_t i
= 0; i
< fake_callbacks_
.size(); ++i
)
122 fake_callbacks_
[i
]->set_half_fill(true);
123 expected_callback_
->set_half_fill(true);
124 // Initialize the AudioBus completely or we'll run into Valgrind problems
125 // during the verification step below.
126 expected_audio_bus_
->Zero();
129 // Render actual audio data.
130 int frames
= mixer_callback_
->Render(audio_bus_
.get(), 0);
131 if (frames
!= audio_bus_
->frames())
134 // Render expected audio data (without scaling).
135 expected_callback_
->Render(expected_audio_bus_
.get(), 0);
138 // In this case, just verify that every frame was initialized, this will
139 // only fail under tooling such as valgrind.
140 return ValidateAudioData(
141 0, frames
, 0, std::numeric_limits
<double>::max());
143 return ValidateAudioData(0, frames
, scale
);
147 // Fill |audio_bus_| fully with |value|.
148 void FillAudioData(float value
) {
149 for (int i
= 0; i
< audio_bus_
->channels(); ++i
) {
150 std::fill(audio_bus_
->channel(i
),
151 audio_bus_
->channel(i
) + audio_bus_
->frames(), value
);
155 // Verify silence when mixer inputs are in pre-Start() and post-Start().
156 void StartTest(int inputs
) {
157 InitializeInputs(inputs
);
159 // Verify silence before any inputs have been started. Fill the buffer
160 // before hand with non-zero data to ensure we get zeros back.
162 EXPECT_TRUE(RenderAndValidateAudioData(0.0f
));
164 // Start() all even numbered mixer inputs and ensure we still get silence.
165 for (size_t i
= 0; i
< mixer_inputs_
.size(); i
+= 2)
166 mixer_inputs_
[i
]->Start();
168 EXPECT_TRUE(RenderAndValidateAudioData(0.0f
));
170 // Start() all mixer inputs and ensure we still get silence.
171 for (size_t i
= 1; i
< mixer_inputs_
.size(); i
+= 2)
172 mixer_inputs_
[i
]->Start();
174 EXPECT_TRUE(RenderAndValidateAudioData(0.0f
));
176 for (size_t i
= 0; i
< mixer_inputs_
.size(); ++i
)
177 mixer_inputs_
[i
]->Stop();
180 // Verify output when mixer inputs are in post-Play() state.
181 void PlayTest(int inputs
) {
182 InitializeInputs(inputs
);
184 // Play() all mixer inputs and ensure we get the right values.
185 for (size_t i
= 0; i
< mixer_inputs_
.size(); ++i
) {
186 mixer_inputs_
[i
]->Start();
187 mixer_inputs_
[i
]->Play();
190 for (int i
= 0; i
< kMixerCycles
; ++i
)
191 ASSERT_TRUE(RenderAndValidateAudioData(mixer_inputs_
.size()));
193 for (size_t i
= 0; i
< mixer_inputs_
.size(); ++i
)
194 mixer_inputs_
[i
]->Stop();
197 // Verify volume adjusted output when mixer inputs are in post-Play() state.
198 void PlayVolumeAdjustedTest(int inputs
) {
199 InitializeInputs(inputs
);
201 for (size_t i
= 0; i
< mixer_inputs_
.size(); ++i
) {
202 mixer_inputs_
[i
]->Start();
203 mixer_inputs_
[i
]->Play();
206 // Set a different volume for each mixer input and verify the results.
207 float total_scale
= 0;
208 for (size_t i
= 0; i
< mixer_inputs_
.size(); ++i
) {
209 float volume
= static_cast<float>(i
) / mixer_inputs_
.size();
210 total_scale
+= volume
;
211 EXPECT_TRUE(mixer_inputs_
[i
]->SetVolume(volume
));
213 for (int i
= 0; i
< kMixerCycles
; ++i
)
214 ASSERT_TRUE(RenderAndValidateAudioData(total_scale
));
216 for (size_t i
= 0; i
< mixer_inputs_
.size(); ++i
)
217 mixer_inputs_
[i
]->Stop();
220 // Verify output when mixer inputs can only partially fulfill a Render().
221 void PlayPartialRenderTest(int inputs
) {
222 InitializeInputs(inputs
);
224 for (size_t i
= 0; i
< mixer_inputs_
.size(); ++i
) {
225 mixer_inputs_
[i
]->Start();
226 mixer_inputs_
[i
]->Play();
229 // Verify a properly filled buffer when half filled (remainder zeroed).
231 ASSERT_TRUE(RenderAndValidateAudioData(mixer_inputs_
.size()));
233 for (size_t i
= 0; i
< mixer_inputs_
.size(); ++i
)
234 mixer_inputs_
[i
]->Stop();
237 // Verify output when mixer inputs are in Pause() state.
238 void PauseTest(int inputs
) {
239 InitializeInputs(inputs
);
241 for (size_t i
= 0; i
< mixer_inputs_
.size(); ++i
) {
242 mixer_inputs_
[i
]->Start();
243 mixer_inputs_
[i
]->Play();
246 // Pause() all even numbered mixer inputs and ensure we get the right value.
247 for (size_t i
= 0; i
< mixer_inputs_
.size(); i
+= 2)
248 mixer_inputs_
[i
]->Pause();
249 for (int i
= 0; i
< kMixerCycles
; ++i
)
250 ASSERT_TRUE(RenderAndValidateAudioData(mixer_inputs_
.size() / 2));
252 for (size_t i
= 0; i
< mixer_inputs_
.size(); ++i
)
253 mixer_inputs_
[i
]->Stop();
256 // Verify output when mixer inputs are in post-Stop() state.
257 void StopTest(int inputs
) {
258 InitializeInputs(inputs
);
260 // Start() and Stop() all inputs.
261 for (size_t i
= 0; i
< mixer_inputs_
.size(); ++i
) {
262 mixer_inputs_
[i
]->Start();
263 mixer_inputs_
[i
]->Stop();
266 // Verify we get silence back; fill |audio_bus_| before hand to be sure.
268 EXPECT_TRUE(RenderAndValidateAudioData(0.0f
));
272 virtual ~AudioRendererMixerTest() {}
274 scoped_refptr
<MockAudioRendererSink
> sink_
;
275 scoped_ptr
<AudioRendererMixer
> mixer_
;
276 AudioRendererSink::RenderCallback
* mixer_callback_
;
277 AudioParameters input_parameters_
;
278 AudioParameters output_parameters_
;
279 scoped_ptr
<AudioBus
> audio_bus_
;
280 scoped_ptr
<AudioBus
> expected_audio_bus_
;
281 std::vector
< scoped_refptr
<AudioRendererMixerInput
> > mixer_inputs_
;
282 ScopedVector
<FakeAudioRenderCallback
> fake_callbacks_
;
283 scoped_ptr
<FakeAudioRenderCallback
> expected_callback_
;
287 DISALLOW_COPY_AND_ASSIGN(AudioRendererMixerTest
);
290 class AudioRendererMixerBehavioralTest
: public AudioRendererMixerTest
{};
292 ACTION_P(SignalEvent
, event
) {
296 // Verify a mixer with no inputs returns silence for all requested frames.
297 TEST_P(AudioRendererMixerTest
, NoInputs
) {
299 EXPECT_TRUE(RenderAndValidateAudioData(0.0f
));
302 // Test mixer output with one input in the pre-Start() and post-Start() state.
303 TEST_P(AudioRendererMixerTest
, OneInputStart
) {
307 // Test mixer output with many inputs in the pre-Start() and post-Start() state.
308 TEST_P(AudioRendererMixerTest
, ManyInputStart
) {
309 StartTest(kMixerInputs
);
312 // Test mixer output with one input in the post-Play() state.
313 TEST_P(AudioRendererMixerTest
, OneInputPlay
) {
317 // Test mixer output with many inputs in the post-Play() state.
318 TEST_P(AudioRendererMixerTest
, ManyInputPlay
) {
319 PlayTest(kMixerInputs
);
322 // Test volume adjusted mixer output with one input in the post-Play() state.
323 TEST_P(AudioRendererMixerTest
, OneInputPlayVolumeAdjusted
) {
324 PlayVolumeAdjustedTest(1);
327 // Test volume adjusted mixer output with many inputs in the post-Play() state.
328 TEST_P(AudioRendererMixerTest
, ManyInputPlayVolumeAdjusted
) {
329 PlayVolumeAdjustedTest(kMixerInputs
);
332 // Test mixer output with one input and partial Render() in post-Play() state.
333 TEST_P(AudioRendererMixerTest
, OneInputPlayPartialRender
) {
334 PlayPartialRenderTest(1);
337 // Test mixer output with many inputs and partial Render() in post-Play() state.
338 TEST_P(AudioRendererMixerTest
, ManyInputPlayPartialRender
) {
339 PlayPartialRenderTest(kMixerInputs
);
342 // Test mixer output with one input in the post-Pause() state.
343 TEST_P(AudioRendererMixerTest
, OneInputPause
) {
347 // Test mixer output with many inputs in the post-Pause() state.
348 TEST_P(AudioRendererMixerTest
, ManyInputPause
) {
349 PauseTest(kMixerInputs
);
352 // Test mixer output with one input in the post-Stop() state.
353 TEST_P(AudioRendererMixerTest
, OneInputStop
) {
357 // Test mixer output with many inputs in the post-Stop() state.
358 TEST_P(AudioRendererMixerTest
, ManyInputStop
) {
359 StopTest(kMixerInputs
);
362 // Test mixer with many inputs in mixed post-Stop() and post-Play() states.
363 TEST_P(AudioRendererMixerTest
, ManyInputMixedStopPlay
) {
364 InitializeInputs(kMixerInputs
);
366 // Start() all inputs.
367 for (size_t i
= 0; i
< mixer_inputs_
.size(); ++i
)
368 mixer_inputs_
[i
]->Start();
370 // Stop() all even numbered mixer inputs and Play() all odd numbered inputs
371 // and ensure we get the right value.
372 for (size_t i
= 1; i
< mixer_inputs_
.size(); i
+= 2) {
373 mixer_inputs_
[i
- 1]->Stop();
374 mixer_inputs_
[i
]->Play();
376 ASSERT_TRUE(RenderAndValidateAudioData(std::max(
377 mixer_inputs_
.size() / 2, static_cast<size_t>(1))));
379 for (size_t i
= 1; i
< mixer_inputs_
.size(); i
+= 2)
380 mixer_inputs_
[i
]->Stop();
383 TEST_P(AudioRendererMixerBehavioralTest
, OnRenderError
) {
384 InitializeInputs(kMixerInputs
);
385 for (size_t i
= 0; i
< mixer_inputs_
.size(); ++i
) {
386 mixer_inputs_
[i
]->Start();
387 mixer_inputs_
[i
]->Play();
388 EXPECT_CALL(*fake_callbacks_
[i
], OnRenderError()).Times(1);
391 mixer_callback_
->OnRenderError();
392 for (size_t i
= 0; i
< mixer_inputs_
.size(); ++i
)
393 mixer_inputs_
[i
]->Stop();
396 TEST_P(AudioRendererMixerBehavioralTest
, OnRenderErrorPausedInput
) {
397 InitializeInputs(kMixerInputs
);
399 for (size_t i
= 0; i
< mixer_inputs_
.size(); ++i
) {
400 mixer_inputs_
[i
]->Start();
401 EXPECT_CALL(*fake_callbacks_
[i
], OnRenderError()).Times(1);
404 // Fire the error before attaching any inputs. Ensure an error is recieved
405 // even if the input is not connected.
406 mixer_callback_
->OnRenderError();
408 for (size_t i
= 0; i
< mixer_inputs_
.size(); ++i
)
409 mixer_inputs_
[i
]->Stop();
412 // Ensure constructing an AudioRendererMixerInput, but not initializing it does
413 // not call RemoveMixer().
414 TEST_P(AudioRendererMixerBehavioralTest
, NoInitialize
) {
415 EXPECT_CALL(*this, RemoveMixer(testing::_
)).Times(0);
416 scoped_refptr
<AudioRendererMixerInput
> audio_renderer_mixer
=
417 new AudioRendererMixerInput(
418 base::Bind(&AudioRendererMixerTest::GetMixer
,
419 base::Unretained(this)),
420 base::Bind(&AudioRendererMixerTest::RemoveMixer
,
421 base::Unretained(this)));
424 // Ensure the physical stream is paused after a certain amount of time with no
425 // inputs playing. The test will hang if the behavior is incorrect.
426 TEST_P(AudioRendererMixerBehavioralTest
, MixerPausesStream
) {
427 const base::TimeDelta kPauseTime
= base::TimeDelta::FromMilliseconds(500);
428 // This value can't be too low or valgrind, tsan will timeout on the bots.
429 const base::TimeDelta kTestTimeout
= 10 * kPauseTime
;
430 mixer_
->set_pause_delay_for_testing(kPauseTime
);
432 base::WaitableEvent
pause_event(true, false);
433 EXPECT_CALL(*sink_
.get(), Pause()).Times(2)
434 .WillRepeatedly(SignalEvent(&pause_event
));
437 // Ensure never playing the input results in a sink pause.
438 const base::TimeDelta kSleepTime
= base::TimeDelta::FromMilliseconds(100);
439 base::TimeTicks start_time
= base::TimeTicks::Now();
440 while (!pause_event
.IsSignaled()) {
441 mixer_callback_
->Render(audio_bus_
.get(), 0);
442 base::PlatformThread::Sleep(kSleepTime
);
443 ASSERT_TRUE(base::TimeTicks::Now() - start_time
< kTestTimeout
);
447 // Playing the input for the first time should cause a sink play.
448 mixer_inputs_
[0]->Start();
449 EXPECT_CALL(*sink_
.get(), Play());
450 mixer_inputs_
[0]->Play();
451 mixer_inputs_
[0]->Pause();
453 // Ensure once the input is paused the sink eventually pauses.
454 start_time
= base::TimeTicks::Now();
455 while (!pause_event
.IsSignaled()) {
456 mixer_callback_
->Render(audio_bus_
.get(), 0);
457 base::PlatformThread::Sleep(kSleepTime
);
458 ASSERT_TRUE(base::TimeTicks::Now() - start_time
< kTestTimeout
);
461 mixer_inputs_
[0]->Stop();
464 INSTANTIATE_TEST_CASE_P(
465 AudioRendererMixerTest
, AudioRendererMixerTest
, testing::Values(
467 std::tr1::make_tuple(44100, 44100, 0.00000048),
470 std::tr1::make_tuple(44100, 48000, 0.033),
473 std::tr1::make_tuple(48000, 41000, 0.042)));
475 // Test cases for behavior which is independent of parameters. Values() doesn't
476 // support single item lists and we don't want these test cases to run for every
478 INSTANTIATE_TEST_CASE_P(
479 AudioRendererMixerBehavioralTest
, AudioRendererMixerBehavioralTest
,
480 testing::ValuesIn(std::vector
<AudioRendererMixerTestData
>(
481 1, std::tr1::make_tuple(44100, 44100, 0))));