Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(172)

Side by Side Diff: media/base/audio_renderer_mixer_unittest.cc

Issue 10698066: Switch to pcm_low_latency and enable resampling. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Comments! Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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.
6 #define _USE_MATH_DEFINES
5 #include <cmath> 7 #include <cmath>
6 8
9 #include "base/bind.h"
10 #include "base/bind_helpers.h"
7 #include "base/memory/scoped_ptr.h" 11 #include "base/memory/scoped_ptr.h"
8 #include "media/audio/audio_util.h" 12 #include "base/memory/scoped_vector.h"
9 #include "media/base/audio_renderer_mixer.h" 13 #include "media/base/audio_renderer_mixer.h"
10 #include "media/base/audio_renderer_mixer_input.h" 14 #include "media/base/audio_renderer_mixer_input.h"
11 #include "media/base/fake_audio_render_callback.h" 15 #include "media/base/fake_audio_render_callback.h"
16 #include "media/base/mock_audio_renderer_sink.h"
12 #include "testing/gmock/include/gmock/gmock.h" 17 #include "testing/gmock/include/gmock/gmock.h"
13 #include "testing/gtest/include/gtest/gtest.h" 18 #include "testing/gtest/include/gtest/gtest.h"
14 19
15 namespace media { 20 namespace media {
16 21
17 // Parameters which control the many input case tests. 22 // Parameters which control the many input case tests.
18 static const int kMixerInputs = 64; 23 static const int kMixerInputs = 8;
19 static const int kMixerCycles = 32; 24 static const int kMixerCycles = 3;
20 25
26 // Parameters used for testing.
21 static const int kBitsPerChannel = 16; 27 static const int kBitsPerChannel = 16;
22 static const int kSampleRate = 48000;
23 static const ChannelLayout kChannelLayout = CHANNEL_LAYOUT_STEREO; 28 static const ChannelLayout kChannelLayout = CHANNEL_LAYOUT_STEREO;
29 static const int kHighLatencyBufferSize = 8192;
30 static const int kLowLatencyBufferSize = 256;
24 31
25 // Multiple rounds of addition result in precision loss with float values, so we 32 // Number of full sine wave cycles for each Render() call.
26 // need an epsilon such that if for all x f(x) = sum(x, m) and g(x) = m * x then 33 static const int kSineCycles = 4;
27 // fabs(f - g) < kEpsilon. The kEpsilon below has been tested with m < 128.
28 static const float kEpsilon = 0.00015f;
29 34
30 class MockAudioRendererSink : public AudioRendererSink { 35 // Tuple of <input sampling rate, output sampling rate, epsilon>.
36 typedef std::tr1::tuple<int, int, double> AudioRendererMixerTestData;
37 class AudioRendererMixerTest
38 : public testing::TestWithParam<AudioRendererMixerTestData> {
31 public: 39 public:
32 MOCK_METHOD0(Start, void()); 40 AudioRendererMixerTest()
33 MOCK_METHOD0(Stop, void()); 41 : epsilon_(std::tr1::get<2>(GetParam())),
34 MOCK_METHOD1(Pause, void(bool flush)); 42 half_fill_(false) {
35 MOCK_METHOD0(Play, void()); 43 // Create input and output parameters based on test parameters.
36 MOCK_METHOD1(SetPlaybackRate, void(float rate)); 44 input_parameters_ = AudioParameters(
37 MOCK_METHOD1(SetVolume, bool(double volume)); 45 AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout,
38 MOCK_METHOD1(GetVolume, void(double* volume)); 46 std::tr1::get<0>(GetParam()), kBitsPerChannel, kHighLatencyBufferSize);
47 output_parameters_ = AudioParameters(
48 AudioParameters::AUDIO_PCM_LOW_LATENCY, kChannelLayout,
49 std::tr1::get<1>(GetParam()), 16, kLowLatencyBufferSize);
39 50
40 void Initialize(const media::AudioParameters& params,
41 AudioRendererSink::RenderCallback* renderer) OVERRIDE {
42 // TODO(dalecurtis): Once we have resampling we need to ensure we are given
43 // an AudioParameters which reflects the hardware settings.
44 callback_ = renderer;
45 };
46
47 AudioRendererSink::RenderCallback* callback() {
48 return callback_;
49 }
50
51 void SimulateRenderError() {
52 callback_->OnRenderError();
53 }
54
55 protected:
56 virtual ~MockAudioRendererSink() {}
57
58 AudioRendererSink::RenderCallback* callback_;
59 };
60
61 class AudioRendererMixerTest : public ::testing::Test {
62 public:
63 AudioRendererMixerTest() {
64 audio_parameters_ = AudioParameters(
65 AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, kSampleRate,
66 kBitsPerChannel, GetHighLatencyOutputBufferSize(kSampleRate));
67 sink_ = new MockAudioRendererSink(); 51 sink_ = new MockAudioRendererSink();
68 EXPECT_CALL(*sink_, Start()); 52 EXPECT_CALL(*sink_, Start());
69 EXPECT_CALL(*sink_, Stop()); 53 EXPECT_CALL(*sink_, Stop());
70 54
71 mixer_ = new AudioRendererMixer(audio_parameters_, sink_); 55 mixer_.reset(new AudioRendererMixer(
56 input_parameters_, output_parameters_, sink_));
72 mixer_callback_ = sink_->callback(); 57 mixer_callback_ = sink_->callback();
73 58
74 // TODO(dalecurtis): If we switch to AVX/SSE optimization, we'll need to 59 // TODO(dalecurtis): If we switch to AVX/SSE optimization, we'll need to
75 // allocate these on 32-byte boundaries and ensure they're sized % 32 bytes. 60 // allocate these on 32-byte boundaries and ensure they're sized % 32 bytes.
76 audio_data_.reserve(audio_parameters_.channels()); 61 audio_data_.reserve(output_parameters_.channels());
77 for (int i = 0; i < audio_parameters_.channels(); ++i) 62 for (int i = 0; i < output_parameters_.channels(); ++i)
78 audio_data_.push_back(new float[audio_parameters_.frames_per_buffer()]); 63 audio_data_.push_back(new float[output_parameters_.frames_per_buffer()]);
79 64
80 fake_callback_.reset(new FakeAudioRenderCallback(audio_parameters_)); 65 // TODO(dalecurtis): If we switch to AVX/SSE optimization, we'll need to
66 // allocate these on 32-byte boundaries and ensure they're sized % 32 bytes.
67 expected_audio_data_.reserve(output_parameters_.channels());
68 for (int i = 0; i < output_parameters_.channels(); ++i) {
69 expected_audio_data_.push_back(
70 new float[output_parameters_.frames_per_buffer()]);
71 }
72
73 // Allocate one callback for generating expected results.
74 double step = kSineCycles / static_cast<double>(
75 output_parameters_.frames_per_buffer());
76 expected_callback_.reset(new FakeAudioRenderCallback(step));
81 } 77 }
82 78
83 void InitializeInputs(int count) { 79 AudioRendererMixer* GetMixer(const AudioParameters& params) {
84 for (int i = 0; i < count; ++i) { 80 return mixer_.get();
85 scoped_refptr<AudioRendererMixerInput> mixer_input(
86 new AudioRendererMixerInput(mixer_));
87 mixer_input->Initialize(audio_parameters_, fake_callback_.get());
88 mixer_input->SetVolume(1.0f);
89 mixer_inputs_.push_back(mixer_input);
90 }
91 } 81 }
92 82
93 bool ValidateAudioData(int start_index, int frames, float check_value) { 83 MOCK_METHOD1(RemoveMixer, void(const AudioParameters&));
84
85 void InitializeInputs(int count) {
86 mixer_inputs_.reserve(count);
87 fake_callbacks_.reserve(count);
88
89 // Setup FakeAudioRenderCallback step to compensate for resampling.
90 double scale_factor = input_parameters_.sample_rate()
91 / static_cast<double>(output_parameters_.sample_rate());
92 double step = kSineCycles / (scale_factor *
93 static_cast<double>(output_parameters_.frames_per_buffer()));
94
95 for (int i = 0; i < count; ++i) {
96 fake_callbacks_.push_back(new FakeAudioRenderCallback(step));
97 mixer_inputs_.push_back(new AudioRendererMixerInput(
98 base::Bind(&AudioRendererMixerTest::GetMixer,
99 base::Unretained(this)),
100 base::Bind(&AudioRendererMixerTest::RemoveMixer,
101 base::Unretained(this))));
102 mixer_inputs_[i]->Initialize(input_parameters_, fake_callbacks_[i]);
103 mixer_inputs_[i]->SetVolume(1.0f);
104 }
105 EXPECT_CALL(*this, RemoveMixer(testing::_)).Times(count);
106 }
107
108 bool ValidateAudioData(int index, int frames, float scale) {
94 for (size_t i = 0; i < audio_data_.size(); ++i) { 109 for (size_t i = 0; i < audio_data_.size(); ++i) {
95 for (int j = start_index; j < frames; j++) { 110 for (int j = index; j < frames; j++) {
96 if (fabs(audio_data_[i][j] - check_value) > kEpsilon) { 111 double error = fabs(
97 EXPECT_NEAR(check_value, audio_data_[i][j], kEpsilon) 112 audio_data_[i][j] - expected_audio_data_[i][j] * scale);
113 if (error > epsilon_) {
114 EXPECT_NEAR(
115 expected_audio_data_[i][j] * scale, audio_data_[i][j], epsilon_)
98 << " i=" << i << ", j=" << j; 116 << " i=" << i << ", j=" << j;
99 return false; 117 return false;
100 } 118 }
101 } 119 }
102 } 120 }
103 return true; 121 return true;
104 } 122 }
105 123
106 // Render audio_parameters_.frames_per_buffer() frames into |audio_data_| and 124 bool RenderAndValidateAudioData(float scale) {
107 // verify the result against |check_value|. 125 int request_frames = output_parameters_.frames_per_buffer();
108 bool RenderAndValidateAudioData(float check_value) { 126
109 int frames = mixer_callback_->Render( 127 // Half fill won't be exactly half when resampling since the resampler
110 audio_data_, audio_parameters_.frames_per_buffer(), 0); 128 // will have enough data to fill out more of the buffer based on its
111 return frames == audio_parameters_.frames_per_buffer() && ValidateAudioData( 129 // internal buffer and kernel size. So special case some of the checks.
112 0, audio_parameters_.frames_per_buffer(), check_value); 130 bool resampling = input_parameters_.sample_rate()
131 != output_parameters_.sample_rate();
132
133 if (half_fill_) {
134 for (size_t i = 0; i < fake_callbacks_.size(); ++i)
135 fake_callbacks_[i]->set_half_fill(true);
136 expected_callback_->set_half_fill(true);
137 }
138
139 // Render actual audio data.
140 int frames = mixer_callback_->Render(audio_data_, request_frames, 0);
141 if (frames != request_frames)
142 return false;
143
144 // Render expected audio data (without scaling).
145 expected_callback_->Render(expected_audio_data_, request_frames, 0);
146
147 if (half_fill_) {
148 // Verify first half of audio data for both resampling and non-resampling.
149 if (!ValidateAudioData(0, frames / 2, scale))
150 return false;
151 // Verify silence in the second half if we're not resampling.
152 if (!resampling)
153 return ValidateAudioData(frames / 2, frames, 0);
154 return true;
155 } else {
156 return ValidateAudioData(0, frames, scale);
157 }
113 } 158 }
114 159
115 // Fill |audio_data_| fully with |value|. 160 // Fill |audio_data_| fully with |value|.
116 void FillAudioData(float value) { 161 void FillAudioData(float value) {
117 for (size_t i = 0; i < audio_data_.size(); ++i) 162 for (size_t i = 0; i < audio_data_.size(); ++i)
118 std::fill(audio_data_[i], 163 std::fill(audio_data_[i],
119 audio_data_[i] + audio_parameters_.frames_per_buffer(), value); 164 audio_data_[i] + output_parameters_.frames_per_buffer(), value);
120 } 165 }
121 166
122 // Verify silence when mixer inputs are in pre-Start() and post-Start(). 167 // Verify silence when mixer inputs are in pre-Start() and post-Start().
123 void StartTest(int inputs) { 168 void StartTest(int inputs) {
124 InitializeInputs(inputs); 169 InitializeInputs(inputs);
125 170
126 // Verify silence before any inputs have been started. Fill the buffer 171 // Verify silence before any inputs have been started. Fill the buffer
127 // before hand with non-zero data to ensure we get zeros back. 172 // before hand with non-zero data to ensure we get zeros back.
128 FillAudioData(1.0f); 173 FillAudioData(1.0f);
129 EXPECT_TRUE(RenderAndValidateAudioData(0.0f)); 174 EXPECT_TRUE(RenderAndValidateAudioData(0.0f));
(...skipping 11 matching lines...) Expand all
141 EXPECT_TRUE(RenderAndValidateAudioData(0.0f)); 186 EXPECT_TRUE(RenderAndValidateAudioData(0.0f));
142 187
143 for (size_t i = 0; i < mixer_inputs_.size(); ++i) 188 for (size_t i = 0; i < mixer_inputs_.size(); ++i)
144 mixer_inputs_[i]->Stop(); 189 mixer_inputs_[i]->Stop();
145 } 190 }
146 191
147 // Verify output when mixer inputs are in post-Play() state. 192 // Verify output when mixer inputs are in post-Play() state.
148 void PlayTest(int inputs) { 193 void PlayTest(int inputs) {
149 InitializeInputs(inputs); 194 InitializeInputs(inputs);
150 195
151 for (size_t i = 0; i < mixer_inputs_.size(); ++i) 196 // Play() all mixer inputs and ensure we get the right values.
197 for (size_t i = 0; i < mixer_inputs_.size(); ++i) {
152 mixer_inputs_[i]->Start(); 198 mixer_inputs_[i]->Start();
153
154 // Play() all even numbered mixer inputs and ensure we get the right value.
155 for (size_t i = 0; i < mixer_inputs_.size(); i += 2)
156 mixer_inputs_[i]->Play(); 199 mixer_inputs_[i]->Play();
157 for (int i = 0; i < kMixerCycles; ++i) {
158 fake_callback_->NextFillValue();
159 ASSERT_TRUE(RenderAndValidateAudioData(
160 fake_callback_->fill_value() * std::max(
161 mixer_inputs_.size() / 2, static_cast<size_t>(1))));
162 } 200 }
163 201
164 // Play() all mixer inputs and ensure we still get the right values. 202 for (int i = 0; i < kMixerCycles; ++i)
165 for (size_t i = 1; i < mixer_inputs_.size(); i += 2) 203 ASSERT_TRUE(RenderAndValidateAudioData(mixer_inputs_.size()));
166 mixer_inputs_[i]->Play();
167 for (int i = 0; i < kMixerCycles; ++i) {
168 fake_callback_->NextFillValue();
169 ASSERT_TRUE(RenderAndValidateAudioData(
170 fake_callback_->fill_value() * mixer_inputs_.size()));
171 }
172 204
173 for (size_t i = 0; i < mixer_inputs_.size(); ++i) 205 for (size_t i = 0; i < mixer_inputs_.size(); ++i)
174 mixer_inputs_[i]->Stop(); 206 mixer_inputs_[i]->Stop();
175 } 207 }
176 208
177 // Verify volume adjusted output when mixer inputs are in post-Play() state. 209 // Verify volume adjusted output when mixer inputs are in post-Play() state.
178 void PlayVolumeAdjustedTest(int inputs) { 210 void PlayVolumeAdjustedTest(int inputs) {
179 InitializeInputs(inputs); 211 InitializeInputs(inputs);
180 212
181 for (size_t i = 0; i < mixer_inputs_.size(); ++i) { 213 for (size_t i = 0; i < mixer_inputs_.size(); ++i) {
182 mixer_inputs_[i]->Start(); 214 mixer_inputs_[i]->Start();
183 mixer_inputs_[i]->Play(); 215 mixer_inputs_[i]->Play();
184 } 216 }
185 217
186 // Set a different volume for each mixer input and verify the results. 218 // Set a different volume for each mixer input and verify the results.
187 float total_scale = 0; 219 float total_scale = 0;
188 for (size_t i = 0; i < mixer_inputs_.size(); ++i) { 220 for (size_t i = 0; i < mixer_inputs_.size(); ++i) {
189 float volume = static_cast<float>(i) / mixer_inputs_.size(); 221 float volume = static_cast<float>(i) / mixer_inputs_.size();
190 total_scale += volume; 222 total_scale += volume;
191 EXPECT_TRUE(mixer_inputs_[i]->SetVolume(volume)); 223 EXPECT_TRUE(mixer_inputs_[i]->SetVolume(volume));
192 } 224 }
193 for (int i = 0; i < kMixerCycles; ++i) { 225 for (int i = 0; i < kMixerCycles; ++i)
194 fake_callback_->NextFillValue(); 226 ASSERT_TRUE(RenderAndValidateAudioData(total_scale));
195 ASSERT_TRUE(RenderAndValidateAudioData(
196 fake_callback_->fill_value() * total_scale));
197 }
198 227
199 for (size_t i = 0; i < mixer_inputs_.size(); ++i) 228 for (size_t i = 0; i < mixer_inputs_.size(); ++i)
200 mixer_inputs_[i]->Stop(); 229 mixer_inputs_[i]->Stop();
201 } 230 }
202 231
203 // Verify output when mixer inputs can only partially fulfill a Render(). 232 // Verify output when mixer inputs can only partially fulfill a Render().
204 void PlayPartialRenderTest(int inputs) { 233 void PlayPartialRenderTest(int inputs) {
205 InitializeInputs(inputs); 234 InitializeInputs(inputs);
206 int frames = audio_parameters_.frames_per_buffer();
207 235
208 for (size_t i = 0; i < mixer_inputs_.size(); ++i) { 236 for (size_t i = 0; i < mixer_inputs_.size(); ++i) {
209 mixer_inputs_[i]->Start(); 237 mixer_inputs_[i]->Start();
210 mixer_inputs_[i]->Play(); 238 mixer_inputs_[i]->Play();
211 } 239 }
212 240
213 // Verify a properly filled buffer when half filled (remainder zeroed). 241 // Verify a properly filled buffer when half filled (remainder zeroed).
214 fake_callback_->set_half_fill(true); 242 half_fill_ = true;
215 for (int i = 0; i < kMixerCycles; ++i) { 243 ASSERT_TRUE(RenderAndValidateAudioData(mixer_inputs_.size()));
216 fake_callback_->NextFillValue();
217 ASSERT_EQ(mixer_callback_->Render(audio_data_, frames, 0), frames);
218 ASSERT_TRUE(ValidateAudioData(
219 0, frames / 2, fake_callback_->fill_value() * mixer_inputs_.size()));
220 ASSERT_TRUE(ValidateAudioData(
221 frames / 2, frames, 0.0f));
222 }
223 fake_callback_->set_half_fill(false);
224 244
225 for (size_t i = 0; i < mixer_inputs_.size(); ++i) 245 for (size_t i = 0; i < mixer_inputs_.size(); ++i)
226 mixer_inputs_[i]->Stop(); 246 mixer_inputs_[i]->Stop();
227 } 247 }
228 248
229 // Verify output when mixer inputs are in Pause() state. 249 // Verify output when mixer inputs are in Pause() state.
230 void PauseTest(int inputs) { 250 void PauseTest(int inputs) {
231 InitializeInputs(inputs); 251 InitializeInputs(inputs);
232 252
233 for (size_t i = 0; i < mixer_inputs_.size(); ++i) { 253 for (size_t i = 0; i < mixer_inputs_.size(); ++i) {
234 mixer_inputs_[i]->Start(); 254 mixer_inputs_[i]->Start();
235 mixer_inputs_[i]->Play(); 255 mixer_inputs_[i]->Play();
236 } 256 }
237 257
238 // Pause() all even numbered mixer inputs and ensure we get the right value. 258 // Pause() all even numbered mixer inputs and ensure we get the right value.
239 for (size_t i = 0; i < mixer_inputs_.size(); i += 2) 259 for (size_t i = 0; i < mixer_inputs_.size(); i += 2)
240 mixer_inputs_[i]->Pause(false); 260 mixer_inputs_[i]->Pause(false);
241 for (int i = 0; i < kMixerCycles; ++i) { 261 for (int i = 0; i < kMixerCycles; ++i)
242 fake_callback_->NextFillValue(); 262 ASSERT_TRUE(RenderAndValidateAudioData(mixer_inputs_.size() / 2));
243 ASSERT_TRUE(RenderAndValidateAudioData(
244 fake_callback_->fill_value() * (mixer_inputs_.size() / 2)));
245 }
246
247 // Pause() all the inputs and verify we get silence back.
248 for (size_t i = 1; i < mixer_inputs_.size(); i += 2)
249 mixer_inputs_[i]->Pause(false);
250 FillAudioData(1.0f);
251 EXPECT_TRUE(RenderAndValidateAudioData(0.0f));
252 263
253 for (size_t i = 0; i < mixer_inputs_.size(); ++i) 264 for (size_t i = 0; i < mixer_inputs_.size(); ++i)
254 mixer_inputs_[i]->Stop(); 265 mixer_inputs_[i]->Stop();
255 } 266 }
256 267
257 // Verify output when mixer inputs are in post-Stop() state. 268 // Verify output when mixer inputs are in post-Stop() state.
258 void StopTest(int inputs) { 269 void StopTest(int inputs) {
259 InitializeInputs(inputs); 270 InitializeInputs(inputs);
260 271
261 // Start() and Stop() all inputs. 272 // Start() and Stop() all inputs.
262 for (size_t i = 0; i < mixer_inputs_.size(); ++i) { 273 for (size_t i = 0; i < mixer_inputs_.size(); ++i) {
263 mixer_inputs_[i]->Start(); 274 mixer_inputs_[i]->Start();
264 mixer_inputs_[i]->Stop(); 275 mixer_inputs_[i]->Stop();
265 } 276 }
266 277
267 // Verify we get silence back; fill |audio_data_| before hand to be sure. 278 // Verify we get silence back; fill |audio_data_| before hand to be sure.
268 FillAudioData(1.0f); 279 FillAudioData(1.0f);
269 EXPECT_TRUE(RenderAndValidateAudioData(0.0f)); 280 EXPECT_TRUE(RenderAndValidateAudioData(0.0f));
270 } 281 }
271 282
272 protected: 283 protected:
273 virtual ~AudioRendererMixerTest() { 284 virtual ~AudioRendererMixerTest() {
274 for (size_t i = 0; i < audio_data_.size(); ++i) 285 for (size_t i = 0; i < audio_data_.size(); ++i)
275 delete [] audio_data_[i]; 286 delete [] audio_data_[i];
276 } 287 }
277 288
278 scoped_refptr<MockAudioRendererSink> sink_; 289 scoped_refptr<MockAudioRendererSink> sink_;
279 scoped_refptr<AudioRendererMixer> mixer_; 290 scoped_ptr<AudioRendererMixer> mixer_;
280 AudioRendererSink::RenderCallback* mixer_callback_; 291 AudioRendererSink::RenderCallback* mixer_callback_;
281 scoped_ptr<FakeAudioRenderCallback> fake_callback_; 292 AudioParameters input_parameters_;
282 AudioParameters audio_parameters_; 293 AudioParameters output_parameters_;
283 std::vector<float*> audio_data_; 294 std::vector<float*> audio_data_;
295 std::vector<float*> expected_audio_data_;
284 std::vector< scoped_refptr<AudioRendererMixerInput> > mixer_inputs_; 296 std::vector< scoped_refptr<AudioRendererMixerInput> > mixer_inputs_;
297 ScopedVector<FakeAudioRenderCallback> fake_callbacks_;
298 scoped_ptr<FakeAudioRenderCallback> expected_callback_;
299 double epsilon_;
300 bool half_fill_;
285 301
286 DISALLOW_COPY_AND_ASSIGN(AudioRendererMixerTest); 302 DISALLOW_COPY_AND_ASSIGN(AudioRendererMixerTest);
287 }; 303 };
288 304
289 // Verify a mixer with no inputs returns silence for all requested frames. 305 // Verify a mixer with no inputs returns silence for all requested frames.
290 TEST_F(AudioRendererMixerTest, NoInputs) { 306 TEST_P(AudioRendererMixerTest, NoInputs) {
291 FillAudioData(1.0f); 307 FillAudioData(1.0f);
292 EXPECT_TRUE(RenderAndValidateAudioData(0.0f)); 308 EXPECT_TRUE(RenderAndValidateAudioData(0.0f));
293 } 309 }
294 310
295 // Test mixer output with one input in the pre-Start() and post-Start() state. 311 // Test mixer output with one input in the pre-Start() and post-Start() state.
296 TEST_F(AudioRendererMixerTest, OneInputStart) { 312 TEST_P(AudioRendererMixerTest, OneInputStart) {
297 StartTest(1); 313 StartTest(1);
298 } 314 }
299 315
300 // Test mixer output with many inputs in the pre-Start() and post-Start() state. 316 // Test mixer output with many inputs in the pre-Start() and post-Start() state.
301 TEST_F(AudioRendererMixerTest, ManyInputStart) { 317 TEST_P(AudioRendererMixerTest, ManyInputStart) {
302 StartTest(kMixerInputs); 318 StartTest(kMixerInputs);
303 } 319 }
304 320
305 // Test mixer output with one input in the post-Play() state. 321 // Test mixer output with one input in the post-Play() state.
306 TEST_F(AudioRendererMixerTest, OneInputPlay) { 322 TEST_P(AudioRendererMixerTest, OneInputPlay) {
307 PlayTest(1); 323 PlayTest(1);
308 } 324 }
309 325
310 // Test mixer output with many inputs in the post-Play() state. 326 // Test mixer output with many inputs in the post-Play() state.
311 TEST_F(AudioRendererMixerTest, ManyInputPlay) { 327 TEST_P(AudioRendererMixerTest, ManyInputPlay) {
312 PlayTest(kMixerInputs); 328 PlayTest(kMixerInputs);
313 } 329 }
314 330
315 // Test volume adjusted mixer output with one input in the post-Play() state. 331 // Test volume adjusted mixer output with one input in the post-Play() state.
316 TEST_F(AudioRendererMixerTest, OneInputPlayVolumeAdjusted) { 332 TEST_P(AudioRendererMixerTest, OneInputPlayVolumeAdjusted) {
317 PlayVolumeAdjustedTest(1); 333 PlayVolumeAdjustedTest(1);
318 } 334 }
319 335
320 // Test volume adjusted mixer output with many inputs in the post-Play() state. 336 // Test volume adjusted mixer output with many inputs in the post-Play() state.
321 TEST_F(AudioRendererMixerTest, ManyInputPlayVolumeAdjusted) { 337 TEST_P(AudioRendererMixerTest, ManyInputPlayVolumeAdjusted) {
322 PlayVolumeAdjustedTest(kMixerInputs); 338 PlayVolumeAdjustedTest(kMixerInputs);
323 } 339 }
324 340
325 // Test mixer output with one input and partial Render() in post-Play() state. 341 // Test mixer output with one input and partial Render() in post-Play() state.
326 TEST_F(AudioRendererMixerTest, OneInputPlayPartialRender) { 342 TEST_P(AudioRendererMixerTest, OneInputPlayPartialRender) {
327 PlayPartialRenderTest(1); 343 PlayPartialRenderTest(1);
328 } 344 }
329 345
330 // Test mixer output with many inputs and partial Render() in post-Play() state. 346 // Test mixer output with many inputs and partial Render() in post-Play() state.
331 TEST_F(AudioRendererMixerTest, ManyInputPlayPartialRender) { 347 TEST_P(AudioRendererMixerTest, ManyInputPlayPartialRender) {
332 PlayPartialRenderTest(kMixerInputs); 348 PlayPartialRenderTest(kMixerInputs);
333 } 349 }
334 350
335 // Test mixer output with one input in the post-Pause() state. 351 // Test mixer output with one input in the post-Pause() state.
336 TEST_F(AudioRendererMixerTest, OneInputPause) { 352 TEST_P(AudioRendererMixerTest, OneInputPause) {
337 PauseTest(1); 353 PauseTest(1);
338 } 354 }
339 355
340 // Test mixer output with many inputs in the post-Pause() state. 356 // Test mixer output with many inputs in the post-Pause() state.
341 TEST_F(AudioRendererMixerTest, ManyInputPause) { 357 TEST_P(AudioRendererMixerTest, ManyInputPause) {
342 PauseTest(kMixerInputs); 358 PauseTest(kMixerInputs);
343 } 359 }
344 360
345 // Test mixer output with one input in the post-Stop() state. 361 // Test mixer output with one input in the post-Stop() state.
346 TEST_F(AudioRendererMixerTest, OneInputStop) { 362 TEST_P(AudioRendererMixerTest, OneInputStop) {
347 StopTest(1); 363 StopTest(1);
348 } 364 }
349 365
350 // Test mixer output with many inputs in the post-Stop() state. 366 // Test mixer output with many inputs in the post-Stop() state.
351 TEST_F(AudioRendererMixerTest, ManyInputStop) { 367 TEST_P(AudioRendererMixerTest, ManyInputStop) {
352 StopTest(kMixerInputs); 368 StopTest(kMixerInputs);
353 } 369 }
354 370
355 // Test mixer with many inputs in mixed post-Stop() and post-Play() states. 371 // Test mixer with many inputs in mixed post-Stop() and post-Play() states.
356 TEST_F(AudioRendererMixerTest, ManyInputMixedStopPlay) { 372 TEST_P(AudioRendererMixerTest, ManyInputMixedStopPlay) {
357 InitializeInputs(kMixerInputs); 373 InitializeInputs(kMixerInputs);
358 374
359 // Start() all inputs. 375 // Start() all inputs.
360 for (size_t i = 0; i < mixer_inputs_.size(); ++i) 376 for (size_t i = 0; i < mixer_inputs_.size(); ++i)
361 mixer_inputs_[i]->Start(); 377 mixer_inputs_[i]->Start();
362 378
363 // Stop() all even numbered mixer inputs and Play() all odd numbered inputs 379 // Stop() all even numbered mixer inputs and Play() all odd numbered inputs
364 // and ensure we get the right value. 380 // and ensure we get the right value.
365 for (size_t i = 1; i < mixer_inputs_.size(); i += 2) { 381 for (size_t i = 1; i < mixer_inputs_.size(); i += 2) {
366 mixer_inputs_[i - 1]->Stop(); 382 mixer_inputs_[i - 1]->Stop();
367 mixer_inputs_[i]->Play(); 383 mixer_inputs_[i]->Play();
368 } 384 }
369 for (int i = 0; i < kMixerCycles; ++i) { 385 ASSERT_TRUE(RenderAndValidateAudioData(std::max(
370 fake_callback_->NextFillValue(); 386 mixer_inputs_.size() / 2, static_cast<size_t>(1))));
371 ASSERT_TRUE(RenderAndValidateAudioData(
372 fake_callback_->fill_value() * std::max(
373 mixer_inputs_.size() / 2, static_cast<size_t>(1))));
374 }
375 387
376 for (size_t i = 1; i < mixer_inputs_.size(); i += 2) 388 for (size_t i = 1; i < mixer_inputs_.size(); i += 2)
377 mixer_inputs_[i]->Stop(); 389 mixer_inputs_[i]->Stop();
378 } 390 }
379 391
380 TEST_F(AudioRendererMixerTest, OnRenderError) { 392 TEST_P(AudioRendererMixerTest, OnRenderError) {
381 std::vector< scoped_refptr<AudioRendererMixerInput> > mixer_inputs; 393 InitializeInputs(kMixerInputs);
382 for (int i = 0; i < kMixerInputs; ++i) { 394 for (size_t i = 0; i < mixer_inputs_.size(); ++i) {
383 scoped_refptr<AudioRendererMixerInput> mixer_input( 395 mixer_inputs_[i]->Start();
384 new AudioRendererMixerInput(mixer_)); 396 EXPECT_CALL(*fake_callbacks_[i], OnRenderError()).Times(1);
385 mixer_input->Initialize(audio_parameters_, fake_callback_.get());
386 mixer_input->SetVolume(1.0f);
387 mixer_input->Start();
388 mixer_inputs_.push_back(mixer_input);
389 } 397 }
390 398
391 EXPECT_CALL(*fake_callback_, OnRenderError()).Times(kMixerInputs); 399 mixer_callback_->OnRenderError();
392 sink_->SimulateRenderError(); 400 for (size_t i = 0; i < mixer_inputs_.size(); ++i)
393 for (int i = 0; i < kMixerInputs; ++i)
394 mixer_inputs_[i]->Stop(); 401 mixer_inputs_[i]->Stop();
395 } 402 }
396 403
404 INSTANTIATE_TEST_CASE_P(
405 AudioRendererMixerTest, AudioRendererMixerTest, testing::Values(
406 // No resampling.
407 std::tr1::make_tuple(44100, 44100, 0.000000477),
408
409 // Upsampling.
410 std::tr1::make_tuple(44100, 48000, 0.0329405),
411
412 // Downsampling.
413 std::tr1::make_tuple(48000, 41000, 0.0410239)));
414
397 } // namespace media 415 } // namespace media
OLDNEW
« no previous file with comments | « media/base/audio_renderer_mixer_input_unittest.cc ('k') | media/base/fake_audio_render_callback.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698