1 /* $OpenBSD: dsp.c,v 1.14 2020/12/10 17:20:39 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->sig && 266 par->bps == sizeof(adata_t) && 267 par->bits == ADATA_BITS && 268 (par->bps == 1 || par->le == ADATA_LE) && 269 (par->bits == par->bps * 8 || !par->msb); 270 } 271 272 /* 273 * Return the number of input and output frame that would be consumed 274 * by resamp_do(p, *icnt, *ocnt). 275 */ 276 void 277 resamp_getcnt(struct resamp *p, int *icnt, int *ocnt) 278 { 279 long long idiff, odiff; 280 int cdiff; 281 282 cdiff = p->oblksz - p->diff; 283 idiff = (long long)*icnt * p->oblksz; 284 odiff = (long long)*ocnt * p->iblksz; 285 if (odiff - idiff >= cdiff) 286 *ocnt = (idiff + cdiff + p->iblksz - 1) / p->iblksz; 287 else 288 *icnt = (odiff + p->diff) / p->oblksz; 289 } 290 291 /* 292 * Resample the given number of frames. The number of output frames 293 * must match the coresponding number of input frames. Either always 294 * use icnt and ocnt such that: 295 * 296 * icnt * oblksz = ocnt * iblksz 297 * 298 * or use resamp_getcnt() to calculate the proper numbers. 299 */ 300 void 301 resamp_do(struct resamp *p, adata_t *in, adata_t *out, int icnt, int ocnt) 302 { 303 unsigned int nch; 304 adata_t *idata; 305 unsigned int oblksz; 306 unsigned int ifr; 307 int s, ds, diff; 308 adata_t *odata; 309 unsigned int iblksz; 310 unsigned int ofr; 311 unsigned int c; 312 adata_t *ctxbuf, *ctx; 313 unsigned int ctx_start; 314 315 /* 316 * Partially copy structures into local variables, to avoid 317 * unnecessary indirections; this also allows the compiler to 318 * order local variables more "cache-friendly". 319 */ 320 idata = in; 321 odata = out; 322 diff = p->diff; 323 iblksz = p->iblksz; 324 oblksz = p->oblksz; 325 ctxbuf = p->ctx; 326 ctx_start = p->ctx_start; 327 nch = p->nch; 328 ifr = icnt; 329 ofr = ocnt; 330 331 /* 332 * Start conversion. 333 */ 334 #ifdef DEBUG 335 if (log_level >= 4) { 336 log_puts("resamp: copying "); 337 log_puti(ifr); 338 log_puts(" -> "); 339 log_putu(ofr); 340 log_puts(" frames, diff = "); 341 log_puti(diff); 342 log_puts("\n"); 343 } 344 #endif 345 for (;;) { 346 if (diff >= oblksz) { 347 if (ifr == 0) 348 break; 349 ctx_start ^= 1; 350 ctx = ctxbuf + ctx_start; 351 for (c = nch; c > 0; c--) { 352 *ctx = *idata++; 353 ctx += RESAMP_NCTX; 354 } 355 diff -= oblksz; 356 ifr--; 357 } else { 358 if (ofr == 0) 359 break; 360 ctx = ctxbuf; 361 for (c = nch; c > 0; c--) { 362 s = ctx[ctx_start ^ 1]; 363 ds = ctx[ctx_start] - s; 364 ctx += RESAMP_NCTX; 365 *odata++ = s + ADATA_MULDIV(ds, diff, oblksz); 366 } 367 diff += iblksz; 368 ofr--; 369 } 370 } 371 p->diff = diff; 372 p->ctx_start = ctx_start; 373 #ifdef DEBUG 374 if (ifr != 0) { 375 log_puts("resamp_do: "); 376 log_puti(ifr); 377 log_puts(": too many input frames\n"); 378 panic(); 379 } 380 if (ofr != 0) { 381 log_puts("resamp_do: "); 382 log_puti(ofr); 383 log_puts(": too many output frames\n"); 384 panic(); 385 } 386 #endif 387 } 388 389 static unsigned int 390 uint_gcd(unsigned int a, unsigned int b) 391 { 392 unsigned int r; 393 394 while (b > 0) { 395 r = a % b; 396 a = b; 397 b = r; 398 } 399 return a; 400 } 401 402 /* 403 * initialize resampler with ibufsz/obufsz factor and "nch" channels 404 */ 405 void 406 resamp_init(struct resamp *p, unsigned int iblksz, 407 unsigned int oblksz, int nch) 408 { 409 unsigned int g; 410 411 /* 412 * reduce iblksz/oblksz fraction 413 */ 414 g = uint_gcd(iblksz, oblksz); 415 iblksz /= g; 416 oblksz /= g; 417 418 /* 419 * ensure weird rates don't cause integer overflow 420 */ 421 while (iblksz > ADATA_UNIT || oblksz > ADATA_UNIT) { 422 iblksz >>= 1; 423 oblksz >>= 1; 424 } 425 426 p->iblksz = iblksz; 427 p->oblksz = oblksz; 428 p->diff = 0; 429 p->nch = nch; 430 p->ctx_start = 0; 431 memset(p->ctx, 0, sizeof(p->ctx)); 432 #ifdef DEBUG 433 if (log_level >= 3) { 434 log_puts("resamp: "); 435 log_putu(iblksz); 436 log_puts("/"); 437 log_putu(oblksz); 438 log_puts("\n"); 439 } 440 #endif 441 } 442 443 /* 444 * encode "todo" frames from native to foreign encoding 445 */ 446 void 447 enc_do(struct conv *p, unsigned char *in, unsigned char *out, int todo) 448 { 449 unsigned int f; 450 adata_t *idata; 451 unsigned int s; 452 unsigned int oshift; 453 unsigned int obias; 454 unsigned int obps; 455 unsigned int i; 456 unsigned char *odata; 457 int obnext; 458 int osnext; 459 460 #ifdef DEBUG 461 if (log_level >= 4) { 462 log_puts("enc: copying "); 463 log_putu(todo); 464 log_puts(" frames\n"); 465 } 466 #endif 467 /* 468 * Partially copy structures into local variables, to avoid 469 * unnecessary indirections; this also allows the compiler to 470 * order local variables more "cache-friendly". 471 */ 472 idata = (adata_t *)in; 473 odata = out; 474 oshift = p->shift; 475 obias = p->bias; 476 obps = p->bps; 477 obnext = p->bnext; 478 osnext = p->snext; 479 480 /* 481 * Start conversion. 482 */ 483 odata += p->bfirst; 484 for (f = todo * p->nch; f > 0; f--) { 485 /* convert adata to u32 */ 486 s = (int)*idata++ + ADATA_UNIT; 487 s <<= 32 - ADATA_BITS; 488 /* convert u32 to uN */ 489 s >>= oshift; 490 /* convert uN to sN */ 491 s -= obias; 492 /* packetize sN */ 493 for (i = obps; i > 0; i--) { 494 *odata = (unsigned char)s; 495 s >>= 8; 496 odata += obnext; 497 } 498 odata += osnext; 499 } 500 } 501 502 /* 503 * store "todo" frames of silence in foreign encoding 504 */ 505 void 506 enc_sil_do(struct conv *p, unsigned char *out, int todo) 507 { 508 unsigned int f; 509 unsigned int s; 510 unsigned int oshift; 511 int obias; 512 unsigned int obps; 513 unsigned int i; 514 unsigned char *odata; 515 int obnext; 516 int osnext; 517 518 #ifdef DEBUG 519 if (log_level >= 4) { 520 log_puts("enc: silence "); 521 log_putu(todo); 522 log_puts(" frames\n"); 523 } 524 #endif 525 /* 526 * Partially copy structures into local variables, to avoid 527 * unnecessary indirections; this also allows the compiler to 528 * order local variables more "cache-friendly". 529 */ 530 odata = out; 531 oshift = p->shift; 532 obias = p->bias; 533 obps = p->bps; 534 obnext = p->bnext; 535 osnext = p->snext; 536 537 /* 538 * Start conversion. 539 */ 540 odata += p->bfirst; 541 for (f = todo * p->nch; f > 0; f--) { 542 s = ((1U << 31) >> oshift) - obias; 543 for (i = obps; i > 0; i--) { 544 *odata = (unsigned char)s; 545 s >>= 8; 546 odata += obnext; 547 } 548 odata += osnext; 549 } 550 } 551 552 /* 553 * initialize encoder from native to foreign encoding 554 */ 555 void 556 enc_init(struct conv *p, struct aparams *par, int nch) 557 { 558 p->nch = nch; 559 p->bps = par->bps; 560 if (par->msb) { 561 p->shift = 32 - par->bps * 8; 562 } else { 563 p->shift = 32 - par->bits; 564 } 565 if (par->sig) { 566 p->bias = (1U << 31) >> p->shift; 567 } else { 568 p->bias = 0; 569 } 570 if (!par->le) { 571 p->bfirst = par->bps - 1; 572 p->bnext = -1; 573 p->snext = 2 * par->bps; 574 } else { 575 p->bfirst = 0; 576 p->bnext = 1; 577 p->snext = 0; 578 } 579 #ifdef DEBUG 580 if (log_level >= 3) { 581 log_puts("enc: "); 582 aparams_log(par); 583 log_puts(", "); 584 log_puti(p->nch); 585 log_puts(" channels\n"); 586 } 587 #endif 588 } 589 590 /* 591 * decode "todo" frames from foreign to native encoding 592 */ 593 void 594 dec_do(struct conv *p, unsigned char *in, unsigned char *out, int todo) 595 { 596 unsigned int f; 597 unsigned int ibps; 598 unsigned int i; 599 unsigned int s = 0xdeadbeef; 600 unsigned char *idata; 601 int ibnext; 602 int isnext; 603 unsigned int ibias; 604 unsigned int ishift; 605 adata_t *odata; 606 607 #ifdef DEBUG 608 if (log_level >= 4) { 609 log_puts("dec: copying "); 610 log_putu(todo); 611 log_puts(" frames\n"); 612 } 613 #endif 614 /* 615 * Partially copy structures into local variables, to avoid 616 * unnecessary indirections; this also allows the compiler to 617 * order local variables more "cache-friendly". 618 */ 619 idata = in; 620 odata = (adata_t *)out; 621 ibps = p->bps; 622 ibnext = p->bnext; 623 ibias = p->bias; 624 ishift = p->shift; 625 isnext = p->snext; 626 627 /* 628 * Start conversion. 629 */ 630 idata += p->bfirst; 631 for (f = todo * p->nch; f > 0; f--) { 632 for (i = ibps; i > 0; i--) { 633 s <<= 8; 634 s |= *idata; 635 idata += ibnext; 636 } 637 idata += isnext; 638 s += ibias; 639 s <<= ishift; 640 s >>= 32 - ADATA_BITS; 641 *odata++ = s - ADATA_UNIT; 642 } 643 } 644 645 /* 646 * convert a 32-bit float to adata_t, clipping to -1:1, boundaries 647 * excluded 648 */ 649 static inline int 650 f32_to_adata(unsigned int x) 651 { 652 unsigned int s, e, m, y; 653 654 s = (x >> 31); 655 e = (x >> 23) & 0xff; 656 m = (x << 8) | 0x80000000; 657 658 /* 659 * f32 exponent is (e - 127) and the point is after the 31-th 660 * bit, thus the shift is: 661 * 662 * 31 - (BITS - 1) - (e - 127) 663 * 664 * to ensure output is in the 0..(2^BITS)-1 range, the minimum 665 * shift is 31 - (BITS - 1) + 1, and maximum shift is 31 666 */ 667 if (e < 127 - (ADATA_BITS - 1)) 668 y = 0; 669 else if (e >= 127) 670 y = ADATA_UNIT - 1; 671 else 672 y = m >> (127 + (32 - ADATA_BITS) - e); 673 return (y ^ -s) + s; 674 } 675 676 /* 677 * convert samples from little endian ieee 754 floats to adata_t 678 */ 679 void 680 dec_do_float(struct conv *p, unsigned char *in, unsigned char *out, int todo) 681 { 682 unsigned int f; 683 unsigned int i; 684 unsigned int s = 0xdeadbeef; 685 unsigned char *idata; 686 int ibnext; 687 int isnext; 688 adata_t *odata; 689 690 #ifdef DEBUG 691 if (log_level >= 4) { 692 log_puts("dec_float: copying "); 693 log_putu(todo); 694 log_puts(" frames\n"); 695 } 696 #endif 697 /* 698 * Partially copy structures into local variables, to avoid 699 * unnecessary indirections; this also allows the compiler to 700 * order local variables more "cache-friendly". 701 */ 702 idata = in; 703 odata = (adata_t *)out; 704 ibnext = p->bnext; 705 isnext = p->snext; 706 707 /* 708 * Start conversion. 709 */ 710 idata += p->bfirst; 711 for (f = todo * p->nch; f > 0; f--) { 712 for (i = 4; i > 0; i--) { 713 s <<= 8; 714 s |= *idata; 715 idata += ibnext; 716 } 717 idata += isnext; 718 *odata++ = f32_to_adata(s); 719 } 720 } 721 722 /* 723 * convert samples from ulaw/alaw to adata_t 724 */ 725 void 726 dec_do_ulaw(struct conv *p, unsigned char *in, 727 unsigned char *out, int todo, int is_alaw) 728 { 729 unsigned int f; 730 unsigned char *idata; 731 adata_t *odata; 732 short *map; 733 734 #ifdef DEBUG 735 if (log_level >= 4) { 736 log_puts("dec_ulaw: copying "); 737 log_putu(todo); 738 log_puts(" frames\n"); 739 } 740 #endif 741 map = is_alaw ? dec_alawmap : dec_ulawmap; 742 idata = in; 743 odata = (adata_t *)out; 744 for (f = todo * p->nch; f > 0; f--) 745 *odata++ = map[*idata++] << (ADATA_BITS - 16); 746 } 747 748 /* 749 * initialize decoder from foreign to native encoding 750 */ 751 void 752 dec_init(struct conv *p, struct aparams *par, int nch) 753 { 754 p->bps = par->bps; 755 p->nch = nch; 756 if (par->msb) { 757 p->shift = 32 - par->bps * 8; 758 } else { 759 p->shift = 32 - par->bits; 760 } 761 if (par->sig) { 762 p->bias = (1U << 31) >> p->shift; 763 } else { 764 p->bias = 0; 765 } 766 if (par->le) { 767 p->bfirst = par->bps - 1; 768 p->bnext = -1; 769 p->snext = 2 * par->bps; 770 } else { 771 p->bfirst = 0; 772 p->bnext = 1; 773 p->snext = 0; 774 } 775 #ifdef DEBUG 776 if (log_level >= 3) { 777 log_puts("dec: "); 778 aparams_log(par); 779 log_puts(", "); 780 log_puti(p->nch); 781 log_puts(" channels\n"); 782 } 783 #endif 784 } 785 786 /* 787 * mix "todo" input frames on the output with the given volume 788 */ 789 void 790 cmap_add(struct cmap *p, void *in, void *out, int vol, int todo) 791 { 792 adata_t *idata, *odata; 793 int i, j, nch, istart, inext, onext, ostart, y, v; 794 795 #ifdef DEBUG 796 if (log_level >= 4) { 797 log_puts("cmap: adding "); 798 log_puti(todo); 799 log_puts(" frames\n"); 800 } 801 #endif 802 idata = in; 803 odata = out; 804 ostart = p->ostart; 805 onext = p->onext; 806 istart = p->istart; 807 inext = p->inext; 808 nch = p->nch; 809 v = vol; 810 811 /* 812 * map/mix input on the output 813 */ 814 for (i = todo; i > 0; i--) { 815 odata += ostart; 816 idata += istart; 817 for (j = nch; j > 0; j--) { 818 y = *odata + ADATA_MUL(*idata, v); 819 if (y >= ADATA_UNIT) 820 y = ADATA_UNIT - 1; 821 else if (y < -ADATA_UNIT) 822 y = -ADATA_UNIT; 823 *odata = y; 824 idata++; 825 odata++; 826 } 827 odata += onext; 828 idata += inext; 829 } 830 } 831 832 /* 833 * overwrite output with "todo" input frames with the given volume 834 */ 835 void 836 cmap_copy(struct cmap *p, void *in, void *out, int vol, int todo) 837 { 838 adata_t *idata, *odata; 839 int i, j, nch, istart, inext, onext, ostart, v; 840 841 #ifdef DEBUG 842 if (log_level >= 4) { 843 log_puts("cmap: copying "); 844 log_puti(todo); 845 log_puts(" frames\n"); 846 } 847 #endif 848 idata = in; 849 odata = out; 850 ostart = p->ostart; 851 onext = p->onext; 852 istart = p->istart; 853 inext = p->inext; 854 nch = p->nch; 855 v = vol; 856 857 /* 858 * copy to the output buffer 859 */ 860 for (i = todo; i > 0; i--) { 861 idata += istart; 862 odata += ostart; 863 for (j = nch; j > 0; j--) { 864 *odata = ADATA_MUL(*idata, v); 865 odata++; 866 idata++; 867 } 868 odata += onext; 869 idata += inext; 870 } 871 } 872 873 /* 874 * initialize channel mapper, to map a subset of input channel range 875 * into a subset of the output channel range 876 */ 877 void 878 cmap_init(struct cmap *p, 879 int imin, int imax, int isubmin, int isubmax, 880 int omin, int omax, int osubmin, int osubmax) 881 { 882 int cmin, cmax; 883 884 cmin = -NCHAN_MAX; 885 if (osubmin > cmin) 886 cmin = osubmin; 887 if (omin > cmin) 888 cmin = omin; 889 if (isubmin > cmin) 890 cmin = isubmin; 891 if (imin > cmin) 892 cmin = imin; 893 894 cmax = NCHAN_MAX; 895 if (osubmax < cmax) 896 cmax = osubmax; 897 if (omax < cmax) 898 cmax = omax; 899 if (isubmax < cmax) 900 cmax = isubmax; 901 if (imax < cmax) 902 cmax = imax; 903 904 p->ostart = cmin - omin; 905 p->onext = omax - cmax; 906 p->istart = cmin - imin; 907 p->inext = imax - cmax; 908 p->nch = cmax - cmin + 1; 909 #ifdef DEBUG 910 if (log_level >= 3) { 911 log_puts("cmap: nch = "); 912 log_puti(p->nch); 913 log_puts(", ostart = "); 914 log_puti(p->ostart); 915 log_puts(", onext = "); 916 log_puti(p->onext); 917 log_puts(", istart = "); 918 log_puti(p->istart); 919 log_puts(", inext = "); 920 log_puti(p->inext); 921 log_puts("\n"); 922 } 923 #endif 924 } 925