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
6 /* For now just use speex, can add more resamplers later. */
7 #include <speex/speex_resampler.h>
8 #include <sys/param.h>
9 #include <syslog.h>
10
11 #include "cras_fmt_conv.h"
12 #include "cras_audio_format.h"
13 #include "cras_util.h"
14 #include "linear_resampler.h"
15
16 /* The quality level is a value between 0 and 10. This is a tradeoff between
17 * performance, latency, and quality. */
18 #define SPEEX_QUALITY_LEVEL 4
19 /* Max number of converters, src, down/up mix, 2xformat, and linear resample. */
20 #define MAX_NUM_CONVERTERS 5
21 /* Channel index for stereo. */
22 #define STEREO_L 0
23 #define STEREO_R 1
24
25 typedef void (*sample_format_converter_t)(const uint8_t *in,
26 size_t in_samples,
27 uint8_t *out);
28 typedef size_t (*channel_converter_t)(struct cras_fmt_conv *conv,
29 const int16_t *in,
30 size_t in_frames,
31 int16_t *out);
32
33 /* Member data for the resampler. */
34 struct cras_fmt_conv {
35 SpeexResamplerState *speex_state;
36 channel_converter_t channel_converter;
37 float **ch_conv_mtx; /* Coefficient matrix for mixing channels. */
38 sample_format_converter_t in_format_converter;
39 sample_format_converter_t out_format_converter;
40 struct linear_resampler *resampler;
41 struct cras_audio_format in_fmt;
42 struct cras_audio_format out_fmt;
43 uint8_t *tmp_bufs[MAX_NUM_CONVERTERS - 1];
44 size_t tmp_buf_frames;
45 size_t pre_linear_resample;
46 size_t num_converters; /* Incremented once for SRC, channel, format. */
47 };
48
49 /* Add and clip two s16 samples. */
s16_add_and_clip(int16_t a,int16_t b)50 static int16_t s16_add_and_clip(int16_t a, int16_t b)
51 {
52 int32_t sum;
53
54 sum = a + b;
55 sum = MAX(sum, -0x8000);
56 sum = MIN(sum, 0x7fff);
57 return (int16_t)sum;
58 }
59
60 /*
61 * Convert between different sample formats.
62 */
63
64 /* Converts from U8 to S16. */
convert_u8_to_s16le(const uint8_t * in,size_t in_samples,uint8_t * out)65 static void convert_u8_to_s16le(const uint8_t *in, size_t in_samples,
66 uint8_t *out)
67 {
68 size_t i;
69 uint16_t *_out = (uint16_t *)out;
70
71 for (i = 0; i < in_samples; i++, in++, _out++)
72 *_out = (uint16_t)((int16_t)*in - 0x80) << 8;
73 }
74
75 /* Converts from S24 to S16. */
convert_s24le_to_s16le(const uint8_t * in,size_t in_samples,uint8_t * out)76 static void convert_s24le_to_s16le(const uint8_t *in, size_t in_samples,
77 uint8_t *out)
78 {
79 size_t i;
80 int32_t *_in = (int32_t *)in;
81 uint16_t *_out = (uint16_t *)out;
82
83 for (i = 0; i < in_samples; i++, _in++, _out++)
84 *_out = (int16_t)((*_in & 0x00ffffff) >> 8);
85 }
86
87 /* Converts from S32 to S16. */
convert_s32le_to_s16le(const uint8_t * in,size_t in_samples,uint8_t * out)88 static void convert_s32le_to_s16le(const uint8_t *in, size_t in_samples,
89 uint8_t *out)
90 {
91 size_t i;
92 int32_t *_in = (int32_t *)in;
93 uint16_t *_out = (uint16_t *)out;
94
95 for (i = 0; i < in_samples; i++, _in++, _out++)
96 *_out = (int16_t)(*_in >> 16);
97 }
98
99 /* Converts from S24_3LE to S16. */
convert_s243le_to_s16le(const uint8_t * in,size_t in_samples,uint8_t * out)100 static void convert_s243le_to_s16le(const uint8_t *in, size_t in_samples,
101 uint8_t *out)
102 {
103 /* find how to calculate in and out size, implement the conversion
104 * between S24_3LE and S16 */
105
106 size_t i;
107 int8_t *_in = (int8_t *)in;
108 uint16_t *_out = (uint16_t *)out;
109
110 for (i = 0; i < in_samples; i++, _in += 3, _out++)
111 memcpy(_out, _in + 1, 2);
112 }
113
114 /* Converts from S16 to U8. */
convert_s16le_to_u8(const uint8_t * in,size_t in_samples,uint8_t * out)115 static void convert_s16le_to_u8(const uint8_t *in, size_t in_samples,
116 uint8_t *out)
117 {
118 size_t i;
119 int16_t *_in = (int16_t *)in;
120
121 for (i = 0; i < in_samples; i++, _in++, out++)
122 *out = (uint8_t)(*_in >> 8) + 128;
123 }
124
125 /* Converts from S16 to S24. */
convert_s16le_to_s24le(const uint8_t * in,size_t in_samples,uint8_t * out)126 static void convert_s16le_to_s24le(const uint8_t *in, size_t in_samples,
127 uint8_t *out)
128 {
129 size_t i;
130 int16_t *_in = (int16_t *)in;
131 uint32_t *_out = (uint32_t *)out;
132
133 for (i = 0; i < in_samples; i++, _in++, _out++)
134 *_out = ((uint32_t)(int32_t)*_in << 8);
135 }
136
137 /* Converts from S16 to S32. */
convert_s16le_to_s32le(const uint8_t * in,size_t in_samples,uint8_t * out)138 static void convert_s16le_to_s32le(const uint8_t *in, size_t in_samples,
139 uint8_t *out)
140 {
141 size_t i;
142 int16_t *_in = (int16_t *)in;
143 uint32_t *_out = (uint32_t *)out;
144
145 for (i = 0; i < in_samples; i++, _in++, _out++)
146 *_out = ((uint32_t)(int32_t)*_in << 16);
147 }
148
149 /* Converts from S16 to S24_3LE. */
convert_s16le_to_s243le(const uint8_t * in,size_t in_samples,uint8_t * out)150 static void convert_s16le_to_s243le(const uint8_t *in, size_t in_samples,
151 uint8_t *out)
152 {
153 size_t i;
154 int16_t *_in = (int16_t *)in;
155 uint8_t *_out = (uint8_t *)out;
156
157 for (i = 0; i < in_samples; i++, _in++, _out += 3) {
158 *_out = 0;
159 memcpy(_out + 1, _in, 2);
160 }
161 }
162
163 /*
164 * Convert between different channel numbers.
165 */
166
167 /* Converts S16 mono to S16 stereo. The out buffer must be double the size of
168 * the input buffer. */
s16_mono_to_stereo(struct cras_fmt_conv * conv,const int16_t * in,size_t in_frames,int16_t * out)169 static size_t s16_mono_to_stereo(struct cras_fmt_conv *conv,
170 const int16_t *in, size_t in_frames,
171 int16_t *out)
172 {
173 size_t i;
174
175 for (i = 0; i < in_frames; i++) {
176 out[2 * i] = in[i];
177 out[2 * i + 1] = in[i];
178 }
179 return in_frames;
180 }
181
182 /* Converts S16 Stereo to S16 mono. The output buffer only need be big enough
183 * for mono samples. */
s16_stereo_to_mono(struct cras_fmt_conv * conv,const int16_t * in,size_t in_frames,int16_t * out)184 static size_t s16_stereo_to_mono(struct cras_fmt_conv *conv,
185 const int16_t *in, size_t in_frames,
186 int16_t *out)
187 {
188 size_t i;
189
190 for (i = 0; i < in_frames; i++)
191 out[i] = s16_add_and_clip(in[2 * i], in[2 * i + 1]);
192 return in_frames;
193 }
194
195 /* Converts S16 mono to 5.1 surround. Fit mono to front center of the
196 * output, or split to front left/right if front center is missing
197 * from the output channel layout.
198 */
s16_mono_to_51(struct cras_fmt_conv * conv,const int16_t * in,size_t in_frames,int16_t * out)199 static size_t s16_mono_to_51(struct cras_fmt_conv *conv,
200 const int16_t *in, size_t in_frames,
201 int16_t *out)
202 {
203 size_t i, left, right, center;
204
205 memset(out, 0, sizeof(*out) * 6 * in_frames);
206 left = conv->out_fmt.channel_layout[CRAS_CH_FL];
207 right = conv->out_fmt.channel_layout[CRAS_CH_FR];
208 center = conv->out_fmt.channel_layout[CRAS_CH_FC];
209
210 if (center != -1)
211 for (i = 0; i < in_frames; i++)
212 out[6 * i + center] = in[i];
213 else if (left != -1 && right != -1)
214 for (i = 0; i < in_frames; i++) {
215 out[6 * i + right] = in[i] / 2;
216 out[6 * 1 + left] = in[i] / 2;
217 }
218 else
219 /* Select the first channel to convert to as the
220 * default behavior.
221 */
222 for (i = 0; i < in_frames; i++)
223 out[6 * i] = in[i];
224
225 return in_frames;
226 }
227
228 /* Converts S16 stereo to 5.1 surround. Fit the left/right of input
229 * to the front left/right of output respectively and fill others
230 * with zero. If any of the front left/right is missed from the output
231 * channel layout, mix to front center.
232 */
s16_stereo_to_51(struct cras_fmt_conv * conv,const int16_t * in,size_t in_frames,int16_t * out)233 static size_t s16_stereo_to_51(struct cras_fmt_conv *conv,
234 const int16_t *in, size_t in_frames,
235 int16_t *out)
236 {
237 size_t i, left, right, center;
238
239 memset(out, 0, sizeof(*out) * 6 * in_frames);
240 left = conv->out_fmt.channel_layout[CRAS_CH_FL];
241 right = conv->out_fmt.channel_layout[CRAS_CH_FR];
242 center = conv->out_fmt.channel_layout[CRAS_CH_FC];
243
244 if (left != -1 && right != -1)
245 for (i = 0; i < in_frames; i++) {
246 out[6 * i + left] = in[2 * i];
247 out[6 * i + right] = in[2 * i + 1];
248 }
249 else if (center != -1)
250 for (i = 0; i < in_frames; i++)
251 out[6 * i + center] = s16_add_and_clip(
252 in[2 * i], in[2 * i + 1]);
253 else
254 /* Select the first two channels to convert to as the
255 * default behavior.
256 */
257 for (i = 0; i < in_frames; i++) {
258 out[6 * i] = in[2 * i];
259 out[6 * i + 1] = in[2 * i + 1];
260 }
261
262 return in_frames;
263 }
264
265 /* Converts S16 5.1 to S16 stereo. The out buffer can have room for just
266 * stereo samples. This convert function is used as the default behavior
267 * when channel layout is not set from the client side. */
s16_51_to_stereo(struct cras_fmt_conv * conv,const int16_t * in,size_t in_frames,int16_t * out)268 static size_t s16_51_to_stereo(struct cras_fmt_conv *conv,
269 const int16_t *in, size_t in_frames,
270 int16_t *out)
271 {
272 static const unsigned int left_idx = 0;
273 static const unsigned int right_idx = 1;
274 /* static const unsigned int left_surround_idx = 2; */
275 /* static const unsigned int right_surround_idx = 3; */
276 static const unsigned int center_idx = 4;
277 /* static const unsigned int lfe_idx = 5; */
278 size_t i;
279
280 for (i = 0; i < in_frames; i++) {
281 unsigned int half_center;
282
283 half_center = in[6 * i + center_idx] / 2;
284 out[2 * i + left_idx] = s16_add_and_clip(in[6 * i + left_idx],
285 half_center);
286 out[2 * i + right_idx] = s16_add_and_clip(in[6 * i + right_idx],
287 half_center);
288 }
289 return in_frames;
290 }
291
292 /* Converts S16 stereo to quad (front L/R, rear L/R). Fit left/right of input
293 * to the front left/right of output respectively and fill others
294 * with zero.
295 */
s16_stereo_to_quad(struct cras_fmt_conv * conv,const int16_t * in,size_t in_frames,int16_t * out)296 static size_t s16_stereo_to_quad(struct cras_fmt_conv *conv,
297 const int16_t *in, size_t in_frames,
298 int16_t *out)
299 {
300 size_t i, front_left, front_right, rear_left, rear_right;
301
302 front_left = conv->out_fmt.channel_layout[CRAS_CH_FL];
303 front_right = conv->out_fmt.channel_layout[CRAS_CH_FR];
304 rear_left = conv->out_fmt.channel_layout[CRAS_CH_RL];
305 rear_right = conv->out_fmt.channel_layout[CRAS_CH_RR];
306
307 if (front_left != -1 && front_right != -1 &&
308 rear_left != -1 && rear_right != -1)
309 for (i = 0; i < in_frames; i++) {
310 out[4 * i + front_left] = in[2 * i];
311 out[4 * i + front_right] = in[2 * i + 1];
312 out[4 * i + rear_left] = in[2 * i];
313 out[4 * i + rear_right] = in[2 * i + 1];
314 }
315 else
316 /* Select the first four channels to convert to as the
317 * default behavior.
318 */
319 for (i = 0; i < in_frames; i++) {
320 out[4 * i] = in[2 * i];
321 out[4 * i + 1] = in[2 * i + 1];
322 out[4 * i + 2] = in[2 * i];
323 out[4 * i + 3] = in[2 * i + 1];
324 }
325
326 return in_frames;
327 }
328
329 /* Converts S16 quad (front L/R, rear L/R) to S16 stereo. The out buffer
330 * can have room for just stereo samples.
331 */
s16_quad_to_stereo(struct cras_fmt_conv * conv,const int16_t * in,size_t in_frames,int16_t * out)332 static size_t s16_quad_to_stereo(struct cras_fmt_conv *conv,
333 const int16_t *in, size_t in_frames,
334 int16_t *out)
335 {
336 size_t i;
337 unsigned int left_idx =
338 conv->in_fmt.channel_layout[CRAS_CH_FL];
339 unsigned int right_idx =
340 conv->in_fmt.channel_layout[CRAS_CH_FR];
341 unsigned int left_rear_idx =
342 conv->in_fmt.channel_layout[CRAS_CH_RL];
343 unsigned int right_rear_idx =
344 conv->in_fmt.channel_layout[CRAS_CH_RR];
345
346 if (left_idx == -1 || right_idx == -1 ||
347 left_rear_idx == -1 || right_rear_idx == -1) {
348 left_idx = 0;
349 right_idx = 1;
350 left_rear_idx = 2;
351 right_rear_idx = 3;
352 }
353
354 for (i = 0; i < in_frames; i++) {
355 out[2 * i] = s16_add_and_clip(
356 in[4 * i + left_idx],
357 in[4 * i + left_rear_idx] / 4);
358 out[2 * i + 1] = s16_add_and_clip(
359 in[4 * i + right_idx],
360 in[4 * i + right_rear_idx] / 4);
361 }
362 return in_frames;
363 }
364
365 /* Converts S16 N channels to S16 M channels. The out buffer must have room for
366 * M channel. This convert function is used as the default behavior when channel
367 * layout is not set from the client side. */
s16_default_all_to_all(struct cras_fmt_conv * conv,const int16_t * in,size_t in_frames,int16_t * out)368 static size_t s16_default_all_to_all(struct cras_fmt_conv *conv,
369 const int16_t *in, size_t in_frames,
370 int16_t *out)
371 {
372 unsigned int num_in_ch = conv->in_fmt.num_channels;
373 unsigned int num_out_ch = conv->out_fmt.num_channels;
374 unsigned int in_ch, out_ch, i;
375
376 memset(out, 0, in_frames * cras_get_format_bytes(&conv->out_fmt));
377 for (out_ch = 0; out_ch < num_out_ch; out_ch++) {
378 for (in_ch = 0; in_ch < num_in_ch; in_ch++) {
379 for (i = 0; i < in_frames; i++) {
380 out[out_ch + i * num_out_ch] +=
381 in[in_ch + i * num_in_ch] / num_in_ch;
382 }
383 }
384 }
385 return in_frames;
386 }
387
is_channel_layout_equal(const struct cras_audio_format * a,const struct cras_audio_format * b)388 static int is_channel_layout_equal(const struct cras_audio_format *a,
389 const struct cras_audio_format *b)
390 {
391 int ch;
392 for (ch = 0; ch < CRAS_CH_MAX; ch++)
393 if (a->channel_layout[ch] != b->channel_layout[ch])
394 return 0;
395
396 return 1;
397 }
398
399 /* Multiplies buffer vector with coefficient vector. */
multiply_buf_with_coef(float * coef,const int16_t * buf,size_t size)400 static int16_t multiply_buf_with_coef(float *coef,
401 const int16_t *buf,
402 size_t size)
403 {
404 int32_t sum = 0;
405 int i;
406
407 for (i = 0; i < size; i++)
408 sum += coef[i] * buf[i];
409 sum = MAX(sum, -0x8000);
410 sum = MIN(sum, 0x7fff);
411 return (int16_t)sum;
412 }
413
normalize_buf(float * buf,size_t size)414 static void normalize_buf(float *buf, size_t size)
415 {
416 int i;
417 float squre_sum = 0.0;
418 for (i = 0; i < size; i++)
419 squre_sum += buf[i] * buf[i];
420 for (i = 0; i < size; i ++)
421 buf[i] /= squre_sum;
422 }
423
424 /* Converts channels based on the channel conversion
425 * coefficient matrix.
426 */
convert_channels(struct cras_fmt_conv * conv,const int16_t * in,size_t in_frames,int16_t * out)427 static size_t convert_channels(struct cras_fmt_conv *conv,
428 const int16_t *in,
429 size_t in_frames,
430 int16_t *out)
431 {
432 unsigned i, fr;
433 unsigned in_idx = 0;
434 unsigned out_idx = 0;
435
436 for (fr = 0; fr < in_frames; fr++) {
437 for (i = 0; i < conv->out_fmt.num_channels; i++)
438 out[out_idx + i] = multiply_buf_with_coef(
439 conv->ch_conv_mtx[i],
440 &in[in_idx],
441 conv->in_fmt.num_channels);
442 in_idx += conv->in_fmt.num_channels;
443 out_idx += conv->out_fmt.num_channels;
444 }
445
446 return in_frames;
447 }
448
449 /* Populates the down mix matrix by rules:
450 * 1. Front/side left(right) channel will mix to left(right) of
451 * full scale.
452 * 2. Center and LFE will be split equally to left and right.
453 * Rear
454 * 3. Rear left/right will split 1/4 of the power to opposite
455 * channel.
456 */
surround51_to_stereo_downmix_mtx(float ** mtx,int8_t layout[CRAS_CH_MAX])457 static void surround51_to_stereo_downmix_mtx(float **mtx,
458 int8_t layout[CRAS_CH_MAX])
459 {
460 if (layout[CRAS_CH_FC] != -1) {
461 mtx[STEREO_L][layout[CRAS_CH_FC]] = 0.707;
462 mtx[STEREO_R][layout[CRAS_CH_FC]] = 0.707;
463 }
464 if (layout[CRAS_CH_FL] != -1 && layout[CRAS_CH_FR] != -1) {
465 mtx[STEREO_L][layout[CRAS_CH_FL]] = 1.0;
466 mtx[STEREO_R][layout[CRAS_CH_FR]] = 1.0;
467 }
468 if (layout[CRAS_CH_SL] != -1 && layout[CRAS_CH_SR] != -1) {
469 mtx[STEREO_L][layout[CRAS_CH_SL]] = 1.0;
470 mtx[STEREO_R][layout[CRAS_CH_SR]] = 1.0;
471 }
472 if (layout[CRAS_CH_RL] != -1 && layout[CRAS_CH_RR] != -1) {
473 /* Split 1/4 power to the other side */
474 mtx[STEREO_L][layout[CRAS_CH_RL]] = 0.866;
475 mtx[STEREO_R][layout[CRAS_CH_RL]] = 0.5;
476 mtx[STEREO_R][layout[CRAS_CH_RR]] = 0.866;
477 mtx[STEREO_L][layout[CRAS_CH_RR]] = 0.5;
478 }
479 if (layout[CRAS_CH_LFE] != -1) {
480 mtx[STEREO_L][layout[CRAS_CH_LFE]] = 0.707;
481 mtx[STEREO_R][layout[CRAS_CH_LFE]] = 0.707;
482 }
483
484 normalize_buf(mtx[STEREO_L], 6);
485 normalize_buf(mtx[STEREO_R], 6);
486 }
487
488 /*
489 * Exported interface
490 */
491
cras_fmt_conv_create(const struct cras_audio_format * in,const struct cras_audio_format * out,size_t max_frames,size_t pre_linear_resample)492 struct cras_fmt_conv *cras_fmt_conv_create(const struct cras_audio_format *in,
493 const struct cras_audio_format *out,
494 size_t max_frames,
495 size_t pre_linear_resample)
496 {
497 struct cras_fmt_conv *conv;
498 int rc;
499 unsigned i;
500
501 conv = calloc(1, sizeof(*conv));
502 if (conv == NULL)
503 return NULL;
504 conv->in_fmt = *in;
505 conv->out_fmt = *out;
506 conv->tmp_buf_frames = max_frames;
507 conv->pre_linear_resample = pre_linear_resample;
508
509 /* Set up sample format conversion. */
510 /* TODO(dgreid) - modify channel and sample rate conversion so
511 * converting to s16 isnt necessary. */
512 if (in->format != SND_PCM_FORMAT_S16_LE) {
513 conv->num_converters++;
514 syslog(LOG_DEBUG, "Convert from format %d to %d.",
515 in->format, out->format);
516 switch(in->format) {
517 case SND_PCM_FORMAT_U8:
518 conv->in_format_converter = convert_u8_to_s16le;
519 break;
520 case SND_PCM_FORMAT_S24_LE:
521 conv->in_format_converter = convert_s24le_to_s16le;
522 break;
523 case SND_PCM_FORMAT_S32_LE:
524 conv->in_format_converter = convert_s32le_to_s16le;
525 break;
526 case SND_PCM_FORMAT_S24_3LE:
527 conv->in_format_converter = convert_s243le_to_s16le;
528 break;
529 default:
530 syslog(LOG_WARNING, "Invalid format %d", in->format);
531 cras_fmt_conv_destroy(&conv);
532 return NULL;
533 }
534 }
535 if (out->format != SND_PCM_FORMAT_S16_LE) {
536 conv->num_converters++;
537 syslog(LOG_DEBUG, "Convert from format %d to %d.",
538 in->format, out->format);
539 switch (out->format) {
540 case SND_PCM_FORMAT_U8:
541 conv->out_format_converter = convert_s16le_to_u8;
542 break;
543 case SND_PCM_FORMAT_S24_LE:
544 conv->out_format_converter = convert_s16le_to_s24le;
545 break;
546 case SND_PCM_FORMAT_S32_LE:
547 conv->out_format_converter = convert_s16le_to_s32le;
548 break;
549 case SND_PCM_FORMAT_S24_3LE:
550 conv->out_format_converter = convert_s16le_to_s243le;
551 break;
552 default:
553 syslog(LOG_WARNING, "Invalid format %d", out->format);
554 cras_fmt_conv_destroy(&conv);
555 return NULL;
556 }
557 }
558
559 /* Set up channel number conversion. */
560 if (in->num_channels != out->num_channels) {
561 conv->num_converters++;
562 syslog(LOG_DEBUG, "Convert from %zu to %zu channels.",
563 in->num_channels, out->num_channels);
564
565 /* Populate the conversion matrix base on in/out channel count
566 * and layout. */
567 if (in->num_channels == 1 && out->num_channels == 2) {
568 conv->channel_converter = s16_mono_to_stereo;
569 } else if (in->num_channels == 1 && out->num_channels == 6) {
570 conv->channel_converter = s16_mono_to_51;
571 } else if (in->num_channels == 2 && out->num_channels == 1) {
572 conv->channel_converter = s16_stereo_to_mono;
573 } else if (in->num_channels == 2 && out->num_channels == 4) {
574 conv->channel_converter = s16_stereo_to_quad;
575 } else if (in->num_channels == 4 && out->num_channels == 2) {
576 conv->channel_converter = s16_quad_to_stereo;
577 } else if (in->num_channels == 2 && out->num_channels == 6) {
578 conv->channel_converter = s16_stereo_to_51;
579 } else if (in->num_channels == 6 && out->num_channels == 2) {
580 int in_channel_layout_set = 0;
581
582 /* Checks if channel_layout is set in the incoming format */
583 for (i = 0; i < CRAS_CH_MAX; i++)
584 if (in->channel_layout[i] != -1)
585 in_channel_layout_set = 1;
586
587 /* Use the conversion matrix based converter when a
588 * channel layout is set, or default to use existing
589 * converter to downmix to stereo */
590 if (in_channel_layout_set) {
591 conv->ch_conv_mtx = cras_channel_conv_matrix_alloc(
592 in->num_channels,
593 out->num_channels);
594 if (conv->ch_conv_mtx == NULL) {
595 cras_fmt_conv_destroy(&conv);
596 return NULL;
597 }
598 conv->channel_converter = convert_channels;
599 surround51_to_stereo_downmix_mtx(
600 conv->ch_conv_mtx,
601 conv->in_fmt.channel_layout);
602 } else {
603 conv->channel_converter = s16_51_to_stereo;
604 }
605 } else {
606 syslog(LOG_WARNING,
607 "Using default channel map for %zu to %zu",
608 in->num_channels, out->num_channels);
609 conv->channel_converter = s16_default_all_to_all;
610 }
611 } else if (in->num_channels > 2 &&
612 !is_channel_layout_equal(in, out)){
613 conv->num_converters++;
614 conv->ch_conv_mtx = cras_channel_conv_matrix_create(in, out);
615 if (conv->ch_conv_mtx == NULL) {
616 syslog(LOG_ERR, "Failed to create channel conversion matrix");
617 cras_fmt_conv_destroy(&conv);
618 return NULL;
619 }
620 conv->channel_converter = convert_channels;
621 }
622 /* Set up sample rate conversion. */
623 if (in->frame_rate != out->frame_rate) {
624 conv->num_converters++;
625 syslog(LOG_DEBUG, "Convert from %zu to %zu Hz.",
626 in->frame_rate, out->frame_rate);
627 conv->speex_state = speex_resampler_init(out->num_channels,
628 in->frame_rate,
629 out->frame_rate,
630 SPEEX_QUALITY_LEVEL,
631 &rc);
632 if (conv->speex_state == NULL) {
633 syslog(LOG_ERR, "Fail to create speex:%zu %zu %zu %d",
634 out->num_channels,
635 in->frame_rate,
636 out->frame_rate,
637 rc);
638 cras_fmt_conv_destroy(&conv);
639 return NULL;
640 }
641 }
642
643 /* Set up linear resampler. */
644 conv->num_converters++;
645 conv->resampler = linear_resampler_create(
646 out->num_channels,
647 cras_get_format_bytes(out),
648 out->frame_rate,
649 out->frame_rate);
650 if (conv->resampler == NULL) {
651 syslog(LOG_ERR, "Fail to create linear resampler");
652 cras_fmt_conv_destroy(&conv);
653 return NULL;
654 }
655
656 /* Need num_converters-1 temp buffers, the final converter renders
657 * directly into the output. */
658 for (i = 0; i < conv->num_converters - 1; i++) {
659 conv->tmp_bufs[i] = malloc(
660 max_frames *
661 4 * /* width in bytes largest format. */
662 MAX(in->num_channels, out->num_channels));
663 if (conv->tmp_bufs[i] == NULL) {
664 cras_fmt_conv_destroy(&conv);
665 return NULL;
666 }
667 }
668
669 assert(conv->num_converters <= MAX_NUM_CONVERTERS);
670
671 return conv;
672 }
673
cras_fmt_conv_destroy(struct cras_fmt_conv ** convp)674 void cras_fmt_conv_destroy(struct cras_fmt_conv **convp)
675 {
676 unsigned i;
677 struct cras_fmt_conv *conv = *convp;
678
679 if (conv->ch_conv_mtx)
680 cras_channel_conv_matrix_destroy(conv->ch_conv_mtx,
681 conv->out_fmt.num_channels);
682 if (conv->speex_state)
683 speex_resampler_destroy(conv->speex_state);
684 if (conv->resampler)
685 linear_resampler_destroy(conv->resampler);
686 for (i = 0; i < MAX_NUM_CONVERTERS - 1; i++)
687 free(conv->tmp_bufs[i]);
688 free(conv);
689 *convp = NULL;
690 }
691
cras_channel_remix_conv_create(unsigned int num_channels,const float * coefficient)692 struct cras_fmt_conv *cras_channel_remix_conv_create(
693 unsigned int num_channels,
694 const float *coefficient)
695 {
696 struct cras_fmt_conv *conv;
697 unsigned out_ch, in_ch;
698
699 conv = calloc(1, sizeof(*conv));
700 if (conv == NULL)
701 return NULL;
702 conv->in_fmt.num_channels = num_channels;
703 conv->out_fmt.num_channels = num_channels;
704
705 conv->ch_conv_mtx = cras_channel_conv_matrix_alloc(num_channels,
706 num_channels);
707 /* Convert the coeffiencnt array to conversion matrix. */
708 for (out_ch = 0; out_ch < num_channels; out_ch++)
709 for (in_ch = 0; in_ch < num_channels; in_ch++)
710 conv->ch_conv_mtx[out_ch][in_ch] =
711 coefficient[in_ch + out_ch * num_channels];
712
713 conv->num_converters = 1;
714 conv->tmp_bufs[0] = malloc(4 * /* width in bytes largest format. */
715 num_channels);
716 return conv;
717 }
718
cras_channel_remix_convert(struct cras_fmt_conv * conv,const struct cras_audio_format * fmt,uint8_t * in_buf,size_t nframes)719 void cras_channel_remix_convert(struct cras_fmt_conv *conv,
720 const struct cras_audio_format *fmt,
721 uint8_t *in_buf,
722 size_t nframes)
723 {
724 unsigned ch, fr;
725 int16_t *tmp = (int16_t *)conv->tmp_bufs[0];
726 int16_t *buf = (int16_t *)in_buf;
727
728 /* Do remix only when input buffer has the same number of channels. */
729 if (fmt->num_channels != conv->in_fmt.num_channels)
730 return;
731
732 for (fr = 0; fr < nframes; fr++) {
733 for (ch = 0; ch < conv->in_fmt.num_channels; ch++)
734 tmp[ch] = multiply_buf_with_coef(
735 conv->ch_conv_mtx[ch],
736 buf,
737 conv->in_fmt.num_channels);
738 for (ch = 0; ch < conv->in_fmt.num_channels; ch++)
739 buf[ch] = tmp[ch];
740 buf += conv->in_fmt.num_channels;
741 }
742 }
743
cras_fmt_conv_in_format(const struct cras_fmt_conv * conv)744 const struct cras_audio_format *cras_fmt_conv_in_format(
745 const struct cras_fmt_conv *conv)
746 {
747 return &conv->in_fmt;
748 }
749
cras_fmt_conv_out_format(const struct cras_fmt_conv * conv)750 const struct cras_audio_format *cras_fmt_conv_out_format(
751 const struct cras_fmt_conv *conv)
752 {
753 return &conv->out_fmt;
754 }
755
cras_fmt_conv_in_frames_to_out(struct cras_fmt_conv * conv,size_t in_frames)756 size_t cras_fmt_conv_in_frames_to_out(struct cras_fmt_conv *conv,
757 size_t in_frames)
758 {
759 if (!conv)
760 return in_frames;
761
762 if (conv->pre_linear_resample)
763 in_frames = linear_resampler_in_frames_to_out(
764 conv->resampler,
765 in_frames);
766 in_frames = cras_frames_at_rate(conv->in_fmt.frame_rate,
767 in_frames,
768 conv->out_fmt.frame_rate);
769 if (!conv->pre_linear_resample)
770 in_frames = linear_resampler_in_frames_to_out(
771 conv->resampler,
772 in_frames);
773 return in_frames;
774 }
775
cras_fmt_conv_out_frames_to_in(struct cras_fmt_conv * conv,size_t out_frames)776 size_t cras_fmt_conv_out_frames_to_in(struct cras_fmt_conv *conv,
777 size_t out_frames)
778 {
779 if (!conv)
780 return out_frames;
781 if (!conv->pre_linear_resample)
782 out_frames = linear_resampler_out_frames_to_in(
783 conv->resampler,
784 out_frames);
785 out_frames = cras_frames_at_rate(conv->out_fmt.frame_rate,
786 out_frames,
787 conv->in_fmt.frame_rate);
788 if (conv->pre_linear_resample)
789 out_frames = linear_resampler_out_frames_to_in(
790 conv->resampler,
791 out_frames);
792 return out_frames;
793 }
794
cras_fmt_conv_set_linear_resample_rates(struct cras_fmt_conv * conv,float from,float to)795 void cras_fmt_conv_set_linear_resample_rates(struct cras_fmt_conv *conv,
796 float from,
797 float to)
798 {
799 linear_resampler_set_rates(conv->resampler, from, to);
800 }
801
cras_fmt_conv_convert_frames(struct cras_fmt_conv * conv,const uint8_t * in_buf,uint8_t * out_buf,unsigned int * in_frames,size_t out_frames)802 size_t cras_fmt_conv_convert_frames(struct cras_fmt_conv *conv,
803 const uint8_t *in_buf,
804 uint8_t *out_buf,
805 unsigned int *in_frames,
806 size_t out_frames)
807 {
808 uint32_t fr_in, fr_out;
809 uint8_t *buffers[MAX_NUM_CONVERTERS + 1]; /* converters + out buffer. */
810 size_t buf_idx = 0;
811 static int logged_frames_dont_fit;
812 unsigned int used_converters = conv->num_converters;
813 unsigned int post_linear_resample = 0;
814 unsigned int pre_linear_resample = 0;
815 unsigned int linear_resample_fr = 0;
816
817 assert(conv);
818 assert(*in_frames <= conv->tmp_buf_frames);
819
820 if (linear_resampler_needed(conv->resampler)) {
821 post_linear_resample = !conv->pre_linear_resample;
822 pre_linear_resample = conv->pre_linear_resample;
823 }
824
825 /* If no SRC, then in_frames should = out_frames. */
826 if (conv->speex_state == NULL) {
827 fr_in = MIN(*in_frames, out_frames);
828 if (out_frames < *in_frames && !logged_frames_dont_fit) {
829 syslog(LOG_INFO,
830 "fmt_conv: %u to %zu no SRC.",
831 *in_frames,
832 out_frames);
833 logged_frames_dont_fit = 1;
834 }
835 } else {
836 fr_in = *in_frames;
837 }
838 fr_out = fr_in;
839
840 /* Set up a chain of buffers. The output buffer of the first conversion
841 * is used as input to the second and so forth, ending in the output
842 * buffer. */
843 if (!linear_resampler_needed(conv->resampler))
844 used_converters--;
845
846 buffers[4] = (uint8_t *)conv->tmp_bufs[3];
847 buffers[3] = (uint8_t *)conv->tmp_bufs[2];
848 buffers[2] = (uint8_t *)conv->tmp_bufs[1];
849 buffers[1] = (uint8_t *)conv->tmp_bufs[0];
850 buffers[0] = (uint8_t *)in_buf;
851 buffers[used_converters] = out_buf;
852
853 if (pre_linear_resample) {
854 linear_resample_fr = fr_in;
855 unsigned resample_limit = out_frames;
856
857 /* If there is a 2nd fmt conversion we should convert the
858 * resample limit and round it to the lower bound in order
859 * not to convert too many frames in the pre linear resampler.
860 */
861 if (conv->speex_state != NULL) {
862 resample_limit = resample_limit *
863 conv->in_fmt.frame_rate /
864 conv->out_fmt.frame_rate;
865 /*
866 * However if the limit frames count is less than
867 * |out_rate / in_rate|, the final limit value could be
868 * rounded to zero so it confuses linear resampler to
869 * do nothing. Make sure it's non-zero in that case.
870 */
871 if (resample_limit == 0)
872 resample_limit = 1;
873 }
874
875 resample_limit = MIN(resample_limit, conv->tmp_buf_frames);
876 fr_in = linear_resampler_resample(
877 conv->resampler,
878 buffers[buf_idx],
879 &linear_resample_fr,
880 buffers[buf_idx + 1],
881 resample_limit);
882 buf_idx++;
883 }
884
885 /* If the input format isn't S16_LE convert to it. */
886 if (conv->in_fmt.format != SND_PCM_FORMAT_S16_LE) {
887 conv->in_format_converter(buffers[buf_idx],
888 fr_in * conv->in_fmt.num_channels,
889 (uint8_t *)buffers[buf_idx + 1]);
890 buf_idx++;
891 }
892
893 /* Then channel conversion. */
894 if (conv->channel_converter != NULL) {
895 conv->channel_converter(conv,
896 (int16_t *)buffers[buf_idx],
897 fr_in,
898 (int16_t *)buffers[buf_idx + 1]);
899 buf_idx++;
900 }
901
902 /* Then SRC. */
903 if (conv->speex_state != NULL) {
904 unsigned int out_limit = out_frames;
905
906 if (post_linear_resample)
907 out_limit = linear_resampler_out_frames_to_in(
908 conv->resampler, out_limit);
909 fr_out = cras_frames_at_rate(conv->in_fmt.frame_rate,
910 fr_in,
911 conv->out_fmt.frame_rate);
912 if (fr_out > out_frames + 1 && !logged_frames_dont_fit) {
913 syslog(LOG_INFO,
914 "fmt_conv: put %u frames in %zu sized buffer",
915 fr_out,
916 out_frames);
917 logged_frames_dont_fit = 1;
918 }
919 /* limit frames to the output size. */
920 fr_out = MIN(fr_out, out_limit);
921 speex_resampler_process_interleaved_int(
922 conv->speex_state,
923 (int16_t *)buffers[buf_idx],
924 &fr_in,
925 (int16_t *)buffers[buf_idx + 1],
926 &fr_out);
927 buf_idx++;
928 }
929
930 if (post_linear_resample) {
931 linear_resample_fr = fr_out;
932 unsigned resample_limit = MIN(conv->tmp_buf_frames, out_frames);
933 fr_out = linear_resampler_resample(
934 conv->resampler,
935 buffers[buf_idx],
936 &linear_resample_fr,
937 buffers[buf_idx + 1],
938 resample_limit);
939 buf_idx++;
940 }
941
942 /* If the output format isn't S16_LE convert to it. */
943 if (conv->out_fmt.format != SND_PCM_FORMAT_S16_LE) {
944 conv->out_format_converter(buffers[buf_idx],
945 fr_out * conv->out_fmt.num_channels,
946 (uint8_t *)buffers[buf_idx + 1]);
947 buf_idx++;
948 }
949
950 if (pre_linear_resample) {
951 *in_frames = linear_resample_fr;
952
953 /* When buffer sizes are small, there's a corner case that
954 * speex library resamples 0 frame to N-1 frames, where N
955 * is the integer ratio of output and input rate. For example,
956 * 16KHz to 48KHz. In this case fmt_conv should claim zero
957 * frames processed, instead of using the linear resampler
958 * processed frames count. Otherwise there will be a frame
959 * leak and, if accumulated, causes delay in multiple devices
960 * use case.
961 */
962 if (conv->speex_state && (fr_in == 0))
963 *in_frames = 0;
964 } else {
965 *in_frames = fr_in;
966 }
967 return fr_out;
968 }
969
cras_fmt_conversion_needed(const struct cras_fmt_conv * conv)970 int cras_fmt_conversion_needed(const struct cras_fmt_conv *conv)
971 {
972 return linear_resampler_needed(conv->resampler) ||
973 (conv->num_converters > 1);
974 }
975
976 /* If the server cannot provide the requested format, configures an audio format
977 * converter that handles transforming the input format to the format used by
978 * the server. */
config_format_converter(struct cras_fmt_conv ** conv,enum CRAS_STREAM_DIRECTION dir,const struct cras_audio_format * from,const struct cras_audio_format * to,unsigned int frames)979 int config_format_converter(struct cras_fmt_conv **conv,
980 enum CRAS_STREAM_DIRECTION dir,
981 const struct cras_audio_format *from,
982 const struct cras_audio_format *to,
983 unsigned int frames)
984 {
985 struct cras_audio_format target;
986
987 /* For input, preserve the channel count and layout of
988 * from format */
989 if (dir == CRAS_STREAM_INPUT) {
990 target = *from;
991 target.format = to->format;
992 target.frame_rate = to->frame_rate;
993 } else {
994 target = *to;
995 }
996
997 syslog(LOG_DEBUG,
998 "format convert: from:%d %zu %zu target: %d %zu %zu "
999 "frames = %u",
1000 from->format, from->frame_rate, from->num_channels,
1001 target.format, target.frame_rate, target.num_channels,
1002 frames);
1003 *conv = cras_fmt_conv_create(from, &target, frames,
1004 (dir == CRAS_STREAM_INPUT));
1005 if (!*conv) {
1006 syslog(LOG_ERR, "Failed to create format converter");
1007 return -ENOMEM;
1008 }
1009
1010 return 0;
1011 }
1012