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 = ((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 = ((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 = ((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 N channels to S16 M channels. The out buffer must have room for
293 * M channel. This convert function is used as the default behavior when channel
294 * 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)295 static size_t s16_default_all_to_all(struct cras_fmt_conv *conv,
296 const int16_t *in, size_t in_frames,
297 int16_t *out)
298 {
299 unsigned int num_in_ch = conv->in_fmt.num_channels;
300 unsigned int num_out_ch = conv->out_fmt.num_channels;
301 unsigned int in_ch, out_ch, i;
302
303 memset(out, 0, num_out_ch * in_frames *
304 cras_get_format_bytes(&conv->out_fmt));
305 for (out_ch = 0; out_ch < num_out_ch; out_ch++) {
306 for (in_ch = 0; in_ch < num_in_ch; in_ch++) {
307 for (i = 0; i < in_frames; i++) {
308 out[out_ch + i * num_out_ch] +=
309 in[in_ch + i * num_in_ch] / num_in_ch;
310 }
311 }
312 }
313 return in_frames;
314 }
315
is_channel_layout_equal(const struct cras_audio_format * a,const struct cras_audio_format * b)316 static int is_channel_layout_equal(const struct cras_audio_format *a,
317 const struct cras_audio_format *b)
318 {
319 int ch;
320 for (ch = 0; ch < CRAS_CH_MAX; ch++)
321 if (a->channel_layout[ch] != b->channel_layout[ch])
322 return 0;
323
324 return 1;
325 }
326
327 /* Multiplies buffer vector with coefficient vector. */
multiply_buf_with_coef(float * coef,const int16_t * buf,size_t size)328 static int16_t multiply_buf_with_coef(float *coef,
329 const int16_t *buf,
330 size_t size)
331 {
332 int32_t sum = 0;
333 int i;
334
335 for (i = 0; i < size; i++)
336 sum += coef[i] * buf[i];
337 sum = MAX(sum, -0x8000);
338 sum = MIN(sum, 0x7fff);
339 return (int16_t)sum;
340 }
341
normalize_buf(float * buf,size_t size)342 static void normalize_buf(float *buf, size_t size)
343 {
344 int i;
345 float squre_sum = 0.0;
346 for (i = 0; i < size; i++)
347 squre_sum += buf[i] * buf[i];
348 for (i = 0; i < size; i ++)
349 buf[i] /= squre_sum;
350 }
351
352 /* Converts channels based on the channel conversion
353 * coefficient matrix.
354 */
convert_channels(struct cras_fmt_conv * conv,const int16_t * in,size_t in_frames,int16_t * out)355 static size_t convert_channels(struct cras_fmt_conv *conv,
356 const int16_t *in,
357 size_t in_frames,
358 int16_t *out)
359 {
360 unsigned i, fr;
361 unsigned in_idx = 0;
362 unsigned out_idx = 0;
363
364 for (fr = 0; fr < in_frames; fr++) {
365 for (i = 0; i < conv->out_fmt.num_channels; i++)
366 out[out_idx + i] = multiply_buf_with_coef(
367 conv->ch_conv_mtx[i],
368 &in[in_idx],
369 conv->in_fmt.num_channels);
370 in_idx += conv->in_fmt.num_channels;
371 out_idx += conv->out_fmt.num_channels;
372 }
373
374 return in_frames;
375 }
376
377 /* Populates the down mix matrix by rules:
378 * 1. Front/side left(right) channel will mix to left(right) of
379 * full scale.
380 * 2. Center and LFE will be split equally to left and right.
381 * Rear
382 * 3. Rear left/right will split 1/4 of the power to opposite
383 * channel.
384 */
surround51_to_stereo_downmix_mtx(float ** mtx,int8_t layout[CRAS_CH_MAX])385 static void surround51_to_stereo_downmix_mtx(float **mtx,
386 int8_t layout[CRAS_CH_MAX])
387 {
388 if (layout[CRAS_CH_FC] != -1) {
389 mtx[STEREO_L][layout[CRAS_CH_FC]] = 0.707;
390 mtx[STEREO_R][layout[CRAS_CH_FC]] = 0.707;
391 }
392 if (layout[CRAS_CH_FL] != -1 && layout[CRAS_CH_FR] != -1) {
393 mtx[STEREO_L][layout[CRAS_CH_FL]] = 1.0;
394 mtx[STEREO_R][layout[CRAS_CH_FR]] = 1.0;
395 }
396 if (layout[CRAS_CH_SL] != -1 && layout[CRAS_CH_SR] != -1) {
397 mtx[STEREO_L][layout[CRAS_CH_SL]] = 1.0;
398 mtx[STEREO_R][layout[CRAS_CH_SR]] = 1.0;
399 }
400 if (layout[CRAS_CH_RL] != -1 && layout[CRAS_CH_RR] != -1) {
401 /* Split 1/4 power to the other side */
402 mtx[STEREO_L][layout[CRAS_CH_RL]] = 0.866;
403 mtx[STEREO_R][layout[CRAS_CH_RL]] = 0.5;
404 mtx[STEREO_R][layout[CRAS_CH_RR]] = 0.866;
405 mtx[STEREO_L][layout[CRAS_CH_RR]] = 0.5;
406 }
407 if (layout[CRAS_CH_LFE] != -1) {
408 mtx[STEREO_L][layout[CRAS_CH_LFE]] = 0.707;
409 mtx[STEREO_R][layout[CRAS_CH_LFE]] = 0.707;
410 }
411
412 normalize_buf(mtx[STEREO_L], 6);
413 normalize_buf(mtx[STEREO_R], 6);
414 }
415
416 /*
417 * Exported interface
418 */
419
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)420 struct cras_fmt_conv *cras_fmt_conv_create(const struct cras_audio_format *in,
421 const struct cras_audio_format *out,
422 size_t max_frames,
423 size_t pre_linear_resample)
424 {
425 struct cras_fmt_conv *conv;
426 int rc;
427 unsigned i;
428
429 conv = calloc(1, sizeof(*conv));
430 if (conv == NULL)
431 return NULL;
432 conv->in_fmt = *in;
433 conv->out_fmt = *out;
434 conv->tmp_buf_frames = max_frames;
435 conv->pre_linear_resample = pre_linear_resample;
436
437 /* Set up sample format conversion. */
438 /* TODO(dgreid) - modify channel and sample rate conversion so
439 * converting to s16 isnt necessary. */
440 if (in->format != SND_PCM_FORMAT_S16_LE) {
441 conv->num_converters++;
442 syslog(LOG_DEBUG, "Convert from format %d to %d.",
443 in->format, out->format);
444 switch(in->format) {
445 case SND_PCM_FORMAT_U8:
446 conv->in_format_converter = convert_u8_to_s16le;
447 break;
448 case SND_PCM_FORMAT_S24_LE:
449 conv->in_format_converter = convert_s24le_to_s16le;
450 break;
451 case SND_PCM_FORMAT_S32_LE:
452 conv->in_format_converter = convert_s32le_to_s16le;
453 break;
454 case SND_PCM_FORMAT_S24_3LE:
455 conv->in_format_converter = convert_s243le_to_s16le;
456 break;
457 default:
458 syslog(LOG_WARNING, "Invalid format %d", in->format);
459 cras_fmt_conv_destroy(conv);
460 return NULL;
461 }
462 }
463 if (out->format != SND_PCM_FORMAT_S16_LE) {
464 conv->num_converters++;
465 syslog(LOG_DEBUG, "Convert from format %d to %d.",
466 in->format, out->format);
467 switch (out->format) {
468 case SND_PCM_FORMAT_U8:
469 conv->out_format_converter = convert_s16le_to_u8;
470 break;
471 case SND_PCM_FORMAT_S24_LE:
472 conv->out_format_converter = convert_s16le_to_s24le;
473 break;
474 case SND_PCM_FORMAT_S32_LE:
475 conv->out_format_converter = convert_s16le_to_s32le;
476 break;
477 case SND_PCM_FORMAT_S24_3LE:
478 conv->out_format_converter = convert_s16le_to_s243le;
479 break;
480 default:
481 syslog(LOG_WARNING, "Invalid format %d", out->format);
482 cras_fmt_conv_destroy(conv);
483 return NULL;
484 }
485 }
486
487 /* Set up channel number conversion. */
488 if (in->num_channels != out->num_channels) {
489 conv->num_converters++;
490 syslog(LOG_DEBUG, "Convert from %zu to %zu channels.",
491 in->num_channels, out->num_channels);
492
493 /* Populate the conversion matrix base on in/out channel count
494 * and layout. */
495 if (in->num_channels == 1 && out->num_channels == 2) {
496 conv->channel_converter = s16_mono_to_stereo;
497 } else if (in->num_channels == 1 && out->num_channels == 6) {
498 conv->channel_converter = s16_mono_to_51;
499 } else if (in->num_channels == 2 && out->num_channels == 1) {
500 conv->channel_converter = s16_stereo_to_mono;
501 } else if (in->num_channels == 2 && out->num_channels == 6) {
502 conv->channel_converter = s16_stereo_to_51;
503 } else if (in->num_channels == 6 && out->num_channels == 2) {
504 int in_channel_layout_set = 0;
505
506 /* Checks if channel_layout is set in the incoming format */
507 for (i = 0; i < CRAS_CH_MAX; i++)
508 if (in->channel_layout[i] != -1)
509 in_channel_layout_set = 1;
510
511 /* Use the conversion matrix based converter when a
512 * channel layout is set, or default to use existing
513 * converter to downmix to stereo */
514 if (in_channel_layout_set) {
515 conv->ch_conv_mtx = cras_channel_conv_matrix_alloc(
516 in->num_channels,
517 out->num_channels);
518 if (conv->ch_conv_mtx == NULL) {
519 cras_fmt_conv_destroy(conv);
520 return NULL;
521 }
522 conv->channel_converter = convert_channels;
523 surround51_to_stereo_downmix_mtx(
524 conv->ch_conv_mtx,
525 conv->in_fmt.channel_layout);
526 } else {
527 conv->channel_converter = s16_51_to_stereo;
528 }
529 } else {
530 syslog(LOG_WARNING,
531 "Using default channel map for %zu to %zu",
532 in->num_channels, out->num_channels);
533 conv->channel_converter = s16_default_all_to_all;
534 }
535 } else if (in->num_channels > 2 &&
536 !is_channel_layout_equal(in, out)){
537 conv->num_converters++;
538 conv->ch_conv_mtx = cras_channel_conv_matrix_create(in, out);
539 if (conv->ch_conv_mtx == NULL) {
540 syslog(LOG_ERR, "Failed to create channel conversion matrix");
541 cras_fmt_conv_destroy(conv);
542 return NULL;
543 }
544 conv->channel_converter = convert_channels;
545 }
546 /* Set up sample rate conversion. */
547 if (in->frame_rate != out->frame_rate) {
548 conv->num_converters++;
549 syslog(LOG_DEBUG, "Convert from %zu to %zu Hz.",
550 in->frame_rate, out->frame_rate);
551 conv->speex_state = speex_resampler_init(out->num_channels,
552 in->frame_rate,
553 out->frame_rate,
554 SPEEX_QUALITY_LEVEL,
555 &rc);
556 if (conv->speex_state == NULL) {
557 syslog(LOG_ERR, "Fail to create speex:%zu %zu %zu %d",
558 out->num_channels,
559 in->frame_rate,
560 out->frame_rate,
561 rc);
562 cras_fmt_conv_destroy(conv);
563 return NULL;
564 }
565 }
566
567 /* Set up linear resampler. */
568 conv->num_converters++;
569 conv->resampler = linear_resampler_create(
570 out->num_channels,
571 cras_get_format_bytes(out),
572 out->frame_rate,
573 out->frame_rate);
574 if (conv->resampler == NULL) {
575 syslog(LOG_ERR, "Fail to create linear resampler");
576 cras_fmt_conv_destroy(conv);
577 return NULL;
578 }
579
580 /* Need num_converters-1 temp buffers, the final converter renders
581 * directly into the output. */
582 for (i = 0; i < conv->num_converters - 1; i++) {
583 conv->tmp_bufs[i] = malloc(
584 max_frames *
585 4 * /* width in bytes largest format. */
586 MAX(in->num_channels, out->num_channels));
587 if (conv->tmp_bufs[i] == NULL) {
588 cras_fmt_conv_destroy(conv);
589 return NULL;
590 }
591 }
592
593 assert(conv->num_converters <= MAX_NUM_CONVERTERS);
594
595 return conv;
596 }
597
cras_fmt_conv_destroy(struct cras_fmt_conv * conv)598 void cras_fmt_conv_destroy(struct cras_fmt_conv *conv)
599 {
600 unsigned i;
601 if (conv->ch_conv_mtx)
602 cras_channel_conv_matrix_destroy(conv->ch_conv_mtx,
603 conv->out_fmt.num_channels);
604 if (conv->speex_state)
605 speex_resampler_destroy(conv->speex_state);
606 if (conv->resampler)
607 linear_resampler_destroy(conv->resampler);
608 for (i = 0; i < MAX_NUM_CONVERTERS - 1; i++)
609 free(conv->tmp_bufs[i]);
610 free(conv);
611 }
612
cras_channel_remix_conv_create(unsigned int num_channels,const float * coefficient)613 struct cras_fmt_conv *cras_channel_remix_conv_create(
614 unsigned int num_channels,
615 const float *coefficient)
616 {
617 struct cras_fmt_conv *conv;
618 unsigned out_ch, in_ch;
619
620 conv = calloc(1, sizeof(*conv));
621 if (conv == NULL)
622 return NULL;
623 conv->in_fmt.num_channels = num_channels;
624 conv->out_fmt.num_channels = num_channels;
625
626 conv->ch_conv_mtx = cras_channel_conv_matrix_alloc(num_channels,
627 num_channels);
628 /* Convert the coeffiencnt array to conversion matrix. */
629 for (out_ch = 0; out_ch < num_channels; out_ch++)
630 for (in_ch = 0; in_ch < num_channels; in_ch++)
631 conv->ch_conv_mtx[out_ch][in_ch] =
632 coefficient[in_ch + out_ch * num_channels];
633
634 conv->num_converters = 1;
635 conv->tmp_bufs[0] = malloc(4 * /* width in bytes largest format. */
636 num_channels);
637 return conv;
638 }
639
cras_channel_remix_convert(struct cras_fmt_conv * conv,const struct cras_audio_format * fmt,uint8_t * in_buf,size_t nframes)640 void cras_channel_remix_convert(struct cras_fmt_conv *conv,
641 const struct cras_audio_format *fmt,
642 uint8_t *in_buf,
643 size_t nframes)
644 {
645 unsigned ch, fr;
646 int16_t *tmp = (int16_t *)conv->tmp_bufs[0];
647 int16_t *buf = (int16_t *)in_buf;
648
649 /* Do remix only when input buffer has the same number of channels. */
650 if (fmt->num_channels != conv->in_fmt.num_channels)
651 return;
652
653 for (fr = 0; fr < nframes; fr++) {
654 for (ch = 0; ch < conv->in_fmt.num_channels; ch++)
655 tmp[ch] = multiply_buf_with_coef(
656 conv->ch_conv_mtx[ch],
657 buf,
658 conv->in_fmt.num_channels);
659 for (ch = 0; ch < conv->in_fmt.num_channels; ch++)
660 buf[ch] = tmp[ch];
661 buf += conv->in_fmt.num_channels;
662 }
663 }
664
cras_fmt_conv_in_format(const struct cras_fmt_conv * conv)665 const struct cras_audio_format *cras_fmt_conv_in_format(
666 const struct cras_fmt_conv *conv)
667 {
668 return &conv->in_fmt;
669 }
670
cras_fmt_conv_out_format(const struct cras_fmt_conv * conv)671 const struct cras_audio_format *cras_fmt_conv_out_format(
672 const struct cras_fmt_conv *conv)
673 {
674 return &conv->out_fmt;
675 }
676
cras_fmt_conv_in_frames_to_out(struct cras_fmt_conv * conv,size_t in_frames)677 size_t cras_fmt_conv_in_frames_to_out(struct cras_fmt_conv *conv,
678 size_t in_frames)
679 {
680 if (!conv)
681 return in_frames;
682
683 if (conv->pre_linear_resample)
684 in_frames = linear_resampler_in_frames_to_out(
685 conv->resampler,
686 in_frames);
687 in_frames = cras_frames_at_rate(conv->in_fmt.frame_rate,
688 in_frames,
689 conv->out_fmt.frame_rate);
690 if (!conv->pre_linear_resample)
691 in_frames = linear_resampler_in_frames_to_out(
692 conv->resampler,
693 in_frames);
694 return in_frames;
695 }
696
cras_fmt_conv_out_frames_to_in(struct cras_fmt_conv * conv,size_t out_frames)697 size_t cras_fmt_conv_out_frames_to_in(struct cras_fmt_conv *conv,
698 size_t out_frames)
699 {
700 if (!conv)
701 return out_frames;
702 if (!conv->pre_linear_resample)
703 out_frames = linear_resampler_out_frames_to_in(
704 conv->resampler,
705 out_frames);
706 out_frames = cras_frames_at_rate(conv->out_fmt.frame_rate,
707 out_frames,
708 conv->in_fmt.frame_rate);
709 if (conv->pre_linear_resample)
710 out_frames = linear_resampler_out_frames_to_in(
711 conv->resampler,
712 out_frames);
713 return out_frames;
714 }
715
cras_fmt_conv_set_linear_resample_rates(struct cras_fmt_conv * conv,float from,float to)716 void cras_fmt_conv_set_linear_resample_rates(struct cras_fmt_conv *conv,
717 float from,
718 float to)
719 {
720 linear_resampler_set_rates(conv->resampler, from, to);
721 }
722
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)723 size_t cras_fmt_conv_convert_frames(struct cras_fmt_conv *conv,
724 const uint8_t *in_buf,
725 uint8_t *out_buf,
726 unsigned int *in_frames,
727 size_t out_frames)
728 {
729 uint32_t fr_in, fr_out;
730 uint8_t *buffers[MAX_NUM_CONVERTERS + 1]; /* converters + out buffer. */
731 size_t buf_idx = 0;
732 static int logged_frames_dont_fit;
733 unsigned int used_converters = conv->num_converters;
734 unsigned int post_linear_resample = 0;
735 unsigned int pre_linear_resample = 0;
736 unsigned int linear_resample_fr = 0;
737
738 assert(conv);
739
740 if (linear_resampler_needed(conv->resampler)) {
741 post_linear_resample = !conv->pre_linear_resample;
742 pre_linear_resample = conv->pre_linear_resample;
743 }
744
745 /* If no SRC, then in_frames should = out_frames. */
746 if (conv->speex_state == NULL) {
747 fr_in = MIN(*in_frames, out_frames);
748 if (out_frames < *in_frames && !logged_frames_dont_fit) {
749 syslog(LOG_INFO,
750 "fmt_conv: %u to %zu no SRC.",
751 *in_frames,
752 out_frames);
753 logged_frames_dont_fit = 1;
754 }
755 } else {
756 fr_in = *in_frames;
757 }
758 fr_out = fr_in;
759
760 /* Set up a chain of buffers. The output buffer of the first conversion
761 * is used as input to the second and so forth, ending in the output
762 * buffer. */
763 if (!linear_resampler_needed(conv->resampler))
764 used_converters--;
765
766 buffers[4] = (uint8_t *)conv->tmp_bufs[3];
767 buffers[3] = (uint8_t *)conv->tmp_bufs[2];
768 buffers[2] = (uint8_t *)conv->tmp_bufs[1];
769 buffers[1] = (uint8_t *)conv->tmp_bufs[0];
770 buffers[0] = (uint8_t *)in_buf;
771 buffers[used_converters] = out_buf;
772
773 if (pre_linear_resample) {
774 linear_resample_fr = fr_in;
775 unsigned resample_limit = out_frames;
776
777 /* If there is a 2nd fmt conversion we should convert the
778 * resample limit and round it to the lower bound in order
779 * not to convert too many frames in the pre linear resampler.
780 */
781 if (conv->speex_state != NULL)
782 resample_limit = resample_limit * conv->in_fmt.frame_rate /
783 conv->out_fmt.frame_rate;
784
785 resample_limit = MIN(resample_limit, conv->tmp_buf_frames);
786 fr_in = linear_resampler_resample(
787 conv->resampler,
788 buffers[buf_idx],
789 &linear_resample_fr,
790 buffers[buf_idx + 1],
791 resample_limit);
792 buf_idx++;
793 }
794
795 /* If the input format isn't S16_LE convert to it. */
796 if (conv->in_fmt.format != SND_PCM_FORMAT_S16_LE) {
797 conv->in_format_converter(buffers[buf_idx],
798 fr_in * conv->in_fmt.num_channels,
799 (uint8_t *)buffers[buf_idx + 1]);
800 buf_idx++;
801 }
802
803 /* Then channel conversion. */
804 if (conv->channel_converter != NULL) {
805 conv->channel_converter(conv,
806 (int16_t *)buffers[buf_idx],
807 fr_in,
808 (int16_t *)buffers[buf_idx + 1]);
809 buf_idx++;
810 }
811
812 /* Then SRC. */
813 if (conv->speex_state != NULL) {
814 unsigned int out_limit = out_frames;
815
816 if (post_linear_resample)
817 out_limit = linear_resampler_out_frames_to_in(
818 conv->resampler, out_limit);
819 fr_out = cras_frames_at_rate(conv->in_fmt.frame_rate,
820 fr_in,
821 conv->out_fmt.frame_rate);
822 if (fr_out > out_frames + 1 && !logged_frames_dont_fit) {
823 syslog(LOG_INFO,
824 "fmt_conv: put %u frames in %zu sized buffer",
825 fr_out,
826 out_frames);
827 logged_frames_dont_fit = 1;
828 }
829 /* limit frames to the output size. */
830 fr_out = MIN(fr_out, out_limit);
831 speex_resampler_process_interleaved_int(
832 conv->speex_state,
833 (int16_t *)buffers[buf_idx],
834 &fr_in,
835 (int16_t *)buffers[buf_idx + 1],
836 &fr_out);
837 buf_idx++;
838 }
839
840 if (post_linear_resample) {
841 linear_resample_fr = fr_out;
842 unsigned resample_limit = MIN(conv->tmp_buf_frames, out_frames);
843 fr_out = linear_resampler_resample(
844 conv->resampler,
845 buffers[buf_idx],
846 &linear_resample_fr,
847 buffers[buf_idx + 1],
848 resample_limit);
849 buf_idx++;
850 }
851
852 /* If the output format isn't S16_LE convert to it. */
853 if (conv->out_fmt.format != SND_PCM_FORMAT_S16_LE) {
854 conv->out_format_converter(buffers[buf_idx],
855 fr_out * conv->out_fmt.num_channels,
856 (uint8_t *)buffers[buf_idx + 1]);
857 buf_idx++;
858 }
859
860 if (pre_linear_resample)
861 *in_frames = linear_resample_fr;
862 else
863 *in_frames = fr_in;
864 return fr_out;
865 }
866
cras_fmt_conversion_needed(const struct cras_fmt_conv * conv)867 int cras_fmt_conversion_needed(const struct cras_fmt_conv *conv)
868 {
869 return linear_resampler_needed(conv->resampler) ||
870 (conv->num_converters > 1);
871 }
872
873 /* If the server cannot provide the requested format, configures an audio format
874 * converter that handles transforming the input format to the format used by
875 * 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)876 int config_format_converter(struct cras_fmt_conv **conv,
877 enum CRAS_STREAM_DIRECTION dir,
878 const struct cras_audio_format *from,
879 const struct cras_audio_format *to,
880 unsigned int frames)
881 {
882 struct cras_audio_format target;
883
884 /* For input, preserve the channel count and layout of
885 * from format */
886 if (dir == CRAS_STREAM_INPUT) {
887 target = *from;
888 target.format = to->format;
889 target.frame_rate = to->frame_rate;
890 } else {
891 target = *to;
892 }
893
894 syslog(LOG_DEBUG,
895 "format convert: from:%d %zu %zu target: %d %zu %zu "
896 "frames = %u",
897 from->format, from->frame_rate, from->num_channels,
898 target.format, target.frame_rate, target.num_channels,
899 frames);
900 *conv = cras_fmt_conv_create(from, &target, frames,
901 (dir == CRAS_STREAM_INPUT));
902 if (!*conv) {
903 syslog(LOG_ERR, "Failed to create format converter");
904 return -ENOMEM;
905 }
906
907 return 0;
908 }
909