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