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