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