Home | History | Annotate | Download | only in server
      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. */
     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. */
     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. */
     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. */
     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. */
    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. */
    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. */
    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. */
    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. */
    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. */
    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. */
    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  */
    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  */
    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. */
    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. */
    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 
    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. */
    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 
    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  */
    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  */
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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. */
    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