• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 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 <limits.h>
7 #include <math.h>
8 #include <stdint.h>
9 #include <sys/param.h>
10 
11 #include <memory>
12 
13 extern "C" {
14 #include "cras_fmt_conv_ops.h"
15 #include "cras_types.h"
16 }
17 
AllocateRandomBytes(size_t size)18 static uint8_t* AllocateRandomBytes(size_t size) {
19   uint8_t* buf = (uint8_t*)malloc(size);
20   while (size--)
21     buf[size] = rand() & 0xff;
22   return buf;
23 }
24 
25 using U8Ptr = std::unique_ptr<uint8_t[], decltype(free)*>;
26 using S16LEPtr = std::unique_ptr<int16_t[], decltype(free)*>;
27 using S243LEPtr = std::unique_ptr<uint8_t[], decltype(free)*>;
28 using S24LEPtr = std::unique_ptr<int32_t[], decltype(free)*>;
29 using S32LEPtr = std::unique_ptr<int32_t[], decltype(free)*>;
30 using FloatPtr = std::unique_ptr<float[], decltype(free)*>;
31 
CreateU8(size_t size)32 static U8Ptr CreateU8(size_t size) {
33   uint8_t* buf = AllocateRandomBytes(size * sizeof(uint8_t));
34   U8Ptr ret(buf, free);
35   return ret;
36 }
37 
CreateS16LE(size_t size)38 static S16LEPtr CreateS16LE(size_t size) {
39   uint8_t* buf = AllocateRandomBytes(size * sizeof(int16_t));
40   S16LEPtr ret(reinterpret_cast<int16_t*>(buf), free);
41   return ret;
42 }
43 
CreateS243LE(size_t size)44 static S243LEPtr CreateS243LE(size_t size) {
45   uint8_t* buf = AllocateRandomBytes(size * sizeof(uint8_t) * 3);
46   S243LEPtr ret(buf, free);
47   return ret;
48 }
49 
CreateS24LE(size_t size)50 static S24LEPtr CreateS24LE(size_t size) {
51   uint8_t* buf = AllocateRandomBytes(size * sizeof(int32_t));
52   S24LEPtr ret(reinterpret_cast<int32_t*>(buf), free);
53   return ret;
54 }
55 
CreateS32LE(size_t size)56 static S32LEPtr CreateS32LE(size_t size) {
57   uint8_t* buf = AllocateRandomBytes(size * sizeof(int32_t));
58   S32LEPtr ret(reinterpret_cast<int32_t*>(buf), free);
59   return ret;
60 }
61 
CreateFloat(size_t size)62 static FloatPtr CreateFloat(size_t size) {
63   float* buf = (float*)malloc(size * sizeof(float));
64   while (size--)
65     buf[size] = (float)(rand() & 0xff) / 0xfff;
66   FloatPtr ret(buf, free);
67   return ret;
68 }
69 
ToS243LE(const uint8_t * in)70 static int32_t ToS243LE(const uint8_t* in) {
71   int32_t ret = 0;
72 
73   ret |= in[2];
74   ret <<= 8;
75   ret |= in[1];
76   ret <<= 8;
77   ret |= in[0];
78   return ret;
79 }
80 
S16AddAndClip(int16_t a,int16_t b)81 static int16_t S16AddAndClip(int16_t a, int16_t b) {
82   int32_t sum;
83 
84   sum = (int32_t)a + (int32_t)b;
85   sum = MAX(sum, SHRT_MIN);
86   sum = MIN(sum, SHRT_MAX);
87   return sum;
88 }
89 
90 // Test U8 to S16_LE conversion.
TEST(FormatConverterOpsTest,ConvertU8ToS16LE)91 TEST(FormatConverterOpsTest, ConvertU8ToS16LE) {
92   const size_t frames = 4096;
93   const size_t in_ch = 2;
94   const size_t out_ch = 2;
95 
96   U8Ptr src = CreateU8(frames * in_ch);
97   S16LEPtr dst = CreateS16LE(frames * out_ch);
98 
99   convert_u8_to_s16le(src.get(), frames * in_ch, (uint8_t*)dst.get());
100 
101   for (size_t i = 0; i < frames * in_ch; ++i) {
102     EXPECT_EQ((int16_t)((uint16_t)((int16_t)(int8_t)src[i] - 0x80) << 8),
103               dst[i]);
104   }
105 }
106 
107 // Test S24_3LE to S16_LE conversion.
TEST(FormatConverterOpsTest,ConvertS243LEToS16LE)108 TEST(FormatConverterOpsTest, ConvertS243LEToS16LE) {
109   const size_t frames = 4096;
110   const size_t in_ch = 2;
111   const size_t out_ch = 2;
112 
113   S243LEPtr src = CreateS243LE(frames * in_ch);
114   S16LEPtr dst = CreateS16LE(frames * out_ch);
115 
116   convert_s243le_to_s16le(src.get(), frames * in_ch, (uint8_t*)dst.get());
117 
118   uint8_t* p = src.get();
119   for (size_t i = 0; i < frames * in_ch; ++i) {
120     EXPECT_EQ((int16_t)(ToS243LE(p) >> 8), dst[i]);
121     p += 3;
122   }
123 }
124 
125 // Test S24_LE to S16_LE conversion.
TEST(FormatConverterOpsTest,ConvertS24LEToS16LE)126 TEST(FormatConverterOpsTest, ConvertS24LEToS16LE) {
127   const size_t frames = 4096;
128   const size_t in_ch = 2;
129   const size_t out_ch = 2;
130 
131   S24LEPtr src = CreateS24LE(frames * in_ch);
132   S16LEPtr dst = CreateS16LE(frames * out_ch);
133 
134   convert_s24le_to_s16le((uint8_t*)src.get(), frames * in_ch,
135                          (uint8_t*)dst.get());
136 
137   for (size_t i = 0; i < frames * in_ch; ++i) {
138     EXPECT_EQ((int16_t)(src[i] >> 8), dst[i]);
139   }
140 }
141 
142 // Test S32_LE to S16_LE conversion.
TEST(FormatConverterOpsTest,ConvertS32LEToS16LE)143 TEST(FormatConverterOpsTest, ConvertS32LEToS16LE) {
144   const size_t frames = 4096;
145   const size_t in_ch = 2;
146   const size_t out_ch = 2;
147 
148   S32LEPtr src = CreateS32LE(frames * in_ch);
149   S16LEPtr dst = CreateS16LE(frames * out_ch);
150 
151   convert_s32le_to_s16le((uint8_t*)src.get(), frames * in_ch,
152                          (uint8_t*)dst.get());
153 
154   for (size_t i = 0; i < frames * in_ch; ++i) {
155     EXPECT_EQ((int16_t)(src[i] >> 16), dst[i]);
156   }
157 }
158 
159 // Test S16_LE to U8 conversion.
TEST(FormatConverterOpsTest,ConvertS16LEToU8)160 TEST(FormatConverterOpsTest, ConvertS16LEToU8) {
161   const size_t frames = 4096;
162   const size_t in_ch = 2;
163   const size_t out_ch = 2;
164 
165   S16LEPtr src = CreateS16LE(frames * in_ch);
166   U8Ptr dst = CreateU8(frames * out_ch);
167 
168   convert_s16le_to_u8((uint8_t*)src.get(), frames * in_ch, dst.get());
169 
170   for (size_t i = 0; i < frames * in_ch; ++i) {
171     EXPECT_EQ((uint8_t)(int8_t)((src[i] >> 8) + 0x80), dst[i]);
172   }
173 }
174 
175 // Test S16_LE to S24_3LE conversion.
TEST(FormatConverterOpsTest,ConvertS16LEToS243LE)176 TEST(FormatConverterOpsTest, ConvertS16LEToS243LE) {
177   const size_t frames = 4096;
178   const size_t in_ch = 2;
179   const size_t out_ch = 2;
180 
181   S16LEPtr src = CreateS16LE(frames * in_ch);
182   S243LEPtr dst = CreateS243LE(frames * out_ch);
183 
184   convert_s16le_to_s243le((uint8_t*)src.get(), frames * in_ch, dst.get());
185 
186   uint8_t* p = dst.get();
187   for (size_t i = 0; i < frames * in_ch; ++i) {
188     EXPECT_EQ((int32_t)((uint32_t)src[i] << 8) & 0x00ffffff,
189               ToS243LE(p) & 0x00ffffff);
190     p += 3;
191   }
192 }
193 
194 // Test S16_LE to S24_LE conversion.
TEST(FormatConverterOpsTest,ConvertS16LEToS24LE)195 TEST(FormatConverterOpsTest, ConvertS16LEToS24LE) {
196   const size_t frames = 4096;
197   const size_t in_ch = 2;
198   const size_t out_ch = 2;
199 
200   S16LEPtr src = CreateS16LE(frames * in_ch);
201   S24LEPtr dst = CreateS24LE(frames * out_ch);
202 
203   convert_s16le_to_s24le((uint8_t*)src.get(), frames * in_ch,
204                          (uint8_t*)dst.get());
205 
206   for (size_t i = 0; i < frames * in_ch; ++i) {
207     EXPECT_EQ((int32_t)((uint32_t)src[i] << 8) & 0x00ffffff,
208               dst[i] & 0x00ffffff);
209   }
210 }
211 
212 // Test S16_LE to S32_LE conversion.
TEST(FormatConverterOpsTest,ConvertS16LEToS32LE)213 TEST(FormatConverterOpsTest, ConvertS16LEToS32LE) {
214   const size_t frames = 4096;
215   const size_t in_ch = 2;
216   const size_t out_ch = 2;
217 
218   S16LEPtr src = CreateS16LE(frames * in_ch);
219   S32LEPtr dst = CreateS32LE(frames * out_ch);
220 
221   convert_s16le_to_s32le((uint8_t*)src.get(), frames * in_ch,
222                          (uint8_t*)dst.get());
223 
224   for (size_t i = 0; i < frames * in_ch; ++i) {
225     EXPECT_EQ((int32_t)((uint32_t)src[i] << 16) & 0xffffff00,
226               dst[i] & 0xffffff00);
227   }
228 }
229 
230 // Test Mono to Stereo conversion.  S16_LE.
TEST(FormatConverterOpsTest,MonoToStereoS16LE)231 TEST(FormatConverterOpsTest, MonoToStereoS16LE) {
232   const size_t frames = 4096;
233   const size_t in_ch = 1;
234   const size_t out_ch = 2;
235 
236   S16LEPtr src = CreateS16LE(frames * in_ch);
237   S16LEPtr dst = CreateS16LE(frames * out_ch);
238 
239   size_t ret =
240       s16_mono_to_stereo((uint8_t*)src.get(), frames, (uint8_t*)dst.get());
241   EXPECT_EQ(ret, frames);
242 
243   for (size_t i = 0; i < frames; ++i) {
244     EXPECT_EQ(src[i], dst[i * 2 + 0]);
245     EXPECT_EQ(src[i], dst[i * 2 + 1]);
246   }
247 }
248 
249 // Test Stereo to Mono conversion.  S16_LE.
TEST(FormatConverterOpsTest,StereoToMonoS16LE)250 TEST(FormatConverterOpsTest, StereoToMonoS16LE) {
251   const size_t frames = 4096;
252   const size_t in_ch = 2;
253   const size_t out_ch = 1;
254 
255   S16LEPtr src = CreateS16LE(frames * in_ch);
256   S16LEPtr dst = CreateS16LE(frames * out_ch);
257   for (size_t i = 0; i < frames; ++i) {
258     src[i * 2 + 0] = 13450;
259     src[i * 2 + 1] = -13449;
260   }
261 
262   size_t ret =
263       s16_stereo_to_mono((uint8_t*)src.get(), frames, (uint8_t*)dst.get());
264   EXPECT_EQ(ret, frames);
265 
266   for (size_t i = 0; i < frames; ++i) {
267     EXPECT_EQ(1, dst[i]);
268   }
269 }
270 
271 // Test Stereo to Mono conversion.  S16_LE, Overflow.
TEST(FormatConverterOpsTest,StereoToMonoS16LEOverflow)272 TEST(FormatConverterOpsTest, StereoToMonoS16LEOverflow) {
273   const size_t frames = 4096;
274   const size_t in_ch = 2;
275   const size_t out_ch = 1;
276 
277   S16LEPtr src = CreateS16LE(frames * in_ch);
278   S16LEPtr dst = CreateS16LE(frames * out_ch);
279   for (size_t i = 0; i < frames; ++i) {
280     src[i * 2 + 0] = 0x7fff;
281     src[i * 2 + 1] = 1;
282   }
283 
284   size_t ret =
285       s16_stereo_to_mono((uint8_t*)src.get(), frames, (uint8_t*)dst.get());
286   EXPECT_EQ(ret, frames);
287 
288   for (size_t i = 0; i < frames; ++i) {
289     EXPECT_EQ(0x7fff, dst[i]);
290   }
291 }
292 
293 // Test Stereo to Mono conversion.  S16_LE, Underflow.
TEST(FormatConverterOpsTest,StereoToMonoS16LEUnderflow)294 TEST(FormatConverterOpsTest, StereoToMonoS16LEUnderflow) {
295   const size_t frames = 4096;
296   const size_t in_ch = 2;
297   const size_t out_ch = 1;
298 
299   S16LEPtr src = CreateS16LE(frames * in_ch);
300   S16LEPtr dst = CreateS16LE(frames * out_ch);
301   for (size_t i = 0; i < frames; ++i) {
302     src[i * 2 + 0] = -0x8000;
303     src[i * 2 + 1] = -0x1;
304   }
305 
306   size_t ret =
307       s16_stereo_to_mono((uint8_t*)src.get(), frames, (uint8_t*)dst.get());
308   EXPECT_EQ(ret, frames);
309 
310   for (size_t i = 0; i < frames; ++i) {
311     EXPECT_EQ(-0x8000, dst[i]);
312   }
313 }
314 
315 // Test Mono to 5.1 conversion.  S16_LE, Center.
TEST(FormatConverterOpsTest,MonoTo51S16LECenter)316 TEST(FormatConverterOpsTest, MonoTo51S16LECenter) {
317   const size_t frames = 4096;
318   const size_t in_ch = 1;
319   const size_t out_ch = 6;
320   const size_t left = 0;
321   const size_t right = 1;
322   const size_t center = 4;
323 
324   S16LEPtr src = CreateS16LE(frames * in_ch);
325   S16LEPtr dst = CreateS16LE(frames * out_ch);
326 
327   size_t ret = s16_mono_to_51(left, right, center, (uint8_t*)src.get(), frames,
328                               (uint8_t*)dst.get());
329   EXPECT_EQ(ret, frames);
330 
331   for (size_t i = 0; i < frames; ++i) {
332     for (size_t k = 0; k < 6; ++k) {
333       if (k == center)
334         EXPECT_EQ(src[i], dst[i * 6 + k]);
335       else
336         EXPECT_EQ(0, dst[i * 6 + k]);
337     }
338   }
339 }
340 
341 // Test Mono to 5.1 conversion.  S16_LE, LeftRight.
TEST(FormatConverterOpsTest,MonoTo51S16LELeftRight)342 TEST(FormatConverterOpsTest, MonoTo51S16LELeftRight) {
343   const size_t frames = 4096;
344   const size_t in_ch = 1;
345   const size_t out_ch = 6;
346   const size_t left = 0;
347   const size_t right = 1;
348   const size_t center = -1;
349 
350   S16LEPtr src = CreateS16LE(frames * in_ch);
351   S16LEPtr dst = CreateS16LE(frames * out_ch);
352 
353   size_t ret = s16_mono_to_51(left, right, center, (uint8_t*)src.get(), frames,
354                               (uint8_t*)dst.get());
355   EXPECT_EQ(ret, frames);
356 
357   for (size_t i = 0; i < frames; ++i) {
358     for (size_t k = 0; k < 6; ++k) {
359       if (k == left)
360         EXPECT_EQ(src[i] / 2, dst[i * 6 + k]);
361       else if (k == right)
362         EXPECT_EQ(src[i] / 2, dst[i * 6 + k]);
363       else
364         EXPECT_EQ(0, dst[i * 6 + k]);
365     }
366   }
367 }
368 
369 // Test Mono to 5.1 conversion.  S16_LE, Unknown.
TEST(FormatConverterOpsTest,MonoTo51S16LEUnknown)370 TEST(FormatConverterOpsTest, MonoTo51S16LEUnknown) {
371   const size_t frames = 4096;
372   const size_t in_ch = 1;
373   const size_t out_ch = 6;
374   const size_t left = -1;
375   const size_t right = -1;
376   const size_t center = -1;
377 
378   S16LEPtr src = CreateS16LE(frames * in_ch);
379   S16LEPtr dst = CreateS16LE(frames * out_ch);
380 
381   size_t ret = s16_mono_to_51(left, right, center, (uint8_t*)src.get(), frames,
382                               (uint8_t*)dst.get());
383   EXPECT_EQ(ret, frames);
384 
385   for (size_t i = 0; i < frames; ++i) {
386     for (size_t k = 0; k < 6; ++k) {
387       if (k == 0)
388         EXPECT_EQ(src[i], dst[i * 6 + k]);
389       else
390         EXPECT_EQ(0, dst[6 * i + k]);
391     }
392   }
393 }
394 
395 // Test Stereo to 5.1 conversion.  S16_LE, Center.
TEST(FormatConverterOpsTest,StereoTo51S16LECenter)396 TEST(FormatConverterOpsTest, StereoTo51S16LECenter) {
397   const size_t frames = 4096;
398   const size_t in_ch = 2;
399   const size_t out_ch = 6;
400   const size_t left = -1;
401   const size_t right = 1;
402   const size_t center = 4;
403 
404   S16LEPtr src = CreateS16LE(frames * in_ch);
405   S16LEPtr dst = CreateS16LE(frames * out_ch);
406 
407   size_t ret = s16_stereo_to_51(left, right, center, (uint8_t*)src.get(),
408                                 frames, (uint8_t*)dst.get());
409   EXPECT_EQ(ret, frames);
410 
411   for (size_t i = 0; i < frames; ++i) {
412     for (size_t k = 0; k < 6; ++k) {
413       if (k == center)
414         EXPECT_EQ(S16AddAndClip(src[i * 2], src[i * 2 + 1]), dst[i * 6 + k]);
415       else
416         EXPECT_EQ(0, dst[i * 6 + k]);
417     }
418   }
419 }
420 
421 // Test Quad to 5.1 conversion. S16_LE.
TEST(FormatConverterOpsTest,QuadTo51S16LE)422 TEST(FormatConverterOpsTest, QuadTo51S16LE) {
423   const size_t frames = 4096;
424   const size_t in_ch = 4;
425   const size_t out_ch = 6;
426   const unsigned int fl_quad = 0;
427   const unsigned int fr_quad = 1;
428   const unsigned int rl_quad = 2;
429   const unsigned int rr_quad = 3;
430 
431   const unsigned int fl_51 = 0;
432   const unsigned int fr_51 = 1;
433   const unsigned int center_51 = 2;
434   const unsigned int lfe_51 = 3;
435   const unsigned int rl_51 = 4;
436   const unsigned int rr_51 = 5;
437 
438   S16LEPtr src = CreateS16LE(frames * in_ch);
439   S16LEPtr dst = CreateS16LE(frames * out_ch);
440 
441   size_t ret = s16_quad_to_51(fl_51, fr_51, rl_51, rr_51, (uint8_t*)src.get(),
442                               frames, (uint8_t*)dst.get());
443   EXPECT_EQ(ret, frames);
444   for (size_t i = 0; i < frames; ++i) {
445     EXPECT_EQ(0, dst[i * 6 + center_51]);
446     EXPECT_EQ(0, dst[i * 6 + lfe_51]);
447     EXPECT_EQ(src[i * 4 + fl_quad], dst[i * 6 + fl_51]);
448     EXPECT_EQ(src[i * 4 + fr_quad], dst[i * 6 + fr_51]);
449     EXPECT_EQ(src[i * 4 + rl_quad], dst[i * 6 + rl_51]);
450     EXPECT_EQ(src[i * 4 + rr_quad], dst[i * 6 + rr_51]);
451   }
452 }
453 
454 // Test Stereo to 5.1 conversion.  S16_LE, LeftRight.
TEST(FormatConverterOpsTest,StereoTo51S16LELeftRight)455 TEST(FormatConverterOpsTest, StereoTo51S16LELeftRight) {
456   const size_t frames = 4096;
457   const size_t in_ch = 2;
458   const size_t out_ch = 6;
459   const size_t left = 0;
460   const size_t right = 1;
461   const size_t center = -1;
462 
463   S16LEPtr src = CreateS16LE(frames * in_ch);
464   S16LEPtr dst = CreateS16LE(frames * out_ch);
465 
466   size_t ret = s16_stereo_to_51(left, right, center, (uint8_t*)src.get(),
467                                 frames, (uint8_t*)dst.get());
468   EXPECT_EQ(ret, frames);
469 
470   for (size_t i = 0; i < frames; ++i) {
471     for (size_t k = 0; k < 6; ++k) {
472       if (k == left)
473         EXPECT_EQ(src[i * 2 + 0], dst[i * 6 + k]);
474       else if (k == right)
475         EXPECT_EQ(src[i * 2 + 1], dst[i * 6 + k]);
476       else
477         EXPECT_EQ(0, dst[i * 6 + k]);
478     }
479   }
480 }
481 
482 // Test Stereo to 5.1 conversion.  S16_LE, Unknown.
TEST(FormatConverterOpsTest,StereoTo51S16LEUnknown)483 TEST(FormatConverterOpsTest, StereoTo51S16LEUnknown) {
484   const size_t frames = 4096;
485   const size_t in_ch = 2;
486   const size_t out_ch = 6;
487   const size_t left = -1;
488   const size_t right = -1;
489   const size_t center = -1;
490 
491   S16LEPtr src = CreateS16LE(frames * in_ch);
492   S16LEPtr dst = CreateS16LE(frames * out_ch);
493 
494   size_t ret = s16_stereo_to_51(left, right, center, (uint8_t*)src.get(),
495                                 frames, (uint8_t*)dst.get());
496   EXPECT_EQ(ret, frames);
497 
498   for (size_t i = 0; i < frames; ++i) {
499     for (size_t k = 0; k < 6; ++k) {
500       if (k == 0 || k == 1)
501         EXPECT_EQ(src[i * 2 + k], dst[i * 6 + k]);
502       else
503         EXPECT_EQ(0, dst[i * 6 + k]);
504     }
505   }
506 }
507 
508 // Test 5.1 to Stereo conversion.  S16_LE.
TEST(FormatConverterOpsTest,_51ToStereoS16LE)509 TEST(FormatConverterOpsTest, _51ToStereoS16LE) {
510   const size_t frames = 4096;
511   const size_t in_ch = 6;
512   const size_t out_ch = 2;
513   const size_t left = 0;
514   const size_t right = 1;
515   const size_t center = 2;
516 
517   S16LEPtr src = CreateS16LE(frames * in_ch);
518   S16LEPtr dst = CreateS16LE(frames * out_ch);
519 
520   size_t ret =
521       s16_51_to_stereo((uint8_t*)src.get(), frames, (uint8_t*)dst.get());
522   EXPECT_EQ(ret, frames);
523 
524   /* Use the normalized_factor from the left channel = 1 / (|1| + |0.707|)
525    * to prevent mixing overflow.
526    */
527   const float normalized_factor = 0.585;
528 
529   for (size_t i = 0; i < frames; ++i) {
530     int16_t half_center = src[i * 6 + center] * 0.707 * normalized_factor;
531     int16_t l = normalized_factor * src[i * 6 + left] + half_center;
532     int16_t r = normalized_factor * src[i * 6 + right] + half_center;
533 
534     EXPECT_EQ(l, dst[i * 2 + left]);
535     EXPECT_EQ(r, dst[i * 2 + right]);
536   }
537 }
538 
539 // Test 5.1 to Quad conversion.  S16_LE.
TEST(FormatConverterOpsTest,_51ToQuadS16LE)540 TEST(FormatConverterOpsTest, _51ToQuadS16LE) {
541   const size_t frames = 4096;
542   const size_t in_ch = 6;
543   const size_t out_ch = 4;
544   const unsigned int fl_quad = 0;
545   const unsigned int fr_quad = 1;
546   const unsigned int rl_quad = 2;
547   const unsigned int rr_quad = 3;
548 
549   const unsigned int fl_51 = 0;
550   const unsigned int fr_51 = 1;
551   const unsigned int center_51 = 2;
552   const unsigned int lfe_51 = 3;
553   const unsigned int rl_51 = 4;
554   const unsigned int rr_51 = 5;
555 
556   S16LEPtr src = CreateS16LE(frames * in_ch);
557   S16LEPtr dst = CreateS16LE(frames * out_ch);
558 
559   size_t ret = s16_51_to_quad((uint8_t*)src.get(), frames, (uint8_t*)dst.get());
560   EXPECT_EQ(ret, frames);
561 
562   /* Use normalized_factor from the left channel = 1 / (|1| + |0.707| + |0.5|)
563    * to prevent overflow. */
564   const float normalized_factor = 0.453;
565   for (size_t i = 0; i < frames; ++i) {
566     int16_t half_center = src[i * 6 + center_51] * 0.707 * normalized_factor;
567     int16_t lfe = src[6 * i + lfe_51] * 0.5 * normalized_factor;
568     int16_t fl = normalized_factor * src[6 * i + fl_51] + half_center + lfe;
569     int16_t fr = normalized_factor * src[6 * i + fr_51] + half_center + lfe;
570     int16_t rl = normalized_factor * src[6 * i + rl_51] + lfe;
571     int16_t rr = normalized_factor * src[6 * i + rr_51] + lfe;
572     EXPECT_EQ(fl, dst[4 * i + fl_quad]);
573     EXPECT_EQ(fr, dst[4 * i + fr_quad]);
574     EXPECT_EQ(rl, dst[4 * i + rl_quad]);
575     EXPECT_EQ(rr, dst[4 * i + rr_quad]);
576   }
577 }
578 
579 // Test Stereo to Quad conversion.  S16_LE, Specify.
TEST(FormatConverterOpsTest,StereoToQuadS16LESpecify)580 TEST(FormatConverterOpsTest, StereoToQuadS16LESpecify) {
581   const size_t frames = 4096;
582   const size_t in_ch = 2;
583   const size_t out_ch = 4;
584   const size_t front_left = 2;
585   const size_t front_right = 3;
586   const size_t rear_left = 0;
587   const size_t rear_right = 1;
588 
589   S16LEPtr src = CreateS16LE(frames * in_ch);
590   S16LEPtr dst = CreateS16LE(frames * out_ch);
591 
592   size_t ret =
593       s16_stereo_to_quad(front_left, front_right, rear_left, rear_right,
594                          (uint8_t*)src.get(), frames, (uint8_t*)dst.get());
595   EXPECT_EQ(ret, frames);
596 
597   for (size_t i = 0; i < frames; ++i) {
598     EXPECT_EQ(src[i * 2 + 0], dst[i * 4 + front_left]);
599     EXPECT_EQ(src[i * 2 + 0], dst[i * 4 + rear_left]);
600     EXPECT_EQ(src[i * 2 + 1], dst[i * 4 + front_right]);
601     EXPECT_EQ(src[i * 2 + 1], dst[i * 4 + rear_right]);
602   }
603 }
604 
605 // Test Stereo to Quad conversion.  S16_LE, Default.
TEST(FormatConverterOpsTest,StereoToQuadS16LEDefault)606 TEST(FormatConverterOpsTest, StereoToQuadS16LEDefault) {
607   const size_t frames = 4096;
608   const size_t in_ch = 2;
609   const size_t out_ch = 4;
610   const size_t front_left = -1;
611   const size_t front_right = -1;
612   const size_t rear_left = -1;
613   const size_t rear_right = -1;
614 
615   S16LEPtr src = CreateS16LE(frames * in_ch);
616   S16LEPtr dst = CreateS16LE(frames * out_ch);
617 
618   size_t ret =
619       s16_stereo_to_quad(front_left, front_right, rear_left, rear_right,
620                          (uint8_t*)src.get(), frames, (uint8_t*)dst.get());
621   EXPECT_EQ(ret, frames);
622 
623   for (size_t i = 0; i < frames; ++i) {
624     EXPECT_EQ(src[i * 2 + 0], dst[i * 4 + 0]);
625     EXPECT_EQ(src[i * 2 + 0], dst[i * 4 + 2]);
626     EXPECT_EQ(src[i * 2 + 1], dst[i * 4 + 1]);
627     EXPECT_EQ(src[i * 2 + 1], dst[i * 4 + 3]);
628   }
629 }
630 
631 // Test Quad to Stereo conversion.  S16_LE, Specify.
TEST(FormatConverterOpsTest,QuadToStereoS16LESpecify)632 TEST(FormatConverterOpsTest, QuadToStereoS16LESpecify) {
633   const size_t frames = 4096;
634   const size_t in_ch = 4;
635   const size_t out_ch = 2;
636   const size_t front_left = 2;
637   const size_t front_right = 3;
638   const size_t rear_left = 0;
639   const size_t rear_right = 1;
640 
641   S16LEPtr src = CreateS16LE(frames * in_ch);
642   S16LEPtr dst = CreateS16LE(frames * out_ch);
643 
644   size_t ret =
645       s16_quad_to_stereo(front_left, front_right, rear_left, rear_right,
646                          (uint8_t*)src.get(), frames, (uint8_t*)dst.get());
647   EXPECT_EQ(ret, frames);
648 
649   for (size_t i = 0; i < frames; ++i) {
650     int16_t left =
651         S16AddAndClip(src[i * 4 + front_left], src[i * 4 + rear_left] / 4);
652     int16_t right =
653         S16AddAndClip(src[i * 4 + front_right], src[i * 4 + rear_right] / 4);
654     EXPECT_EQ(left, dst[i * 2 + 0]);
655     EXPECT_EQ(right, dst[i * 2 + 1]);
656   }
657 }
658 
659 // Test Quad to Stereo conversion.  S16_LE, Default.
TEST(FormatConverterOpsTest,QuadToStereoS16LEDefault)660 TEST(FormatConverterOpsTest, QuadToStereoS16LEDefault) {
661   const size_t frames = 4096;
662   const size_t in_ch = 4;
663   const size_t out_ch = 2;
664   const size_t front_left = -1;
665   const size_t front_right = -1;
666   const size_t rear_left = -1;
667   const size_t rear_right = -1;
668 
669   S16LEPtr src = CreateS16LE(frames * in_ch);
670   S16LEPtr dst = CreateS16LE(frames * out_ch);
671 
672   size_t ret =
673       s16_quad_to_stereo(front_left, front_right, rear_left, rear_right,
674                          (uint8_t*)src.get(), frames, (uint8_t*)dst.get());
675   EXPECT_EQ(ret, frames);
676 
677   for (size_t i = 0; i < frames; ++i) {
678     int16_t left = S16AddAndClip(src[i * 4 + 0], src[i * 4 + 2] / 4);
679     int16_t right = S16AddAndClip(src[i * 4 + 1], src[i * 4 + 3] / 4);
680     EXPECT_EQ(left, dst[i * 2 + 0]);
681     EXPECT_EQ(right, dst[i * 2 + 1]);
682   }
683 }
684 
685 // Test Stereo to 3ch conversion.  S16_LE.
TEST(FormatConverterOpsTest,StereoTo3chS16LE)686 TEST(FormatConverterOpsTest, StereoTo3chS16LE) {
687   const size_t frames = 4096;
688   const size_t in_ch = 2;
689   const size_t out_ch = 3;
690   struct cras_audio_format fmt = {
691       .format = SND_PCM_FORMAT_S16_LE,
692       .frame_rate = 48000,
693       .num_channels = 3,
694   };
695 
696   S16LEPtr src = CreateS16LE(frames * in_ch);
697   S16LEPtr dst = CreateS16LE(frames * out_ch);
698 
699   size_t ret = s16_default_all_to_all(&fmt, in_ch, out_ch, (uint8_t*)src.get(),
700                                       frames, (uint8_t*)dst.get());
701   EXPECT_EQ(ret, frames);
702 
703   for (size_t i = 0; i < frames; ++i) {
704     int32_t sum = 0;
705     for (size_t k = 0; k < in_ch; ++k)
706       sum += (int32_t)src[i * in_ch + k];
707     src[i * in_ch + 0] = (int16_t)(sum / (int32_t)in_ch);
708   }
709   for (size_t i = 0; i < frames; ++i) {
710     for (size_t k = 0; k < out_ch; ++k)
711       EXPECT_EQ(src[i * in_ch + 0], dst[i * out_ch + k]);
712   }
713 }
714 
715 // Test 6ch to 8ch conversion.  S16_LE.
716 TEST(FormatConverterOpsTest, 6chTo8chS16LE) {
717   const size_t frames = 65536;
718   const size_t in_ch = 6;
719   const size_t out_ch = 8;
720   struct cras_audio_format fmt = {
721       .format = SND_PCM_FORMAT_S16_LE,
722       .frame_rate = 48000,
723       .num_channels = 8,
724   };
725 
726   S16LEPtr src = CreateS16LE(frames * in_ch);
727   S16LEPtr dst = CreateS16LE(frames * out_ch);
728   for (size_t i = 0; i < frames; ++i) {
729     for (size_t k = 0; k < in_ch; k++) {
730       src[i * in_ch + k] = (k == 0) ? (INT16_MIN + (int16_t)i) : 0;
731     }
732   }
733 
734   size_t ret = s16_default_all_to_all(&fmt, in_ch, out_ch, (uint8_t*)src.get(),
735                                       frames, (uint8_t*)dst.get());
736   EXPECT_EQ(ret, frames);
737 
738   for (size_t i = 0; i < frames; ++i) {
739     src[i * in_ch + 0] /= (int16_t)in_ch;
740     for (size_t k = 0; k < out_ch; ++k)
741       EXPECT_EQ(src[i * in_ch + 0], dst[i * out_ch + k]);
742   }
743 }
744 
745 // Test Multiply with Coef.  S16_LE.
TEST(FormatConverterOpsTest,MultiplyWithCoefS16LE)746 TEST(FormatConverterOpsTest, MultiplyWithCoefS16LE) {
747   const size_t buf_size = 4096;
748 
749   S16LEPtr buf = CreateS16LE(buf_size);
750   FloatPtr coef = CreateFloat(buf_size);
751 
752   int16_t ret = s16_multiply_buf_with_coef(coef.get(), buf.get(), buf_size);
753 
754   int32_t exp = 0;
755   for (size_t i = 0; i < buf_size; ++i)
756     exp += coef[i] * buf[i];
757   exp = MIN(MAX(exp, SHRT_MIN), SHRT_MAX);
758 
759   EXPECT_EQ((int16_t)exp, ret);
760 }
761 
762 // Test Convert Channels.  S16_LE.
TEST(FormatConverterOpsTest,ConvertChannelsS16LE)763 TEST(FormatConverterOpsTest, ConvertChannelsS16LE) {
764   const size_t frames = 4096;
765   const size_t in_ch = 2;
766   const size_t out_ch = 3;
767 
768   S16LEPtr src = CreateS16LE(frames * in_ch);
769   S16LEPtr dst = CreateS16LE(frames * out_ch);
770   FloatPtr ch_conv_mtx = CreateFloat(out_ch * in_ch);
771   std::unique_ptr<float*[]> mtx(new float*[out_ch]);
772   for (size_t i = 0; i < out_ch; ++i)
773     mtx[i] = &ch_conv_mtx[i * in_ch];
774 
775   size_t ret =
776       s16_convert_channels(mtx.get(), in_ch, out_ch, (uint8_t*)src.get(),
777                            frames, (uint8_t*)dst.get());
778   EXPECT_EQ(ret, frames);
779 
780   for (size_t fr = 0; fr < frames; ++fr) {
781     for (size_t i = 0; i < out_ch; ++i) {
782       int16_t exp = 0;
783       for (size_t k = 0; k < in_ch; ++k)
784         exp += mtx[i][k] * src[fr * in_ch + k];
785       exp = MIN(MAX(exp, SHRT_MIN), SHRT_MAX);
786       EXPECT_EQ(exp, dst[fr * out_ch + i]);
787     }
788   }
789 }
790 
791 // Test Stereo to 20ch conversion.  S16_LE.
TEST(FormatConverterOpsTest,TwoToTwentyS16LE)792 TEST(FormatConverterOpsTest, TwoToTwentyS16LE) {
793   const size_t frames = 4096;
794   const size_t in_ch = 2;
795   const size_t out_ch = 20;
796   struct cras_audio_format fmt = {
797       .format = SND_PCM_FORMAT_S16_LE,
798       .frame_rate = 48000,
799       .num_channels = 20,
800   };
801 
802   S16LEPtr src = CreateS16LE(frames * in_ch);
803   S16LEPtr dst = CreateS16LE(frames * out_ch);
804 
805   size_t ret = s16_some_to_some(&fmt, in_ch, out_ch, (uint8_t*)src.get(),
806                                 frames, (uint8_t*)dst.get());
807   EXPECT_EQ(ret, frames);
808 
809   for (size_t i = 0; i < frames; ++i) {
810     size_t k;
811     // Input channles should be directly copied over.
812     for (k = 0; k < in_ch; ++k) {
813         EXPECT_EQ(src[i * in_ch + k], dst[i * out_ch + k]);
814     }
815     // The rest should be zeroed.
816     for (; k < out_ch; ++k) {
817         EXPECT_EQ(0, dst[i * out_ch + k]);
818     }
819 
820   }
821 }
822 
823 // Test 20ch to Stereo.  S16_LE.
TEST(FormatConverterOpsTest,TwentyToTwoS16LE)824 TEST(FormatConverterOpsTest, TwentyToTwoS16LE) {
825   const size_t frames = 4096;
826   const size_t in_ch = 20;
827   const size_t out_ch = 2;
828   struct cras_audio_format fmt = {
829       .format = SND_PCM_FORMAT_S16_LE,
830       .frame_rate = 48000,
831       .num_channels = 2,
832   };
833 
834   S16LEPtr src = CreateS16LE(frames * in_ch);
835   S16LEPtr dst = CreateS16LE(frames * out_ch);
836 
837   size_t ret = s16_some_to_some(&fmt, in_ch, out_ch, (uint8_t*)src.get(),
838                                 frames, (uint8_t*)dst.get());
839   EXPECT_EQ(ret, frames);
840 
841   for (size_t i = 0; i < frames; ++i) {
842     size_t k;
843     // Input channles should be directly copied over.
844     for (k = 0; k < out_ch; ++k) {
845         EXPECT_EQ(src[i * in_ch + k], dst[i * out_ch + k]);
846     }
847   }
848 }
849 
850 extern "C" {}  // extern "C"
851 
main(int argc,char ** argv)852 int main(int argc, char** argv) {
853   ::testing::InitGoogleTest(&argc, argv);
854   return RUN_ALL_TESTS();
855 }
856