• 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 #include <endian.h>
11 #include <limits.h>
12 #include <math.h>
13 
14 #include "cras_fmt_conv.h"
15 #include "cras_fmt_conv_ops.h"
16 #include "cras_audio_format.h"
17 #include "cras_util.h"
18 #include "linear_resampler.h"
19 
20 /* The quality level is a value between 0 and 10. This is a tradeoff between
21  * performance, latency, and quality. */
22 #define SPEEX_QUALITY_LEVEL 4
23 /* Max number of converters, src, down/up mix, 2xformat, and linear resample. */
24 #define MAX_NUM_CONVERTERS 5
25 /* Channel index for stereo. */
26 #define STEREO_L 0
27 #define STEREO_R 1
28 
29 typedef void (*sample_format_converter_t)(const uint8_t *in, size_t in_samples,
30 					  uint8_t *out);
31 typedef size_t (*channel_converter_t)(struct cras_fmt_conv *conv,
32 				      const uint8_t *in, size_t in_frames,
33 				      uint8_t *out);
34 
35 /* Member data for the resampler. */
36 struct cras_fmt_conv {
37 	SpeexResamplerState *speex_state;
38 	channel_converter_t channel_converter;
39 	float **ch_conv_mtx; /* Coefficient matrix for mixing channels. */
40 	sample_format_converter_t in_format_converter;
41 	sample_format_converter_t out_format_converter;
42 	struct linear_resampler *resampler;
43 	struct cras_audio_format in_fmt;
44 	struct cras_audio_format out_fmt;
45 	uint8_t *tmp_bufs[MAX_NUM_CONVERTERS - 1];
46 	size_t tmp_buf_frames;
47 	size_t pre_linear_resample;
48 	size_t num_converters; /* Incremented once for SRC, channel, format. */
49 };
50 
is_channel_layout_equal(const struct cras_audio_format * a,const struct cras_audio_format * b)51 static int is_channel_layout_equal(const struct cras_audio_format *a,
52 				   const struct cras_audio_format *b)
53 {
54 	int ch;
55 	for (ch = 0; ch < CRAS_CH_MAX; ch++)
56 		if (a->channel_layout[ch] != b->channel_layout[ch])
57 			return 0;
58 
59 	return 1;
60 }
61 
62 /*
63  * Calculates the normalize_factor abs_sum(ci) from given coefficients.
64  * Since sum(ci / abs_sum(ci)) <= 1, this could prevent sample overflow while
65  * upmixing or downmixing.
66  */
normalize_factor(float * buf,size_t n)67 static float normalize_factor(float *buf, size_t n)
68 {
69 	int i;
70 	float abs_sum = 0.0;
71 	for (i = 0; i < n; i++)
72 		abs_sum += fabs(buf[i]);
73 
74 	return 1.0 / abs_sum;
75 }
76 
77 /*
78  * Normalize all channels with the same factor to maintain
79  * the energy ratio between original channels.
80  */
normalize(float ** mtx,size_t m,size_t n,float factor)81 static void normalize(float **mtx, size_t m, size_t n, float factor)
82 {
83 	int i, j;
84 	for (i = 0; i < m; i++)
85 		for (j = 0; j < n; j++)
86 			mtx[i][j] *= factor;
87 }
88 
89 /*
90  * Populates the down mix matrix by rules:
91  * 1. Front/side left(right) channel will mix to left(right) of
92  *    full scale.
93  * 2. Center and LFE will be split equally to left and right.
94  *    Rear
95  * 3. Rear left/right will split 1/4 of the power to opposite
96  *    channel.
97  */
surround51_to_stereo_downmix_mtx(float ** mtx,int8_t layout[CRAS_CH_MAX])98 static void surround51_to_stereo_downmix_mtx(float **mtx,
99 					     int8_t layout[CRAS_CH_MAX])
100 {
101 	if (layout[CRAS_CH_FC] != -1) {
102 		mtx[STEREO_L][layout[CRAS_CH_FC]] = 0.707;
103 		mtx[STEREO_R][layout[CRAS_CH_FC]] = 0.707;
104 	}
105 	if (layout[CRAS_CH_FL] != -1 && layout[CRAS_CH_FR] != -1) {
106 		mtx[STEREO_L][layout[CRAS_CH_FL]] = 1.0;
107 		mtx[STEREO_R][layout[CRAS_CH_FR]] = 1.0;
108 	}
109 	if (layout[CRAS_CH_SL] != -1 && layout[CRAS_CH_SR] != -1) {
110 		mtx[STEREO_L][layout[CRAS_CH_SL]] = 1.0;
111 		mtx[STEREO_R][layout[CRAS_CH_SR]] = 1.0;
112 	}
113 	if (layout[CRAS_CH_RL] != -1 && layout[CRAS_CH_RR] != -1) {
114 		/* Split 1/4 power to the other side */
115 		mtx[STEREO_L][layout[CRAS_CH_RL]] = 0.866;
116 		mtx[STEREO_R][layout[CRAS_CH_RL]] = 0.5;
117 		mtx[STEREO_R][layout[CRAS_CH_RR]] = 0.866;
118 		mtx[STEREO_L][layout[CRAS_CH_RR]] = 0.5;
119 	}
120 	if (layout[CRAS_CH_LFE] != -1) {
121 		mtx[STEREO_L][layout[CRAS_CH_LFE]] = 0.707;
122 		mtx[STEREO_R][layout[CRAS_CH_LFE]] = 0.707;
123 	}
124 	normalize(mtx, 2, 6, normalize_factor(mtx[STEREO_L], 6));
125 }
126 
127 /* Populates the down mix matrix by rules:
128  * 1. Front left(right) channel will mix to the front left(right) of
129  *    full scale.
130  * 2. Rear and side left(right) channel will mix to the rear left(right) of
131  *    full scale.
132  * 3. Center will be split equally to the front left and right.
133  * 4. LFE will be split equally to the other channels.
134  */
surround51_to_quad_downmix_mtx(float ** mtx,int8_t layout[CRAS_CH_MAX])135 static void surround51_to_quad_downmix_mtx(float **mtx,
136 					   int8_t layout[CRAS_CH_MAX])
137 {
138 	if (layout[CRAS_CH_FL] != -1 && layout[CRAS_CH_FR] != -1) {
139 		mtx[CRAS_CH_FL][layout[CRAS_CH_FL]] = 1.0;
140 		mtx[CRAS_CH_FR][layout[CRAS_CH_FR]] = 1.0;
141 	}
142 	if (layout[CRAS_CH_RL] != -1 && layout[CRAS_CH_RR] != -1) {
143 		mtx[CRAS_CH_RL][layout[CRAS_CH_RL]] = 1.0;
144 		mtx[CRAS_CH_RR][layout[CRAS_CH_RR]] = 1.0;
145 	}
146 	if (layout[CRAS_CH_SL] != -1 && layout[CRAS_CH_SR] != -1) {
147 		mtx[CRAS_CH_RL][layout[CRAS_CH_SL]] = 1.0;
148 		mtx[CRAS_CH_RR][layout[CRAS_CH_SR]] = 1.0;
149 	}
150 	if (layout[CRAS_CH_FC] != -1) {
151 		/* Split 1/2 power to the front L/R */
152 		mtx[CRAS_CH_FL][layout[CRAS_CH_FC]] = 0.707;
153 		mtx[CRAS_CH_FR][layout[CRAS_CH_FC]] = 0.707;
154 	}
155 	if (layout[CRAS_CH_LFE] != -1) {
156 		/* Split 1/4 power to the other channel */
157 		mtx[CRAS_CH_FL][layout[CRAS_CH_LFE]] = 0.5;
158 		mtx[CRAS_CH_FR][layout[CRAS_CH_LFE]] = 0.5;
159 		mtx[CRAS_CH_RL][layout[CRAS_CH_LFE]] = 0.5;
160 		mtx[CRAS_CH_RR][layout[CRAS_CH_LFE]] = 0.5;
161 	}
162 
163 	normalize(mtx, 4, 6, normalize_factor(mtx[CRAS_CH_FL], 6));
164 }
165 
is_supported_format(const struct cras_audio_format * fmt)166 static int is_supported_format(const struct cras_audio_format *fmt)
167 {
168 	if (!fmt)
169 		return 0;
170 
171 	switch (fmt->format) {
172 	case SND_PCM_FORMAT_U8:
173 	case SND_PCM_FORMAT_S16_LE:
174 	case SND_PCM_FORMAT_S24_3LE:
175 	case SND_PCM_FORMAT_S24_LE:
176 	case SND_PCM_FORMAT_S32_LE:
177 		return 1;
178 	default:
179 		return 0;
180 	}
181 }
182 
mono_to_stereo(struct cras_fmt_conv * conv,const uint8_t * in,size_t in_frames,uint8_t * out)183 static size_t mono_to_stereo(struct cras_fmt_conv *conv, const uint8_t *in,
184 			     size_t in_frames, uint8_t *out)
185 {
186 	return s16_mono_to_stereo(in, in_frames, out);
187 }
188 
stereo_to_mono(struct cras_fmt_conv * conv,const uint8_t * in,size_t in_frames,uint8_t * out)189 static size_t stereo_to_mono(struct cras_fmt_conv *conv, const uint8_t *in,
190 			     size_t in_frames, uint8_t *out)
191 {
192 	return s16_stereo_to_mono(in, in_frames, out);
193 }
194 
mono_to_51(struct cras_fmt_conv * conv,const uint8_t * in,size_t in_frames,uint8_t * out)195 static size_t mono_to_51(struct cras_fmt_conv *conv, const uint8_t *in,
196 			 size_t in_frames, uint8_t *out)
197 {
198 	size_t left, right, center;
199 
200 	left = conv->out_fmt.channel_layout[CRAS_CH_FL];
201 	right = conv->out_fmt.channel_layout[CRAS_CH_FR];
202 	center = conv->out_fmt.channel_layout[CRAS_CH_FC];
203 
204 	return s16_mono_to_51(left, right, center, in, in_frames, out);
205 }
206 
stereo_to_51(struct cras_fmt_conv * conv,const uint8_t * in,size_t in_frames,uint8_t * out)207 static size_t stereo_to_51(struct cras_fmt_conv *conv, const uint8_t *in,
208 			   size_t in_frames, uint8_t *out)
209 {
210 	size_t left, right, center;
211 
212 	left = conv->out_fmt.channel_layout[CRAS_CH_FL];
213 	right = conv->out_fmt.channel_layout[CRAS_CH_FR];
214 	center = conv->out_fmt.channel_layout[CRAS_CH_FC];
215 
216 	return s16_stereo_to_51(left, right, center, in, in_frames, out);
217 }
218 
quad_to_51(struct cras_fmt_conv * conv,const uint8_t * in,size_t in_frames,uint8_t * out)219 static size_t quad_to_51(struct cras_fmt_conv *conv, const uint8_t *in,
220 			 size_t in_frames, uint8_t *out)
221 {
222 	size_t fl, fr, rl, rr;
223 
224 	fl = conv->out_fmt.channel_layout[CRAS_CH_FL];
225 	fr = conv->out_fmt.channel_layout[CRAS_CH_FR];
226 	rl = conv->out_fmt.channel_layout[CRAS_CH_RL];
227 	rr = conv->out_fmt.channel_layout[CRAS_CH_RR];
228 
229 	return s16_quad_to_51(fl, fr, rl, rr, in, in_frames, out);
230 }
231 
_51_to_stereo(struct cras_fmt_conv * conv,const uint8_t * in,size_t in_frames,uint8_t * out)232 static size_t _51_to_stereo(struct cras_fmt_conv *conv, const uint8_t *in,
233 			    size_t in_frames, uint8_t *out)
234 {
235 	return s16_51_to_stereo(in, in_frames, out);
236 }
237 
_51_to_quad(struct cras_fmt_conv * conv,const uint8_t * in,size_t in_frames,uint8_t * out)238 static size_t _51_to_quad(struct cras_fmt_conv *conv, const uint8_t *in,
239 			  size_t in_frames, uint8_t *out)
240 {
241 	return s16_51_to_quad(in, in_frames, out);
242 }
243 
stereo_to_quad(struct cras_fmt_conv * conv,const uint8_t * in,size_t in_frames,uint8_t * out)244 static size_t stereo_to_quad(struct cras_fmt_conv *conv, const uint8_t *in,
245 			     size_t in_frames, uint8_t *out)
246 {
247 	size_t front_left, front_right, rear_left, rear_right;
248 
249 	front_left = conv->out_fmt.channel_layout[CRAS_CH_FL];
250 	front_right = conv->out_fmt.channel_layout[CRAS_CH_FR];
251 	rear_left = conv->out_fmt.channel_layout[CRAS_CH_RL];
252 	rear_right = conv->out_fmt.channel_layout[CRAS_CH_RR];
253 
254 	return s16_stereo_to_quad(front_left, front_right, rear_left,
255 				  rear_right, in, in_frames, out);
256 }
257 
quad_to_stereo(struct cras_fmt_conv * conv,const uint8_t * in,size_t in_frames,uint8_t * out)258 static size_t quad_to_stereo(struct cras_fmt_conv *conv, const uint8_t *in,
259 			     size_t in_frames, uint8_t *out)
260 {
261 	size_t front_left, front_right, rear_left, rear_right;
262 
263 	front_left = conv->in_fmt.channel_layout[CRAS_CH_FL];
264 	front_right = conv->in_fmt.channel_layout[CRAS_CH_FR];
265 	rear_left = conv->in_fmt.channel_layout[CRAS_CH_RL];
266 	rear_right = conv->in_fmt.channel_layout[CRAS_CH_RR];
267 
268 	return s16_quad_to_stereo(front_left, front_right, rear_left,
269 				  rear_right, in, in_frames, out);
270 }
271 
default_all_to_all(struct cras_fmt_conv * conv,const uint8_t * in,size_t in_frames,uint8_t * out)272 static size_t default_all_to_all(struct cras_fmt_conv *conv, const uint8_t *in,
273 				 size_t in_frames, uint8_t *out)
274 {
275 	size_t num_in_ch, num_out_ch;
276 
277 	num_in_ch = conv->in_fmt.num_channels;
278 	num_out_ch = conv->out_fmt.num_channels;
279 
280 	return s16_default_all_to_all(&conv->out_fmt, num_in_ch, num_out_ch, in,
281 				      in_frames, out);
282 }
283 
284 // Fill min(in channels, out_channels), leave the rest 0s.
default_some_to_some(struct cras_fmt_conv * conv,const uint8_t * in,size_t in_frames,uint8_t * out)285 static size_t default_some_to_some(struct cras_fmt_conv *conv,
286 				   const uint8_t *in,
287 				   size_t in_frames,
288 				   uint8_t *out)
289 {
290 	size_t num_in_ch, num_out_ch;
291 
292 	num_in_ch = conv->in_fmt.num_channels;
293 	num_out_ch = conv->out_fmt.num_channels;
294 
295 	return s16_some_to_some(&conv->out_fmt, num_in_ch, num_out_ch, in,
296 				in_frames, out);
297 }
298 
convert_channels(struct cras_fmt_conv * conv,const uint8_t * in,size_t in_frames,uint8_t * out)299 static size_t convert_channels(struct cras_fmt_conv *conv, const uint8_t *in,
300 			       size_t in_frames, uint8_t *out)
301 {
302 	float **ch_conv_mtx;
303 	size_t num_in_ch, num_out_ch;
304 
305 	ch_conv_mtx = conv->ch_conv_mtx;
306 	num_in_ch = conv->in_fmt.num_channels;
307 	num_out_ch = conv->out_fmt.num_channels;
308 
309 	return s16_convert_channels(ch_conv_mtx, num_in_ch, num_out_ch, in,
310 				    in_frames, out);
311 }
312 
313 /*
314  * Exported interface
315  */
316 
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)317 struct cras_fmt_conv *cras_fmt_conv_create(const struct cras_audio_format *in,
318 					   const struct cras_audio_format *out,
319 					   size_t max_frames,
320 					   size_t pre_linear_resample)
321 {
322 	struct cras_fmt_conv *conv;
323 	int rc;
324 	unsigned i;
325 
326 	conv = calloc(1, sizeof(*conv));
327 	if (conv == NULL)
328 		return NULL;
329 	conv->in_fmt = *in;
330 	conv->out_fmt = *out;
331 	conv->tmp_buf_frames = max_frames;
332 	conv->pre_linear_resample = pre_linear_resample;
333 
334 	if (!is_supported_format(in)) {
335 		syslog(LOG_ERR, "Invalid input format %d", in->format);
336 		cras_fmt_conv_destroy(&conv);
337 		return NULL;
338 	}
339 
340 	if (!is_supported_format(out)) {
341 		syslog(LOG_ERR, "Invalid output format %d", out->format);
342 		cras_fmt_conv_destroy(&conv);
343 		return NULL;
344 	}
345 
346 	/* Set up sample format conversion. */
347 	/* TODO(dgreid) - modify channel and sample rate conversion so
348 	 * converting to s16 isnt necessary. */
349 	if (in->format != SND_PCM_FORMAT_S16_LE) {
350 		conv->num_converters++;
351 		syslog(LOG_DEBUG, "Convert from format %d to %d.", in->format,
352 		       out->format);
353 		switch (in->format) {
354 		case SND_PCM_FORMAT_U8:
355 			conv->in_format_converter = convert_u8_to_s16le;
356 			break;
357 		case SND_PCM_FORMAT_S24_LE:
358 			conv->in_format_converter = convert_s24le_to_s16le;
359 			break;
360 		case SND_PCM_FORMAT_S32_LE:
361 			conv->in_format_converter = convert_s32le_to_s16le;
362 			break;
363 		case SND_PCM_FORMAT_S24_3LE:
364 			conv->in_format_converter = convert_s243le_to_s16le;
365 			break;
366 		default:
367 			syslog(LOG_ERR, "Should never reachable");
368 			break;
369 		}
370 	}
371 	if (out->format != SND_PCM_FORMAT_S16_LE) {
372 		conv->num_converters++;
373 		syslog(LOG_DEBUG, "Convert from format %d to %d.", in->format,
374 		       out->format);
375 		switch (out->format) {
376 		case SND_PCM_FORMAT_U8:
377 			conv->out_format_converter = convert_s16le_to_u8;
378 			break;
379 		case SND_PCM_FORMAT_S24_LE:
380 			conv->out_format_converter = convert_s16le_to_s24le;
381 			break;
382 		case SND_PCM_FORMAT_S32_LE:
383 			conv->out_format_converter = convert_s16le_to_s32le;
384 			break;
385 		case SND_PCM_FORMAT_S24_3LE:
386 			conv->out_format_converter = convert_s16le_to_s243le;
387 			break;
388 		default:
389 			syslog(LOG_ERR, "Should never reachable");
390 			break;
391 		}
392 	}
393 
394 	/* Set up channel number conversion. */
395 	if (in->num_channels != out->num_channels) {
396 		conv->num_converters++;
397 		syslog(LOG_DEBUG, "Convert from %zu to %zu channels.",
398 		       in->num_channels, out->num_channels);
399 
400 		/* Populate the conversion matrix base on in/out channel count
401 		 * and layout. */
402 		if (in->num_channels == 1 && out->num_channels == 2) {
403 			conv->channel_converter = mono_to_stereo;
404 		} else if (in->num_channels == 1 && out->num_channels == 6) {
405 			conv->channel_converter = mono_to_51;
406 		} else if (in->num_channels == 2 && out->num_channels == 1) {
407 			conv->channel_converter = stereo_to_mono;
408 		} else if (in->num_channels == 2 && out->num_channels == 4) {
409 			conv->channel_converter = stereo_to_quad;
410 		} else if (in->num_channels == 4 && out->num_channels == 2) {
411 			conv->channel_converter = quad_to_stereo;
412 		} else if (in->num_channels == 2 && out->num_channels == 6) {
413 			conv->channel_converter = stereo_to_51;
414 		} else if (in->num_channels == 4 && out->num_channels == 6) {
415 			conv->channel_converter = quad_to_51;
416 		} else if (in->num_channels == 6 &&
417 			   (out->num_channels == 2 || out->num_channels == 4)) {
418 			int in_channel_layout_set = 0;
419 
420 			/* Checks if channel_layout is set in the incoming format */
421 			for (i = 0; i < CRAS_CH_MAX; i++)
422 				if (in->channel_layout[i] != -1)
423 					in_channel_layout_set = 1;
424 
425 			/* Use the conversion matrix based converter when a
426 			 * channel layout is set, or default to use existing
427 			 * converter to downmix to stereo */
428 			if (in_channel_layout_set) {
429 				conv->ch_conv_mtx =
430 					cras_channel_conv_matrix_alloc(
431 						in->num_channels,
432 						out->num_channels);
433 				if (conv->ch_conv_mtx == NULL) {
434 					cras_fmt_conv_destroy(&conv);
435 					return NULL;
436 				}
437 				conv->channel_converter = convert_channels;
438 				if (out->num_channels == 4) {
439 					surround51_to_quad_downmix_mtx(
440 						conv->ch_conv_mtx,
441 						conv->in_fmt.channel_layout);
442 				} else {
443 					surround51_to_stereo_downmix_mtx(
444 						conv->ch_conv_mtx,
445 						conv->in_fmt.channel_layout);
446 				}
447 			} else {
448 				if (out->num_channels == 4)
449 					conv->channel_converter = _51_to_quad;
450 				else
451 					conv->channel_converter = _51_to_stereo;
452 			}
453 		} else if (in->num_channels <= 8 && out->num_channels <= 8) {
454 			// For average channel counts mix from all to all.
455 			syslog(LOG_WARNING,
456 			       "Using all_to_all map for %zu to %zu",
457 			       in->num_channels, out->num_channels);
458 			conv->channel_converter = default_all_to_all;
459 		} else {
460 			syslog(LOG_WARNING,
461 			       "Using some_to_some channel map for %zu to %zu",
462 			       in->num_channels, out->num_channels);
463 			conv->channel_converter = default_some_to_some;
464 		}
465 	} else if (in->num_channels > 2 && !is_channel_layout_equal(in, out)) {
466 		conv->num_converters++;
467 		conv->ch_conv_mtx = cras_channel_conv_matrix_create(in, out);
468 		if (conv->ch_conv_mtx == NULL) {
469 			syslog(LOG_ERR,
470 			       "Failed to create channel conversion matrix."
471 			       "Fallback to default_all_to_all.");
472 			conv->channel_converter = default_all_to_all;
473 		} else {
474 			conv->channel_converter = convert_channels;
475 		}
476 	}
477 	/* Set up sample rate conversion. */
478 	if (in->frame_rate != out->frame_rate) {
479 		conv->num_converters++;
480 		syslog(LOG_DEBUG, "Convert from %zu to %zu Hz.", in->frame_rate,
481 		       out->frame_rate);
482 		conv->speex_state =
483 			speex_resampler_init(out->num_channels, in->frame_rate,
484 					     out->frame_rate,
485 					     SPEEX_QUALITY_LEVEL, &rc);
486 		if (conv->speex_state == NULL) {
487 			syslog(LOG_ERR, "Fail to create speex:%zu %zu %zu %d",
488 			       out->num_channels, in->frame_rate,
489 			       out->frame_rate, rc);
490 			cras_fmt_conv_destroy(&conv);
491 			return NULL;
492 		}
493 	}
494 
495 	/*
496 	 * Set up linear resampler.
497 	 *
498 	 * Note: intended to give both src_rate and dst_rate the same value
499 	 * (i.e. out->frame_rate).  They will be updated in runtime in
500 	 * update_estimated_rate() when the audio thread wants to adjust the
501 	 * rate for inaccurate device consumption rate.
502 	 */
503 	conv->num_converters++;
504 	conv->resampler =
505 		linear_resampler_create(out->num_channels,
506 					cras_get_format_bytes(out),
507 					out->frame_rate, out->frame_rate);
508 	if (conv->resampler == NULL) {
509 		syslog(LOG_ERR, "Fail to create linear resampler");
510 		cras_fmt_conv_destroy(&conv);
511 		return NULL;
512 	}
513 
514 	/* Need num_converters-1 temp buffers, the final converter renders
515 	 * directly into the output. */
516 	for (i = 0; i < conv->num_converters - 1; i++) {
517 		conv->tmp_bufs[i] = malloc(
518 			max_frames * 4 * /* width in bytes largest format. */
519 			MAX(in->num_channels, out->num_channels));
520 		if (conv->tmp_bufs[i] == NULL) {
521 			cras_fmt_conv_destroy(&conv);
522 			return NULL;
523 		}
524 	}
525 
526 	assert(conv->num_converters <= MAX_NUM_CONVERTERS);
527 
528 	return conv;
529 }
530 
cras_fmt_conv_destroy(struct cras_fmt_conv ** convp)531 void cras_fmt_conv_destroy(struct cras_fmt_conv **convp)
532 {
533 	unsigned i;
534 	struct cras_fmt_conv *conv = *convp;
535 
536 	if (conv->ch_conv_mtx)
537 		cras_channel_conv_matrix_destroy(conv->ch_conv_mtx,
538 						 conv->out_fmt.num_channels);
539 	if (conv->speex_state)
540 		speex_resampler_destroy(conv->speex_state);
541 	if (conv->resampler)
542 		linear_resampler_destroy(conv->resampler);
543 	for (i = 0; i < MAX_NUM_CONVERTERS - 1; i++)
544 		free(conv->tmp_bufs[i]);
545 	free(conv);
546 	*convp = NULL;
547 }
548 
cras_channel_remix_conv_create(unsigned int num_channels,const float * coefficient)549 struct cras_fmt_conv *cras_channel_remix_conv_create(unsigned int num_channels,
550 						     const float *coefficient)
551 {
552 	struct cras_fmt_conv *conv;
553 	unsigned out_ch, in_ch;
554 
555 	conv = calloc(1, sizeof(*conv));
556 	if (conv == NULL)
557 		return NULL;
558 	conv->in_fmt.num_channels = num_channels;
559 	conv->out_fmt.num_channels = num_channels;
560 
561 	conv->ch_conv_mtx =
562 		cras_channel_conv_matrix_alloc(num_channels, num_channels);
563 	/* Convert the coeffiencnt array to conversion matrix. */
564 	for (out_ch = 0; out_ch < num_channels; out_ch++)
565 		for (in_ch = 0; in_ch < num_channels; in_ch++)
566 			conv->ch_conv_mtx[out_ch][in_ch] =
567 				coefficient[in_ch + out_ch * num_channels];
568 
569 	conv->num_converters = 1;
570 	conv->tmp_bufs[0] = malloc(4 * /* width in bytes largest format. */
571 				   num_channels);
572 	return conv;
573 }
574 
cras_channel_remix_convert(struct cras_fmt_conv * conv,const struct cras_audio_format * fmt,uint8_t * in_buf,size_t nframes)575 void cras_channel_remix_convert(struct cras_fmt_conv *conv,
576 				const struct cras_audio_format *fmt,
577 				uint8_t *in_buf, size_t nframes)
578 {
579 	unsigned ch, fr;
580 	int16_t *tmp = (int16_t *)conv->tmp_bufs[0];
581 	int16_t *buf = (int16_t *)in_buf;
582 
583 	/*
584 	 * Skip remix for non S16_LE format.
585 	 * TODO(tzungbi): support 24 bits remix convert.
586 	 */
587 	if (fmt->format != SND_PCM_FORMAT_S16_LE)
588 		return;
589 
590 	/* Do remix only when input buffer has the same number of channels. */
591 	if (fmt->num_channels != conv->in_fmt.num_channels)
592 		return;
593 
594 	for (fr = 0; fr < nframes; fr++) {
595 		for (ch = 0; ch < conv->in_fmt.num_channels; ch++)
596 			tmp[ch] = s16_multiply_buf_with_coef(
597 				conv->ch_conv_mtx[ch], buf,
598 				conv->in_fmt.num_channels);
599 		for (ch = 0; ch < conv->in_fmt.num_channels; ch++)
600 			buf[ch] = tmp[ch];
601 		buf += conv->in_fmt.num_channels;
602 	}
603 }
604 
605 const struct cras_audio_format *
cras_fmt_conv_in_format(const struct cras_fmt_conv * conv)606 cras_fmt_conv_in_format(const struct cras_fmt_conv *conv)
607 {
608 	return &conv->in_fmt;
609 }
610 
611 const struct cras_audio_format *
cras_fmt_conv_out_format(const struct cras_fmt_conv * conv)612 cras_fmt_conv_out_format(const struct cras_fmt_conv *conv)
613 {
614 	return &conv->out_fmt;
615 }
616 
cras_fmt_conv_in_frames_to_out(struct cras_fmt_conv * conv,size_t in_frames)617 size_t cras_fmt_conv_in_frames_to_out(struct cras_fmt_conv *conv,
618 				      size_t in_frames)
619 {
620 	if (!conv)
621 		return in_frames;
622 
623 	if (conv->pre_linear_resample)
624 		in_frames = linear_resampler_in_frames_to_out(conv->resampler,
625 							      in_frames);
626 	in_frames = cras_frames_at_rate(conv->in_fmt.frame_rate, in_frames,
627 					conv->out_fmt.frame_rate);
628 	if (!conv->pre_linear_resample)
629 		in_frames = linear_resampler_in_frames_to_out(conv->resampler,
630 							      in_frames);
631 	return in_frames;
632 }
633 
cras_fmt_conv_out_frames_to_in(struct cras_fmt_conv * conv,size_t out_frames)634 size_t cras_fmt_conv_out_frames_to_in(struct cras_fmt_conv *conv,
635 				      size_t out_frames)
636 {
637 	if (!conv)
638 		return out_frames;
639 	if (!conv->pre_linear_resample)
640 		out_frames = linear_resampler_out_frames_to_in(conv->resampler,
641 							       out_frames);
642 	out_frames = cras_frames_at_rate(conv->out_fmt.frame_rate, out_frames,
643 					 conv->in_fmt.frame_rate);
644 	if (conv->pre_linear_resample)
645 		out_frames = linear_resampler_out_frames_to_in(conv->resampler,
646 							       out_frames);
647 	return out_frames;
648 }
649 
cras_fmt_conv_set_linear_resample_rates(struct cras_fmt_conv * conv,float from,float to)650 void cras_fmt_conv_set_linear_resample_rates(struct cras_fmt_conv *conv,
651 					     float from, float to)
652 {
653 	linear_resampler_set_rates(conv->resampler, from, to);
654 }
655 
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)656 size_t cras_fmt_conv_convert_frames(struct cras_fmt_conv *conv,
657 				    const uint8_t *in_buf, uint8_t *out_buf,
658 				    unsigned int *in_frames, size_t out_frames)
659 {
660 	uint32_t fr_in, fr_out;
661 	uint8_t *buffers[MAX_NUM_CONVERTERS + 1]; /* converters + out buffer. */
662 	size_t buf_idx = 0;
663 	static int logged_frames_dont_fit;
664 	unsigned int used_converters = conv->num_converters;
665 	unsigned int post_linear_resample = 0;
666 	unsigned int pre_linear_resample = 0;
667 	unsigned int linear_resample_fr = 0;
668 
669 	assert(conv);
670 	assert(*in_frames <= conv->tmp_buf_frames);
671 
672 	if (linear_resampler_needed(conv->resampler)) {
673 		post_linear_resample = !conv->pre_linear_resample;
674 		pre_linear_resample = conv->pre_linear_resample;
675 	}
676 
677 	/* If no SRC, then in_frames should = out_frames. */
678 	if (conv->speex_state == NULL) {
679 		fr_in = MIN(*in_frames, out_frames);
680 		if (out_frames < *in_frames && !logged_frames_dont_fit) {
681 			syslog(LOG_INFO, "fmt_conv: %u to %zu no SRC.",
682 			       *in_frames, out_frames);
683 			logged_frames_dont_fit = 1;
684 		}
685 	} else {
686 		fr_in = *in_frames;
687 	}
688 	fr_out = fr_in;
689 
690 	/* Set up a chain of buffers.  The output buffer of the first conversion
691 	 * is used as input to the second and so forth, ending in the output
692 	 * buffer. */
693 	if (!linear_resampler_needed(conv->resampler))
694 		used_converters--;
695 
696 	buffers[4] = (uint8_t *)conv->tmp_bufs[3];
697 	buffers[3] = (uint8_t *)conv->tmp_bufs[2];
698 	buffers[2] = (uint8_t *)conv->tmp_bufs[1];
699 	buffers[1] = (uint8_t *)conv->tmp_bufs[0];
700 	buffers[0] = (uint8_t *)in_buf;
701 	buffers[used_converters] = out_buf;
702 
703 	if (pre_linear_resample) {
704 		linear_resample_fr = fr_in;
705 		unsigned resample_limit = out_frames;
706 
707 		/* If there is a 2nd fmt conversion we should convert the
708 		 * resample limit and round it to the lower bound in order
709 		 * not to convert too many frames in the pre linear resampler.
710 		 */
711 		if (conv->speex_state != NULL) {
712 			resample_limit = resample_limit *
713 					 conv->in_fmt.frame_rate /
714 					 conv->out_fmt.frame_rate;
715 			/*
716 			 * However if the limit frames count is less than
717 			 * |out_rate / in_rate|, the final limit value could be
718 			 * rounded to zero so it confuses linear resampler to
719 			 * do nothing. Make sure it's non-zero in that case.
720 			 */
721 			if (resample_limit == 0)
722 				resample_limit = 1;
723 		}
724 
725 		resample_limit = MIN(resample_limit, conv->tmp_buf_frames);
726 		fr_in = linear_resampler_resample(
727 			conv->resampler, buffers[buf_idx], &linear_resample_fr,
728 			buffers[buf_idx + 1], resample_limit);
729 		buf_idx++;
730 	}
731 
732 	/* If the input format isn't S16_LE convert to it. */
733 	if (conv->in_fmt.format != SND_PCM_FORMAT_S16_LE) {
734 		conv->in_format_converter(buffers[buf_idx],
735 					  fr_in * conv->in_fmt.num_channels,
736 					  (uint8_t *)buffers[buf_idx + 1]);
737 		buf_idx++;
738 	}
739 
740 	/* Then channel conversion. */
741 	if (conv->channel_converter != NULL) {
742 		conv->channel_converter(conv, buffers[buf_idx], fr_in,
743 					buffers[buf_idx + 1]);
744 		buf_idx++;
745 	}
746 
747 	/* Then SRC. */
748 	if (conv->speex_state != NULL) {
749 		unsigned int out_limit = out_frames;
750 
751 		if (post_linear_resample)
752 			out_limit = linear_resampler_out_frames_to_in(
753 				conv->resampler, out_limit);
754 		fr_out = cras_frames_at_rate(conv->in_fmt.frame_rate, fr_in,
755 					     conv->out_fmt.frame_rate);
756 		if (fr_out > out_frames + 1 && !logged_frames_dont_fit) {
757 			syslog(LOG_INFO,
758 			       "fmt_conv: put %u frames in %zu sized buffer",
759 			       fr_out, out_frames);
760 			logged_frames_dont_fit = 1;
761 		}
762 		/* limit frames to the output size. */
763 		fr_out = MIN(fr_out, out_limit);
764 		speex_resampler_process_interleaved_int(
765 			conv->speex_state, (int16_t *)buffers[buf_idx], &fr_in,
766 			(int16_t *)buffers[buf_idx + 1], &fr_out);
767 		buf_idx++;
768 	}
769 
770 	if (post_linear_resample) {
771 		linear_resample_fr = fr_out;
772 		unsigned resample_limit = MIN(conv->tmp_buf_frames, out_frames);
773 		fr_out = linear_resampler_resample(
774 			conv->resampler, buffers[buf_idx], &linear_resample_fr,
775 			buffers[buf_idx + 1], resample_limit);
776 		buf_idx++;
777 	}
778 
779 	/* If the output format isn't S16_LE convert to it. */
780 	if (conv->out_fmt.format != SND_PCM_FORMAT_S16_LE) {
781 		conv->out_format_converter(buffers[buf_idx],
782 					   fr_out * conv->out_fmt.num_channels,
783 					   (uint8_t *)buffers[buf_idx + 1]);
784 		buf_idx++;
785 	}
786 
787 	if (pre_linear_resample) {
788 		*in_frames = linear_resample_fr;
789 
790 		/* When buffer sizes are small, there's a corner case that
791 		 * speex library resamples 0 frame to N-1 frames, where N
792 		 * is the integer ratio of output and input rate. For example,
793 		 * 16KHz to 48KHz. In this case fmt_conv should claim zero
794 		 * frames processed, instead of using the linear resampler
795 		 * processed frames count. Otherwise there will be a frame
796 		 * leak and, if accumulated, causes delay in multiple devices
797 		 * use case.
798 		 */
799 		if (conv->speex_state && (fr_in == 0))
800 			*in_frames = 0;
801 	} else {
802 		*in_frames = fr_in;
803 	}
804 	return fr_out;
805 }
806 
cras_fmt_conversion_needed(const struct cras_fmt_conv * conv)807 int cras_fmt_conversion_needed(const struct cras_fmt_conv *conv)
808 {
809 	return linear_resampler_needed(conv->resampler) ||
810 	       (conv->num_converters > 1);
811 }
812 
813 /* If the server cannot provide the requested format, configures an audio format
814  * converter that handles transforming the input format to the format used by
815  * 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)816 int config_format_converter(struct cras_fmt_conv **conv,
817 			    enum CRAS_STREAM_DIRECTION dir,
818 			    const struct cras_audio_format *from,
819 			    const struct cras_audio_format *to,
820 			    unsigned int frames)
821 {
822 	struct cras_audio_format target;
823 
824 	/* For input, preserve the channel count and layout of
825 	 * from format */
826 	if (dir == CRAS_STREAM_INPUT) {
827 		target = *from;
828 		target.format = to->format;
829 		target.frame_rate = to->frame_rate;
830 	} else {
831 		target = *to;
832 	}
833 
834 	syslog(LOG_DEBUG,
835 	       "format convert: from:%d %zu %zu target: %d %zu %zu "
836 	       "frames = %u",
837 	       from->format, from->frame_rate, from->num_channels,
838 	       target.format, target.frame_rate, target.num_channels, frames);
839 	*conv = cras_fmt_conv_create(from, &target, frames,
840 				     (dir == CRAS_STREAM_INPUT));
841 	if (!*conv) {
842 		syslog(LOG_ERR, "Failed to create format converter");
843 		return -ENOMEM;
844 	}
845 
846 	return 0;
847 }
848