fmt_conv_unittest.cc revision 51b38808ffe2a26fa58e969c801fbc6c90e1edc7
1// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <gtest/gtest.h>
6
7extern "C" {
8#include "cras_fmt_conv.h"
9#include "cras_types.h"
10}
11
12static int surround_channel_layout[CRAS_CH_MAX] =
13	{0, 1, 2, 3, 4, 5, -1, -1, -1, -1, -1};
14
15// Like malloc or calloc, but fill the memory with random bytes.
16static void *ralloc(size_t size) {
17  unsigned char *buf = (unsigned char *)malloc(size);
18  while (size--)
19    buf[size] = rand() & 0xff;
20  return buf;
21}
22
23static void swap_channel_layout(int8_t *layout,
24                                CRAS_CHANNEL a,
25				CRAS_CHANNEL b) {
26	int8_t tmp = layout[a];
27	layout[a] = layout[b];
28	layout[b] = tmp;
29}
30
31// Don't yet support up/down mix.
32TEST(FormatConverterTest,  InvalidParamsUpDownMix) {
33  struct cras_audio_format in_fmt;
34  struct cras_audio_format out_fmt;
35  struct cras_fmt_conv *c;
36
37  in_fmt.format = out_fmt.format = SND_PCM_FORMAT_S16_LE;
38  in_fmt.num_channels = 4;
39  out_fmt.num_channels = 2;
40  c = cras_fmt_conv_create(&in_fmt, &out_fmt, 4096);
41  EXPECT_EQ(NULL, c);
42}
43
44// Only support LE, BE should fail.
45TEST(FormatConverterTest,  InvalidParamsOnlyLE) {
46  struct cras_audio_format in_fmt;
47  struct cras_audio_format out_fmt;
48  struct cras_fmt_conv *c;
49
50  in_fmt.format = out_fmt.format = SND_PCM_FORMAT_S32_BE;
51  in_fmt.num_channels = out_fmt.num_channels = 2;
52  c = cras_fmt_conv_create(&in_fmt, &out_fmt, 4096);
53  EXPECT_EQ(NULL, c);
54}
55
56// Test Mono to Stereo mix.
57TEST(FormatConverterTest, MonoToStereo) {
58  struct cras_fmt_conv *c;
59  struct cras_audio_format in_fmt;
60  struct cras_audio_format out_fmt;
61
62  size_t out_frames;
63  int16_t *in_buff;
64  int16_t *out_buff;
65  const size_t buf_size = 4096;
66
67  in_fmt.format = SND_PCM_FORMAT_S16_LE;
68  out_fmt.format = SND_PCM_FORMAT_S16_LE;
69  in_fmt.num_channels = 1;
70  out_fmt.num_channels = 2;
71  in_fmt.frame_rate = 48000;
72  out_fmt.frame_rate = 48000;
73
74  c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size);
75  ASSERT_NE(c, (void *)NULL);
76
77  out_frames = cras_fmt_conv_out_frames_to_in(c, buf_size);
78  EXPECT_EQ(buf_size, out_frames);
79
80  out_frames = cras_fmt_conv_in_frames_to_out(c, buf_size);
81  EXPECT_EQ(buf_size, out_frames);
82
83  in_buff = (int16_t *)ralloc(buf_size * 2 * cras_get_format_bytes(&in_fmt));
84  out_buff = (int16_t *)ralloc(buf_size * 2 * cras_get_format_bytes(&out_fmt));
85  out_frames = cras_fmt_conv_convert_frames(c,
86                                            (uint8_t *)in_buff,
87                                            (uint8_t *)out_buff,
88                                            buf_size,
89                                            buf_size);
90  EXPECT_EQ(buf_size, out_frames);
91  for (size_t i = 0; i < buf_size; i++) {
92    if (in_buff[i] != out_buff[i*2] ||
93        in_buff[i] != out_buff[i*2 + 1]) {
94      EXPECT_TRUE(false);
95      break;
96    }
97  }
98
99  cras_fmt_conv_destroy(c);
100  free(in_buff);
101  free(out_buff);
102}
103
104// Test Stereo to Mono mix.
105TEST(FormatConverterTest, StereoToMono) {
106  struct cras_fmt_conv *c;
107  struct cras_audio_format in_fmt;
108  struct cras_audio_format out_fmt;
109
110  size_t out_frames;
111  int16_t *in_buff;
112  int16_t *out_buff;
113  unsigned int i;
114  const size_t buf_size = 4096;
115
116  in_fmt.format = SND_PCM_FORMAT_S16_LE;
117  out_fmt.format = SND_PCM_FORMAT_S16_LE;
118  in_fmt.num_channels = 2;
119  out_fmt.num_channels = 1;
120  in_fmt.frame_rate = 48000;
121  out_fmt.frame_rate = 48000;
122
123  c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size);
124  ASSERT_NE(c, (void *)NULL);
125
126  out_frames = cras_fmt_conv_out_frames_to_in(c, buf_size);
127  EXPECT_EQ(buf_size, out_frames);
128
129  out_frames = cras_fmt_conv_in_frames_to_out(c, buf_size);
130  EXPECT_EQ(buf_size, out_frames);
131
132  in_buff = (int16_t *)malloc(buf_size * 2 * cras_get_format_bytes(&in_fmt));
133  out_buff = (int16_t *)malloc(buf_size * cras_get_format_bytes(&out_fmt));
134  for (i = 0; i < buf_size; i++) {
135    in_buff[i * 2] = 13450;
136    in_buff[i * 2 + 1] = -13449;
137  }
138  out_frames = cras_fmt_conv_convert_frames(c,
139                                            (uint8_t *)in_buff,
140                                            (uint8_t *)out_buff,
141                                            buf_size,
142                                            buf_size);
143  EXPECT_EQ(buf_size, out_frames);
144  for (i = 0; i < buf_size; i++) {
145    EXPECT_EQ(1, out_buff[i]);
146  }
147
148  cras_fmt_conv_destroy(c);
149  free(in_buff);
150  free(out_buff);
151}
152
153// Test 5.1 to Stereo mix.
154TEST(FormatConverterTest, SurroundToStereo) {
155  struct cras_fmt_conv *c;
156  struct cras_audio_format in_fmt;
157  struct cras_audio_format out_fmt;
158
159  size_t out_frames;
160  int16_t *in_buff;
161  int16_t *out_buff;
162  unsigned int i;
163  const size_t buf_size = 4096;
164
165  in_fmt.format = SND_PCM_FORMAT_S16_LE;
166  out_fmt.format = SND_PCM_FORMAT_S16_LE;
167  in_fmt.num_channels = 6;
168  out_fmt.num_channels = 2;
169  in_fmt.frame_rate = 48000;
170  out_fmt.frame_rate = 48000;
171  for (i = 0; i < CRAS_CH_MAX; i++)
172    in_fmt.channel_layout[i] = surround_channel_layout[i];
173
174  c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size);
175  ASSERT_NE(c, (void *)NULL);
176
177  out_frames = cras_fmt_conv_out_frames_to_in(c, buf_size);
178  EXPECT_EQ(buf_size, out_frames);
179
180  out_frames = cras_fmt_conv_in_frames_to_out(c, buf_size);
181  EXPECT_EQ(buf_size, out_frames);
182
183  in_buff = (int16_t *)malloc(buf_size * 2 * cras_get_format_bytes(&in_fmt));
184
185  /* Swap channel to FL = 13450, RL = -100.
186   * Assert right channel is silent.
187   */
188  for (i = 0; i < buf_size; i++) {
189    in_buff[i * 6] = 13450;
190    in_buff[i * 6 + 1] = 0;
191    in_buff[i * 6 + 2] = -100;
192    in_buff[i * 6 + 3] = 0;
193    in_buff[i * 6 + 4] = 0;
194    in_buff[i * 6 + 5] = 0;
195  }
196  out_buff = (int16_t *)malloc(buf_size * 2 * cras_get_format_bytes(&out_fmt));
197  out_frames = cras_fmt_conv_convert_frames(c,
198                                            (uint8_t *)in_buff,
199                                            (uint8_t *)out_buff,
200                                            buf_size,
201                                            buf_size);
202  EXPECT_EQ(buf_size, out_frames);
203  for (i = 0; i < buf_size; i++)
204    EXPECT_LT(0, out_buff[i * 2]);
205
206  /* Swap channel to FR = 13450, RR = -100.
207   * Assert left channel is silent.
208   */
209  swap_channel_layout(in_fmt.channel_layout, CRAS_CH_FL, CRAS_CH_FR);
210  swap_channel_layout(in_fmt.channel_layout, CRAS_CH_RL, CRAS_CH_RR);
211  c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size);
212  out_frames = cras_fmt_conv_convert_frames(c,
213                                            (uint8_t *)in_buff,
214                                            (uint8_t *)out_buff,
215                                            buf_size,
216                                            buf_size);
217  EXPECT_EQ(buf_size, out_frames);
218  for (i = 0; i < buf_size; i++)
219    EXPECT_LT(0, out_buff[i * 2 + 1]);
220
221  /* Swap channel to FC = 13450, LFE = -100.
222   * Assert output left and right has equal magnitude.
223   */
224  swap_channel_layout(in_fmt.channel_layout, CRAS_CH_FR, CRAS_CH_FC);
225  swap_channel_layout(in_fmt.channel_layout, CRAS_CH_RR, CRAS_CH_LFE);
226  c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size);
227  out_frames = cras_fmt_conv_convert_frames(c,
228                                            (uint8_t *)in_buff,
229                                            (uint8_t *)out_buff,
230                                            buf_size,
231                                            buf_size);
232  EXPECT_EQ(buf_size, out_frames);
233  for (i = 0; i < buf_size; i++) {
234    EXPECT_NE(0, out_buff[i * 2]);
235    EXPECT_EQ(out_buff[i * 2], out_buff[i * 2 + 1]);
236  }
237
238  /* Swap channel to FR = 13450, FL = -100.
239   * Assert output left is positive and right is negative. */
240  swap_channel_layout(in_fmt.channel_layout, CRAS_CH_LFE, CRAS_CH_FR);
241  swap_channel_layout(in_fmt.channel_layout, CRAS_CH_FC, CRAS_CH_FL);
242  c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size);
243  out_frames = cras_fmt_conv_convert_frames(c,
244                                            (uint8_t *)in_buff,
245                                            (uint8_t *)out_buff,
246                                            buf_size,
247                                            buf_size);
248  EXPECT_EQ(buf_size, out_frames);
249  for (i = 0; i < buf_size; i++) {
250    EXPECT_LT(0, out_buff[i * 2]);
251    EXPECT_GT(0, out_buff[i * 2 + 1]);
252  }
253
254  cras_fmt_conv_destroy(c);
255  free(in_buff);
256  free(out_buff);
257}
258
259// Test 2 to 1 SRC.
260TEST(FormatConverterTest,  Convert2To1) {
261  struct cras_fmt_conv *c;
262  struct cras_audio_format in_fmt;
263  struct cras_audio_format out_fmt;
264
265  size_t out_frames;
266  int16_t *in_buff;
267  int16_t *out_buff;
268  const size_t buf_size = 4096;
269
270  in_fmt.format = out_fmt.format = SND_PCM_FORMAT_S16_LE;
271  in_fmt.num_channels = out_fmt.num_channels = 2;
272  in_fmt.frame_rate = 96000;
273  out_fmt.frame_rate = 48000;
274
275  c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size);
276  ASSERT_NE(c, (void *)NULL);
277
278  out_frames = cras_fmt_conv_in_frames_to_out(c, buf_size);
279  EXPECT_EQ(buf_size/2, out_frames);
280
281  in_buff = (int16_t *)ralloc(buf_size * 2 * cras_get_format_bytes(&in_fmt));
282  out_buff = (int16_t *)ralloc(buf_size/2 * cras_get_format_bytes(&out_fmt));
283  out_frames = cras_fmt_conv_convert_frames(c,
284                                            (uint8_t *)in_buff,
285                                            (uint8_t *)out_buff,
286                                            buf_size,
287                                            buf_size / 2);
288  cras_fmt_conv_destroy(c);
289  free(in_buff);
290  free(out_buff);
291}
292
293// Test 1 to 2 SRC.
294TEST(FormatConverterTest,  Convert1To2) {
295  struct cras_fmt_conv *c;
296  struct cras_audio_format in_fmt;
297  struct cras_audio_format out_fmt;
298  size_t out_frames;
299  int16_t *in_buff;
300  int16_t *out_buff;
301  const size_t buf_size = 4096;
302
303  in_fmt.format = out_fmt.format = SND_PCM_FORMAT_S16_LE;
304  in_fmt.num_channels = out_fmt.num_channels = 2;
305  in_fmt.frame_rate = 22050;
306  out_fmt.frame_rate = 44100;
307
308  c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size);
309  ASSERT_NE(c, (void *)NULL);
310
311  out_frames = cras_fmt_conv_in_frames_to_out(c, buf_size);
312  EXPECT_EQ(buf_size*2, out_frames);
313
314  in_buff = (int16_t *)ralloc(buf_size * 2 * cras_get_format_bytes(&in_fmt));
315  out_buff = (int16_t *)ralloc(buf_size*2 * cras_get_format_bytes(&out_fmt));
316  out_frames = cras_fmt_conv_convert_frames(c,
317                                            (uint8_t *)in_buff,
318                                            (uint8_t *)out_buff,
319                                            buf_size,
320                                            buf_size * 2);
321  cras_fmt_conv_destroy(c);
322  free(in_buff);
323  free(out_buff);
324}
325
326// Test 1 to 2 SRC with mono to stereo conversion.
327TEST(FormatConverterTest,  Convert1To2MonoToStereo) {
328  struct cras_fmt_conv *c;
329  struct cras_audio_format in_fmt;
330  struct cras_audio_format out_fmt;
331  size_t out_frames;
332  int16_t *in_buff;
333  int16_t *out_buff;
334  const size_t buf_size = 4096;
335
336  in_fmt.format = out_fmt.format = SND_PCM_FORMAT_S16_LE;
337  in_fmt.num_channels = 1;
338  out_fmt.num_channels = 2;
339  in_fmt.frame_rate = 22050;
340  out_fmt.frame_rate = 44100;
341
342  c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size);
343  ASSERT_NE(c, (void *)NULL);
344
345  out_frames = cras_fmt_conv_out_frames_to_in(c, buf_size);
346  EXPECT_EQ(buf_size / 2, out_frames);
347
348  out_frames = cras_fmt_conv_in_frames_to_out(c, buf_size);
349  EXPECT_EQ(buf_size * 2, out_frames);
350
351  in_buff = (int16_t *)ralloc(buf_size * 2 * cras_get_format_bytes(&in_fmt));
352  out_buff = (int16_t *)ralloc(buf_size * 2 * cras_get_format_bytes(&out_fmt));
353  out_frames = cras_fmt_conv_convert_frames(c,
354                                            (uint8_t *)in_buff,
355                                            (uint8_t *)out_buff,
356                                            buf_size,
357                                            buf_size * 2);
358  cras_fmt_conv_destroy(c);
359  free(in_buff);
360  free(out_buff);
361}
362
363// Test 32 to 16 bit conversion.
364TEST(FormatConverterTest, ConvertS32LEToS16LE) {
365  struct cras_fmt_conv *c;
366  struct cras_audio_format in_fmt;
367  struct cras_audio_format out_fmt;
368
369  size_t out_frames;
370  int32_t *in_buff;
371  int16_t *out_buff;
372  const size_t buf_size = 4096;
373
374  in_fmt.format = SND_PCM_FORMAT_S32_LE;
375  out_fmt.format = SND_PCM_FORMAT_S16_LE;
376  in_fmt.num_channels = out_fmt.num_channels = 2;
377  in_fmt.frame_rate = 48000;
378  out_fmt.frame_rate = 48000;
379
380  c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size);
381  ASSERT_NE(c, (void *)NULL);
382
383  out_frames = cras_fmt_conv_in_frames_to_out(c, buf_size);
384  EXPECT_EQ(buf_size, out_frames);
385
386  in_buff = (int32_t *)ralloc(buf_size * 2 * cras_get_format_bytes(&in_fmt));
387  out_buff = (int16_t *)ralloc(buf_size * cras_get_format_bytes(&out_fmt));
388  out_frames = cras_fmt_conv_convert_frames(c,
389                                            (uint8_t *)in_buff,
390                                            (uint8_t *)out_buff,
391                                            buf_size,
392                                            buf_size);
393  EXPECT_EQ(buf_size, out_frames);
394  for (unsigned int i = 0; i < buf_size; i++)
395    EXPECT_EQ((int16_t)(in_buff[i] >> 16), out_buff[i]);
396
397  cras_fmt_conv_destroy(c);
398  free(in_buff);
399  free(out_buff);
400}
401
402// Test 24 to 16 bit conversion.
403TEST(FormatConverterTest, ConvertS24LEToS16LE) {
404  struct cras_fmt_conv *c;
405  struct cras_audio_format in_fmt;
406  struct cras_audio_format out_fmt;
407
408  size_t out_frames;
409  int32_t *in_buff;
410  int16_t *out_buff;
411  const size_t buf_size = 4096;
412
413  in_fmt.format = SND_PCM_FORMAT_S24_LE;
414  out_fmt.format = SND_PCM_FORMAT_S16_LE;
415  in_fmt.num_channels = out_fmt.num_channels = 2;
416  in_fmt.frame_rate = 48000;
417  out_fmt.frame_rate = 48000;
418
419  c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size);
420  ASSERT_NE(c, (void *)NULL);
421
422  out_frames = cras_fmt_conv_in_frames_to_out(c, buf_size);
423  EXPECT_EQ(buf_size, out_frames);
424
425  in_buff = (int32_t *)ralloc(buf_size * 2 * cras_get_format_bytes(&in_fmt));
426  out_buff = (int16_t *)ralloc(buf_size * cras_get_format_bytes(&out_fmt));
427  out_frames = cras_fmt_conv_convert_frames(c,
428                                            (uint8_t *)in_buff,
429                                            (uint8_t *)out_buff,
430                                            buf_size,
431                                            buf_size);
432  EXPECT_EQ(buf_size, out_frames);
433  for (unsigned int i = 0; i < buf_size; i++)
434    EXPECT_EQ((int16_t)(in_buff[i] >> 8), out_buff[i]);
435
436  cras_fmt_conv_destroy(c);
437  free(in_buff);
438  free(out_buff);
439}
440
441// Test 8 to 16 bit conversion.
442TEST(FormatConverterTest, ConvertU8LEToS16LE) {
443  struct cras_fmt_conv *c;
444  struct cras_audio_format in_fmt;
445  struct cras_audio_format out_fmt;
446
447  size_t out_frames;
448  uint8_t *in_buff;
449  int16_t *out_buff;
450  const size_t buf_size = 4096;
451
452  in_fmt.format = SND_PCM_FORMAT_U8;
453  out_fmt.format = SND_PCM_FORMAT_S16_LE;
454  in_fmt.num_channels = 2;
455  out_fmt.num_channels = 2;
456  in_fmt.frame_rate = 48000;
457  out_fmt.frame_rate = 48000;
458
459  c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size);
460  ASSERT_NE(c, (void *)NULL);
461
462  out_frames = cras_fmt_conv_in_frames_to_out(c, buf_size);
463  EXPECT_EQ(buf_size, out_frames);
464
465  in_buff = (uint8_t *)ralloc(buf_size * 2 * cras_get_format_bytes(&in_fmt));
466  out_buff = (int16_t *)ralloc(buf_size * cras_get_format_bytes(&out_fmt));
467  out_frames = cras_fmt_conv_convert_frames(c,
468                                            (uint8_t *)in_buff,
469                                            (uint8_t *)out_buff,
470                                            buf_size,
471                                            buf_size);
472  EXPECT_EQ(buf_size, out_frames);
473  for (unsigned int i = 0; i < buf_size; i++)
474    EXPECT_EQ(((int16_t)(in_buff[i] - 128) << 8), out_buff[i]);
475
476  cras_fmt_conv_destroy(c);
477  free(in_buff);
478  free(out_buff);
479}
480
481// Test 16 to 32 bit conversion.
482TEST(FormatConverterTest, ConvertS16LEToS32LE) {
483  struct cras_fmt_conv *c;
484  struct cras_audio_format in_fmt;
485  struct cras_audio_format out_fmt;
486
487  size_t out_frames;
488  int16_t *in_buff;
489  int32_t *out_buff;
490  const size_t buf_size = 4096;
491
492  in_fmt.format = SND_PCM_FORMAT_S16_LE;
493  out_fmt.format = SND_PCM_FORMAT_S32_LE;
494  in_fmt.num_channels = out_fmt.num_channels = 2;
495  in_fmt.frame_rate = 48000;
496  out_fmt.frame_rate = 48000;
497
498  c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size);
499  ASSERT_NE(c, (void *)NULL);
500
501  out_frames = cras_fmt_conv_in_frames_to_out(c, buf_size);
502  EXPECT_EQ(buf_size, out_frames);
503
504  in_buff = (int16_t *)ralloc(buf_size * cras_get_format_bytes(&in_fmt));
505  out_buff = (int32_t *)ralloc(buf_size * cras_get_format_bytes(&out_fmt));
506  out_frames = cras_fmt_conv_convert_frames(c,
507                                            (uint8_t *)in_buff,
508                                            (uint8_t *)out_buff,
509                                            buf_size,
510                                            buf_size);
511  EXPECT_EQ(buf_size, out_frames);
512  for (unsigned int i = 0; i < buf_size; i++)
513    EXPECT_EQ(((int32_t)in_buff[i] << 16), out_buff[i]);
514
515  cras_fmt_conv_destroy(c);
516  free(in_buff);
517  free(out_buff);
518}
519
520// Test 16 to 24 bit conversion.
521TEST(FormatConverterTest, ConvertS16LEToS24LE) {
522  struct cras_fmt_conv *c;
523  struct cras_audio_format in_fmt;
524  struct cras_audio_format out_fmt;
525
526  size_t out_frames;
527  int16_t *in_buff;
528  int32_t *out_buff;
529  const size_t buf_size = 4096;
530
531  in_fmt.format = SND_PCM_FORMAT_S16_LE;
532  out_fmt.format = SND_PCM_FORMAT_S24_LE;
533  in_fmt.num_channels = out_fmt.num_channels = 2;
534  in_fmt.frame_rate = 48000;
535  out_fmt.frame_rate = 48000;
536
537  c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size);
538  ASSERT_NE(c, (void *)NULL);
539
540  out_frames = cras_fmt_conv_in_frames_to_out(c, buf_size);
541  EXPECT_EQ(buf_size, out_frames);
542
543  in_buff = (int16_t *)ralloc(buf_size * cras_get_format_bytes(&in_fmt));
544  out_buff = (int32_t *)ralloc(buf_size * 2 * cras_get_format_bytes(&out_fmt));
545  out_frames = cras_fmt_conv_convert_frames(c,
546                                            (uint8_t *)in_buff,
547                                            (uint8_t *)out_buff,
548                                            buf_size,
549                                            buf_size);
550  EXPECT_EQ(buf_size, out_frames);
551  for (unsigned int i = 0; i < buf_size; i++)
552    EXPECT_EQ(((int32_t)in_buff[i] << 8), out_buff[i]);
553
554  cras_fmt_conv_destroy(c);
555  free(in_buff);
556  free(out_buff);
557}
558
559// Test 16 to 8 bit conversion.
560TEST(FormatConverterTest, ConvertS16LEToU8) {
561  struct cras_fmt_conv *c;
562  struct cras_audio_format in_fmt;
563  struct cras_audio_format out_fmt;
564
565  size_t out_frames;
566  int16_t *in_buff;
567  uint8_t *out_buff;
568  const size_t buf_size = 4096;
569
570  in_fmt.format = SND_PCM_FORMAT_S16_LE;
571  out_fmt.format = SND_PCM_FORMAT_U8;
572  in_fmt.num_channels = 2;
573  out_fmt.num_channels = 2;
574  in_fmt.frame_rate = 48000;
575  out_fmt.frame_rate = 48000;
576
577  c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size);
578  ASSERT_NE(c, (void *)NULL);
579
580  out_frames = cras_fmt_conv_in_frames_to_out(c, buf_size);
581  EXPECT_EQ(buf_size, out_frames);
582
583  in_buff = (int16_t *)ralloc(buf_size * cras_get_format_bytes(&in_fmt));
584  out_buff = (uint8_t *)ralloc(buf_size * cras_get_format_bytes(&out_fmt));
585  out_frames = cras_fmt_conv_convert_frames(c,
586                                            (uint8_t *)in_buff,
587                                            (uint8_t *)out_buff,
588                                            buf_size,
589                                            buf_size);
590  EXPECT_EQ(buf_size, out_frames);
591  for (unsigned int i = 0; i < buf_size; i++)
592    EXPECT_EQ((in_buff[i] >> 8) + 128, out_buff[i]);
593
594  cras_fmt_conv_destroy(c);
595  free(in_buff);
596  free(out_buff);
597}
598
599// Test 32 bit 5.1 to 16 bit stereo conversion.
600TEST(FormatConverterTest, ConvertS32LEToS16LEDownmix51ToStereo) {
601  struct cras_fmt_conv *c;
602  struct cras_audio_format in_fmt;
603  struct cras_audio_format out_fmt;
604
605  size_t out_frames;
606  int32_t *in_buff;
607  int16_t *out_buff;
608  const size_t buf_size = 4096;
609  int i;
610
611
612  in_fmt.format = SND_PCM_FORMAT_S32_LE;
613  out_fmt.format = SND_PCM_FORMAT_S16_LE;
614  in_fmt.num_channels = 6;
615  out_fmt.num_channels = 2;
616  in_fmt.frame_rate = 48000;
617  out_fmt.frame_rate = 48000;
618  for (i = 0; i < CRAS_CH_MAX; i++)
619    in_fmt.channel_layout[i] = surround_channel_layout[i];
620
621  c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size);
622  ASSERT_NE(c, (void *)NULL);
623
624  out_frames = cras_fmt_conv_in_frames_to_out(c, buf_size);
625  EXPECT_EQ(buf_size, out_frames);
626
627  in_buff = (int32_t *)ralloc(buf_size * 2 * cras_get_format_bytes(&in_fmt));
628  out_buff = (int16_t *)ralloc(buf_size * cras_get_format_bytes(&out_fmt));
629  out_frames = cras_fmt_conv_convert_frames(c,
630                                            (uint8_t *)in_buff,
631                                            (uint8_t *)out_buff,
632                                            buf_size,
633                                            buf_size);
634  EXPECT_EQ(buf_size, out_frames);
635
636  cras_fmt_conv_destroy(c);
637  free(in_buff);
638  free(out_buff);
639}
640
641// Test 16 bit stereo to 5.1 conversion.
642TEST(FormatConverterTest, ConvertS16LEToS16LEStereoTo51) {
643  struct cras_fmt_conv *c;
644  struct cras_audio_format in_fmt;
645  struct cras_audio_format out_fmt;
646
647  size_t out_frames;
648  int16_t *in_buff;
649  int16_t *out_buff;
650  const size_t buf_size = 4096;
651  int i;
652
653
654  in_fmt.format = SND_PCM_FORMAT_S16_LE;
655  out_fmt.format = SND_PCM_FORMAT_S16_LE;
656  in_fmt.num_channels = 2;
657  out_fmt.num_channels = 6;
658  in_fmt.frame_rate = 48000;
659  out_fmt.frame_rate = 48000;
660  for (i = 0; i < CRAS_CH_MAX; i++)
661    out_fmt.channel_layout[i] = surround_channel_layout[i];
662
663  c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size);
664  ASSERT_NE(c, (void *)NULL);
665
666  out_frames = cras_fmt_conv_in_frames_to_out(c, buf_size);
667  EXPECT_EQ(buf_size, out_frames);
668
669  in_buff = (int16_t *)ralloc(buf_size * cras_get_format_bytes(&in_fmt));
670  out_buff = (int16_t *)ralloc(buf_size * cras_get_format_bytes(&out_fmt));
671  out_frames = cras_fmt_conv_convert_frames(c,
672                                            (uint8_t *)in_buff,
673                                            (uint8_t *)out_buff,
674                                            buf_size,
675                                            buf_size);
676  EXPECT_EQ(buf_size, out_frames);
677  for (unsigned int i = 0; i < buf_size; i++) {
678    /* Check mono be converted to CRAS_CH_FL and CRAS_CH_FR */
679    EXPECT_EQ(in_buff[2 * i], out_buff[6 * i]);
680    EXPECT_EQ(in_buff[2 * i + 1], out_buff[6 * i + 1]);
681    EXPECT_EQ(0, out_buff[6 * i + 2]);
682    EXPECT_EQ(0, out_buff[6 * i + 3]);
683    EXPECT_EQ(0, out_buff[6 * i + 4]);
684    EXPECT_EQ(0, out_buff[6 * i + 5]);
685  }
686
687  cras_fmt_conv_destroy(c);
688  free(in_buff);
689  free(out_buff);
690}
691
692// Test 16 bit mono to 5.1 conversion.
693TEST(FormatConverterTest, ConvertS16LEToS16LEMonoTo51) {
694  struct cras_fmt_conv *c;
695  struct cras_audio_format in_fmt;
696  struct cras_audio_format out_fmt;
697
698  size_t out_frames;
699  int16_t *in_buff;
700  int16_t *out_buff;
701  const size_t buf_size = 4096;
702  int i;
703
704
705  in_fmt.format = SND_PCM_FORMAT_S16_LE;
706  out_fmt.format = SND_PCM_FORMAT_S16_LE;
707  in_fmt.num_channels = 1;
708  out_fmt.num_channels = 6;
709  in_fmt.frame_rate = 48000;
710  out_fmt.frame_rate = 48000;
711  for (i = 0; i < CRAS_CH_MAX; i++)
712    out_fmt.channel_layout[i] = surround_channel_layout[i];
713
714  c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size);
715  ASSERT_NE(c, (void *)NULL);
716
717  out_frames = cras_fmt_conv_in_frames_to_out(c, buf_size);
718  EXPECT_EQ(buf_size, out_frames);
719
720  in_buff = (int16_t *)ralloc(buf_size * cras_get_format_bytes(&in_fmt));
721  out_buff = (int16_t *)ralloc(buf_size * cras_get_format_bytes(&out_fmt));
722  out_frames = cras_fmt_conv_convert_frames(c,
723                                            (uint8_t *)in_buff,
724                                            (uint8_t *)out_buff,
725                                            buf_size,
726                                            buf_size);
727  EXPECT_EQ(buf_size, out_frames);
728  for (unsigned int i = 0; i < buf_size; i++) {
729    /* Check mono be converted to CRAS_CH_FC */
730    EXPECT_EQ(in_buff[i], out_buff[6 * i + 4]);
731    EXPECT_EQ(0, out_buff[6 * i + 0]);
732    EXPECT_EQ(0, out_buff[6 * i + 1]);
733    EXPECT_EQ(0, out_buff[6 * i + 2]);
734    EXPECT_EQ(0, out_buff[6 * i + 3]);
735    EXPECT_EQ(0, out_buff[6 * i + 5]);
736  }
737
738  cras_fmt_conv_destroy(c);
739  free(in_buff);
740  free(out_buff);
741}
742
743// Test 32 bit 5.1 to 16 bit stereo conversion with SRC 1 to 2.
744TEST(FormatConverterTest, ConvertS32LEToS16LEDownmix51ToStereo48To96) {
745  struct cras_fmt_conv *c;
746  struct cras_audio_format in_fmt;
747  struct cras_audio_format out_fmt;
748
749  size_t out_frames;
750  int32_t *in_buff;
751  int16_t *out_buff;
752  const size_t buf_size = 4096;
753  int i;
754
755  in_fmt.format = SND_PCM_FORMAT_S32_LE;
756  out_fmt.format = SND_PCM_FORMAT_S16_LE;
757  in_fmt.num_channels = 6;
758  out_fmt.num_channels = 2;
759  in_fmt.frame_rate = 48000;
760  out_fmt.frame_rate = 96000;
761  for (i = 0; i < CRAS_CH_MAX; i++)
762    in_fmt.channel_layout[i] = surround_channel_layout[i];
763
764  c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size);
765  ASSERT_NE(c, (void *)NULL);
766
767  out_frames = cras_fmt_conv_in_frames_to_out(c, buf_size);
768  EXPECT_EQ(buf_size * 2, out_frames);
769
770  in_buff = (int32_t *)ralloc(buf_size * cras_get_format_bytes(&in_fmt));
771  out_buff = (int16_t *)ralloc(buf_size * 2 * cras_get_format_bytes(&out_fmt));
772  out_frames = cras_fmt_conv_convert_frames(c,
773                                            (uint8_t *)in_buff,
774                                            (uint8_t *)out_buff,
775                                            buf_size,
776                                            buf_size * 2);
777  EXPECT_EQ(buf_size * 2, out_frames);
778
779  cras_fmt_conv_destroy(c);
780  free(in_buff);
781  free(out_buff);
782}
783
784// Test 32 bit 5.1 to 16 bit stereo conversion with SRC 2 to 1.
785TEST(FormatConverterTest, ConvertS32LEToS16LEDownmix51ToStereo96To48) {
786  struct cras_fmt_conv *c;
787  struct cras_audio_format in_fmt;
788  struct cras_audio_format out_fmt;
789
790  size_t out_frames;
791  int32_t *in_buff;
792  int16_t *out_buff;
793  const size_t buf_size = 4096;
794  int i;
795
796  in_fmt.format = SND_PCM_FORMAT_S32_LE;
797  out_fmt.format = SND_PCM_FORMAT_S16_LE;
798  in_fmt.num_channels = 6;
799  out_fmt.num_channels = 2;
800  in_fmt.frame_rate = 96000;
801  out_fmt.frame_rate = 48000;
802  for (i = 0; i < CRAS_CH_MAX; i++)
803    in_fmt.channel_layout[i] = surround_channel_layout[i];
804
805  c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size);
806  ASSERT_NE(c, (void *)NULL);
807
808  out_frames = cras_fmt_conv_in_frames_to_out(c, buf_size);
809  EXPECT_EQ(buf_size / 2, out_frames);
810
811  in_buff = (int32_t *)ralloc(buf_size * cras_get_format_bytes(&in_fmt));
812  out_buff = (int16_t *)ralloc(buf_size / 2 * cras_get_format_bytes(&out_fmt));
813  out_frames = cras_fmt_conv_convert_frames(c,
814                                            (uint8_t *)in_buff,
815                                            (uint8_t *)out_buff,
816                                            buf_size,
817                                            buf_size / 2);
818  EXPECT_EQ(buf_size / 2, out_frames);
819
820  cras_fmt_conv_destroy(c);
821  free(in_buff);
822  free(out_buff);
823}
824
825// Test 32 bit 5.1 to 16 bit stereo conversion with SRC 48 to 44.1.
826TEST(FormatConverterTest, ConvertS32LEToS16LEDownmix51ToStereo48To441) {
827  struct cras_fmt_conv *c;
828  struct cras_audio_format in_fmt;
829  struct cras_audio_format out_fmt;
830
831  size_t out_frames;
832  size_t ret_frames;
833  int32_t *in_buff;
834  int16_t *out_buff;
835  const size_t buf_size = 4096;
836  int i;
837
838  in_fmt.format = SND_PCM_FORMAT_S32_LE;
839  out_fmt.format = SND_PCM_FORMAT_S16_LE;
840  in_fmt.num_channels = 6;
841  out_fmt.num_channels = 2;
842  in_fmt.frame_rate = 48000;
843  out_fmt.frame_rate = 44100;
844  for (i = 0; i < CRAS_CH_MAX; i++)
845    in_fmt.channel_layout[i] = surround_channel_layout[i];
846
847  c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size);
848  ASSERT_NE(c, (void *)NULL);
849
850  out_frames = cras_fmt_conv_in_frames_to_out(c, buf_size);
851  EXPECT_LT(out_frames, buf_size);
852
853  in_buff = (int32_t *)ralloc(buf_size * cras_get_format_bytes(&in_fmt));
854  out_buff = (int16_t *)ralloc(out_frames * cras_get_format_bytes(&out_fmt));
855  ret_frames = cras_fmt_conv_convert_frames(c,
856                                            (uint8_t *)in_buff,
857                                            (uint8_t *)out_buff,
858                                            buf_size,
859                                            out_frames);
860  EXPECT_EQ(out_frames, ret_frames);
861
862  cras_fmt_conv_destroy(c);
863  free(in_buff);
864  free(out_buff);
865}
866
867// Test 32 bit 5.1 to 16 bit stereo conversion with SRC 441 to 48.
868TEST(FormatConverterTest, ConvertS32LEToS16LEDownmix51ToStereo441To48) {
869  struct cras_fmt_conv *c;
870  struct cras_audio_format in_fmt;
871  struct cras_audio_format out_fmt;
872
873  size_t out_frames;
874  size_t ret_frames;
875  int32_t *in_buff;
876  int16_t *out_buff;
877  const size_t buf_size = 4096;
878  int i;
879
880  in_fmt.format = SND_PCM_FORMAT_S32_LE;
881  out_fmt.format = SND_PCM_FORMAT_S16_LE;
882  in_fmt.num_channels = 6;
883  out_fmt.num_channels = 2;
884  in_fmt.frame_rate = 44100;
885  out_fmt.frame_rate = 48000;
886  for (i = 0; i < CRAS_CH_MAX; i++)
887    in_fmt.channel_layout[i] = surround_channel_layout[i];
888
889  c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size);
890  ASSERT_NE(c, (void *)NULL);
891
892  out_frames = cras_fmt_conv_in_frames_to_out(c, buf_size);
893  EXPECT_GT(out_frames, buf_size);
894
895  in_buff = (int32_t *)ralloc(buf_size * cras_get_format_bytes(&in_fmt));
896  out_buff = (int16_t *)ralloc((out_frames - 1) *
897                               cras_get_format_bytes(&out_fmt));
898  ret_frames = cras_fmt_conv_convert_frames(c,
899                                            (uint8_t *)in_buff,
900                                            (uint8_t *)out_buff,
901                                            buf_size,
902                                            out_frames - 1);
903  EXPECT_EQ(out_frames - 1, ret_frames);
904
905  cras_fmt_conv_destroy(c);
906  free(in_buff);
907  free(out_buff);
908}
909
910// Test Invalid buffer length just truncates.
911TEST(FormatConverterTest, ConvertS32LEToS16LEDownmix51ToStereo96To48Short) {
912  struct cras_fmt_conv *c;
913  struct cras_audio_format in_fmt;
914  struct cras_audio_format out_fmt;
915
916  size_t out_frames;
917  size_t ret_frames;
918  int32_t *in_buff;
919  int16_t *out_buff;
920  const size_t buf_size = 4096;
921  int i;
922
923  in_fmt.format = SND_PCM_FORMAT_S32_LE;
924  out_fmt.format = SND_PCM_FORMAT_S16_LE;
925  in_fmt.num_channels = 6;
926  out_fmt.num_channels = 2;
927  in_fmt.frame_rate = 96000;
928  out_fmt.frame_rate = 48000;
929  for (i = 0; i < CRAS_CH_MAX; i++)
930    in_fmt.channel_layout[i] = surround_channel_layout[i];
931
932  c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size);
933  ASSERT_NE(c, (void *)NULL);
934
935  out_frames = cras_fmt_conv_in_frames_to_out(c, buf_size);
936  EXPECT_EQ(buf_size / 2, out_frames);
937
938  in_buff = (int32_t *)ralloc(buf_size * cras_get_format_bytes(&in_fmt));
939  out_buff = (int16_t *)ralloc((out_frames - 2) *
940                               cras_get_format_bytes(&out_fmt));
941  ret_frames = cras_fmt_conv_convert_frames(c,
942                                            (uint8_t *)in_buff,
943                                            (uint8_t *)out_buff,
944                                            buf_size,
945                                            out_frames - 2);
946  EXPECT_EQ(out_frames - 2, ret_frames);
947
948  cras_fmt_conv_destroy(c);
949  free(in_buff);
950  free(out_buff);
951}
952
953int main(int argc, char **argv) {
954  ::testing::InitGoogleTest(&argc, argv);
955  return RUN_ALL_TESTS();
956}
957
958extern "C" {
959float** cras_channel_conv_matrix_alloc(size_t in_ch, size_t out_ch)
960{
961  int i;
962  float** conv_mtx;
963  conv_mtx = (float **)calloc(CRAS_CH_MAX, sizeof(*conv_mtx));
964  for (i = 0; i < CRAS_CH_MAX; i++)
965    conv_mtx[i] = (float *)calloc(CRAS_CH_MAX, sizeof(*conv_mtx[i]));
966  return conv_mtx;
967}
968void cras_channel_conv_matrix_destroy(float **mtx, size_t out_ch)
969{
970  int i;
971  for (i = 0; i < CRAS_CH_MAX; i++)
972    free(mtx[i]);
973  free(mtx);
974}
975float **cras_channel_conv_matrix_create(const struct cras_audio_format *in,
976					const struct cras_audio_format *out)
977{
978  return cras_channel_conv_matrix_alloc(in->num_channels,
979					out->num_channels);
980}
981} // extern "C"
982