1 /* $OpenBSD: dsp.c,v 1.9 2016/06/10 06:42:22 ratchov Exp $ */ 2 /* 3 * Copyright (c) 2008-2012 Alexandre Ratchov <alex@caoua.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 #include <string.h> 18 #include "dsp.h" 19 #include "utils.h" 20 21 int aparams_ctltovol[128] = { 22 0, 23 256, 266, 276, 287, 299, 310, 323, 335, 24 348, 362, 376, 391, 406, 422, 439, 456, 25 474, 493, 512, 532, 553, 575, 597, 621, 26 645, 670, 697, 724, 753, 782, 813, 845, 27 878, 912, 948, 985, 1024, 1064, 1106, 1149, 28 1195, 1241, 1290, 1341, 1393, 1448, 1505, 1564, 29 1625, 1689, 1756, 1825, 1896, 1971, 2048, 2128, 30 2212, 2299, 2389, 2483, 2580, 2682, 2787, 2896, 31 3010, 3128, 3251, 3379, 3511, 3649, 3792, 3941, 32 4096, 4257, 4424, 4598, 4778, 4966, 5161, 5363, 33 5574, 5793, 6020, 6256, 6502, 6757, 7023, 7298, 34 7585, 7883, 8192, 8514, 8848, 9195, 9556, 9931, 35 10321, 10726, 11148, 11585, 12040, 12513, 13004, 13515, 36 14045, 14596, 15170, 15765, 16384, 17027, 17696, 18390, 37 19112, 19863, 20643, 21453, 22295, 23170, 24080, 25025, 38 26008, 27029, 28090, 29193, 30339, 31530, 32768 39 }; 40 41 short dec_ulawmap[256] = { 42 -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956, 43 -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764, 44 -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412, 45 -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316, 46 -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140, 47 -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092, 48 -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004, 49 -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980, 50 -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436, 51 -1372, -1308, -1244, -1180, -1116, -1052, -988, -924, 52 -876, -844, -812, -780, -748, -716, -684, -652, 53 -620, -588, -556, -524, -492, -460, -428, -396, 54 -372, -356, -340, -324, -308, -292, -276, -260, 55 -244, -228, -212, -196, -180, -164, -148, -132, 56 -120, -112, -104, -96, -88, -80, -72, -64, 57 -56, -48, -40, -32, -24, -16, -8, 0, 58 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956, 59 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764, 60 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412, 61 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316, 62 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140, 63 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092, 64 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004, 65 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980, 66 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436, 67 1372, 1308, 1244, 1180, 1116, 1052, 988, 924, 68 876, 844, 812, 780, 748, 716, 684, 652, 69 620, 588, 556, 524, 492, 460, 428, 396, 70 372, 356, 340, 324, 308, 292, 276, 260, 71 244, 228, 212, 196, 180, 164, 148, 132, 72 120, 112, 104, 96, 88, 80, 72, 64, 73 56, 48, 40, 32, 24, 16, 8, 0 74 }; 75 76 short dec_alawmap[256] = { 77 -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736, 78 -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784, 79 -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368, 80 -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392, 81 -22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944, 82 -30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136, 83 -11008, -10496, -12032, -11520, -8960, -8448, -9984, -9472, 84 -15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568, 85 -344, -328, -376, -360, -280, -264, -312, -296, 86 -472, -456, -504, -488, -408, -392, -440, -424, 87 -88, -72, -120, -104, -24, -8, -56, -40, 88 -216, -200, -248, -232, -152, -136, -184, -168, 89 -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184, 90 -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696, 91 -688, -656, -752, -720, -560, -528, -624, -592, 92 -944, -912, -1008, -976, -816, -784, -880, -848, 93 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736, 94 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784, 95 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368, 96 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392, 97 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944, 98 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136, 99 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472, 100 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568, 101 344, 328, 376, 360, 280, 264, 312, 296, 102 472, 456, 504, 488, 408, 392, 440, 424, 103 88, 72, 120, 104, 24, 8, 56, 40, 104 216, 200, 248, 232, 152, 136, 184, 168, 105 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184, 106 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696, 107 688, 656, 752, 720, 560, 528, 624, 592, 108 944, 912, 1008, 976, 816, 784, 880, 848 109 }; 110 111 /* 112 * Generate a string corresponding to the encoding in par, 113 * return the length of the resulting string. 114 */ 115 int 116 aparams_enctostr(struct aparams *par, char *ostr) 117 { 118 char *p = ostr; 119 120 *p++ = par->sig ? 's' : 'u'; 121 if (par->bits > 9) 122 *p++ = '0' + par->bits / 10; 123 *p++ = '0' + par->bits % 10; 124 if (par->bps > 1) { 125 *p++ = par->le ? 'l' : 'b'; 126 *p++ = 'e'; 127 if (par->bps != APARAMS_BPS(par->bits) || 128 par->bits < par->bps * 8) { 129 *p++ = par->bps + '0'; 130 if (par->bits < par->bps * 8) { 131 *p++ = par->msb ? 'm' : 'l'; 132 *p++ = 's'; 133 *p++ = 'b'; 134 } 135 } 136 } 137 *p++ = '\0'; 138 return p - ostr - 1; 139 } 140 141 /* 142 * Parse an encoding string, examples: s8, u8, s16, s16le, s24be ... 143 * set *istr to the char following the encoding. Return the number 144 * of bytes consumed. 145 */ 146 int 147 aparams_strtoenc(struct aparams *par, char *istr) 148 { 149 char *p = istr; 150 int i, sig, bits, le, bps, msb; 151 152 #define IS_SEP(c) \ 153 (((c) < 'a' || (c) > 'z') && \ 154 ((c) < 'A' || (c) > 'Z') && \ 155 ((c) < '0' || (c) > '9')) 156 157 /* 158 * get signedness 159 */ 160 if (*p == 's') { 161 sig = 1; 162 } else if (*p == 'u') { 163 sig = 0; 164 } else 165 return 0; 166 p++; 167 168 /* 169 * get number of bits per sample 170 */ 171 bits = 0; 172 for (i = 0; i < 2; i++) { 173 if (*p < '0' || *p > '9') 174 break; 175 bits = (bits * 10) + *p - '0'; 176 p++; 177 } 178 if (bits < BITS_MIN || bits > BITS_MAX) 179 return 0; 180 bps = APARAMS_BPS(bits); 181 msb = 1; 182 le = ADATA_LE; 183 184 /* 185 * get (optional) endianness 186 */ 187 if (p[0] == 'l' && p[1] == 'e') { 188 le = 1; 189 p += 2; 190 } else if (p[0] == 'b' && p[1] == 'e') { 191 le = 0; 192 p += 2; 193 } else if (IS_SEP(*p)) { 194 goto done; 195 } else 196 return 0; 197 198 /* 199 * get (optional) number of bytes 200 */ 201 if (*p >= '0' && *p <= '9') { 202 bps = *p - '0'; 203 if (bps < (bits + 7) / 8 || 204 bps > (BITS_MAX + 7) / 8) 205 return 0; 206 p++; 207 208 /* 209 * get (optional) alignment 210 */ 211 if (p[0] == 'm' && p[1] == 's' && p[2] == 'b') { 212 msb = 1; 213 p += 3; 214 } else if (p[0] == 'l' && p[1] == 's' && p[2] == 'b') { 215 msb = 0; 216 p += 3; 217 } else if (IS_SEP(*p)) { 218 goto done; 219 } else 220 return 0; 221 } else if (!IS_SEP(*p)) 222 return 0; 223 224 done: 225 par->msb = msb; 226 par->sig = sig; 227 par->bits = bits; 228 par->bps = bps; 229 par->le = le; 230 return p - istr; 231 } 232 233 /* 234 * Initialise parameters structure with the defaults natively supported 235 * by the machine. 236 */ 237 void 238 aparams_init(struct aparams *par) 239 { 240 par->bps = sizeof(adata_t); 241 par->bits = ADATA_BITS; 242 par->le = ADATA_LE; 243 par->sig = 1; 244 par->msb = 0; 245 } 246 247 /* 248 * log the given format/channels/encoding 249 */ 250 void 251 aparams_log(struct aparams *par) 252 { 253 char enc[ENCMAX]; 254 255 aparams_enctostr(par, enc); 256 log_puts(enc); 257 } 258 259 /* 260 * return true if encoding corresponds to what we store in adata_t 261 */ 262 int 263 aparams_native(struct aparams *par) 264 { 265 return par->bps == sizeof(adata_t) && par->bits == ADATA_BITS && 266 (par->bps == 1 || par->le == ADATA_LE) && 267 (par->bits == par->bps * 8 || !par->msb); 268 } 269 270 /* 271 * Return the number of input and output frame that would be consumed 272 * by resamp_do(p, *icnt, *ocnt). 273 */ 274 void 275 resamp_getcnt(struct resamp *p, int *icnt, int *ocnt) 276 { 277 long long idiff, odiff; 278 int cdiff; 279 280 cdiff = p->oblksz - p->diff; 281 idiff = (long long)*icnt * p->oblksz; 282 odiff = (long long)*ocnt * p->iblksz; 283 if (odiff - idiff >= cdiff) 284 *ocnt = (idiff + cdiff + p->iblksz - 1) / p->iblksz; 285 else 286 *icnt = (odiff + p->diff) / p->oblksz; 287 } 288 289 /* 290 * Resample the given number of frames. The number of output frames 291 * must match the coresponding number the input frames. Either always 292 * use icnt and ocnt such that: 293 * 294 * icnt * oblksz = ocnt * iblksz 295 * 296 * or use resamp_getcnt() to calculate the proper numbers. 297 */ 298 void 299 resamp_do(struct resamp *p, adata_t *in, adata_t *out, int icnt, int ocnt) 300 { 301 unsigned int nch; 302 adata_t *idata; 303 unsigned int oblksz; 304 unsigned int ifr; 305 int s, ds, diff; 306 adata_t *odata; 307 unsigned int iblksz; 308 unsigned int ofr; 309 unsigned int c; 310 adata_t *ctxbuf, *ctx; 311 unsigned int ctx_start; 312 313 /* 314 * Partially copy structures into local variables, to avoid 315 * unnecessary indirections; this also allows the compiler to 316 * order local variables more "cache-friendly". 317 */ 318 idata = in; 319 odata = out; 320 diff = p->diff; 321 iblksz = p->iblksz; 322 oblksz = p->oblksz; 323 ctxbuf = p->ctx; 324 ctx_start = p->ctx_start; 325 nch = p->nch; 326 ifr = icnt; 327 ofr = ocnt; 328 329 /* 330 * Start conversion. 331 */ 332 #ifdef DEBUG 333 if (log_level >= 4) { 334 log_puts("resamp: copying "); 335 log_puti(ifr); 336 log_puts(" -> "); 337 log_putu(ofr); 338 log_puts(" frames, diff = "); 339 log_puti(diff); 340 log_puts("\n"); 341 } 342 #endif 343 for (;;) { 344 if (diff >= oblksz) { 345 if (ifr == 0) 346 break; 347 ctx_start ^= 1; 348 ctx = ctxbuf + ctx_start; 349 for (c = nch; c > 0; c--) { 350 *ctx = *idata++; 351 ctx += RESAMP_NCTX; 352 } 353 diff -= oblksz; 354 ifr--; 355 } else { 356 if (ofr == 0) 357 break; 358 ctx = ctxbuf; 359 for (c = nch; c > 0; c--) { 360 s = ctx[ctx_start ^ 1]; 361 ds = ctx[ctx_start] - s; 362 ctx += RESAMP_NCTX; 363 *odata++ = s + ADATA_MULDIV(ds, diff, oblksz); 364 } 365 diff += iblksz; 366 ofr--; 367 } 368 } 369 p->diff = diff; 370 p->ctx_start = ctx_start; 371 #ifdef DEBUG 372 if (ifr != 0) { 373 log_puts("resamp_do: "); 374 log_puti(ifr); 375 log_puts(": too many input frames\n"); 376 panic(); 377 } 378 if (ofr != 0) { 379 log_puts("resamp_do: "); 380 log_puti(ofr); 381 log_puts(": too many output frames\n"); 382 panic(); 383 } 384 #endif 385 } 386 387 static unsigned int 388 uint_gcd(unsigned int a, unsigned int b) 389 { 390 unsigned int r; 391 392 while (b > 0) { 393 r = a % b; 394 a = b; 395 b = r; 396 } 397 return a; 398 } 399 400 /* 401 * initialize resampler with ibufsz/obufsz factor and "nch" channels 402 */ 403 void 404 resamp_init(struct resamp *p, unsigned int iblksz, 405 unsigned int oblksz, int nch) 406 { 407 unsigned int i, g; 408 409 /* 410 * reduice iblksz/oblksz fraction 411 */ 412 g = uint_gcd(iblksz, oblksz); 413 iblksz /= g; 414 oblksz /= g; 415 416 /* 417 * ensure weired rates dont cause integer overflows 418 */ 419 while (iblksz > ADATA_UNIT || oblksz > ADATA_UNIT) { 420 iblksz >>= 1; 421 oblksz >>= 1; 422 } 423 424 p->iblksz = iblksz; 425 p->oblksz = oblksz; 426 p->diff = 0; 427 p->nch = nch; 428 p->ctx_start = 0; 429 for (i = 0; i < NCHAN_MAX * RESAMP_NCTX; i++) 430 p->ctx[i] = 0; 431 #ifdef DEBUG 432 if (log_level >= 3) { 433 log_puts("resamp: "); 434 log_putu(iblksz); 435 log_puts("/"); 436 log_putu(oblksz); 437 log_puts("\n"); 438 } 439 #endif 440 } 441 442 /* 443 * encode "todo" frames from native to foreign encoding 444 */ 445 void 446 enc_do(struct conv *p, unsigned char *in, unsigned char *out, int todo) 447 { 448 unsigned int f; 449 adata_t *idata; 450 unsigned int s; 451 unsigned int oshift; 452 unsigned int obias; 453 unsigned int obps; 454 unsigned int i; 455 unsigned char *odata; 456 int obnext; 457 int osnext; 458 459 #ifdef DEBUG 460 if (log_level >= 4) { 461 log_puts("enc: copying "); 462 log_putu(todo); 463 log_puts(" frames\n"); 464 } 465 #endif 466 /* 467 * Partially copy structures into local variables, to avoid 468 * unnecessary indirections; this also allows the compiler to 469 * order local variables more "cache-friendly". 470 */ 471 idata = (adata_t *)in; 472 odata = out; 473 oshift = p->shift; 474 obias = p->bias; 475 obps = p->bps; 476 obnext = p->bnext; 477 osnext = p->snext; 478 479 /* 480 * Start conversion. 481 */ 482 odata += p->bfirst; 483 for (f = todo * p->nch; f > 0; f--) { 484 /* convert adata to u32 */ 485 s = (int)*idata++ + ADATA_UNIT; 486 s <<= 32 - ADATA_BITS; 487 /* convert u32 to uN */ 488 s >>= oshift; 489 /* convert uN to sN */ 490 s -= obias; 491 /* packetize sN */ 492 for (i = obps; i > 0; i--) { 493 *odata = (unsigned char)s; 494 s >>= 8; 495 odata += obnext; 496 } 497 odata += osnext; 498 } 499 } 500 501 /* 502 * store "todo" frames of silence in foreign encoding 503 */ 504 void 505 enc_sil_do(struct conv *p, unsigned char *out, int todo) 506 { 507 unsigned int f; 508 unsigned int s; 509 unsigned int oshift; 510 int obias; 511 unsigned int obps; 512 unsigned int i; 513 unsigned char *odata; 514 int obnext; 515 int osnext; 516 517 #ifdef DEBUG 518 if (log_level >= 4) { 519 log_puts("enc: silence "); 520 log_putu(todo); 521 log_puts(" frames\n"); 522 } 523 #endif 524 /* 525 * Partially copy structures into local variables, to avoid 526 * unnecessary indirections; this also allows the compiler to 527 * order local variables more "cache-friendly". 528 */ 529 odata = out; 530 oshift = p->shift; 531 obias = p->bias; 532 obps = p->bps; 533 obnext = p->bnext; 534 osnext = p->snext; 535 536 /* 537 * Start conversion. 538 */ 539 odata += p->bfirst; 540 for (f = todo * p->nch; f > 0; f--) { 541 s = ((1U << 31) >> oshift) - obias; 542 for (i = obps; i > 0; i--) { 543 *odata = (unsigned char)s; 544 s >>= 8; 545 odata += obnext; 546 } 547 odata += osnext; 548 } 549 } 550 551 /* 552 * initialize encoder from native to foreign encoding 553 */ 554 void 555 enc_init(struct conv *p, struct aparams *par, int nch) 556 { 557 p->nch = nch; 558 p->bps = par->bps; 559 if (par->msb) { 560 p->shift = 32 - par->bps * 8; 561 } else { 562 p->shift = 32 - par->bits; 563 } 564 if (par->sig) { 565 p->bias = (1U << 31) >> p->shift; 566 } else { 567 p->bias = 0; 568 } 569 if (!par->le) { 570 p->bfirst = par->bps - 1; 571 p->bnext = -1; 572 p->snext = 2 * par->bps; 573 } else { 574 p->bfirst = 0; 575 p->bnext = 1; 576 p->snext = 0; 577 } 578 #ifdef DEBUG 579 if (log_level >= 3) { 580 log_puts("enc: "); 581 aparams_log(par); 582 log_puts(", "); 583 log_puti(p->nch); 584 log_puts(" channels\n"); 585 } 586 #endif 587 } 588 589 /* 590 * decode "todo" frames from from foreign to native encoding 591 */ 592 void 593 dec_do(struct conv *p, unsigned char *in, unsigned char *out, int todo) 594 { 595 unsigned int f; 596 unsigned int ibps; 597 unsigned int i; 598 unsigned int s = 0xdeadbeef; 599 unsigned char *idata; 600 int ibnext; 601 int isnext; 602 unsigned int ibias; 603 unsigned int ishift; 604 adata_t *odata; 605 606 #ifdef DEBUG 607 if (log_level >= 4) { 608 log_puts("dec: copying "); 609 log_putu(todo); 610 log_puts(" frames\n"); 611 } 612 #endif 613 /* 614 * Partially copy structures into local variables, to avoid 615 * unnecessary indirections; this also allows the compiler to 616 * order local variables more "cache-friendly". 617 */ 618 idata = in; 619 odata = (adata_t *)out; 620 ibps = p->bps; 621 ibnext = p->bnext; 622 ibias = p->bias; 623 ishift = p->shift; 624 isnext = p->snext; 625 626 /* 627 * Start conversion. 628 */ 629 idata += p->bfirst; 630 for (f = todo * p->nch; f > 0; f--) { 631 for (i = ibps; i > 0; i--) { 632 s <<= 8; 633 s |= *idata; 634 idata += ibnext; 635 } 636 idata += isnext; 637 s += ibias; 638 s <<= ishift; 639 s >>= 32 - ADATA_BITS; 640 *odata++ = s - ADATA_UNIT; 641 } 642 } 643 644 /* 645 * convert a 32-bit float to adata_t, clipping to -1:1, boundaries 646 * excluded 647 */ 648 static inline int 649 f32_to_adata(unsigned int x) 650 { 651 unsigned int s, e, m, y; 652 653 s = (x >> 31); 654 e = (x >> 23) & 0xff; 655 m = (x << 8) | 0x80000000; 656 657 /* 658 * f32 exponent is (e - 127) and the point is after the 31-th 659 * bit, thus the shift is: 660 * 661 * 31 - (BITS - 1) - (e - 127) 662 * 663 * to ensure output is in the 0..(2^BITS)-1 range, the minimum 664 * shift is 31 - (BITS - 1), and maximum shift is 31 665 */ 666 if (e < 127 - (ADATA_BITS - 1)) 667 y = 0; 668 else if (e > 127) 669 y = ADATA_UNIT - 1; 670 else 671 y = m >> (127 + (32 - ADATA_BITS) - e); 672 return (y ^ -s) + s; 673 } 674 675 /* 676 * convert samples from little endian ieee 754 floats to adata_t 677 */ 678 void 679 dec_do_float(struct conv *p, unsigned char *in, unsigned char *out, int todo) 680 { 681 unsigned int f; 682 unsigned int i; 683 unsigned int s = 0xdeadbeef; 684 unsigned char *idata; 685 int ibnext; 686 int isnext; 687 adata_t *odata; 688 689 #ifdef DEBUG 690 if (log_level >= 4) { 691 log_puts("dec_float: copying "); 692 log_putu(todo); 693 log_puts(" frames\n"); 694 } 695 #endif 696 /* 697 * Partially copy structures into local variables, to avoid 698 * unnecessary indirections; this also allows the compiler to 699 * order local variables more "cache-friendly". 700 */ 701 idata = in; 702 odata = (adata_t *)out; 703 ibnext = p->bnext; 704 isnext = p->snext; 705 706 /* 707 * Start conversion. 708 */ 709 idata += p->bfirst; 710 for (f = todo * p->nch; f > 0; f--) { 711 for (i = 4; i > 0; i--) { 712 s <<= 8; 713 s |= *idata; 714 idata += ibnext; 715 } 716 idata += isnext; 717 *odata++ = f32_to_adata(s); 718 } 719 } 720 721 /* 722 * convert samples from ulaw/alaw to adata_t 723 */ 724 void 725 dec_do_ulaw(struct conv *p, unsigned char *in, 726 unsigned char *out, int todo, int is_alaw) 727 { 728 unsigned int f; 729 unsigned char *idata; 730 adata_t *odata; 731 short *map; 732 733 #ifdef DEBUG 734 if (log_level >= 4) { 735 log_puts("dec_ulaw: copying "); 736 log_putu(todo); 737 log_puts(" frames\n"); 738 } 739 #endif 740 map = is_alaw ? dec_alawmap : dec_ulawmap; 741 idata = in; 742 odata = (adata_t *)out; 743 for (f = todo * p->nch; f > 0; f--) 744 *odata++ = map[*idata++] << (ADATA_BITS - 16); 745 } 746 747 /* 748 * initialize decoder from foreign to native encoding 749 */ 750 void 751 dec_init(struct conv *p, struct aparams *par, int nch) 752 { 753 p->bps = par->bps; 754 p->nch = nch; 755 if (par->msb) { 756 p->shift = 32 - par->bps * 8; 757 } else { 758 p->shift = 32 - par->bits; 759 } 760 if (par->sig) { 761 p->bias = (1U << 31) >> p->shift; 762 } else { 763 p->bias = 0; 764 } 765 if (par->le) { 766 p->bfirst = par->bps - 1; 767 p->bnext = -1; 768 p->snext = 2 * par->bps; 769 } else { 770 p->bfirst = 0; 771 p->bnext = 1; 772 p->snext = 0; 773 } 774 #ifdef DEBUG 775 if (log_level >= 3) { 776 log_puts("dec: "); 777 aparams_log(par); 778 log_puts(", "); 779 log_puti(p->nch); 780 log_puts(" channels\n"); 781 } 782 #endif 783 } 784 785 /* 786 * mix "todo" input frames on the output with the given volume 787 */ 788 void 789 cmap_add(struct cmap *p, void *in, void *out, int vol, int todo) 790 { 791 adata_t *idata, *odata; 792 int i, j, nch, istart, inext, onext, ostart, y, v; 793 794 #ifdef DEBUG 795 if (log_level >= 4) { 796 log_puts("cmap: adding "); 797 log_puti(todo); 798 log_puts(" frames\n"); 799 } 800 #endif 801 idata = in; 802 odata = out; 803 ostart = p->ostart; 804 onext = p->onext; 805 istart = p->istart; 806 inext = p->inext; 807 nch = p->nch; 808 v = vol; 809 810 /* 811 * map/mix input on the output 812 */ 813 for (i = todo; i > 0; i--) { 814 odata += ostart; 815 idata += istart; 816 for (j = nch; j > 0; j--) { 817 y = *odata + ADATA_MUL(*idata, v); 818 if (y >= ADATA_UNIT) 819 y = ADATA_UNIT - 1; 820 else if (y < -ADATA_UNIT) 821 y = -ADATA_UNIT; 822 *odata = y; 823 idata++; 824 odata++; 825 } 826 odata += onext; 827 idata += inext; 828 } 829 } 830 831 /* 832 * overwrite output with "todo" input frames with with the given volume 833 */ 834 void 835 cmap_copy(struct cmap *p, void *in, void *out, int vol, int todo) 836 { 837 adata_t *idata, *odata; 838 int i, j, nch, istart, inext, onext, ostart, v; 839 840 #ifdef DEBUG 841 if (log_level >= 4) { 842 log_puts("cmap: copying "); 843 log_puti(todo); 844 log_puts(" frames\n"); 845 } 846 #endif 847 idata = in; 848 odata = out; 849 ostart = p->ostart; 850 onext = p->onext; 851 istart = p->istart; 852 inext = p->inext; 853 nch = p->nch; 854 v = vol; 855 856 /* 857 * copy to the output buffer 858 */ 859 for (i = todo; i > 0; i--) { 860 idata += istart; 861 odata += ostart; 862 for (j = nch; j > 0; j--) { 863 *odata = ADATA_MUL(*idata, v); 864 odata++; 865 idata++; 866 } 867 odata += onext; 868 idata += inext; 869 } 870 } 871 872 /* 873 * initialize channel mapper, to map a subset of input channel range 874 * into a subset of the output channel range 875 */ 876 void 877 cmap_init(struct cmap *p, 878 int imin, int imax, int isubmin, int isubmax, 879 int omin, int omax, int osubmin, int osubmax) 880 { 881 int cmin, cmax; 882 883 cmin = -NCHAN_MAX; 884 if (osubmin > cmin) 885 cmin = osubmin; 886 if (omin > cmin) 887 cmin = omin; 888 if (isubmin > cmin) 889 cmin = isubmin; 890 if (imin > cmin) 891 cmin = imin; 892 893 cmax = NCHAN_MAX; 894 if (osubmax < cmax) 895 cmax = osubmax; 896 if (omax < cmax) 897 cmax = omax; 898 if (isubmax < cmax) 899 cmax = isubmax; 900 if (imax < cmax) 901 cmax = imax; 902 903 p->ostart = cmin - omin; 904 p->onext = omax - cmax; 905 p->istart = cmin - imin; 906 p->inext = imax - cmax; 907 p->nch = cmax - cmin + 1; 908 #ifdef DEBUG 909 if (log_level >= 3) { 910 log_puts("cmap: nch = "); 911 log_puti(p->nch); 912 log_puts(", ostart = "); 913 log_puti(p->ostart); 914 log_puts(", onext = "); 915 log_puti(p->onext); 916 log_puts(", istart = "); 917 log_puti(p->istart); 918 log_puts(", inext = "); 919 log_puti(p->inext); 920 log_puts("\n"); 921 } 922 #endif 923 } 924