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