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: Virtual mixing audio output routines 29 * 30 * This file contains the actual mixing and resampling engine for output. 31 */ 32 33 #include <sys/ddi.h> 34 #include <sys/sunddi.h> 35 #include <sys/sysmacros.h> 36 #include "audio_impl.h" 37 38 #define DECL_AUDIO_EXPORT(NAME, TYPE, SAMPLE) \ 39 void \ 40 auimpl_export_##NAME(audio_engine_t *eng, uint_t nfr, uint_t froff) \ 41 { \ 42 int nch = eng->e_nchan; \ 43 uint_t hidx = eng->e_hidx; \ 44 TYPE *out = (void *)eng->e_data; \ 45 int ch = 0; \ 46 \ 47 do { /* for each channel */ \ 48 int32_t *ip; \ 49 TYPE *op; \ 50 int i; \ 51 int incr = eng->e_chincr[ch]; \ 52 \ 53 /* get value and adjust next channel offset */ \ 54 op = out + eng->e_choffs[ch] + (hidx * incr); \ 55 ip = eng->e_chbufs[ch]; \ 56 ip += froff; \ 57 \ 58 i = nfr; \ 59 \ 60 do { /* for each frame */ \ 61 int32_t sample = *ip; \ 62 \ 63 *op = SAMPLE; \ 64 op += incr; \ 65 ip++; \ 66 \ 67 } while (--i); \ 68 \ 69 ch++; \ 70 } while (ch < nch); \ 71 } 72 73 DECL_AUDIO_EXPORT(16ne, int16_t, sample >> 8) 74 DECL_AUDIO_EXPORT(16oe, int16_t, ddi_swap16(sample >> 8)) 75 DECL_AUDIO_EXPORT(32ne, int32_t, sample << 8) 76 DECL_AUDIO_EXPORT(32oe, int32_t, ddi_swap32(sample << 8)) 77 DECL_AUDIO_EXPORT(24ne, int32_t, sample) 78 DECL_AUDIO_EXPORT(24oe, int32_t, ddi_swap32(sample)) 79 80 /* 81 * Simple limiter to prevent overflows when using fixed point computations 82 */ 83 static void 84 auimpl_output_limiter(audio_engine_t *eng) 85 { 86 int k, t; 87 uint_t q, amp, amp2; 88 int nchan = eng->e_nchan; 89 uint_t fragfr = eng->e_fragfr; 90 int32_t **chbufs = eng->e_chbufs; 91 uint_t statevar = eng->e_limiter_state; 92 93 for (t = 0; t < fragfr; t++) { 94 95 amp = (uint_t)ABS(chbufs[0][t]); 96 97 for (k = 1; k < nchan; k++) { 98 amp2 = (uint_t)ABS(chbufs[k][t]); 99 if (amp2 > amp) 100 amp = amp2; 101 } 102 103 amp >>= 8; 104 q = 0x10000; 105 106 if (amp > 0x7FFF) 107 q = 0x7FFF0000 / amp; 108 109 if (statevar > q) { 110 statevar = q; 111 } else { 112 q = statevar; 113 114 /* 115 * Simplier (linear) tracking algo 116 * (gives less distortion, but more pumping) 117 */ 118 statevar += 2; 119 if (statevar > 0x10000) 120 statevar = 0x10000; 121 122 /* 123 * Classic tracking algo 124 * gives more distortion with no-lookahead 125 * statevar=0x10000-((0x10000-statevar)*0xFFF4>>16); 126 */ 127 } 128 129 for (k = 0; k < nchan; k++) { 130 int32_t in = chbufs[k][t]; 131 int32_t out = 0; 132 uint_t p; 133 134 if (in >= 0) { 135 p = in; 136 p = ((p & 0xFFFF) * (q >> 4) >> 12) + 137 (p >> 16) * q; 138 out = p; 139 } else { 140 p = -in; 141 p = ((p & 0xFFFF) * (q >> 4) >> 12) + 142 (p >> 16) * q; 143 out = -p; 144 } 145 /* safety code */ 146 /* 147 * if output after limiter is clamped, then it 148 * can be dropped 149 */ 150 if (out > 0x7FFFFF) 151 out = 0x7FFFFF; 152 else if (out < -0x7FFFFF) 153 out = -0x7FFFFF; 154 155 chbufs[k][t] = out; 156 } 157 } 158 159 eng->e_limiter_state = statevar; 160 } 161 162 /* 163 * Output mixing function. Assumption: all work is done in 24-bit native PCM. 164 */ 165 static void 166 auimpl_output_mix(audio_stream_t *sp, int offset, int nfr) 167 { 168 audio_engine_t *eng = sp->s_engine; 169 const int32_t *src; 170 int choffs; 171 int nch; 172 int vol; 173 174 /* 175 * Initial setup. 176 */ 177 178 src = sp->s_cnv_ptr; 179 choffs = sp->s_choffs; 180 nch = sp->s_cnv_dst_nchan; 181 vol = sp->s_gain_eff; 182 183 /* 184 * Do the mixing. We de-interleave the source stream at the 185 * same time. 186 */ 187 for (int ch = 0; ch < nch; ch++) { 188 int32_t *op; 189 const int32_t *ip; 190 191 192 ip = src + ch; 193 op = eng->e_chbufs[ch + choffs]; 194 op += offset; 195 196 for (int i = nfr; i; i--) { 197 198 int64_t samp; 199 200 samp = *ip; 201 samp *= vol; 202 samp /= AUDIO_VOL_SCALE; 203 204 ip += nch; 205 *op += (int32_t)samp; 206 op++; 207 } 208 } 209 210 sp->s_cnv_cnt -= nfr; 211 sp->s_cnv_ptr += (nch * nfr); 212 } 213 214 /* 215 * Consume a fragment's worth of data. This is called when the data in 216 * the conversion buffer is exhausted, and we need to refill it from the 217 * source buffer. We always consume data from the client in quantities of 218 * a fragment at a time (assuming that a fragment is available.) 219 */ 220 static void 221 auimpl_consume_fragment(audio_stream_t *sp) 222 { 223 uint_t count; 224 uint_t avail; 225 uint_t nframes; 226 uint_t fragfr; 227 uint_t framesz; 228 caddr_t cnvbuf; 229 230 sp->s_cnv_src = sp->s_cnv_buf0; 231 sp->s_cnv_dst = sp->s_cnv_buf1; 232 233 fragfr = sp->s_fragfr; 234 nframes = sp->s_nframes; 235 framesz = sp->s_framesz; 236 237 ASSERT(sp->s_head >= sp->s_tail); 238 239 avail = sp->s_head - sp->s_tail; 240 cnvbuf = sp->s_cnv_src; 241 242 count = min(avail, fragfr); 243 244 /* 245 * Copy data. We deal properly with wraps. Done as a 246 * do...while to minimize the number of tests. 247 */ 248 do { 249 uint_t n; 250 uint_t nbytes; 251 252 n = min(nframes - sp->s_tidx, count); 253 nbytes = framesz * n; 254 bcopy(sp->s_data + (sp->s_tidx * framesz), cnvbuf, nbytes); 255 cnvbuf += nbytes; 256 count -= n; 257 sp->s_samples += n; 258 sp->s_tail += n; 259 sp->s_tidx += n; 260 if (sp->s_tidx >= nframes) 261 sp->s_tidx -= nframes; 262 } while (count); 263 264 /* Note: data conversion is optional! */ 265 count = min(avail, fragfr); 266 if (sp->s_converter != NULL) { 267 sp->s_cnv_cnt = sp->s_converter(sp, count); 268 } else { 269 sp->s_cnv_cnt = count; 270 } 271 } 272 273 static void 274 auimpl_output_callback_impl(audio_engine_t *eng, audio_client_t **output, 275 audio_client_t **drain) 276 { 277 uint_t fragfr = eng->e_fragfr; 278 uint_t resid; 279 280 /* clear any preexisting mix results */ 281 for (int i = 0; i < eng->e_nchan; i++) 282 bzero(eng->e_chbufs[i], AUDIO_CHBUFS * sizeof (int32_t)); 283 284 for (audio_stream_t *sp = list_head(&eng->e_streams); 285 sp != NULL; 286 sp = list_next(&eng->e_streams, sp)) { 287 288 int need; 289 int avail; 290 int used; 291 int offset; 292 boolean_t drained = B_FALSE; 293 audio_client_t *c = sp->s_client; 294 295 /* 296 * We need/want a full fragment. If the client has 297 * less than that available, it will cause a client 298 * underrun in auimpl_consume_fragment, but in such a 299 * case we should get silence bytes. Assignments done 300 * ahead of the lock to minimize lock contention. 301 */ 302 need = fragfr; 303 offset = 0; 304 305 mutex_enter(&sp->s_lock); 306 /* skip over streams not running or paused */ 307 if ((!sp->s_running) || (sp->s_paused)) { 308 mutex_exit(&sp->s_lock); 309 continue; 310 } 311 312 do { 313 /* make sure we have data to chew on */ 314 if ((avail = sp->s_cnv_cnt) == 0) { 315 auimpl_consume_fragment(sp); 316 sp->s_cnv_ptr = sp->s_cnv_src; 317 avail = sp->s_cnv_cnt; 318 } 319 320 /* 321 * We might have got more data than we need 322 * right now. (E.g. 8kHz expanding to 48kHz.) 323 * Take only what we need. 324 */ 325 used = min(avail, need); 326 327 /* 328 * Mix the results, as much data as we can use 329 * this round. 330 */ 331 auimpl_output_mix(sp, offset, used); 332 333 /* 334 * Save the offset for the next round, so we don't 335 * remix into the same location. 336 */ 337 offset += used; 338 339 /* 340 * Okay, we mixed some data, but it might not 341 * have been all we need. This can happen 342 * either because we just mixed up some 343 * partial/residual data, or because the 344 * client has a fragment size which expands to 345 * less than a full fragment for us. (Such as 346 * a client wanting to operate at a higher 347 * data rate than the engine.) 348 */ 349 need -= used; 350 351 } while (need && avail); 352 353 if (avail == 0) { 354 /* underrun or end of data */ 355 if (sp->s_draining) { 356 if (sp->s_drain_idx == 0) { 357 sp->s_drain_idx = eng->e_head; 358 } 359 if (eng->e_tail >= sp->s_drain_idx) { 360 sp->s_drain_idx = 0; 361 sp->s_draining = B_FALSE; 362 /* 363 * After draining, stop the 364 * stream cleanly. This 365 * prevents underrun errors. 366 * 367 * (Stream will auto-start if 368 * client submits more data to 369 * it.) 370 * 371 * AC3: When an AC3 stream 372 * drains we should probably 373 * stop the actual hardware 374 * engine. 375 */ 376 ASSERT(mutex_owned(&eng->e_lock)); 377 sp->s_running = B_FALSE; 378 drained = B_TRUE; 379 } 380 } else { 381 sp->s_errors += need; 382 eng->e_stream_underruns++; 383 } 384 } 385 386 /* wake threads waiting for stream (blocking writes, etc.) */ 387 cv_broadcast(&sp->s_cv); 388 389 mutex_exit(&sp->s_lock); 390 391 392 /* 393 * Asynchronously notify clients. We do as much as 394 * possible of this outside of the lock, it avoids 395 * s_lock and c_lock contention and eliminates any 396 * chance of deadlock. 397 */ 398 399 /* 400 * NB: The only lock we are holding now is the engine 401 * lock. But the client can't go away because the 402 * closer would have to get the engine lock to remove 403 * the client's stream from engine. So we're safe. 404 */ 405 406 if (output && (c->c_output != NULL) && 407 (c->c_next_output == NULL)) { 408 auclnt_hold(c); 409 c->c_next_output = *output; 410 *output = c; 411 } 412 413 if (drain && drained && (c->c_drain != NULL) && 414 (c->c_next_drain == NULL)) { 415 auclnt_hold(c); 416 c->c_next_drain = *drain; 417 *drain = c; 418 } 419 } 420 421 /* 422 * Deal with 24-bit overflows (from mixing) gracefully. 423 */ 424 auimpl_output_limiter(eng); 425 426 /* 427 * Export the data (a whole fragment) to the device. Deal 428 * properly with wraps. Note that the test and subtraction is 429 * faster for dealing with wrap than modulo. 430 */ 431 resid = fragfr; 432 do { 433 uint_t part = min(resid, eng->e_nframes - eng->e_hidx); 434 eng->e_export(eng, part, fragfr - resid); 435 eng->e_head += part; 436 eng->e_hidx += part; 437 if (eng->e_hidx == eng->e_nframes) 438 eng->e_hidx = 0; 439 resid -= part; 440 } while (resid); 441 442 /* 443 * Consider doing the SYNC outside of the lock. 444 */ 445 ENG_SYNC(eng, fragfr); 446 } 447 448 /* 449 * Outer loop attempts to keep playing until we hit maximum playahead. 450 */ 451 452 void 453 auimpl_output_callback(void *arg) 454 { 455 audio_engine_t *e = arg; 456 int64_t cnt; 457 audio_client_t *c; 458 audio_client_t *output = NULL; 459 audio_client_t *drain = NULL; 460 uint64_t t; 461 462 mutex_enter(&e->e_lock); 463 464 if (e->e_suspended || e->e_failed || !e->e_periodic) { 465 mutex_exit(&e->e_lock); 466 return; 467 } 468 469 if (e->e_need_start) { 470 int rv; 471 if ((rv = ENG_START(e)) != 0) { 472 e->e_failed = B_TRUE; 473 mutex_exit(&e->e_lock); 474 audio_dev_warn(e->e_dev, 475 "failed starting output, rv = %d", rv); 476 return; 477 } 478 e->e_need_start = B_FALSE; 479 } 480 481 t = ENG_COUNT(e); 482 if (t < e->e_tail) { 483 /* 484 * This is a sign of a serious bug. We should 485 * probably offline the device via FMA, if we ever 486 * support FMA for audio devices. 487 */ 488 e->e_failed = B_TRUE; 489 ENG_STOP(e); 490 mutex_exit(&e->e_lock); 491 audio_dev_warn(e->e_dev, 492 "device malfunction: broken play back sample counter"); 493 return; 494 495 } 496 e->e_tail = t; 497 498 if (e->e_tail > e->e_head) { 499 /* want more than we have */ 500 e->e_errors++; 501 e->e_underruns++; 502 } 503 504 cnt = e->e_head - e->e_tail; 505 506 /* stay a bit ahead */ 507 while (cnt < e->e_playahead) { 508 auimpl_output_callback_impl(e, &output, &drain); 509 cnt = e->e_head - e->e_tail; 510 } 511 mutex_exit(&e->e_lock); 512 513 /* 514 * Notify client personalities. 515 */ 516 while ((c = output) != NULL) { 517 518 output = c->c_next_output; 519 c->c_next_output = NULL; 520 c->c_output(c); 521 auclnt_release(c); 522 } 523 524 while ((c = drain) != NULL) { 525 526 drain = c->c_next_drain; 527 c->c_next_drain = NULL; 528 c->c_drain(c); 529 auclnt_release(c); 530 } 531 532 } 533 534 void 535 auimpl_output_preload(audio_engine_t *e) 536 { 537 int64_t cnt; 538 539 ASSERT(mutex_owned(&e->e_lock)); 540 541 if (e->e_tail > e->e_head) { 542 /* want more than we have */ 543 e->e_errors++; 544 e->e_underruns++; 545 e->e_tail = e->e_head; 546 } 547 cnt = e->e_head - e->e_tail; 548 549 /* stay a bit ahead */ 550 while (cnt < e->e_playahead) { 551 auimpl_output_callback_impl(e, NULL, NULL); 552 cnt = e->e_head - e->e_tail; 553 } 554 } 555