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

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

Powered by Google App Engine
This is Rietveld 408576698