• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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