1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright (C) 4Front Technologies 1996-2008. 23 * 24 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 25 * Use is subject to license terms. 26 */ 27 28 /* 29 * Purpose: Audio format conversion routines used by audio.c 30 */ 31 32 #include <sys/types.h> 33 #include <sys/ddi.h> 34 #include <sys/sunddi.h> 35 #include <sys/audio/g711.h> 36 37 #include "audio_impl.h" 38 #include "audio_grc3.h" 39 40 41 /* 42 * Note: In the function below, the division by the number of channels is 43 * probably fairly expensive. It turns out that we usually deal with stereo 44 * or mono data, so perhaps it would be useful to build custom versions of 45 * this function that only dealt with stereo or mono. 46 */ 47 static int 48 do_src(audio_stream_t *sp, void *p1, void *p2, int len, int nchan) 49 { 50 int ch, size; 51 52 /* 53 * Note that we presume that we are doing sample rate 54 * conversions on AUDIO_FORMAT_S24_NE, which means that have 4 55 * byte and 32-bit samples. 56 */ 57 size = sp->s_cnv_max / 4; /* sample size is 4 */ 58 size /= nchan; 59 60 for (ch = 0; ch < nchan; ch++) { 61 grc3_convert(sp->s_src_state[ch], sp->s_src_quality, 62 p1, p2, len, size, nchan, ch); 63 } 64 return (((grc3state_t *)sp->s_src_state[0])->outsz); 65 } 66 67 static void 68 setup_src(audio_stream_t *sp, int srate, int trate, int sch, int tch) 69 { 70 int ch, nch; 71 72 nch = min(sch, tch); 73 74 ASSERT(nch <= AUDIO_MAX_CHANNELS); 75 76 if (sp->s_src_quality < 1) 77 sp->s_src_quality = 1; 78 if (sp->s_src_quality > 5) 79 sp->s_src_quality = 5; 80 81 for (ch = 0; ch < nch; ch++) { 82 grc3_reset(sp->s_src_state[ch]); 83 grc3_setup(sp->s_src_state[ch], srate, trate); 84 } 85 } 86 87 static int 88 cnv_srconly(audio_stream_t *sp, int len) 89 { 90 void *src = sp->s_cnv_src; 91 void *dst = sp->s_cnv_dst; 92 93 /* 94 * We must be using 24-bit native signed. 95 */ 96 len = do_src(sp, src, dst, len, sp->s_cnv_src_nchan); 97 98 sp->s_cnv_src = dst; 99 sp->s_cnv_dst = src; 100 101 return (len); 102 } 103 104 static int 105 cnv_s24oe(audio_stream_t *sp, int len) 106 { 107 /* 108 * Endian switch works in both directions. We do it in place. 109 */ 110 int32_t *src = sp->s_cnv_src; 111 112 for (int i = len * sp->s_cnv_src_nchan; i; i--) { 113 *src = ddi_swap32(*src); 114 src++; 115 } 116 117 return (len); 118 } 119 120 121 static int 122 cnv_from_s8(audio_stream_t *sp, int len) 123 { 124 void *s = sp->s_cnv_src; 125 void *d = sp->s_cnv_dst; 126 int8_t *src = s; 127 int32_t *dst = d; 128 129 for (int i = len * sp->s_cnv_src_nchan; i; i--) 130 *dst++ = (*src++) << 16; 131 132 sp->s_cnv_src = d; 133 sp->s_cnv_dst = s; 134 return (len); 135 } 136 137 static int 138 cnv_from_u8(audio_stream_t *sp, int len) 139 { 140 void *s = sp->s_cnv_src; 141 void *d = sp->s_cnv_dst; 142 uint8_t *src = s; 143 int32_t *dst = d; 144 145 for (int i = len * sp->s_cnv_src_nchan; i; i--) 146 *dst++ = (int8_t)((*src++) ^ 0x80) << 16; 147 148 sp->s_cnv_src = d; 149 sp->s_cnv_dst = s; 150 return (len); 151 } 152 153 static int 154 cnv_from_ulaw(audio_stream_t *sp, int len) 155 { 156 void *s = sp->s_cnv_src; 157 void *d = sp->s_cnv_dst; 158 uint8_t *src = s; 159 int32_t *dst = d; 160 161 for (int i = len * sp->s_cnv_src_nchan; i; i--) { 162 *dst++ = _8ulaw2linear16[(*src++)] << 8; 163 } 164 sp->s_cnv_src = d; 165 sp->s_cnv_dst = s; 166 return (len); 167 } 168 169 static int 170 cnv_from_alaw(audio_stream_t *sp, int len) 171 { 172 void *s = sp->s_cnv_src; 173 void *d = sp->s_cnv_dst; 174 uint8_t *src = s; 175 int32_t *dst = d; 176 177 for (int i = len * sp->s_cnv_src_nchan; i; i--) { 178 *dst++ = _8alaw2linear16[(*src++)] << 8; 179 } 180 sp->s_cnv_src = d; 181 sp->s_cnv_dst = s; 182 return (len); 183 } 184 185 static int 186 cnv_from_s16ne(audio_stream_t *sp, int len) 187 { 188 void *s = sp->s_cnv_src; 189 void *d = sp->s_cnv_dst; 190 int16_t *src = s; 191 int32_t *dst = d; 192 193 for (int i = len * sp->s_cnv_src_nchan; i; i--) 194 *dst++ = (*src++) << 8; 195 196 sp->s_cnv_src = d; 197 sp->s_cnv_dst = s; 198 return (len); 199 } 200 201 static int 202 cnv_from_s16oe(audio_stream_t *sp, int len) 203 { 204 void *s = sp->s_cnv_src; 205 void *d = sp->s_cnv_dst; 206 int16_t *src = s; 207 int32_t *dst = d; 208 209 for (int i = len * sp->s_cnv_src_nchan; i; i--) 210 *dst++ = (int16_t)(ddi_swap16(*src++)) << 8; 211 212 sp->s_cnv_src = d; 213 sp->s_cnv_dst = s; 214 return (len); 215 } 216 217 static int 218 cnv_from_u16ne(audio_stream_t *sp, int len) 219 { 220 void *s = sp->s_cnv_src; 221 void *d = sp->s_cnv_dst; 222 uint16_t *src = s; 223 int32_t *dst = d; 224 225 for (int i = len * sp->s_cnv_src_nchan; i; i--) 226 *dst++ = (int16_t)((*src++) ^ 0x8000) << 8; 227 228 sp->s_cnv_src = d; 229 sp->s_cnv_dst = s; 230 return (len); 231 } 232 233 static int 234 cnv_from_u16oe(audio_stream_t *sp, int len) 235 { 236 void *s = sp->s_cnv_src; 237 void *d = sp->s_cnv_dst; 238 uint16_t *src = s; 239 int32_t *dst = d; 240 241 for (int i = len * sp->s_cnv_src_nchan; i; i--) 242 *dst++ = (int16_t)(ddi_swap16((*src++) ^ 0x8000)) << 8; 243 244 sp->s_cnv_src = d; 245 sp->s_cnv_dst = s; 246 return (len); 247 } 248 249 static int 250 cnv_from_s24p(audio_stream_t *sp, int len) 251 { 252 void *s = sp->s_cnv_src; 253 void *d = sp->s_cnv_dst; 254 uint8_t *src = s; 255 int32_t *dst = d; 256 int32_t tmp; 257 258 for (int i = len * sp->s_cnv_src_nchan; i; i--) { 259 /* NB: this is a little endian format */ 260 tmp = (*src++); 261 tmp |= (*src++) << 8; 262 tmp |= (*src++) << 16; 263 *dst++ = tmp; 264 } 265 266 sp->s_cnv_src = d; 267 sp->s_cnv_dst = s; 268 return (len); 269 } 270 271 static int 272 cnv_from_s32ne(audio_stream_t *sp, int len) 273 { 274 /* 32-bit conversions can be done in place */ 275 int32_t *src = sp->s_cnv_src; 276 277 for (int i = len * sp->s_cnv_src_nchan; i; i--, src++) 278 *src = *src >> 8; 279 280 return (len); 281 } 282 283 static int 284 cnv_from_s32oe(audio_stream_t *sp, int len) 285 { 286 /* 32-bit conversions can be done in place */ 287 int32_t *src = sp->s_cnv_src; 288 289 for (int i = len * sp->s_cnv_src_nchan; i; i--, src++) 290 *src = (int32_t)(ddi_swap32(*src)) >> 8; 291 292 return (len); 293 } 294 295 /* 296 * NB: All the destination format conversions use the same or fewer 297 * bytes as the 24-bit unpacked (32-bits used per sample), so we can 298 * convert all of them in place. 299 */ 300 301 static int 302 cnv_to_u8(audio_stream_t *sp, int len) 303 { 304 int32_t *src = sp->s_cnv_src; 305 uint8_t *dst = (void *)src; 306 307 for (int i = len * sp->s_cnv_dst_nchan; i; i--) 308 *dst++ = (*src++ >> 16) ^ 0x80; 309 310 return (len); 311 } 312 313 static int 314 cnv_to_s8(audio_stream_t *sp, int len) 315 { 316 int32_t *src = sp->s_cnv_src; 317 int8_t *dst = (void *)src; 318 319 for (int i = len * sp->s_cnv_dst_nchan; i; i--) 320 *dst++ = *src++ >> 16; 321 322 return (len); 323 } 324 325 static int 326 cnv_to_ulaw(audio_stream_t *sp, int len) 327 { 328 int32_t *src = sp->s_cnv_src; 329 uint8_t *dst = (void *)src; 330 331 for (int i = len * sp->s_cnv_dst_nchan; i; i--) { 332 int idx = *src++; 333 idx >>= 10; 334 idx += G711_ULAW_MIDPOINT; 335 idx &= 0x3fff; /* safety precaution */ 336 *dst++ = _14linear2ulaw8[idx]; 337 } 338 339 return (len); 340 } 341 342 static int 343 cnv_to_alaw(audio_stream_t *sp, int len) 344 { 345 int32_t *src = sp->s_cnv_src; 346 uint8_t *dst = (void *)src; 347 348 for (int i = len * sp->s_cnv_dst_nchan; i; i--) { 349 int idx = *src++; 350 idx >>= 11; 351 idx += G711_ALAW_MIDPOINT; 352 idx &= 0x1fff; /* safety precaution */ 353 *dst++ = _13linear2alaw8[idx]; 354 } 355 356 return (len); 357 } 358 359 static int 360 cnv_to_s16ne(audio_stream_t *sp, int len) 361 { 362 int32_t *src = sp->s_cnv_src; 363 int16_t *dst = (void *)src; 364 365 for (int i = len * sp->s_cnv_dst_nchan; i; i--) 366 *dst++ = *src++ >> 8; 367 368 return (len); 369 } 370 371 static int 372 cnv_to_s16oe(audio_stream_t *sp, int len) 373 { 374 int32_t *src = sp->s_cnv_src; 375 int16_t *dst = (void *)src; 376 377 for (int i = len * sp->s_cnv_dst_nchan; i; i--) 378 *dst++ = ddi_swap16(*src++ >> 8); 379 380 return (len); 381 } 382 383 static int 384 cnv_to_u16ne(audio_stream_t *sp, int len) 385 { 386 int32_t *src = sp->s_cnv_src; 387 uint16_t *dst = (void *)src; 388 389 for (int i = len * sp->s_cnv_dst_nchan; i; i--) 390 *dst++ = (*src++ >> 8) ^ 0x8000; 391 392 return (len); 393 } 394 395 static int 396 cnv_to_u16oe(audio_stream_t *sp, int len) 397 { 398 int32_t *src = sp->s_cnv_src; 399 uint16_t *dst = (void *)src; 400 401 for (int i = len * sp->s_cnv_dst_nchan; i; i--) 402 *dst++ = ddi_swap16(*src++ >> 8) ^ 0x8000; 403 404 return (len); 405 } 406 407 static int 408 cnv_to_s24p(audio_stream_t *sp, int len) 409 { 410 int32_t *src = sp->s_cnv_src; 411 uint8_t *dst = (void *)src; 412 int32_t d; 413 414 for (int i = len * sp->s_cnv_dst_nchan; i; i--) { 415 /* NB: this is a little endian format */ 416 d = *src++; 417 *dst++ = d & 0xff; 418 *dst++ = (d >> 8) & 0xff; 419 *dst++ = (d >> 16) & 0xff; 420 } 421 422 return (len); 423 } 424 425 static int 426 cnv_to_s32ne(audio_stream_t *sp, int len) 427 { 428 int32_t *src = sp->s_cnv_src; 429 430 for (int i = len * sp->s_cnv_dst_nchan; i; i--, src++) 431 *src = *src << 8; 432 433 return (len); 434 } 435 436 static int 437 cnv_to_s32oe(audio_stream_t *sp, int len) 438 { 439 int32_t *src = sp->s_cnv_src; 440 441 for (int i = len * sp->s_cnv_dst_nchan; i; i--, src++) 442 *src = ddi_swap32(*src << 8); 443 444 return (len); 445 } 446 447 static int 448 cnv_default(audio_stream_t *sp, int len) 449 { 450 /* 451 * Note that the formats were already preverified during 452 * select_converter, to ensure that only supported formats are 453 * used. 454 */ 455 456 /* 457 * Convert samples to 24 bit (32 bit lsb aligned) if 458 * necessary. 459 */ 460 461 switch (sp->s_cnv_src_format) { 462 463 case AUDIO_FORMAT_U8: 464 len = cnv_from_u8(sp, len); 465 break; 466 467 case AUDIO_FORMAT_S8: 468 len = cnv_from_s8(sp, len); 469 break; 470 471 case AUDIO_FORMAT_ULAW: 472 len = cnv_from_ulaw(sp, len); 473 break; 474 475 case AUDIO_FORMAT_ALAW: 476 len = cnv_from_alaw(sp, len); 477 break; 478 479 case AUDIO_FORMAT_S16_NE: 480 len = cnv_from_s16ne(sp, len); 481 break; 482 483 case AUDIO_FORMAT_S16_OE: 484 len = cnv_from_s16oe(sp, len); 485 break; 486 487 case AUDIO_FORMAT_U16_NE: 488 len = cnv_from_u16ne(sp, len); 489 break; 490 491 case AUDIO_FORMAT_U16_OE: 492 len = cnv_from_u16oe(sp, len); 493 break; 494 495 case AUDIO_FORMAT_S32_NE: 496 len = cnv_from_s32ne(sp, len); 497 break; 498 499 case AUDIO_FORMAT_S32_OE: 500 len = cnv_from_s32oe(sp, len); 501 break; 502 503 case AUDIO_FORMAT_S24_OE: 504 len = cnv_s24oe(sp, len); 505 break; 506 507 case AUDIO_FORMAT_S24_PACKED: 508 len = cnv_from_s24p(sp, len); 509 break; 510 } 511 512 /* 513 * If we aren't decreasing the number of channels, then do the 514 * SRC now. (We prefer to do SRC on the smaller number of channels.) 515 */ 516 if (sp->s_cnv_src_rate != sp->s_cnv_dst_rate && 517 sp->s_cnv_src_nchan <= sp->s_cnv_dst_nchan) { 518 int32_t *src = sp->s_cnv_src; 519 int32_t *dst = sp->s_cnv_dst; 520 521 len = do_src(sp, src, dst, len, sp->s_cnv_src_nchan); 522 523 sp->s_cnv_src = dst; 524 sp->s_cnv_dst = src; 525 } 526 527 /* 528 * Convert between mono and stereo 529 */ 530 531 if (sp->s_cnv_src_nchan != sp->s_cnv_dst_nchan) { 532 int32_t *src = sp->s_cnv_src; 533 int32_t *dst = sp->s_cnv_dst; 534 int tc = sp->s_cnv_dst_nchan; 535 int sc = sp->s_cnv_src_nchan; 536 int nc; 537 int i; 538 539 sp->s_cnv_src = dst; 540 sp->s_cnv_dst = src; 541 542 if (sc == 1) { 543 /* 544 * Mono expansion. We expand into the stereo 545 * channel, and leave other channels silent. 546 */ 547 for (i = len; i; i--) { 548 *dst++ = *src; 549 *dst++ = *src++; 550 for (int j = tc - 2; j > 0; j--) { 551 *dst++ = 0; 552 } 553 554 } 555 556 } else if (sc == 2 && tc == 1) { 557 /* 558 * Stereo -> mono. We do stereo separately to make 559 * the division fast (div by const 2 is just shift). 560 */ 561 for (i = len; i; i--) { 562 /* 563 * Take just the left channel sample, 564 * discard the right channel. 565 */ 566 *dst++ = *src++; /* left */ 567 src++; /* right */ 568 } 569 } else { 570 /* 571 * Multi channel conversions. We just copy the 572 * minimum number of channels. 573 */ 574 575 /* Calculate number of frames */ 576 577 nc = min(sc, tc); 578 579 /* Clear destination */ 580 bzero(dst, (len * tc * sizeof (int32_t))); 581 582 for (i = len; i; i--) { 583 int c; 584 585 for (c = 0; c < nc; c++) 586 dst[c] = src[c]; 587 588 src += sc; 589 dst += tc; 590 } 591 } 592 } 593 594 /* 595 * If we didn't do SRC pre-conversion, then do it now. 596 */ 597 if (sp->s_cnv_src_rate != sp->s_cnv_dst_rate && 598 sp->s_cnv_src_nchan > sp->s_cnv_dst_nchan) { 599 600 int32_t *src = sp->s_cnv_src; 601 int32_t *dst = sp->s_cnv_dst; 602 603 len = do_src(sp, src, dst, len, sp->s_cnv_dst_nchan); 604 605 sp->s_cnv_src = dst; 606 sp->s_cnv_dst = src; 607 } 608 609 /* 610 * Finally convert samples from internal 24 bit format to target format 611 */ 612 613 switch (sp->s_cnv_dst_format) { 614 case AUDIO_FORMAT_U8: 615 len = cnv_to_u8(sp, len); 616 break; 617 618 case AUDIO_FORMAT_S8: 619 len = cnv_to_s8(sp, len); 620 break; 621 622 case AUDIO_FORMAT_S16_NE: 623 len = cnv_to_s16ne(sp, len); 624 break; 625 626 case AUDIO_FORMAT_S16_OE: 627 len = cnv_to_s16oe(sp, len); 628 break; 629 630 case AUDIO_FORMAT_U16_NE: 631 len = cnv_to_u16ne(sp, len); 632 break; 633 634 case AUDIO_FORMAT_U16_OE: 635 len = cnv_to_u16oe(sp, len); 636 break; 637 638 case AUDIO_FORMAT_S24_OE: 639 len = cnv_s24oe(sp, len); 640 break; 641 642 case AUDIO_FORMAT_S24_PACKED: 643 len = cnv_to_s24p(sp, len); 644 break; 645 646 case AUDIO_FORMAT_S32_NE: 647 len = cnv_to_s32ne(sp, len); 648 break; 649 650 case AUDIO_FORMAT_S32_OE: 651 len = cnv_to_s32oe(sp, len); 652 break; 653 654 case AUDIO_FORMAT_ULAW: 655 len = cnv_to_ulaw(sp, len); 656 break; 657 658 case AUDIO_FORMAT_ALAW: 659 len = cnv_to_alaw(sp, len); 660 break; 661 } 662 663 return (len); 664 } 665 666 static const struct audio_format_info { 667 unsigned format; 668 int sampsize; 669 audio_cnv_func_t from; 670 audio_cnv_func_t to; 671 } audio_format_info[] = { 672 { AUDIO_FORMAT_S8, 1, cnv_from_s8, cnv_to_s8 }, 673 { AUDIO_FORMAT_U8, 1, cnv_from_u8, cnv_to_u8 }, 674 { AUDIO_FORMAT_ULAW, 1, cnv_from_ulaw, cnv_to_ulaw }, 675 { AUDIO_FORMAT_ALAW, 1, cnv_from_alaw, cnv_to_alaw }, 676 { AUDIO_FORMAT_S16_NE, 2, cnv_from_s16ne, cnv_to_s16ne }, 677 { AUDIO_FORMAT_S16_OE, 2, cnv_from_s16oe, cnv_to_s16oe }, 678 { AUDIO_FORMAT_U16_NE, 2, cnv_from_u16ne, cnv_to_u16ne }, 679 { AUDIO_FORMAT_U16_OE, 2, cnv_from_u16oe, cnv_to_u16oe }, 680 { AUDIO_FORMAT_S32_NE, 4, cnv_from_s32ne, cnv_to_s32ne }, 681 { AUDIO_FORMAT_S32_OE, 4, cnv_from_s32oe, cnv_to_s32oe }, 682 683 /* 24-bit formats are "special" */ 684 { AUDIO_FORMAT_S24_NE, 4, NULL, NULL }, 685 { AUDIO_FORMAT_S24_OE, 4, cnv_s24oe, cnv_s24oe }, 686 { AUDIO_FORMAT_S24_PACKED, 3, cnv_from_s24p, cnv_to_s24p }, 687 688 /* sentinel */ 689 { AUDIO_FORMAT_NONE, 0, NULL, NULL } 690 }; 691 692 int 693 auimpl_format_setup(audio_stream_t *sp, audio_parms_t *uparms) 694 { 695 audio_parms_t *source = &sp->s_cnv_src_parms; 696 audio_parms_t *target = &sp->s_cnv_dst_parms; 697 audio_cnv_func_t converter = NULL; 698 const struct audio_format_info *info; 699 int expand = AUDIO_UNIT_EXPAND; 700 unsigned cnv_sampsz = sizeof (uint32_t); 701 unsigned cnv_max; 702 703 if (sp == &sp->s_client->c_ostream) { 704 source = uparms; 705 } else { 706 target = uparms; 707 } 708 709 ASSERT(mutex_owned(&sp->s_lock)); 710 711 /* 712 * At least one of the source or target are S24_NE. 713 * 714 * If we have a signed/native endian format, then pick an 715 * optimized converter. While at it, ensure that a valid 716 * format is selected. 717 */ 718 if (source->p_format != AUDIO_FORMAT_S24_NE) { 719 for (info = &audio_format_info[0]; info->sampsize; info++) { 720 if (source->p_format == info->format) { 721 converter = info->from; 722 expand *= sizeof (int32_t); 723 expand /= info->sampsize; 724 /* save source frame size */ 725 cnv_sampsz = info->sampsize; 726 break; 727 } 728 } 729 if (info->format == AUDIO_FORMAT_NONE) { 730 audio_dev_warn(sp->s_client->c_dev, 731 "invalid source format selected"); 732 return (EINVAL); 733 } 734 735 } else if (target->p_format != AUDIO_FORMAT_S24_NE) { 736 for (info = &audio_format_info[0]; info->sampsize; info++) { 737 if (target->p_format == info->format) { 738 converter = info->to; 739 expand *= info->sampsize; 740 expand /= sizeof (int32_t); 741 break; 742 } 743 } 744 if (info->format == AUDIO_FORMAT_NONE) { 745 audio_dev_warn(sp->s_client->c_dev, 746 "invalid target format selected"); 747 return (EINVAL); 748 } 749 } 750 751 if (source->p_nchan != target->p_nchan) { 752 /* 753 * if channels need conversion, then we must use the 754 * default. 755 */ 756 converter = cnv_default; 757 expand *= target->p_nchan; 758 expand /= source->p_nchan; 759 } 760 761 if (source->p_rate != target->p_rate) { 762 /* 763 * We need SRC; if we can avoid data conversion, do so. 764 */ 765 setup_src(sp, source->p_rate, target->p_rate, 766 source->p_nchan, target->p_nchan); 767 768 converter = (converter == NULL) ? cnv_srconly : cnv_default; 769 770 expand *= target->p_rate; 771 expand /= source->p_rate; 772 } 773 774 ASSERT(sp->s_engine); 775 ASSERT(sp->s_engine->e_intrs); 776 777 /* 778 * Figure out the size of the conversion buffer we need. We 779 * assume room for two full source fragments, which ought to 780 * be enough, even with rounding errors. 781 */ 782 cnv_max = 2 * (source->p_rate / sp->s_engine->e_intrs) * 783 cnv_sampsz * source->p_nchan; 784 785 /* 786 * If the conversion will cause us to expand fragments, then 787 * we need to increase cnv_max. Scale by AUDIO_UNIT_EXPAND to 788 * avoid rouding errors or losing bits when doing reducing 789 * conversions. 790 */ 791 if (expand > AUDIO_UNIT_EXPAND) { 792 cnv_max *= expand; 793 cnv_max /= AUDIO_UNIT_EXPAND; 794 } 795 796 /* 797 * Now we need to allocate space. 798 */ 799 if (sp->s_cnv_max < cnv_max) { 800 uint32_t *buf0, *buf1; 801 802 buf0 = kmem_alloc(cnv_max, KM_NOSLEEP); 803 buf1 = kmem_alloc(cnv_max, KM_NOSLEEP); 804 if ((buf0 == NULL) || (buf1 == NULL)) { 805 audio_dev_warn(sp->s_client->c_dev, 806 "failed to allocate audio conversion buffer " 807 "(%u bytes)", cnv_max); 808 if (buf0) 809 kmem_free(buf0, cnv_max); 810 if (buf1) 811 kmem_free(buf1, cnv_max); 812 return (ENOMEM); 813 } 814 815 if (sp->s_cnv_buf0) 816 kmem_free(sp->s_cnv_buf0, sp->s_cnv_max); 817 if (sp->s_cnv_buf1) 818 kmem_free(sp->s_cnv_buf1, sp->s_cnv_max); 819 820 sp->s_cnv_buf0 = buf0; 821 sp->s_cnv_buf1 = buf1; 822 sp->s_cnv_max = cnv_max; 823 } 824 825 /* 826 * NB: From here on, we must not fail. 827 */ 828 829 /* 830 * Configure default fragment setup. 831 */ 832 for (info = &audio_format_info[0]; info->sampsize; info++) { 833 if (uparms->p_format == info->format) { 834 break; 835 } 836 } 837 ASSERT(info->sampsize); 838 839 sp->s_framesz = info->sampsize * uparms->p_nchan; 840 sp->s_fragfr = (uparms->p_rate / sp->s_engine->e_intrs); 841 sp->s_fragbytes = sp->s_fragfr * sp->s_framesz; 842 sp->s_nfrags = sp->s_allocsz / sp->s_fragbytes; 843 sp->s_nframes = sp->s_nfrags * sp->s_fragfr; 844 sp->s_nbytes = sp->s_nframes * sp->s_framesz; 845 *sp->s_user_parms = *uparms; 846 sp->s_converter = converter; 847 848 /* 849 * Ensure that we toss any stale data -- probably wrong format. 850 * Note that as a consequence of this, all of the offsets and 851 * counters get reset. Clients should not rely on these values 852 * being preserved when changing formats. 853 * 854 * Its critical that we reset the indices, in particular, 855 * because not only will the data be the wrong format, but the 856 * indices themselves are quite possibly going to be invalid. 857 */ 858 sp->s_cnv_cnt = 0; 859 sp->s_tail = sp->s_head = 0; 860 sp->s_tidx = sp->s_hidx = 0; 861 862 return (0); 863 } 864 865 int 866 auimpl_format_alloc(audio_stream_t *sp) 867 { 868 int i; 869 870 ASSERT(mutex_owned(&sp->s_lock)); 871 for (i = 0; i < AUDIO_MAX_CHANNELS; i++) { 872 sp->s_src_state[i] = 873 kmem_zalloc(sizeof (grc3state_t), KM_NOSLEEP); 874 if (sp->s_src_state[i] == NULL) { 875 audio_dev_warn(sp->s_client->c_dev, 876 "unable to allocate SRC state structures"); 877 return (ENOMEM); 878 } 879 } 880 return (0); 881 } 882 883 void 884 auimpl_format_free(audio_stream_t *sp) 885 { 886 int i; 887 888 for (i = 0; i < AUDIO_MAX_CHANNELS; i++) { 889 if (sp->s_src_state[i] != NULL) { 890 kmem_free(sp->s_src_state[i], sizeof (grc3state_t)); 891 sp->s_src_state[i] = NULL; 892 } 893 } 894 } 895