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 (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 25 */ 26 27 /* 28 * Purpose: Audio format conversion routines used by audio.c 29 */ 30 31 #include <sys/types.h> 32 #include <sys/ddi.h> 33 #include <sys/sunddi.h> 34 #include <sys/audio/g711.h> 35 36 #include "audio_impl.h" 37 #include "audio_grc3.h" 38 39 extern uint_t audio_intrhz; 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 *parms, uint_t mask) 694 { 695 audio_parms_t source; 696 audio_parms_t target; 697 audio_parms_t *uparms; 698 audio_cnv_func_t converter = NULL; 699 const struct audio_format_info *info; 700 int expand = AUDIO_UNIT_EXPAND; 701 unsigned cnv_sampsz = sizeof (uint32_t); 702 unsigned cnv_max; 703 boolean_t needsrc = B_FALSE; 704 705 uint_t framesz; 706 uint_t fragfr; 707 uint_t fragbytes; 708 uint_t nfrags; 709 710 ASSERT(mutex_owned(&sp->s_lock)); 711 712 source = sp->s_cnv_src_parms; 713 target = sp->s_cnv_dst_parms; 714 715 if (sp == &sp->s_client->c_ostream) { 716 if (mask & FORMAT_MSK_FMT) 717 source.p_format = parms->p_format; 718 if (mask & FORMAT_MSK_RATE) 719 source.p_rate = parms->p_rate; 720 if (mask & FORMAT_MSK_CHAN) 721 source.p_nchan = parms->p_nchan; 722 uparms = &source; 723 } else { 724 if (mask & FORMAT_MSK_FMT) 725 target.p_format = parms->p_format; 726 if (mask & FORMAT_MSK_RATE) 727 target.p_rate = parms->p_rate; 728 if (mask & FORMAT_MSK_CHAN) 729 target.p_nchan = parms->p_nchan; 730 uparms = ⌖ 731 } 732 733 /* 734 * At least one of the source or target are S24_NE. 735 * 736 * If we have a signed/native endian format, then pick an 737 * optimized converter. While at it, ensure that a valid 738 * format is selected. 739 * 740 * After this function executes, "info" will point to the 741 * format information for the user parameters. 742 */ 743 if (source.p_format != AUDIO_FORMAT_S24_NE) { 744 for (info = &audio_format_info[0]; info->sampsize; info++) { 745 if (source.p_format == info->format) { 746 converter = info->from; 747 expand *= sizeof (int32_t); 748 expand /= info->sampsize; 749 /* save source frame size */ 750 cnv_sampsz = info->sampsize; 751 break; 752 } 753 } 754 } else { 755 /* 756 * Target format. Note that this case is also taken 757 * if we're operating on S24_NE data. In that case 758 * the converter will be NULL and expand will not be 759 * altered. 760 */ 761 for (info = &audio_format_info[0]; info->sampsize; info++) { 762 if (target.p_format == info->format) { 763 converter = info->to; 764 expand *= info->sampsize; 765 expand /= sizeof (int32_t); 766 break; 767 } 768 } 769 } 770 if (info->format == AUDIO_FORMAT_NONE) { 771 audio_dev_warn(sp->s_client->c_dev, "invalid format selected"); 772 return (EINVAL); 773 } 774 775 776 ASSERT(info->sampsize); 777 778 if (source.p_nchan != target.p_nchan) { 779 /* 780 * if channels need conversion, then we must use the 781 * default. 782 */ 783 converter = cnv_default; 784 expand *= target.p_nchan; 785 expand /= source.p_nchan; 786 } 787 788 if (source.p_rate != target.p_rate) { 789 needsrc = B_TRUE; 790 converter = (converter == NULL) ? cnv_srconly : cnv_default; 791 792 expand *= target.p_rate; 793 expand /= source.p_rate; 794 } 795 796 /* 797 * Figure out the size of the conversion buffer we need. We 798 * assume room for two full source fragments, which ought to 799 * be enough, even with rounding errors. 800 */ 801 cnv_max = 2 * (source.p_rate / audio_intrhz) * 802 cnv_sampsz * source.p_nchan; 803 804 /* 805 * If the conversion will cause us to expand fragments, then 806 * we need to increase cnv_max. Scale by AUDIO_UNIT_EXPAND to 807 * avoid rouding errors or losing bits when doing reducing 808 * conversions. 809 */ 810 if (expand > AUDIO_UNIT_EXPAND) { 811 cnv_max *= expand; 812 cnv_max /= AUDIO_UNIT_EXPAND; 813 } 814 815 framesz = info->sampsize * uparms->p_nchan; 816 fragfr = (uparms->p_rate / audio_intrhz); 817 fragbytes = fragfr * framesz; 818 819 /* 820 * We need to "tune" the buffer and fragment counts for some 821 * uses... OSS applications may like to configure a low 822 * latency, and they rely upon write() to block to prevent too 823 * much data from being queued up. 824 */ 825 if (sp->s_hintsz) { 826 nfrags = sp->s_hintsz / fragbytes; 827 } else if (sp->s_hintfrags) { 828 nfrags = sp->s_hintfrags; 829 } else { 830 nfrags = sp->s_allocsz / fragbytes; 831 } 832 833 /* 834 * Now make sure that the hint works -- we need at least 2 fragments, 835 * and we need to fit within the room allocated to us. 836 */ 837 if (nfrags < 2) { 838 nfrags = 2; 839 } 840 while ((nfrags * fragbytes) > sp->s_allocsz) { 841 nfrags--; 842 } 843 /* if the resulting configuration is invalid, note it */ 844 if (nfrags < 2) { 845 return (EINVAL); 846 } 847 848 /* 849 * Now we need to allocate space. 850 * 851 * NB: Once the allocation succeeds, we must not fail. We are 852 * modifying the the stream settings and these changes must be 853 * made atomically. 854 */ 855 if (sp->s_cnv_max < cnv_max) { 856 uint32_t *buf0, *buf1; 857 858 buf0 = kmem_alloc(cnv_max, KM_NOSLEEP); 859 buf1 = kmem_alloc(cnv_max, KM_NOSLEEP); 860 if ((buf0 == NULL) || (buf1 == NULL)) { 861 audio_dev_warn(sp->s_client->c_dev, 862 "failed to allocate audio conversion buffer " 863 "(%u bytes)", cnv_max); 864 if (buf0) 865 kmem_free(buf0, cnv_max); 866 if (buf1) 867 kmem_free(buf1, cnv_max); 868 return (ENOMEM); 869 } 870 871 if (sp->s_cnv_buf0) 872 kmem_free(sp->s_cnv_buf0, sp->s_cnv_max); 873 if (sp->s_cnv_buf1) 874 kmem_free(sp->s_cnv_buf1, sp->s_cnv_max); 875 876 sp->s_cnv_buf0 = buf0; 877 sp->s_cnv_buf1 = buf1; 878 sp->s_cnv_max = cnv_max; 879 } 880 881 /* Set up the SRC state if we will be using SRC. */ 882 if (needsrc) { 883 setup_src(sp, source.p_rate, target.p_rate, 884 source.p_nchan, target.p_nchan); 885 } 886 887 888 sp->s_framesz = framesz; 889 sp->s_fragfr = fragfr; 890 sp->s_fragbytes = fragbytes; 891 sp->s_nfrags = nfrags; 892 sp->s_nframes = nfrags * fragfr; 893 sp->s_nbytes = sp->s_nframes * framesz; 894 *sp->s_user_parms = *uparms; 895 sp->s_converter = converter; 896 897 /* 898 * Ensure that we toss any stale data -- probably wrong format. 899 * Note that as a consequence of this, all of the offsets and 900 * counters get reset. Clients should not rely on these values 901 * being preserved when changing formats. 902 * 903 * Its critical that we reset the indices, in particular, 904 * because not only will the data be the wrong format, but the 905 * indices themselves are quite possibly going to be invalid. 906 */ 907 sp->s_cnv_cnt = 0; 908 sp->s_tail = sp->s_head = 0; 909 sp->s_tidx = sp->s_hidx = 0; 910 911 return (0); 912 } 913 914 int 915 auimpl_format_alloc(audio_stream_t *sp) 916 { 917 int i; 918 919 ASSERT(mutex_owned(&sp->s_lock)); 920 for (i = 0; i < AUDIO_MAX_CHANNELS; i++) { 921 sp->s_src_state[i] = 922 kmem_zalloc(sizeof (grc3state_t), KM_NOSLEEP); 923 if (sp->s_src_state[i] == NULL) { 924 audio_dev_warn(sp->s_client->c_dev, 925 "unable to allocate SRC state structures"); 926 return (ENOMEM); 927 } 928 } 929 return (0); 930 } 931 932 void 933 auimpl_format_free(audio_stream_t *sp) 934 { 935 int i; 936 937 for (i = 0; i < AUDIO_MAX_CHANNELS; i++) { 938 if (sp->s_src_state[i] != NULL) { 939 kmem_free(sp->s_src_state[i], sizeof (grc3state_t)); 940 sp->s_src_state[i] = NULL; 941 } 942 } 943 } 944