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 static const int kMixerInputs
= 8;
26 static const int kMixerCycles
= 3;
28 // Parameters used for testing.
29 static const int kBitsPerChannel
= 32;
30 static const ChannelLayout kChannelLayout
= CHANNEL_LAYOUT_STEREO
;
31 static const int kHighLatencyBufferSize
= 8192;
32 static const int kLowLatencyBufferSize
= 256;
33 static const int kSampleRate
= 48000;
35 // Number of full sine wave cycles for each Render() call.
36 static const int kSineCycles
= 4;
38 // Tuple of <input sampling rate, output sampling rate, epsilon>.
39 typedef std::tr1::tuple
<int, int, double> AudioRendererMixerTestData
;
40 class AudioRendererMixerTest
41 : public testing::TestWithParam
<AudioRendererMixerTestData
> {
43 AudioRendererMixerTest()
44 : epsilon_(std::tr1::get
<2>(GetParam())),
46 // Create input and output parameters based on test parameters.
47 input_parameters_
= AudioParameters(
48 AudioParameters::AUDIO_PCM_LINEAR
, kChannelLayout
,
49 std::tr1::get
<0>(GetParam()), kBitsPerChannel
, kHighLatencyBufferSize
);
50 output_parameters_
= AudioParameters(
51 AudioParameters::AUDIO_PCM_LOW_LATENCY
, kChannelLayout
,
52 std::tr1::get
<1>(GetParam()), 16, kLowLatencyBufferSize
);
54 sink_
= new MockAudioRendererSink();
55 EXPECT_CALL(*sink_
.get(), Start());
56 EXPECT_CALL(*sink_
.get(), Stop());
58 mixer_
.reset(new AudioRendererMixer(
59 input_parameters_
, output_parameters_
, sink_
));
60 mixer_callback_
= sink_
->callback();
62 audio_bus_
= AudioBus::Create(output_parameters_
);
63 expected_audio_bus_
= AudioBus::Create(output_parameters_
);
65 // Allocate one callback for generating expected results.
66 double step
= kSineCycles
/ static_cast<double>(
67 output_parameters_
.frames_per_buffer());
68 expected_callback_
.reset(new FakeAudioRenderCallback(step
));
71 AudioRendererMixer
* GetMixer(const AudioParameters
& params
) {
75 MOCK_METHOD1(RemoveMixer
, void(const AudioParameters
&));
77 void InitializeInputs(int count
) {
78 mixer_inputs_
.reserve(count
);
79 fake_callbacks_
.reserve(count
);
81 // Setup FakeAudioRenderCallback step to compensate for resampling.
82 double scale_factor
= input_parameters_
.sample_rate() /
83 static_cast<double>(output_parameters_
.sample_rate());
84 double step
= kSineCycles
/ (scale_factor
*
85 static_cast<double>(output_parameters_
.frames_per_buffer()));
87 for (int i
= 0; i
< count
; ++i
) {
88 fake_callbacks_
.push_back(new FakeAudioRenderCallback(step
));
89 mixer_inputs_
.push_back(new AudioRendererMixerInput(
90 base::Bind(&AudioRendererMixerTest::GetMixer
,
91 base::Unretained(this)),
92 base::Bind(&AudioRendererMixerTest::RemoveMixer
,
93 base::Unretained(this))));
94 mixer_inputs_
[i
]->Initialize(input_parameters_
, fake_callbacks_
[i
]);
95 mixer_inputs_
[i
]->SetVolume(1.0f
);
97 EXPECT_CALL(*this, RemoveMixer(testing::_
)).Times(count
);
100 bool ValidateAudioData(int index
, int frames
, float scale
, double epsilon
) {
101 for (int i
= 0; i
< audio_bus_
->channels(); ++i
) {
102 for (int j
= index
; j
< frames
; j
++) {
103 double error
= fabs(audio_bus_
->channel(i
)[j
] -
104 expected_audio_bus_
->channel(i
)[j
] * scale
);
105 if (error
> epsilon
) {
106 EXPECT_NEAR(expected_audio_bus_
->channel(i
)[j
] * scale
,
107 audio_bus_
->channel(i
)[j
], epsilon
)
108 << " i=" << i
<< ", j=" << j
;
116 bool ValidateAudioData(int index
, int frames
, float scale
) {
117 return ValidateAudioData(index
, frames
, scale
, epsilon_
);
120 bool RenderAndValidateAudioData(float scale
) {
122 for (size_t i
= 0; i
< fake_callbacks_
.size(); ++i
)
123 fake_callbacks_
[i
]->set_half_fill(true);
124 expected_callback_
->set_half_fill(true);
125 // Initialize the AudioBus completely or we'll run into Valgrind problems
126 // during the verification step below.
127 expected_audio_bus_
->Zero();
130 // Render actual audio data.
131 int frames
= mixer_callback_
->Render(audio_bus_
.get(), 0);
132 if (frames
!= audio_bus_
->frames())
135 // Render expected audio data (without scaling).
136 expected_callback_
->Render(expected_audio_bus_
.get(), 0);
139 // In this case, just verify that every frame was initialized, this will
140 // only fail under tooling such as valgrind.
141 return ValidateAudioData(
142 0, frames
, 0, std::numeric_limits
<double>::max());
144 return ValidateAudioData(0, frames
, scale
);
148 // Fill |audio_bus_| fully with |value|.
149 void FillAudioData(float value
) {
150 for (int i
= 0; i
< audio_bus_
->channels(); ++i
) {
151 std::fill(audio_bus_
->channel(i
),
152 audio_bus_
->channel(i
) + audio_bus_
->frames(), value
);
156 // Verify silence when mixer inputs are in pre-Start() and post-Start().
157 void StartTest(int inputs
) {
158 InitializeInputs(inputs
);
160 // Verify silence before any inputs have been started. Fill the buffer
161 // before hand with non-zero data to ensure we get zeros back.
163 EXPECT_TRUE(RenderAndValidateAudioData(0.0f
));
165 // Start() all even numbered mixer inputs and ensure we still get silence.
166 for (size_t i
= 0; i
< mixer_inputs_
.size(); i
+= 2)
167 mixer_inputs_
[i
]->Start();
169 EXPECT_TRUE(RenderAndValidateAudioData(0.0f
));
171 // Start() all mixer inputs and ensure we still get silence.
172 for (size_t i
= 1; i
< mixer_inputs_
.size(); i
+= 2)
173 mixer_inputs_
[i
]->Start();
175 EXPECT_TRUE(RenderAndValidateAudioData(0.0f
));
177 for (size_t i
= 0; i
< mixer_inputs_
.size(); ++i
)
178 mixer_inputs_
[i
]->Stop();
181 // Verify output when mixer inputs are in post-Play() state.
182 void PlayTest(int inputs
) {
183 InitializeInputs(inputs
);
185 // Play() all mixer inputs and ensure we get the right values.
186 for (size_t i
= 0; i
< mixer_inputs_
.size(); ++i
) {
187 mixer_inputs_
[i
]->Start();
188 mixer_inputs_
[i
]->Play();
191 for (int i
= 0; i
< kMixerCycles
; ++i
)
192 ASSERT_TRUE(RenderAndValidateAudioData(mixer_inputs_
.size()));
194 for (size_t i
= 0; i
< mixer_inputs_
.size(); ++i
)
195 mixer_inputs_
[i
]->Stop();
198 // Verify volume adjusted output when mixer inputs are in post-Play() state.
199 void PlayVolumeAdjustedTest(int inputs
) {
200 InitializeInputs(inputs
);
202 for (size_t i
= 0; i
< mixer_inputs_
.size(); ++i
) {
203 mixer_inputs_
[i
]->Start();
204 mixer_inputs_
[i
]->Play();
207 // Set a different volume for each mixer input and verify the results.
208 float total_scale
= 0;
209 for (size_t i
= 0; i
< mixer_inputs_
.size(); ++i
) {
210 float volume
= static_cast<float>(i
) / mixer_inputs_
.size();
211 total_scale
+= volume
;
212 EXPECT_TRUE(mixer_inputs_
[i
]->SetVolume(volume
));
214 for (int i
= 0; i
< kMixerCycles
; ++i
)
215 ASSERT_TRUE(RenderAndValidateAudioData(total_scale
));
217 for (size_t i
= 0; i
< mixer_inputs_
.size(); ++i
)
218 mixer_inputs_
[i
]->Stop();
221 // Verify output when mixer inputs can only partially fulfill a Render().
222 void PlayPartialRenderTest(int inputs
) {
223 InitializeInputs(inputs
);
225 for (size_t i
= 0; i
< mixer_inputs_
.size(); ++i
) {
226 mixer_inputs_
[i
]->Start();
227 mixer_inputs_
[i
]->Play();
230 // Verify a properly filled buffer when half filled (remainder zeroed).
232 ASSERT_TRUE(RenderAndValidateAudioData(mixer_inputs_
.size()));
234 for (size_t i
= 0; i
< mixer_inputs_
.size(); ++i
)
235 mixer_inputs_
[i
]->Stop();
238 // Verify output when mixer inputs are in Pause() state.
239 void PauseTest(int inputs
) {
240 InitializeInputs(inputs
);
242 for (size_t i
= 0; i
< mixer_inputs_
.size(); ++i
) {
243 mixer_inputs_
[i
]->Start();
244 mixer_inputs_
[i
]->Play();
247 // Pause() all even numbered mixer inputs and ensure we get the right value.
248 for (size_t i
= 0; i
< mixer_inputs_
.size(); i
+= 2)
249 mixer_inputs_
[i
]->Pause();
250 for (int i
= 0; i
< kMixerCycles
; ++i
)
251 ASSERT_TRUE(RenderAndValidateAudioData(mixer_inputs_
.size() / 2));
253 for (size_t i
= 0; i
< mixer_inputs_
.size(); ++i
)
254 mixer_inputs_
[i
]->Stop();
257 // Verify output when mixer inputs are in post-Stop() state.
258 void StopTest(int inputs
) {
259 InitializeInputs(inputs
);
261 // Start() and Stop() all inputs.
262 for (size_t i
= 0; i
< mixer_inputs_
.size(); ++i
) {
263 mixer_inputs_
[i
]->Start();
264 mixer_inputs_
[i
]->Stop();
267 // Verify we get silence back; fill |audio_bus_| before hand to be sure.
269 EXPECT_TRUE(RenderAndValidateAudioData(0.0f
));
273 virtual ~AudioRendererMixerTest() {}
275 scoped_refptr
<MockAudioRendererSink
> sink_
;
276 scoped_ptr
<AudioRendererMixer
> mixer_
;
277 AudioRendererSink::RenderCallback
* mixer_callback_
;
278 AudioParameters input_parameters_
;
279 AudioParameters output_parameters_
;
280 scoped_ptr
<AudioBus
> audio_bus_
;
281 scoped_ptr
<AudioBus
> expected_audio_bus_
;
282 std::vector
< scoped_refptr
<AudioRendererMixerInput
> > mixer_inputs_
;
283 ScopedVector
<FakeAudioRenderCallback
> fake_callbacks_
;
284 scoped_ptr
<FakeAudioRenderCallback
> expected_callback_
;
288 DISALLOW_COPY_AND_ASSIGN(AudioRendererMixerTest
);
291 class AudioRendererMixerBehavioralTest
: public AudioRendererMixerTest
{};
293 ACTION_P(SignalEvent
, event
) {
297 // Verify a mixer with no inputs returns silence for all requested frames.
298 TEST_P(AudioRendererMixerTest
, NoInputs
) {
300 EXPECT_TRUE(RenderAndValidateAudioData(0.0f
));
303 // Test mixer output with one input in the pre-Start() and post-Start() state.
304 TEST_P(AudioRendererMixerTest
, OneInputStart
) {
308 // Test mixer output with many inputs in the pre-Start() and post-Start() state.
309 TEST_P(AudioRendererMixerTest
, ManyInputStart
) {
310 StartTest(kMixerInputs
);
313 // Test mixer output with one input in the post-Play() state.
314 TEST_P(AudioRendererMixerTest
, OneInputPlay
) {
318 // Test mixer output with many inputs in the post-Play() state.
319 TEST_P(AudioRendererMixerTest
, ManyInputPlay
) {
320 PlayTest(kMixerInputs
);
323 // Test volume adjusted mixer output with one input in the post-Play() state.
324 TEST_P(AudioRendererMixerTest
, OneInputPlayVolumeAdjusted
) {
325 PlayVolumeAdjustedTest(1);
328 // Test volume adjusted mixer output with many inputs in the post-Play() state.
329 TEST_P(AudioRendererMixerTest
, ManyInputPlayVolumeAdjusted
) {
330 PlayVolumeAdjustedTest(kMixerInputs
);
333 // Test mixer output with one input and partial Render() in post-Play() state.
334 TEST_P(AudioRendererMixerTest
, OneInputPlayPartialRender
) {
335 PlayPartialRenderTest(1);
338 // Test mixer output with many inputs and partial Render() in post-Play() state.
339 TEST_P(AudioRendererMixerTest
, ManyInputPlayPartialRender
) {
340 PlayPartialRenderTest(kMixerInputs
);
343 // Test mixer output with one input in the post-Pause() state.
344 TEST_P(AudioRendererMixerTest
, OneInputPause
) {
348 // Test mixer output with many inputs in the post-Pause() state.
349 TEST_P(AudioRendererMixerTest
, ManyInputPause
) {
350 PauseTest(kMixerInputs
);
353 // Test mixer output with one input in the post-Stop() state.
354 TEST_P(AudioRendererMixerTest
, OneInputStop
) {
358 // Test mixer output with many inputs in the post-Stop() state.
359 TEST_P(AudioRendererMixerTest
, ManyInputStop
) {
360 StopTest(kMixerInputs
);
363 // Test mixer with many inputs in mixed post-Stop() and post-Play() states.
364 TEST_P(AudioRendererMixerTest
, ManyInputMixedStopPlay
) {
365 InitializeInputs(kMixerInputs
);
367 // Start() all inputs.
368 for (size_t i
= 0; i
< mixer_inputs_
.size(); ++i
)
369 mixer_inputs_
[i
]->Start();
371 // Stop() all even numbered mixer inputs and Play() all odd numbered inputs
372 // and ensure we get the right value.
373 for (size_t i
= 1; i
< mixer_inputs_
.size(); i
+= 2) {
374 mixer_inputs_
[i
- 1]->Stop();
375 mixer_inputs_
[i
]->Play();
377 ASSERT_TRUE(RenderAndValidateAudioData(std::max(
378 mixer_inputs_
.size() / 2, static_cast<size_t>(1))));
380 for (size_t i
= 1; i
< mixer_inputs_
.size(); i
+= 2)
381 mixer_inputs_
[i
]->Stop();
384 TEST_P(AudioRendererMixerBehavioralTest
, OnRenderError
) {
385 InitializeInputs(kMixerInputs
);
386 for (size_t i
= 0; i
< mixer_inputs_
.size(); ++i
) {
387 mixer_inputs_
[i
]->Start();
388 mixer_inputs_
[i
]->Play();
389 EXPECT_CALL(*fake_callbacks_
[i
], OnRenderError()).Times(1);
392 mixer_callback_
->OnRenderError();
393 for (size_t i
= 0; i
< mixer_inputs_
.size(); ++i
)
394 mixer_inputs_
[i
]->Stop();
397 // Ensure constructing an AudioRendererMixerInput, but not initializing it does
398 // not call RemoveMixer().
399 TEST_P(AudioRendererMixerBehavioralTest
, NoInitialize
) {
400 EXPECT_CALL(*this, RemoveMixer(testing::_
)).Times(0);
401 scoped_refptr
<AudioRendererMixerInput
> audio_renderer_mixer
=
402 new AudioRendererMixerInput(
403 base::Bind(&AudioRendererMixerTest::GetMixer
,
404 base::Unretained(this)),
405 base::Bind(&AudioRendererMixerTest::RemoveMixer
,
406 base::Unretained(this)));
409 // Ensure the physical stream is paused after a certain amount of time with no
410 // inputs playing. The test will hang if the behavior is incorrect.
411 TEST_P(AudioRendererMixerBehavioralTest
, MixerPausesStream
) {
412 const base::TimeDelta kPauseTime
= base::TimeDelta::FromMilliseconds(500);
413 // This value can't be too low or valgrind, tsan will timeout on the bots.
414 const base::TimeDelta kTestTimeout
= 10 * kPauseTime
;
415 mixer_
->set_pause_delay_for_testing(kPauseTime
);
417 base::WaitableEvent
pause_event(true, false);
418 EXPECT_CALL(*sink_
.get(), Pause()).Times(2)
419 .WillRepeatedly(SignalEvent(&pause_event
));
422 // Ensure never playing the input results in a sink pause.
423 const base::TimeDelta kSleepTime
= base::TimeDelta::FromMilliseconds(100);
424 base::TimeTicks start_time
= base::TimeTicks::Now();
425 while (!pause_event
.IsSignaled()) {
426 mixer_callback_
->Render(audio_bus_
.get(), 0);
427 base::PlatformThread::Sleep(kSleepTime
);
428 ASSERT_TRUE(base::TimeTicks::Now() - start_time
< kTestTimeout
);
432 // Playing the input for the first time should cause a sink play.
433 mixer_inputs_
[0]->Start();
434 EXPECT_CALL(*sink_
.get(), Play());
435 mixer_inputs_
[0]->Play();
436 mixer_inputs_
[0]->Pause();
438 // Ensure once the input is paused the sink eventually pauses.
439 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
);
446 mixer_inputs_
[0]->Stop();
449 INSTANTIATE_TEST_CASE_P(
450 AudioRendererMixerTest
, AudioRendererMixerTest
, testing::Values(
452 std::tr1::make_tuple(44100, 44100, 0.00000048),
455 std::tr1::make_tuple(44100, 48000, 0.033),
458 std::tr1::make_tuple(48000, 41000, 0.042)));
460 // Test cases for behavior which is independent of parameters. Values() doesn't
461 // support single item lists and we don't want these test cases to run for every
463 INSTANTIATE_TEST_CASE_P(
464 AudioRendererMixerBehavioralTest
, AudioRendererMixerBehavioralTest
,
465 testing::ValuesIn(std::vector
<AudioRendererMixerTestData
>(
466 1, std::tr1::make_tuple(44100, 44100, 0))));