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