1 /* $OpenBSD: dsp.c,v 1.13 2018/11/07 21:22:34 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 of 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 g; 408 409 /* 410 * reduce iblksz/oblksz fraction 411 */ 412 g = uint_gcd(iblksz, oblksz); 413 iblksz /= g; 414 oblksz /= g; 415 416 /* 417 * ensure weird rates don't cause integer overflow 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 memset(p->ctx, 0, sizeof(p->ctx)); 430 #ifdef DEBUG 431 if (log_level >= 3) { 432 log_puts("resamp: "); 433 log_putu(iblksz); 434 log_puts("/"); 435 log_putu(oblksz); 436 log_puts("\n"); 437 } 438 #endif 439 } 440 441 /* 442 * encode "todo" frames from native to foreign encoding 443 */ 444 void 445 enc_do(struct conv *p, unsigned char *in, unsigned char *out, int todo) 446 { 447 unsigned int f; 448 adata_t *idata; 449 unsigned int s; 450 unsigned int oshift; 451 unsigned int obias; 452 unsigned int obps; 453 unsigned int i; 454 unsigned char *odata; 455 int obnext; 456 int osnext; 457 458 #ifdef DEBUG 459 if (log_level >= 4) { 460 log_puts("enc: copying "); 461 log_putu(todo); 462 log_puts(" frames\n"); 463 } 464 #endif 465 /* 466 * Partially copy structures into local variables, to avoid 467 * unnecessary indirections; this also allows the compiler to 468 * order local variables more "cache-friendly". 469 */ 470 idata = (adata_t *)in; 471 odata = out; 472 oshift = p->shift; 473 obias = p->bias; 474 obps = p->bps; 475 obnext = p->bnext; 476 osnext = p->snext; 477 478 /* 479 * Start conversion. 480 */ 481 odata += p->bfirst; 482 for (f = todo * p->nch; f > 0; f--) { 483 /* convert adata to u32 */ 484 s = (int)*idata++ + ADATA_UNIT; 485 s <<= 32 - ADATA_BITS; 486 /* convert u32 to uN */ 487 s >>= oshift; 488 /* convert uN to sN */ 489 s -= obias; 490 /* packetize sN */ 491 for (i = obps; i > 0; i--) { 492 *odata = (unsigned char)s; 493 s >>= 8; 494 odata += obnext; 495 } 496 odata += osnext; 497 } 498 } 499 500 /* 501 * store "todo" frames of silence in foreign encoding 502 */ 503 void 504 enc_sil_do(struct conv *p, unsigned char *out, int todo) 505 { 506 unsigned int f; 507 unsigned int s; 508 unsigned int oshift; 509 int obias; 510 unsigned int obps; 511 unsigned int i; 512 unsigned char *odata; 513 int obnext; 514 int osnext; 515 516 #ifdef DEBUG 517 if (log_level >= 4) { 518 log_puts("enc: silence "); 519 log_putu(todo); 520 log_puts(" frames\n"); 521 } 522 #endif 523 /* 524 * Partially copy structures into local variables, to avoid 525 * unnecessary indirections; this also allows the compiler to 526 * order local variables more "cache-friendly". 527 */ 528 odata = out; 529 oshift = p->shift; 530 obias = p->bias; 531 obps = p->bps; 532 obnext = p->bnext; 533 osnext = p->snext; 534 535 /* 536 * Start conversion. 537 */ 538 odata += p->bfirst; 539 for (f = todo * p->nch; f > 0; f--) { 540 s = ((1U << 31) >> oshift) - obias; 541 for (i = obps; i > 0; i--) { 542 *odata = (unsigned char)s; 543 s >>= 8; 544 odata += obnext; 545 } 546 odata += osnext; 547 } 548 } 549 550 /* 551 * initialize encoder from native to foreign encoding 552 */ 553 void 554 enc_init(struct conv *p, struct aparams *par, int nch) 555 { 556 p->nch = nch; 557 p->bps = par->bps; 558 if (par->msb) { 559 p->shift = 32 - par->bps * 8; 560 } else { 561 p->shift = 32 - par->bits; 562 } 563 if (par->sig) { 564 p->bias = (1U << 31) >> p->shift; 565 } else { 566 p->bias = 0; 567 } 568 if (!par->le) { 569 p->bfirst = par->bps - 1; 570 p->bnext = -1; 571 p->snext = 2 * par->bps; 572 } else { 573 p->bfirst = 0; 574 p->bnext = 1; 575 p->snext = 0; 576 } 577 #ifdef DEBUG 578 if (log_level >= 3) { 579 log_puts("enc: "); 580 aparams_log(par); 581 log_puts(", "); 582 log_puti(p->nch); 583 log_puts(" channels\n"); 584 } 585 #endif 586 } 587 588 /* 589 * decode "todo" frames from foreign to native encoding 590 */ 591 void 592 dec_do(struct conv *p, unsigned char *in, unsigned char *out, int todo) 593 { 594 unsigned int f; 595 unsigned int ibps; 596 unsigned int i; 597 unsigned int s = 0xdeadbeef; 598 unsigned char *idata; 599 int ibnext; 600 int isnext; 601 unsigned int ibias; 602 unsigned int ishift; 603 adata_t *odata; 604 605 #ifdef DEBUG 606 if (log_level >= 4) { 607 log_puts("dec: copying "); 608 log_putu(todo); 609 log_puts(" frames\n"); 610 } 611 #endif 612 /* 613 * Partially copy structures into local variables, to avoid 614 * unnecessary indirections; this also allows the compiler to 615 * order local variables more "cache-friendly". 616 */ 617 idata = in; 618 odata = (adata_t *)out; 619 ibps = p->bps; 620 ibnext = p->bnext; 621 ibias = p->bias; 622 ishift = p->shift; 623 isnext = p->snext; 624 625 /* 626 * Start conversion. 627 */ 628 idata += p->bfirst; 629 for (f = todo * p->nch; f > 0; f--) { 630 for (i = ibps; i > 0; i--) { 631 s <<= 8; 632 s |= *idata; 633 idata += ibnext; 634 } 635 idata += isnext; 636 s += ibias; 637 s <<= ishift; 638 s >>= 32 - ADATA_BITS; 639 *odata++ = s - ADATA_UNIT; 640 } 641 } 642 643 /* 644 * convert a 32-bit float to adata_t, clipping to -1:1, boundaries 645 * excluded 646 */ 647 static inline int 648 f32_to_adata(unsigned int x) 649 { 650 unsigned int s, e, m, y; 651 652 s = (x >> 31); 653 e = (x >> 23) & 0xff; 654 m = (x << 8) | 0x80000000; 655 656 /* 657 * f32 exponent is (e - 127) and the point is after the 31-th 658 * bit, thus the shift is: 659 * 660 * 31 - (BITS - 1) - (e - 127) 661 * 662 * to ensure output is in the 0..(2^BITS)-1 range, the minimum 663 * shift is 31 - (BITS - 1) + 1, and maximum shift is 31 664 */ 665 if (e < 127 - (ADATA_BITS - 1)) 666 y = 0; 667 else if (e >= 127) 668 y = ADATA_UNIT - 1; 669 else 670 y = m >> (127 + (32 - ADATA_BITS) - e); 671 return (y ^ -s) + s; 672 } 673 674 /* 675 * convert samples from little endian ieee 754 floats to adata_t 676 */ 677 void 678 dec_do_float(struct conv *p, unsigned char *in, unsigned char *out, int todo) 679 { 680 unsigned int f; 681 unsigned int i; 682 unsigned int s = 0xdeadbeef; 683 unsigned char *idata; 684 int ibnext; 685 int isnext; 686 adata_t *odata; 687 688 #ifdef DEBUG 689 if (log_level >= 4) { 690 log_puts("dec_float: copying "); 691 log_putu(todo); 692 log_puts(" frames\n"); 693 } 694 #endif 695 /* 696 * Partially copy structures into local variables, to avoid 697 * unnecessary indirections; this also allows the compiler to 698 * order local variables more "cache-friendly". 699 */ 700 idata = in; 701 odata = (adata_t *)out; 702 ibnext = p->bnext; 703 isnext = p->snext; 704 705 /* 706 * Start conversion. 707 */ 708 idata += p->bfirst; 709 for (f = todo * p->nch; f > 0; f--) { 710 for (i = 4; i > 0; i--) { 711 s <<= 8; 712 s |= *idata; 713 idata += ibnext; 714 } 715 idata += isnext; 716 *odata++ = f32_to_adata(s); 717 } 718 } 719 720 /* 721 * convert samples from ulaw/alaw to adata_t 722 */ 723 void 724 dec_do_ulaw(struct conv *p, unsigned char *in, 725 unsigned char *out, int todo, int is_alaw) 726 { 727 unsigned int f; 728 unsigned char *idata; 729 adata_t *odata; 730 short *map; 731 732 #ifdef DEBUG 733 if (log_level >= 4) { 734 log_puts("dec_ulaw: copying "); 735 log_putu(todo); 736 log_puts(" frames\n"); 737 } 738 #endif 739 map = is_alaw ? dec_alawmap : dec_ulawmap; 740 idata = in; 741 odata = (adata_t *)out; 742 for (f = todo * p->nch; f > 0; f--) 743 *odata++ = map[*idata++] << (ADATA_BITS - 16); 744 } 745 746 /* 747 * initialize decoder from foreign to native encoding 748 */ 749 void 750 dec_init(struct conv *p, struct aparams *par, int nch) 751 { 752 p->bps = par->bps; 753 p->nch = nch; 754 if (par->msb) { 755 p->shift = 32 - par->bps * 8; 756 } else { 757 p->shift = 32 - par->bits; 758 } 759 if (par->sig) { 760 p->bias = (1U << 31) >> p->shift; 761 } else { 762 p->bias = 0; 763 } 764 if (par->le) { 765 p->bfirst = par->bps - 1; 766 p->bnext = -1; 767 p->snext = 2 * par->bps; 768 } else { 769 p->bfirst = 0; 770 p->bnext = 1; 771 p->snext = 0; 772 } 773 #ifdef DEBUG 774 if (log_level >= 3) { 775 log_puts("dec: "); 776 aparams_log(par); 777 log_puts(", "); 778 log_puti(p->nch); 779 log_puts(" channels\n"); 780 } 781 #endif 782 } 783 784 /* 785 * mix "todo" input frames on the output with the given volume 786 */ 787 void 788 cmap_add(struct cmap *p, void *in, void *out, int vol, int todo) 789 { 790 adata_t *idata, *odata; 791 int i, j, nch, istart, inext, onext, ostart, y, v; 792 793 #ifdef DEBUG 794 if (log_level >= 4) { 795 log_puts("cmap: adding "); 796 log_puti(todo); 797 log_puts(" frames\n"); 798 } 799 #endif 800 idata = in; 801 odata = out; 802 ostart = p->ostart; 803 onext = p->onext; 804 istart = p->istart; 805 inext = p->inext; 806 nch = p->nch; 807 v = vol; 808 809 /* 810 * map/mix input on the output 811 */ 812 for (i = todo; i > 0; i--) { 813 odata += ostart; 814 idata += istart; 815 for (j = nch; j > 0; j--) { 816 y = *odata + ADATA_MUL(*idata, v); 817 if (y >= ADATA_UNIT) 818 y = ADATA_UNIT - 1; 819 else if (y < -ADATA_UNIT) 820 y = -ADATA_UNIT; 821 *odata = y; 822 idata++; 823 odata++; 824 } 825 odata += onext; 826 idata += inext; 827 } 828 } 829 830 /* 831 * overwrite output with "todo" input frames with the given volume 832 */ 833 void 834 cmap_copy(struct cmap *p, void *in, void *out, int vol, int todo) 835 { 836 adata_t *idata, *odata; 837 int i, j, nch, istart, inext, onext, ostart, v; 838 839 #ifdef DEBUG 840 if (log_level >= 4) { 841 log_puts("cmap: copying "); 842 log_puti(todo); 843 log_puts(" frames\n"); 844 } 845 #endif 846 idata = in; 847 odata = out; 848 ostart = p->ostart; 849 onext = p->onext; 850 istart = p->istart; 851 inext = p->inext; 852 nch = p->nch; 853 v = vol; 854 855 /* 856 * copy to the output buffer 857 */ 858 for (i = todo; i > 0; i--) { 859 idata += istart; 860 odata += ostart; 861 for (j = nch; j > 0; j--) { 862 *odata = ADATA_MUL(*idata, v); 863 odata++; 864 idata++; 865 } 866 odata += onext; 867 idata += inext; 868 } 869 } 870 871 /* 872 * initialize channel mapper, to map a subset of input channel range 873 * into a subset of the output channel range 874 */ 875 void 876 cmap_init(struct cmap *p, 877 int imin, int imax, int isubmin, int isubmax, 878 int omin, int omax, int osubmin, int osubmax) 879 { 880 int cmin, cmax; 881 882 cmin = -NCHAN_MAX; 883 if (osubmin > cmin) 884 cmin = osubmin; 885 if (omin > cmin) 886 cmin = omin; 887 if (isubmin > cmin) 888 cmin = isubmin; 889 if (imin > cmin) 890 cmin = imin; 891 892 cmax = NCHAN_MAX; 893 if (osubmax < cmax) 894 cmax = osubmax; 895 if (omax < cmax) 896 cmax = omax; 897 if (isubmax < cmax) 898 cmax = isubmax; 899 if (imax < cmax) 900 cmax = imax; 901 902 p->ostart = cmin - omin; 903 p->onext = omax - cmax; 904 p->istart = cmin - imin; 905 p->inext = imax - cmax; 906 p->nch = cmax - cmin + 1; 907 #ifdef DEBUG 908 if (log_level >= 3) { 909 log_puts("cmap: nch = "); 910 log_puti(p->nch); 911 log_puts(", ostart = "); 912 log_puti(p->ostart); 913 log_puts(", onext = "); 914 log_puti(p->onext); 915 log_puts(", istart = "); 916 log_puti(p->istart); 917 log_puts(", inext = "); 918 log_puti(p->inext); 919 log_puts("\n"); 920 } 921 #endif 922 } 923