1 // Copyright (c) 2012 The Chromium OS 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.
4
5 #include <gtest/gtest.h>
6 #include <stdio.h>
7
8 extern "C" {
9 #include "cras_mix.h"
10 #include "cras_shm.h"
11 #include "cras_types.h"
12 }
13
14 namespace {
15
16 static const size_t kBufferFrames = 8192;
17 static const size_t kNumChannels = 2;
18 static const size_t kNumSamples = kBufferFrames * kNumChannels;
19 static const float kMaxVolumeToScale = 0.9999999;
20 static const float kMinVolumeToScale = 0.0000001;
21
need_to_scale(float scaler)22 static inline int need_to_scale(float scaler) {
23 return (scaler < 0.99 || scaler > 1.01);
24 }
25
26 class MixTestSuiteS16_LE : public testing::Test {
27 protected:
SetUp()28 virtual void SetUp() {
29 fmt_ = SND_PCM_FORMAT_S16_LE;
30 mix_buffer_ = (int16_t*)malloc(kBufferFrames * 4);
31 src_buffer_ = static_cast<int16_t*>(
32 calloc(1, kBufferFrames * 4 + sizeof(cras_audio_shm_header)));
33
34 for (size_t i = 0; i < kBufferFrames * 2; i++) {
35 src_buffer_[i] = i;
36 mix_buffer_[i] = -i;
37 }
38
39 compare_buffer_ = (int16_t*)malloc(kBufferFrames * 4);
40 }
41
TearDown()42 virtual void TearDown() {
43 free(mix_buffer_);
44 free(compare_buffer_);
45 free(src_buffer_);
46 }
47
_SetupBuffer()48 void _SetupBuffer() {
49 for (size_t i = 0; i < kBufferFrames; i++) {
50 src_buffer_[i] = i + (INT16_MAX >> 2);
51 mix_buffer_[i] = i + (INT16_MAX >> 2);
52 compare_buffer_[i] = mix_buffer_[i];
53 }
54 for (size_t i = kBufferFrames; i < kBufferFrames * 2; i++) {
55 src_buffer_[i] = i - (INT16_MAX >> 2);
56 mix_buffer_[i] = i - (INT16_MAX >> 2);
57 compare_buffer_[i] = mix_buffer_[i];
58 }
59 }
60
TestScaleStride(float scaler)61 void TestScaleStride(float scaler) {
62 _SetupBuffer();
63 for (size_t i = 0; i < kBufferFrames * 2; i += 2) {
64 int32_t tmp;
65 if (need_to_scale(scaler))
66 tmp = mix_buffer_[i] + src_buffer_[i / 2] * scaler;
67 else
68 tmp = mix_buffer_[i] + src_buffer_[i / 2];
69 if (tmp > INT16_MAX)
70 tmp = INT16_MAX;
71 else if (tmp < INT16_MIN)
72 tmp = INT16_MIN;
73 compare_buffer_[i] = tmp;
74 }
75
76 cras_mix_add_scale_stride(fmt_, (uint8_t*)mix_buffer_,
77 (uint8_t*)src_buffer_, kBufferFrames, 4, 2,
78 scaler);
79
80 EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * 4));
81 }
82
ScaleIncrement(float start_scaler,float increment,float target)83 void ScaleIncrement(float start_scaler, float increment, float target) {
84 float scaler = start_scaler;
85 for (size_t i = 0; i < kBufferFrames * 2; i++) {
86 float applied_scaler = scaler;
87
88 if ((applied_scaler > target && increment > 0) ||
89 (applied_scaler < target && increment < 0))
90 applied_scaler = target;
91
92 if (applied_scaler > kMaxVolumeToScale) {
93 } else if (applied_scaler < kMinVolumeToScale) {
94 compare_buffer_[i] = 0;
95 } else {
96 compare_buffer_[i] = mix_buffer_[i] * applied_scaler;
97 }
98
99 if (i % 2 == 1)
100 scaler += increment;
101 }
102 }
103
104 int16_t* mix_buffer_;
105 int16_t* src_buffer_;
106 int16_t* compare_buffer_;
107 snd_pcm_format_t fmt_;
108 };
109
TEST_F(MixTestSuiteS16_LE,MixFirst)110 TEST_F(MixTestSuiteS16_LE, MixFirst) {
111 cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples,
112 0, 0, 1.0);
113 EXPECT_EQ(0, memcmp(mix_buffer_, src_buffer_, kBufferFrames * 4));
114 }
115
TEST_F(MixTestSuiteS16_LE,MixTwo)116 TEST_F(MixTestSuiteS16_LE, MixTwo) {
117 cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples,
118 0, 0, 1.0);
119 cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples,
120 1, 0, 1.0);
121
122 for (size_t i = 0; i < kBufferFrames * 2; i++)
123 compare_buffer_[i] = src_buffer_[i] * 2;
124 EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * 4));
125 }
126
TEST_F(MixTestSuiteS16_LE,MixTwoClip)127 TEST_F(MixTestSuiteS16_LE, MixTwoClip) {
128 cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples,
129 0, 0, 1.0);
130 for (size_t i = 0; i < kBufferFrames * 2; i++)
131 src_buffer_[i] = INT16_MAX;
132 cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples,
133 1, 0, 1.0);
134
135 for (size_t i = 0; i < kBufferFrames * 2; i++)
136 compare_buffer_[i] = INT16_MAX;
137 EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * 4));
138 }
139
TEST_F(MixTestSuiteS16_LE,MixFirstMuted)140 TEST_F(MixTestSuiteS16_LE, MixFirstMuted) {
141 cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples,
142 0, 1, 1.0);
143
144 for (size_t i = 0; i < kBufferFrames * 2; i++)
145 compare_buffer_[i] = 0;
146 EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * 4));
147 }
148
TEST_F(MixTestSuiteS16_LE,MixFirstZeroVolume)149 TEST_F(MixTestSuiteS16_LE, MixFirstZeroVolume) {
150 cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples,
151 0, 0, 0.0);
152
153 for (size_t i = 0; i < kBufferFrames * 2; i++)
154 compare_buffer_[i] = 0;
155 EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * 4));
156 }
157
TEST_F(MixTestSuiteS16_LE,MixFirstHalfVolume)158 TEST_F(MixTestSuiteS16_LE, MixFirstHalfVolume) {
159 cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples,
160 0, 0, 0.5);
161
162 for (size_t i = 0; i < kBufferFrames * 2; i++)
163 compare_buffer_[i] = src_buffer_[i] * 0.5;
164 EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * 4));
165 }
166
TEST_F(MixTestSuiteS16_LE,MixTwoSecondHalfVolume)167 TEST_F(MixTestSuiteS16_LE, MixTwoSecondHalfVolume) {
168 cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples,
169 0, 0, 1.0);
170 cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples,
171 1, 0, 0.5);
172
173 for (size_t i = 0; i < kBufferFrames * 2; i++)
174 compare_buffer_[i] = src_buffer_[i] + (int16_t)(src_buffer_[i] * 0.5);
175 EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * 4));
176 }
177
TEST_F(MixTestSuiteS16_LE,ScaleFullVolumeIncrement)178 TEST_F(MixTestSuiteS16_LE, ScaleFullVolumeIncrement) {
179 float increment = 0.01;
180 int step = 2;
181 float start_scaler = 0.999999999;
182 float target = 1.0;
183
184 _SetupBuffer();
185 // Scale full volume with positive increment will not change buffer.
186 memcpy(compare_buffer_, src_buffer_, kBufferFrames * 4);
187 cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames,
188 start_scaler, increment, target, step);
189
190 EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * 4));
191 }
192
TEST_F(MixTestSuiteS16_LE,ScaleMinVolumeIncrement)193 TEST_F(MixTestSuiteS16_LE, ScaleMinVolumeIncrement) {
194 float increment = -0.01;
195 int step = 2;
196 float start_scaler = 0.000000001;
197 float target = 0.0;
198
199 _SetupBuffer();
200 // Scale min volume with negative increment will change buffer to zeros.
201 memset(compare_buffer_, 0, kBufferFrames * 4);
202 cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames,
203 start_scaler, increment, target, step);
204
205 EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * 4));
206 }
207
TEST_F(MixTestSuiteS16_LE,ScaleVolumePositiveIncrement)208 TEST_F(MixTestSuiteS16_LE, ScaleVolumePositiveIncrement) {
209 float increment = 0.0001;
210 int step = 2;
211 float start_scaler = 0.1;
212 float target = 1.0;
213
214 _SetupBuffer();
215 ScaleIncrement(start_scaler, increment, target);
216
217 cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames,
218 start_scaler, increment, target, step);
219 EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * 4));
220 }
221
TEST_F(MixTestSuiteS16_LE,ScaleVolumeNegativeIncrement)222 TEST_F(MixTestSuiteS16_LE, ScaleVolumeNegativeIncrement) {
223 float increment = -0.0001;
224 int step = 2;
225 float start_scaler = 0.8;
226 float target = 0.0;
227
228 _SetupBuffer();
229 ScaleIncrement(start_scaler, increment, target);
230
231 cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames,
232 start_scaler, increment, target, step);
233
234 EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * 4));
235 }
236
TEST_F(MixTestSuiteS16_LE,ScaleVolumeStartFullNegativeIncrement)237 TEST_F(MixTestSuiteS16_LE, ScaleVolumeStartFullNegativeIncrement) {
238 float increment = -0.0001;
239 int step = 2;
240 float start_scaler = 1.0;
241 float target = 0.0;
242
243 _SetupBuffer();
244 ScaleIncrement(start_scaler, increment, target);
245
246 cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames,
247 start_scaler, increment, target, step);
248
249 EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * 4));
250 }
251
TEST_F(MixTestSuiteS16_LE,ScaleVolumeStartZeroPositiveIncrement)252 TEST_F(MixTestSuiteS16_LE, ScaleVolumeStartZeroPositiveIncrement) {
253 float increment = 0.0001;
254 int step = 2;
255 float start_scaler = 0.0;
256 float target = 1.0;
257
258 _SetupBuffer();
259 ScaleIncrement(start_scaler, increment, target);
260
261 cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames,
262 start_scaler, increment, target, step);
263
264 EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * 4));
265 }
266
TEST_F(MixTestSuiteS16_LE,ScaleVolumePositiveIncrementCappedByTarget)267 TEST_F(MixTestSuiteS16_LE, ScaleVolumePositiveIncrementCappedByTarget) {
268 float increment = 0.0001;
269 int step = 2;
270 float start_scaler = 0.1;
271 float target = 0.5;
272
273 _SetupBuffer();
274 ScaleIncrement(start_scaler, increment, target);
275
276 cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames,
277 start_scaler, increment, target, step);
278 EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * 4));
279 }
280
TEST_F(MixTestSuiteS16_LE,ScaleVolumeNegativeIncrementCappedByTarget)281 TEST_F(MixTestSuiteS16_LE, ScaleVolumeNegativeIncrementCappedByTarget) {
282 float increment = -0.01;
283 int step = 2;
284 float start_scaler = 0.8;
285 float target = 0.5;
286
287 _SetupBuffer();
288 ScaleIncrement(start_scaler, increment, target);
289
290 cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames,
291 start_scaler, increment, target, step);
292 EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * 4));
293 }
294
TEST_F(MixTestSuiteS16_LE,ScaleFullVolume)295 TEST_F(MixTestSuiteS16_LE, ScaleFullVolume) {
296 memcpy(compare_buffer_, src_buffer_, kBufferFrames * 4);
297 cras_scale_buffer(fmt_, (uint8_t*)mix_buffer_, kNumSamples, 0.999999999);
298
299 EXPECT_EQ(0, memcmp(compare_buffer_, src_buffer_, kBufferFrames * 4));
300 }
301
TEST_F(MixTestSuiteS16_LE,ScaleMinVolume)302 TEST_F(MixTestSuiteS16_LE, ScaleMinVolume) {
303 memset(compare_buffer_, 0, kBufferFrames * 4);
304 cras_scale_buffer(fmt_, (uint8_t*)src_buffer_, kNumSamples, 0.0000000001);
305
306 EXPECT_EQ(0, memcmp(compare_buffer_, src_buffer_, kBufferFrames * 4));
307 }
308
TEST_F(MixTestSuiteS16_LE,ScaleHalfVolume)309 TEST_F(MixTestSuiteS16_LE, ScaleHalfVolume) {
310 for (size_t i = 0; i < kBufferFrames * 2; i++)
311 compare_buffer_[i] = src_buffer_[i] * 0.5;
312 cras_scale_buffer(fmt_, (uint8_t*)src_buffer_, kNumSamples, 0.5);
313
314 EXPECT_EQ(0, memcmp(compare_buffer_, src_buffer_, kBufferFrames * 4));
315 }
316
TEST_F(MixTestSuiteS16_LE,StrideCopy)317 TEST_F(MixTestSuiteS16_LE, StrideCopy) {
318 TestScaleStride(1.0);
319 TestScaleStride(100);
320 TestScaleStride(0.5);
321 }
322
323 class MixTestSuiteS24_LE : public testing::Test {
324 protected:
SetUp()325 virtual void SetUp() {
326 fmt_ = SND_PCM_FORMAT_S24_LE;
327 fr_bytes_ = 4 * kNumChannels;
328 mix_buffer_ = (int32_t*)malloc(kBufferFrames * fr_bytes_);
329 src_buffer_ = static_cast<int32_t*>(
330 calloc(1, kBufferFrames * fr_bytes_ + sizeof(cras_audio_shm_header)));
331
332 for (size_t i = 0; i < kBufferFrames * 2; i++) {
333 src_buffer_[i] = i;
334 mix_buffer_[i] = -i;
335 }
336
337 compare_buffer_ = (int32_t*)malloc(kBufferFrames * fr_bytes_);
338 }
339
TearDown()340 virtual void TearDown() {
341 free(mix_buffer_);
342 free(compare_buffer_);
343 free(src_buffer_);
344 }
345
_SetupBuffer()346 void _SetupBuffer() {
347 for (size_t i = 0; i < kBufferFrames; i++) {
348 src_buffer_[i] = i + (0x007fffff >> 2);
349 mix_buffer_[i] = i + (0x007fffff >> 2);
350 compare_buffer_[i] = mix_buffer_[i];
351 }
352 for (size_t i = kBufferFrames; i < kBufferFrames * 2; i++) {
353 src_buffer_[i] = -i - (0x007fffff >> 2);
354 mix_buffer_[i] = -i - (0x007fffff >> 2);
355 compare_buffer_[i] = mix_buffer_[i];
356 }
357 }
358
TestScaleStride(float scaler)359 void TestScaleStride(float scaler) {
360 _SetupBuffer();
361 for (size_t i = 0; i < kBufferFrames * 2; i += 2) {
362 int32_t tmp;
363 if (need_to_scale(scaler))
364 tmp = mix_buffer_[i] + Scale(src_buffer_[i / 2], scaler);
365 else
366 tmp = mix_buffer_[i] + src_buffer_[i / 2];
367 if (tmp > 0x007fffff)
368 tmp = 0x007fffff;
369 else if (tmp < (int32_t)0xff800000)
370 tmp = (int32_t)0xff800000;
371 compare_buffer_[i] = tmp;
372 }
373
374 cras_mix_add_scale_stride(fmt_, (uint8_t*)mix_buffer_,
375 (uint8_t*)src_buffer_, kBufferFrames, 8, 4,
376 scaler);
377
378 EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * 8));
379 }
380
ScaleIncrement(float start_scaler,float increment,float target)381 void ScaleIncrement(float start_scaler, float increment, float target) {
382 float scaler = start_scaler;
383
384 for (size_t i = 0; i < kBufferFrames * 2; i++) {
385 float applied_scaler = scaler;
386
387 if ((applied_scaler > target && increment > 0) ||
388 (applied_scaler < target && increment < 0))
389 applied_scaler = target;
390
391 if (applied_scaler > kMaxVolumeToScale) {
392 } else if (applied_scaler < kMinVolumeToScale) {
393 compare_buffer_[i] = 0;
394 } else {
395 compare_buffer_[i] = Scale(mix_buffer_[i], applied_scaler);
396 }
397
398 if (i % 2 == 1)
399 scaler += increment;
400 }
401 }
402
Scale(int32_t value,float scaler)403 int32_t Scale(int32_t value, float scaler) {
404 value = ((uint32_t)(value & 0x00ffffff)) << 8;
405 value *= scaler;
406 return (value >> 8) & 0x00ffffff;
407 }
408
409 int32_t* mix_buffer_;
410 int32_t* src_buffer_;
411 int32_t* compare_buffer_;
412 snd_pcm_format_t fmt_;
413 unsigned int fr_bytes_;
414 };
415
TEST_F(MixTestSuiteS24_LE,MixFirst)416 TEST_F(MixTestSuiteS24_LE, MixFirst) {
417 cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples,
418 0, 0, 1.0);
419 EXPECT_EQ(0, memcmp(mix_buffer_, src_buffer_, kBufferFrames * fr_bytes_));
420 }
421
TEST_F(MixTestSuiteS24_LE,MixTwo)422 TEST_F(MixTestSuiteS24_LE, MixTwo) {
423 cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples,
424 0, 0, 1.0);
425 cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples,
426 1, 0, 1.0);
427
428 for (size_t i = 0; i < kBufferFrames * 2; i++)
429 compare_buffer_[i] = Scale(src_buffer_[i], 2);
430 EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * fr_bytes_));
431 }
432
TEST_F(MixTestSuiteS24_LE,MixTwoClip)433 TEST_F(MixTestSuiteS24_LE, MixTwoClip) {
434 cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples,
435 0, 0, 1.0);
436 for (size_t i = 0; i < kBufferFrames * 2; i++)
437 src_buffer_[i] = 0x007fffff;
438 cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples,
439 1, 0, 1.0);
440
441 for (size_t i = 0; i < kBufferFrames * 2; i++)
442 compare_buffer_[i] = 0x007fffff;
443 EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * fr_bytes_));
444 }
445
TEST_F(MixTestSuiteS24_LE,MixFirstMuted)446 TEST_F(MixTestSuiteS24_LE, MixFirstMuted) {
447 cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples,
448 0, 1, 1.0);
449
450 for (size_t i = 0; i < kBufferFrames * 2; i++)
451 compare_buffer_[i] = 0;
452 EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * fr_bytes_));
453 }
454
TEST_F(MixTestSuiteS24_LE,MixFirstZeroVolume)455 TEST_F(MixTestSuiteS24_LE, MixFirstZeroVolume) {
456 cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples,
457 0, 0, 0.0);
458
459 for (size_t i = 0; i < kBufferFrames * 2; i++)
460 compare_buffer_[i] = 0;
461 EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * fr_bytes_));
462 }
463
TEST_F(MixTestSuiteS24_LE,MixFirstHalfVolume)464 TEST_F(MixTestSuiteS24_LE, MixFirstHalfVolume) {
465 cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples,
466 0, 0, 0.5);
467
468 for (size_t i = 0; i < kBufferFrames * 2; i++)
469 compare_buffer_[i] = Scale(src_buffer_[i], 0.5);
470 EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * fr_bytes_));
471 }
472
TEST_F(MixTestSuiteS24_LE,MixTwoSecondHalfVolume)473 TEST_F(MixTestSuiteS24_LE, MixTwoSecondHalfVolume) {
474 cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples,
475 0, 0, 1.0);
476 cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples,
477 1, 0, 0.5);
478
479 for (size_t i = 0; i < kBufferFrames * 2; i++)
480 compare_buffer_[i] = src_buffer_[i] + Scale(src_buffer_[i], 0.5);
481 EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * fr_bytes_));
482 }
483
TEST_F(MixTestSuiteS24_LE,ScaleFullVolumeIncrement)484 TEST_F(MixTestSuiteS24_LE, ScaleFullVolumeIncrement) {
485 float increment = 0.01;
486 int step = 2;
487 float start_scaler = 0.999999999;
488 float target = 1.0;
489
490 _SetupBuffer();
491 // Scale full volume with positive increment will not change buffer.
492 memcpy(compare_buffer_, src_buffer_, kBufferFrames * fr_bytes_);
493 cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames,
494 start_scaler, increment, target, step);
495
496 EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * fr_bytes_));
497 }
498
TEST_F(MixTestSuiteS24_LE,ScaleMinVolumeIncrement)499 TEST_F(MixTestSuiteS24_LE, ScaleMinVolumeIncrement) {
500 float increment = -0.01;
501 int step = 2;
502 float start_scaler = 0.000000001;
503 float target = 0.0;
504
505 _SetupBuffer();
506 // Scale min volume with negative increment will change buffer to zeros.
507 memset(compare_buffer_, 0, kBufferFrames * fr_bytes_);
508 cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames,
509 start_scaler, increment, target, step);
510
511 EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * fr_bytes_));
512 }
513
TEST_F(MixTestSuiteS24_LE,ScaleVolumePositiveIncrement)514 TEST_F(MixTestSuiteS24_LE, ScaleVolumePositiveIncrement) {
515 float increment = 0.0001;
516 int step = 2;
517 float start_scaler = 0.1;
518 float target = 1.0;
519
520 _SetupBuffer();
521 ScaleIncrement(start_scaler, increment, target);
522
523 cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames,
524 start_scaler, increment, target, step);
525 EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * fr_bytes_));
526 }
527
TEST_F(MixTestSuiteS24_LE,ScaleVolumeNegativeIncrement)528 TEST_F(MixTestSuiteS24_LE, ScaleVolumeNegativeIncrement) {
529 float increment = -0.0001;
530 int step = 2;
531 float start_scaler = 0.8;
532 float target = 0.0;
533
534 _SetupBuffer();
535 ScaleIncrement(start_scaler, increment, target);
536
537 cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames,
538 start_scaler, increment, target, step);
539
540 EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * fr_bytes_));
541 }
542
TEST_F(MixTestSuiteS24_LE,ScaleVolumeStartFullNegativeIncrement)543 TEST_F(MixTestSuiteS24_LE, ScaleVolumeStartFullNegativeIncrement) {
544 float increment = -0.0001;
545 int step = 2;
546 float start_scaler = 1.0;
547 float target = 0.0;
548
549 _SetupBuffer();
550 ScaleIncrement(start_scaler, increment, target);
551
552 cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames,
553 start_scaler, increment, target, step);
554
555 EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * 4));
556 }
557
TEST_F(MixTestSuiteS24_LE,ScaleVolumeStartZeroPositiveIncrement)558 TEST_F(MixTestSuiteS24_LE, ScaleVolumeStartZeroPositiveIncrement) {
559 float increment = 0.0001;
560 int step = 2;
561 float start_scaler = 0.0;
562 float target = 1.0;
563
564 _SetupBuffer();
565 ScaleIncrement(start_scaler, increment, target);
566
567 cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames,
568 start_scaler, increment, target, step);
569
570 EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * 4));
571 }
572
TEST_F(MixTestSuiteS24_LE,ScaleVolumePositiveIncrementCappedByTarget)573 TEST_F(MixTestSuiteS24_LE, ScaleVolumePositiveIncrementCappedByTarget) {
574 float increment = 0.0001;
575 int step = 2;
576 float start_scaler = 0.1;
577 float target = 0.5;
578
579 _SetupBuffer();
580 ScaleIncrement(start_scaler, increment, target);
581
582 cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames,
583 start_scaler, increment, target, step);
584 EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * fr_bytes_));
585 }
586
TEST_F(MixTestSuiteS24_LE,ScaleVolumeNegativeIncrementCappedByTarget)587 TEST_F(MixTestSuiteS24_LE, ScaleVolumeNegativeIncrementCappedByTarget) {
588 float increment = -0.01;
589 int step = 2;
590 float start_scaler = 0.8;
591 float target = 0.5;
592
593 _SetupBuffer();
594 ScaleIncrement(start_scaler, increment, target);
595
596 cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames,
597 start_scaler, increment, target, step);
598 EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * fr_bytes_));
599 }
600
TEST_F(MixTestSuiteS24_LE,ScaleFullVolume)601 TEST_F(MixTestSuiteS24_LE, ScaleFullVolume) {
602 memcpy(compare_buffer_, src_buffer_, kBufferFrames * fr_bytes_);
603 cras_scale_buffer(fmt_, (uint8_t*)mix_buffer_, kNumSamples, 0.999999999);
604
605 EXPECT_EQ(0, memcmp(compare_buffer_, src_buffer_, kBufferFrames * fr_bytes_));
606 }
607
TEST_F(MixTestSuiteS24_LE,ScaleMinVolume)608 TEST_F(MixTestSuiteS24_LE, ScaleMinVolume) {
609 memset(compare_buffer_, 0, kBufferFrames * fr_bytes_);
610 cras_scale_buffer(fmt_, (uint8_t*)src_buffer_, kNumSamples, 0.0000000001);
611
612 EXPECT_EQ(0, memcmp(compare_buffer_, src_buffer_, kBufferFrames * fr_bytes_));
613 }
614
TEST_F(MixTestSuiteS24_LE,ScaleHalfVolume)615 TEST_F(MixTestSuiteS24_LE, ScaleHalfVolume) {
616 for (size_t i = 0; i < kBufferFrames * 2; i++)
617 compare_buffer_[i] = Scale(src_buffer_[i], 0.5);
618 cras_scale_buffer(fmt_, (uint8_t*)src_buffer_, kNumSamples, 0.5);
619
620 EXPECT_EQ(0, memcmp(compare_buffer_, src_buffer_, kBufferFrames * fr_bytes_));
621 }
622
TEST_F(MixTestSuiteS24_LE,StrideCopy)623 TEST_F(MixTestSuiteS24_LE, StrideCopy) {
624 TestScaleStride(1.0);
625 TestScaleStride(100);
626 TestScaleStride(0.1);
627 }
628
629 class MixTestSuiteS32_LE : public testing::Test {
630 protected:
SetUp()631 virtual void SetUp() {
632 fmt_ = SND_PCM_FORMAT_S32_LE;
633 fr_bytes_ = 4 * kNumChannels;
634 mix_buffer_ = (int32_t*)malloc(kBufferFrames * fr_bytes_);
635 src_buffer_ = static_cast<int32_t*>(
636 calloc(1, kBufferFrames * fr_bytes_ + sizeof(cras_audio_shm_header)));
637
638 for (size_t i = 0; i < kBufferFrames * 2; i++) {
639 src_buffer_[i] = i;
640 mix_buffer_[i] = -i;
641 }
642
643 compare_buffer_ = (int32_t*)malloc(kBufferFrames * fr_bytes_);
644 }
645
TearDown()646 virtual void TearDown() {
647 free(mix_buffer_);
648 free(compare_buffer_);
649 free(src_buffer_);
650 }
651
_SetupBuffer()652 void _SetupBuffer() {
653 for (size_t i = 0; i < kBufferFrames; i++) {
654 src_buffer_[i] = i + (INT32_MAX >> 2);
655 mix_buffer_[i] = i + (INT32_MAX >> 2);
656 compare_buffer_[i] = mix_buffer_[i];
657 }
658 for (size_t i = kBufferFrames; i < kBufferFrames * 2; i++) {
659 src_buffer_[i] = i - (INT32_MAX >> 2);
660 mix_buffer_[i] = i - (INT32_MAX >> 2);
661 compare_buffer_[i] = mix_buffer_[i];
662 }
663 }
664
TestScaleStride(float scaler)665 void TestScaleStride(float scaler) {
666 _SetupBuffer();
667 for (size_t i = 0; i < kBufferFrames * 2; i += 2) {
668 int64_t tmp;
669 if (need_to_scale(scaler))
670 tmp = mix_buffer_[i] + src_buffer_[i / 2] * scaler;
671 else
672 tmp = mix_buffer_[i] + src_buffer_[i / 2];
673 if (tmp > INT32_MAX)
674 tmp = INT32_MAX;
675 else if (tmp < INT32_MIN)
676 tmp = INT32_MIN;
677 compare_buffer_[i] = tmp;
678 }
679
680 cras_mix_add_scale_stride(fmt_, (uint8_t*)mix_buffer_,
681 (uint8_t*)src_buffer_, kBufferFrames, 8, 4,
682 scaler);
683
684 EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * 8));
685 }
686
ScaleIncrement(float start_scaler,float increment,float target)687 void ScaleIncrement(float start_scaler, float increment, float target) {
688 float scaler = start_scaler;
689
690 for (size_t i = 0; i < kBufferFrames * 2; i++) {
691 float applied_scaler = scaler;
692
693 if ((applied_scaler > target && increment > 0) ||
694 (applied_scaler < target && increment < 0))
695 applied_scaler = target;
696
697 if (applied_scaler > kMaxVolumeToScale) {
698 } else if (applied_scaler < kMinVolumeToScale) {
699 compare_buffer_[i] = 0;
700 } else {
701 compare_buffer_[i] = mix_buffer_[i] * applied_scaler;
702 }
703
704 if (i % 2 == 1)
705 scaler += increment;
706 }
707 }
708
709 int32_t* mix_buffer_;
710 int32_t* src_buffer_;
711 int32_t* compare_buffer_;
712 snd_pcm_format_t fmt_;
713 unsigned int fr_bytes_;
714 };
715
TEST_F(MixTestSuiteS32_LE,MixFirst)716 TEST_F(MixTestSuiteS32_LE, MixFirst) {
717 cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples,
718 0, 0, 1.0);
719 EXPECT_EQ(0, memcmp(mix_buffer_, src_buffer_, kBufferFrames * fr_bytes_));
720 }
721
TEST_F(MixTestSuiteS32_LE,MixTwo)722 TEST_F(MixTestSuiteS32_LE, MixTwo) {
723 cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples,
724 0, 0, 1.0);
725 cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples,
726 1, 0, 1.0);
727
728 for (size_t i = 0; i < kBufferFrames * 2; i++)
729 compare_buffer_[i] = src_buffer_[i] * 2;
730 EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * fr_bytes_));
731 }
732
TEST_F(MixTestSuiteS32_LE,MixTwoClip)733 TEST_F(MixTestSuiteS32_LE, MixTwoClip) {
734 cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples,
735 0, 0, 1.0);
736 for (size_t i = 0; i < kBufferFrames * 2; i++)
737 src_buffer_[i] = INT32_MAX;
738 cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples,
739 1, 0, 1.0);
740
741 for (size_t i = 0; i < kBufferFrames * 2; i++)
742 compare_buffer_[i] = INT32_MAX;
743 EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * fr_bytes_));
744 }
745
TEST_F(MixTestSuiteS32_LE,MixFirstMuted)746 TEST_F(MixTestSuiteS32_LE, MixFirstMuted) {
747 cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples,
748 0, 1, 1.0);
749
750 for (size_t i = 0; i < kBufferFrames * 2; i++)
751 compare_buffer_[i] = 0;
752 EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * fr_bytes_));
753 }
754
TEST_F(MixTestSuiteS32_LE,MixFirstZeroVolume)755 TEST_F(MixTestSuiteS32_LE, MixFirstZeroVolume) {
756 cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples,
757 0, 0, 0.0);
758
759 for (size_t i = 0; i < kBufferFrames * 2; i++)
760 compare_buffer_[i] = 0;
761 EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * fr_bytes_));
762 }
763
TEST_F(MixTestSuiteS32_LE,MixFirstHalfVolume)764 TEST_F(MixTestSuiteS32_LE, MixFirstHalfVolume) {
765 cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples,
766 0, 0, 0.5);
767
768 for (size_t i = 0; i < kBufferFrames * 2; i++)
769 compare_buffer_[i] = src_buffer_[i] * 0.5;
770 EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * fr_bytes_));
771 }
772
TEST_F(MixTestSuiteS32_LE,MixTwoSecondHalfVolume)773 TEST_F(MixTestSuiteS32_LE, MixTwoSecondHalfVolume) {
774 cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples,
775 0, 0, 1.0);
776 cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples,
777 1, 0, 0.5);
778
779 for (size_t i = 0; i < kBufferFrames * 2; i++)
780 compare_buffer_[i] = src_buffer_[i] + (int32_t)(src_buffer_[i] * 0.5);
781 EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * fr_bytes_));
782 }
783
TEST_F(MixTestSuiteS32_LE,ScaleFullVolumeIncrement)784 TEST_F(MixTestSuiteS32_LE, ScaleFullVolumeIncrement) {
785 float increment = 0.01;
786 int step = 2;
787 float start_scaler = 0.999999999;
788 float target = 1.0;
789
790 _SetupBuffer();
791 // Scale full volume with positive increment will not change buffer.
792 memcpy(compare_buffer_, src_buffer_, kBufferFrames * fr_bytes_);
793 cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames,
794 start_scaler, increment, target, step);
795
796 EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * fr_bytes_));
797 }
798
TEST_F(MixTestSuiteS32_LE,ScaleMinVolumeIncrement)799 TEST_F(MixTestSuiteS32_LE, ScaleMinVolumeIncrement) {
800 float increment = -0.01;
801 int step = 2;
802 float start_scaler = 0.000000001;
803 float target = 0.0;
804
805 _SetupBuffer();
806 // Scale min volume with negative increment will change buffer to zeros.
807 memset(compare_buffer_, 0, kBufferFrames * fr_bytes_);
808 cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames,
809 start_scaler, increment, target, step);
810
811 EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * fr_bytes_));
812 }
813
TEST_F(MixTestSuiteS32_LE,ScaleVolumePositiveIncrement)814 TEST_F(MixTestSuiteS32_LE, ScaleVolumePositiveIncrement) {
815 float increment = 0.0001;
816 int step = 2;
817 float start_scaler = 0.1;
818 float target = 1.0;
819
820 _SetupBuffer();
821 ScaleIncrement(start_scaler, increment, target);
822
823 cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames,
824 start_scaler, increment, target, step);
825 EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * fr_bytes_));
826 }
827
TEST_F(MixTestSuiteS32_LE,ScaleVolumeNegativeIncrement)828 TEST_F(MixTestSuiteS32_LE, ScaleVolumeNegativeIncrement) {
829 float increment = -0.0001;
830 int step = 2;
831 float start_scaler = 0.8;
832 float target = 0.0;
833
834 _SetupBuffer();
835 ScaleIncrement(start_scaler, increment, target);
836
837 cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames,
838 start_scaler, increment, target, step);
839
840 EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * fr_bytes_));
841 }
842
TEST_F(MixTestSuiteS32_LE,ScaleVolumeStartFullNegativeIncrement)843 TEST_F(MixTestSuiteS32_LE, ScaleVolumeStartFullNegativeIncrement) {
844 float increment = -0.0001;
845 int step = 2;
846 float start_scaler = 1.0;
847 float target = 0.0;
848
849 _SetupBuffer();
850 ScaleIncrement(start_scaler, increment, target);
851
852 cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames,
853 start_scaler, increment, target, step);
854
855 EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * 4));
856 }
857
TEST_F(MixTestSuiteS32_LE,ScaleVolumeStartZeroPositiveIncrement)858 TEST_F(MixTestSuiteS32_LE, ScaleVolumeStartZeroPositiveIncrement) {
859 float increment = 0.0001;
860 int step = 2;
861 float start_scaler = 0.0;
862 float target = 1.0;
863
864 _SetupBuffer();
865 ScaleIncrement(start_scaler, increment, target);
866
867 cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames,
868 start_scaler, increment, target, step);
869
870 EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * 4));
871 }
872
TEST_F(MixTestSuiteS32_LE,ScaleVolumePositiveIncrementCappedByTarget)873 TEST_F(MixTestSuiteS32_LE, ScaleVolumePositiveIncrementCappedByTarget) {
874 float increment = 0.0001;
875 int step = 2;
876 float start_scaler = 0.1;
877 float target = 0.5;
878
879 _SetupBuffer();
880 ScaleIncrement(start_scaler, increment, target);
881
882 cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames,
883 start_scaler, increment, target, step);
884 EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * fr_bytes_));
885 }
886
TEST_F(MixTestSuiteS32_LE,ScaleVolumeNegativeIncrementCappedByTarget)887 TEST_F(MixTestSuiteS32_LE, ScaleVolumeNegativeIncrementCappedByTarget) {
888 float increment = -0.01;
889 int step = 2;
890 float start_scaler = 0.8;
891 float target = 0.5;
892
893 _SetupBuffer();
894 ScaleIncrement(start_scaler, increment, target);
895
896 cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames,
897 start_scaler, increment, target, step);
898 EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * fr_bytes_));
899 }
900
TEST_F(MixTestSuiteS32_LE,ScaleFullVolume)901 TEST_F(MixTestSuiteS32_LE, ScaleFullVolume) {
902 memcpy(compare_buffer_, src_buffer_, kBufferFrames * fr_bytes_);
903 cras_scale_buffer(fmt_, (uint8_t*)mix_buffer_, kNumSamples, 0.999999999);
904
905 EXPECT_EQ(0, memcmp(compare_buffer_, src_buffer_, kBufferFrames * fr_bytes_));
906 }
907
TEST_F(MixTestSuiteS32_LE,ScaleMinVolume)908 TEST_F(MixTestSuiteS32_LE, ScaleMinVolume) {
909 memset(compare_buffer_, 0, kBufferFrames * fr_bytes_);
910 cras_scale_buffer(fmt_, (uint8_t*)src_buffer_, kNumSamples, 0.0000000001);
911
912 EXPECT_EQ(0, memcmp(compare_buffer_, src_buffer_, kBufferFrames * fr_bytes_));
913 }
914
TEST_F(MixTestSuiteS32_LE,ScaleHalfVolume)915 TEST_F(MixTestSuiteS32_LE, ScaleHalfVolume) {
916 for (size_t i = 0; i < kBufferFrames * 2; i++)
917 compare_buffer_[i] = src_buffer_[i] * 0.5;
918 cras_scale_buffer(fmt_, (uint8_t*)src_buffer_, kNumSamples, 0.5);
919
920 EXPECT_EQ(0, memcmp(compare_buffer_, src_buffer_, kBufferFrames * fr_bytes_));
921 }
922
TEST_F(MixTestSuiteS32_LE,StrideCopy)923 TEST_F(MixTestSuiteS32_LE, StrideCopy) {
924 TestScaleStride(1.0);
925 TestScaleStride(100);
926 TestScaleStride(0.1);
927 }
928
929 class MixTestSuiteS24_3LE : public testing::Test {
930 protected:
SetUp()931 virtual void SetUp() {
932 fmt_ = SND_PCM_FORMAT_S24_3LE;
933 fr_bytes_ = 3 * kNumChannels;
934 mix_buffer_ = (uint8_t*)malloc(kBufferFrames * fr_bytes_);
935 src_buffer_ = static_cast<uint8_t*>(
936 calloc(1, kBufferFrames * fr_bytes_ + sizeof(cras_audio_shm_header)));
937
938 for (size_t i = 0; i < kBufferFrames * kNumChannels; i++) {
939 memcpy(src_buffer_ + 3 * i, &i, 3);
940 int32_t tmp = -i * 256;
941 memcpy(mix_buffer_ + 3 * i, (uint8_t*)&tmp + 1, 3);
942 }
943
944 compare_buffer_ = (uint8_t*)malloc(kBufferFrames * fr_bytes_);
945 }
946
TearDown()947 virtual void TearDown() {
948 free(mix_buffer_);
949 free(compare_buffer_);
950 free(src_buffer_);
951 }
952
_SetupBuffer()953 void _SetupBuffer() {
954 memset(compare_buffer_, 0, kBufferFrames * fr_bytes_);
955 for (size_t i = 0; i < kBufferFrames; i++) {
956 int32_t tmp = (i << 8) + (INT32_MAX >> 2);
957 memcpy(src_buffer_ + 3 * i, (uint8_t*)&tmp + 1, 3);
958 memcpy(mix_buffer_ + 3 * i, (uint8_t*)&tmp + 1, 3);
959 memcpy(compare_buffer_ + 3 * i, (uint8_t*)&tmp + 1, 3);
960 }
961 for (size_t i = kBufferFrames; i < kBufferFrames * 2; i++) {
962 int32_t tmp = (i << 8) - (INT32_MAX >> 2);
963 memcpy(src_buffer_ + 3 * i, (uint8_t*)&tmp + 1, 3);
964 memcpy(mix_buffer_ + 3 * i, (uint8_t*)&tmp + 1, 3);
965 memcpy(compare_buffer_ + 3 * i, (uint8_t*)&tmp + 1, 3);
966 }
967 }
968
TestScaleStride(float scaler)969 void TestScaleStride(float scaler) {
970 _SetupBuffer();
971 for (size_t i = 0; i < kBufferFrames * kNumChannels; i += 2) {
972 int64_t tmp;
973 int32_t src_frame = 0;
974 int32_t dst_frame = 0;
975 memcpy((uint8_t*)&src_frame + 1, src_buffer_ + 3 * i / 2, 3);
976 memcpy((uint8_t*)&dst_frame + 1, mix_buffer_ + 3 * i, 3);
977 if (need_to_scale(scaler))
978 tmp = (int64_t)dst_frame + (int64_t)src_frame * scaler;
979 else
980 tmp = (int64_t)dst_frame + (int64_t)src_frame;
981 if (tmp > INT32_MAX)
982 tmp = INT32_MAX;
983 else if (tmp < INT32_MIN)
984 tmp = INT32_MIN;
985 dst_frame = (int32_t)tmp;
986 memcpy(compare_buffer_ + 3 * i, (uint8_t*)&dst_frame + 1, 3);
987 }
988
989 cras_mix_add_scale_stride(fmt_, (uint8_t*)mix_buffer_,
990 (uint8_t*)src_buffer_, kBufferFrames, 6, 3,
991 scaler);
992
993 EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * 6));
994 }
995
ScaleIncrement(float start_scaler,float increment,float target)996 void ScaleIncrement(float start_scaler, float increment, float target) {
997 float scaler = start_scaler;
998
999 for (size_t i = 0; i < kBufferFrames * kNumChannels; i++) {
1000 float applied_scaler = scaler;
1001 int32_t tmp = 0;
1002 memcpy((uint8_t*)&tmp + 1, src_buffer_ + 3 * i, 3);
1003
1004 if ((applied_scaler > target && increment > 0) ||
1005 (applied_scaler < target && increment < 0))
1006 applied_scaler = target;
1007
1008 if (applied_scaler > kMaxVolumeToScale) {
1009 } else if (applied_scaler < kMinVolumeToScale) {
1010 tmp = 0;
1011 } else {
1012 tmp *= applied_scaler;
1013 }
1014
1015 memcpy(compare_buffer_ + 3 * i, (uint8_t*)&tmp + 1, 3);
1016
1017 if (i % 2 == 1)
1018 scaler += increment;
1019 }
1020 }
1021
1022 uint8_t* mix_buffer_;
1023 uint8_t* src_buffer_;
1024 uint8_t* compare_buffer_;
1025 snd_pcm_format_t fmt_;
1026 unsigned int fr_bytes_;
1027 };
1028
TEST_F(MixTestSuiteS24_3LE,MixFirst)1029 TEST_F(MixTestSuiteS24_3LE, MixFirst) {
1030 cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples,
1031 0, 0, 1.0);
1032 EXPECT_EQ(0, memcmp(mix_buffer_, src_buffer_, kBufferFrames * fr_bytes_));
1033 }
1034
TEST_F(MixTestSuiteS24_3LE,MixTwo)1035 TEST_F(MixTestSuiteS24_3LE, MixTwo) {
1036 cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples,
1037 0, 0, 1.0);
1038 cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples,
1039 1, 0, 1.0);
1040
1041 for (size_t i = 0; i < kBufferFrames * kNumChannels; i++) {
1042 int32_t tmp = 0;
1043 memcpy((uint8_t*)&tmp + 1, src_buffer_ + 3 * i, 3);
1044 tmp *= 2;
1045 memcpy(compare_buffer_ + 3 * i, (uint8_t*)&tmp + 1, 3);
1046 }
1047 EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * fr_bytes_));
1048 }
1049
TEST_F(MixTestSuiteS24_3LE,MixTwoClip)1050 TEST_F(MixTestSuiteS24_3LE, MixTwoClip) {
1051 cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples,
1052 0, 0, 1.0);
1053 for (size_t i = 0; i < kBufferFrames * kNumChannels; i++) {
1054 int32_t tmp = INT32_MAX;
1055 memcpy(src_buffer_ + 3 * i, (uint8_t*)&tmp + 1, 3);
1056 }
1057 cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples,
1058 1, 0, 1.0);
1059
1060 for (size_t i = 0; i < kBufferFrames * kNumChannels; i++) {
1061 int32_t tmp = INT32_MAX;
1062 memcpy(compare_buffer_ + 3 * i, (uint8_t*)&tmp + 1, 3);
1063 }
1064 EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * fr_bytes_));
1065 }
1066
TEST_F(MixTestSuiteS24_3LE,MixFirstMuted)1067 TEST_F(MixTestSuiteS24_3LE, MixFirstMuted) {
1068 cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples,
1069 0, 1, 1.0);
1070
1071 for (size_t i = 0; i < kBufferFrames * kNumChannels; i++)
1072 memset(compare_buffer_ + 3 * i, 0, 3);
1073 EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * fr_bytes_));
1074 }
1075
TEST_F(MixTestSuiteS24_3LE,MixFirstZeroVolume)1076 TEST_F(MixTestSuiteS24_3LE, MixFirstZeroVolume) {
1077 cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples,
1078 0, 0, 0.0);
1079
1080 for (size_t i = 0; i < kBufferFrames * kNumChannels; i++)
1081 memset(compare_buffer_ + 3 * i, 0, 3);
1082 EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * fr_bytes_));
1083 }
1084
TEST_F(MixTestSuiteS24_3LE,MixFirstHalfVolume)1085 TEST_F(MixTestSuiteS24_3LE, MixFirstHalfVolume) {
1086 cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples,
1087 0, 0, 0.5);
1088
1089 for (size_t i = 0; i < kBufferFrames * kNumChannels; i++) {
1090 int32_t tmp = 0;
1091 memcpy((uint8_t*)&tmp + 1, src_buffer_ + 3 * i, 3);
1092 tmp *= 0.5;
1093 memcpy(compare_buffer_ + 3 * i, (uint8_t*)&tmp + 1, 3);
1094 }
1095 EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * fr_bytes_));
1096 }
1097
TEST_F(MixTestSuiteS24_3LE,MixTwoSecondHalfVolume)1098 TEST_F(MixTestSuiteS24_3LE, MixTwoSecondHalfVolume) {
1099 cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples,
1100 0, 0, 1.0);
1101 cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples,
1102 1, 0, 0.5);
1103
1104 for (size_t i = 0; i < kBufferFrames * kNumChannels; i++) {
1105 int32_t tmp1 = 0, tmp2 = 0;
1106 memcpy((uint8_t*)&tmp1 + 1, src_buffer_ + 3 * i, 3);
1107 memcpy((uint8_t*)&tmp2 + 1, src_buffer_ + 3 * i, 3);
1108 tmp1 = tmp1 + (int32_t)(tmp2 * 0.5);
1109 memcpy(compare_buffer_ + 3 * i, (uint8_t*)&tmp1 + 1, 3);
1110 }
1111 EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * fr_bytes_));
1112 }
1113
TEST_F(MixTestSuiteS24_3LE,ScaleFullVolumeIncrement)1114 TEST_F(MixTestSuiteS24_3LE, ScaleFullVolumeIncrement) {
1115 float increment = 0.01;
1116 int step = 2;
1117 float start_scaler = 0.999999999;
1118 float target = 1.0;
1119
1120 _SetupBuffer();
1121 // Scale full volume with positive increment will not change buffer.
1122 memcpy(compare_buffer_, src_buffer_, kBufferFrames * fr_bytes_);
1123 cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames,
1124 start_scaler, increment, target, step);
1125
1126 EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * fr_bytes_));
1127 }
1128
TEST_F(MixTestSuiteS24_3LE,ScaleMinVolumeIncrement)1129 TEST_F(MixTestSuiteS24_3LE, ScaleMinVolumeIncrement) {
1130 float increment = -0.01;
1131 int step = 2;
1132 float start_scaler = 0.000000001;
1133 float target = 0.0;
1134
1135 _SetupBuffer();
1136 // Scale min volume with negative increment will change buffer to zeros.
1137 memset(compare_buffer_, 0, kBufferFrames * fr_bytes_);
1138 cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames,
1139 start_scaler, increment, target, step);
1140
1141 EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * fr_bytes_));
1142 }
1143
TEST_F(MixTestSuiteS24_3LE,ScaleVolumePositiveIncrement)1144 TEST_F(MixTestSuiteS24_3LE, ScaleVolumePositiveIncrement) {
1145 float increment = 0.0001;
1146 int step = 2;
1147 float start_scaler = 0.1;
1148 float target = 1.0;
1149
1150 _SetupBuffer();
1151 ScaleIncrement(start_scaler, increment, target);
1152
1153 cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames,
1154 start_scaler, increment, target, step);
1155 EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * fr_bytes_));
1156 }
1157
TEST_F(MixTestSuiteS24_3LE,ScaleVolumeNegativeIncrement)1158 TEST_F(MixTestSuiteS24_3LE, ScaleVolumeNegativeIncrement) {
1159 float increment = -0.0001;
1160 int step = 2;
1161 float start_scaler = 0.8;
1162 float target = 0.0;
1163
1164 _SetupBuffer();
1165 ScaleIncrement(start_scaler, increment, target);
1166
1167 cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames,
1168 start_scaler, increment, target, step);
1169
1170 EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * fr_bytes_));
1171 }
1172
TEST_F(MixTestSuiteS24_3LE,ScaleVolumeStartFullNegativeIncrement)1173 TEST_F(MixTestSuiteS24_3LE, ScaleVolumeStartFullNegativeIncrement) {
1174 float increment = -0.0001;
1175 int step = 2;
1176 float start_scaler = 1.0;
1177 float target = 0.0;
1178
1179 _SetupBuffer();
1180 ScaleIncrement(start_scaler, increment, target);
1181
1182 cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames,
1183 start_scaler, increment, target, step);
1184
1185 EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * 4));
1186 }
1187
TEST_F(MixTestSuiteS24_3LE,ScaleVolumeStartZeroPositiveIncrement)1188 TEST_F(MixTestSuiteS24_3LE, ScaleVolumeStartZeroPositiveIncrement) {
1189 float increment = 0.0001;
1190 int step = 2;
1191 float start_scaler = 0.0;
1192 float target = 1.0;
1193
1194 _SetupBuffer();
1195 ScaleIncrement(start_scaler, increment, target);
1196
1197 cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames,
1198 start_scaler, increment, target, step);
1199
1200 EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * 4));
1201 }
1202
TEST_F(MixTestSuiteS24_3LE,ScaleVolumePositiveIncrementCappedByTarget)1203 TEST_F(MixTestSuiteS24_3LE, ScaleVolumePositiveIncrementCappedByTarget) {
1204 float increment = 0.0001;
1205 int step = 2;
1206 float start_scaler = 0.1;
1207 float target = 0.5;
1208
1209 _SetupBuffer();
1210 ScaleIncrement(start_scaler, increment, target);
1211
1212 cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames,
1213 start_scaler, increment, target, step);
1214 EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * fr_bytes_));
1215 }
1216
TEST_F(MixTestSuiteS24_3LE,ScaleVolumeNegativeIncrementCappedByTarget)1217 TEST_F(MixTestSuiteS24_3LE, ScaleVolumeNegativeIncrementCappedByTarget) {
1218 float increment = -0.01;
1219 int step = 2;
1220 float start_scaler = 0.8;
1221 float target = 0.5;
1222
1223 _SetupBuffer();
1224 ScaleIncrement(start_scaler, increment, target);
1225
1226 cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames,
1227 start_scaler, increment, target, step);
1228 EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * fr_bytes_));
1229 }
1230
TEST_F(MixTestSuiteS24_3LE,ScaleFullVolume)1231 TEST_F(MixTestSuiteS24_3LE, ScaleFullVolume) {
1232 memcpy(compare_buffer_, src_buffer_, kBufferFrames * fr_bytes_);
1233 cras_scale_buffer(fmt_, (uint8_t*)mix_buffer_, kNumSamples, 0.999999999);
1234
1235 EXPECT_EQ(0, memcmp(compare_buffer_, src_buffer_, kBufferFrames * fr_bytes_));
1236 }
1237
TEST_F(MixTestSuiteS24_3LE,ScaleMinVolume)1238 TEST_F(MixTestSuiteS24_3LE, ScaleMinVolume) {
1239 memset(compare_buffer_, 0, kBufferFrames * fr_bytes_);
1240 cras_scale_buffer(fmt_, (uint8_t*)src_buffer_, kNumSamples, 0.0000000001);
1241
1242 EXPECT_EQ(0, memcmp(compare_buffer_, src_buffer_, kBufferFrames * fr_bytes_));
1243 }
1244
TEST_F(MixTestSuiteS24_3LE,ScaleHalfVolume)1245 TEST_F(MixTestSuiteS24_3LE, ScaleHalfVolume) {
1246 for (size_t i = 0; i < kBufferFrames * kNumChannels; i++) {
1247 int32_t tmp = 0;
1248 memcpy((uint8_t*)&tmp + 1, src_buffer_ + 3 * i, 3);
1249 tmp *= 0.5;
1250 memcpy(compare_buffer_ + 3 * i, (uint8_t*)&tmp + 1, 3);
1251 }
1252 cras_scale_buffer(fmt_, (uint8_t*)src_buffer_, kNumSamples, 0.5);
1253
1254 EXPECT_EQ(0, memcmp(compare_buffer_, src_buffer_, kBufferFrames * fr_bytes_));
1255 }
1256
TEST_F(MixTestSuiteS24_3LE,StrideCopy)1257 TEST_F(MixTestSuiteS24_3LE, StrideCopy) {
1258 TestScaleStride(1.0);
1259 TestScaleStride(100);
1260 TestScaleStride(0.1);
1261 }
1262
1263 /* Stubs */
1264 extern "C" {} // extern "C"
1265
1266 } // namespace
1267
main(int argc,char ** argv)1268 int main(int argc, char** argv) {
1269 ::testing::InitGoogleTest(&argc, argv);
1270 return RUN_ALL_TESTS();
1271 }
1272