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 #define DECL_AUDIO_EXPORT(NAME, TYPE, SAMPLE) \ 40 void \ 41 auimpl_export_##NAME(audio_engine_t *eng) \ 42 { \ 43 int fragfr = eng->e_fragfr; \ 44 int nch = eng->e_nchan; \ 45 unsigned hidx = eng->e_hidx; \ 46 TYPE *out = (void *)eng->e_data; \ 47 int ch = 0; \ 48 \ 49 do { /* for each channel */ \ 50 int32_t *ip; \ 51 TYPE *op; \ 52 int i; \ 53 int incr = eng->e_chincr[ch]; \ 54 \ 55 /* get value and adjust next channel offset */ \ 56 op = out + eng->e_choffs[ch] + (hidx * incr); \ 57 ip = eng->e_chbufs[ch]; \ 58 \ 59 i = fragfr; \ 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 unsigned int q, amp, amp2; 89 int nchan = eng->e_nchan; 90 int fragfr = eng->e_fragfr; 91 int32_t **chbufs = eng->e_chbufs; 92 unsigned int statevar = eng->e_limiter_state; 93 94 for (t = 0; t < fragfr; t++) { 95 96 amp = (unsigned)ABS(chbufs[0][t]); 97 98 for (k = 1; k < nchan; k++) { 99 amp2 = (unsigned)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 unsigned int 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 unsigned count; 225 unsigned avail; 226 unsigned nframes; 227 unsigned fragfr; 228 unsigned 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 unsigned n; 251 unsigned 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) 276 { 277 int fragfr = eng->e_fragfr; 278 279 /* clear any preexisting mix results */ 280 for (int i = 0; i < eng->e_nchan; i++) 281 bzero(eng->e_chbufs[i], AUDIO_CHBUFS * sizeof (int32_t)); 282 283 for (audio_stream_t *sp = list_head(&eng->e_streams); 284 sp != NULL; 285 sp = list_next(&eng->e_streams, sp)) { 286 287 int need; 288 int avail; 289 int used; 290 int offset; 291 boolean_t drained = B_FALSE; 292 audio_client_t *c = sp->s_client; 293 294 /* 295 * We need/want a full fragment. If the client has 296 * less than that available, it will cause a client 297 * underrun in auimpl_consume_fragment, but in such a 298 * case we should get silence bytes. Assignments done 299 * ahead of the lock to minimize lock contention. 300 */ 301 need = fragfr; 302 offset = 0; 303 304 mutex_enter(&sp->s_lock); 305 /* skip over streams not running or paused */ 306 if ((!sp->s_running) || (sp->s_paused) || eng->e_suspended) { 307 mutex_exit(&sp->s_lock); 308 continue; 309 } 310 311 do { 312 /* make sure we have data to chew on */ 313 if ((avail = sp->s_cnv_cnt) == 0) { 314 auimpl_consume_fragment(sp); 315 sp->s_cnv_ptr = sp->s_cnv_src; 316 avail = sp->s_cnv_cnt; 317 } 318 319 /* 320 * We might have got more data than we need 321 * right now. (E.g. 8kHz expanding to 48kHz.) 322 * Take only what we need. 323 */ 324 used = min(avail, need); 325 326 /* 327 * Mix the results, as much data as we can use 328 * this round. 329 */ 330 auimpl_output_mix(sp, offset, used); 331 332 /* 333 * Save the offset for the next round, so we don't 334 * remix into the same location. 335 */ 336 offset += used; 337 338 /* 339 * Okay, we mixed some data, but it might not 340 * have been all we need. This can happen 341 * either because we just mixed up some 342 * partial/residual data, or because the 343 * client has a fragment size which expands to 344 * less than a full fragment for us. (Such as 345 * a client wanting to operate at a higher 346 * data rate than the engine.) 347 */ 348 need -= used; 349 350 } while (need && avail); 351 352 if (avail == 0) { 353 /* underrun or end of data */ 354 if (sp->s_draining) { 355 if (sp->s_drain_idx == 0) { 356 sp->s_drain_idx = eng->e_head; 357 } 358 if (eng->e_tail >= sp->s_drain_idx) { 359 sp->s_drain_idx = 0; 360 sp->s_draining = B_FALSE; 361 /* 362 * After draining, stop the 363 * stream cleanly. This 364 * prevents underrun errors. 365 * 366 * (Stream will auto-start if 367 * client submits more data to 368 * it.) 369 * 370 * AC3: When an AC3 stream 371 * drains we should probably 372 * stop the actual hardware 373 * engine. 374 */ 375 ASSERT(mutex_owned(&eng->e_lock)); 376 sp->s_running = B_FALSE; 377 drained = B_TRUE; 378 } 379 } else { 380 sp->s_errors += need; 381 eng->e_stream_underruns++; 382 } 383 } 384 385 /* wake threads waiting for stream (blocking writes, etc.) */ 386 cv_broadcast(&sp->s_cv); 387 388 mutex_exit(&sp->s_lock); 389 390 391 /* 392 * Asynchronously notify clients. We do as much as 393 * possible of this outside of the lock, it avoids 394 * s_lock and c_lock contention and eliminates any 395 * chance of deadlock. 396 */ 397 398 /* 399 * NB: The only lock we are holding now is the engine 400 * lock. But the client can't go away because the 401 * closer would have to get the engine lock to remove 402 * the client's stream from engine. So we're safe. 403 */ 404 405 if (c->c_output != NULL) { 406 c->c_output(c); 407 } 408 409 if (drained && (c->c_drain != NULL)) { 410 c->c_drain(c); 411 } 412 } 413 414 /* 415 * Deal with 24-bit overflows (from mixing) gracefully. 416 */ 417 auimpl_output_limiter(eng); 418 419 /* 420 * Export the data (a whole fragment) to the device. 421 */ 422 eng->e_export(eng); 423 424 /* 425 * Update the head and offset. The head counts without 426 * wrapping, whereas the offset wraps. Note that the test + 427 * subtraction is faster for dealing with wrap than modulo. 428 */ 429 eng->e_head += fragfr; 430 eng->e_hidx += fragfr; 431 if (eng->e_hidx >= eng->e_nframes) 432 eng->e_hidx -= eng->e_nframes; 433 434 /* 435 * Consider doing the SYNC outside of the lock. 436 */ 437 ENG_SYNC(eng, fragfr); 438 } 439 440 /* 441 * Outer loop attempts to keep playing until we hit maximum playahead. 442 */ 443 444 void 445 auimpl_output_callback(audio_engine_t *eng) 446 { 447 unsigned fragfr; 448 int64_t cnt; 449 450 fragfr = eng->e_fragfr; 451 cnt = eng->e_head - eng->e_tail; 452 453 /* stay a bit ahead */ 454 while (cnt < ((fragfr * 3) / 2)) { 455 auimpl_output_callback_impl(eng); 456 cnt = eng->e_head - eng->e_tail; 457 } 458 } 459