• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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