Annotation of src/usr.bin/aucat/dsp.c, Revision 1.12
1.12 ! miko 1: /* $OpenBSD: dsp.c,v 1.11 2016/09/30 08:43:23 ratchov Exp $ */
1.1 ratchov 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: */
1.12 ! miko 17: #include <string.h>
1.1 ratchov 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:
1.3 ratchov 225: par->msb = msb;
1.1 ratchov 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: /*
1.9 ratchov 271: * Return the number of input and output frame that would be consumed
272: * by resamp_do(p, *icnt, *ocnt).
1.5 ratchov 273: */
1.7 ratchov 274: void
275: resamp_getcnt(struct resamp *p, int *icnt, int *ocnt)
1.5 ratchov 276: {
1.9 ratchov 277: long long idiff, odiff;
278: int cdiff;
1.7 ratchov 279:
1.9 ratchov 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;
1.5 ratchov 287: }
288:
289: /*
290: * Resample the given number of frames. The number of output frames
1.10 ratchov 291: * must match the coresponding number of input frames. Either always
1.7 ratchov 292: * use icnt and ocnt such that:
1.5 ratchov 293: *
1.7 ratchov 294: * icnt * oblksz = ocnt * iblksz
1.5 ratchov 295: *
1.7 ratchov 296: * or use resamp_getcnt() to calculate the proper numbers.
1.1 ratchov 297: */
1.4 ratchov 298: void
1.5 ratchov 299: resamp_do(struct resamp *p, adata_t *in, adata_t *out, int icnt, int ocnt)
1.1 ratchov 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;
1.5 ratchov 326: ifr = icnt;
327: ofr = ocnt;
1.1 ratchov 328:
329: /*
330: * Start conversion.
331: */
332: #ifdef DEBUG
333: if (log_level >= 4) {
334: log_puts("resamp: copying ");
1.4 ratchov 335: log_puti(ifr);
1.5 ratchov 336: log_puts(" -> ");
337: log_putu(ofr);
1.1 ratchov 338: log_puts(" frames, diff = ");
1.5 ratchov 339: log_puti(diff);
1.1 ratchov 340: log_puts("\n");
341: }
342: #endif
343: for (;;) {
1.9 ratchov 344: if (diff >= oblksz) {
1.1 ratchov 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: }
1.9 ratchov 353: diff -= oblksz;
1.1 ratchov 354: ifr--;
1.9 ratchov 355: } else {
1.1 ratchov 356: if (ofr == 0)
357: break;
358: ctx = ctxbuf;
359: for (c = nch; c > 0; c--) {
1.9 ratchov 360: s = ctx[ctx_start ^ 1];
361: ds = ctx[ctx_start] - s;
1.1 ratchov 362: ctx += RESAMP_NCTX;
363: *odata++ = s + ADATA_MULDIV(ds, diff, oblksz);
364: }
1.9 ratchov 365: diff += iblksz;
1.1 ratchov 366: ofr--;
367: }
368: }
369: p->diff = diff;
370: p->ctx_start = ctx_start;
1.5 ratchov 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
1.1 ratchov 385: }
386:
1.6 ratchov 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:
1.1 ratchov 400: /*
401: * initialize resampler with ibufsz/obufsz factor and "nch" channels
402: */
403: void
1.3 ratchov 404: resamp_init(struct resamp *p, unsigned int iblksz,
405: unsigned int oblksz, int nch)
1.1 ratchov 406: {
1.12 ! miko 407: unsigned int g;
1.6 ratchov 408:
409: /*
1.10 ratchov 410: * reduce iblksz/oblksz fraction
1.6 ratchov 411: */
412: g = uint_gcd(iblksz, oblksz);
413: iblksz /= g;
414: oblksz /= g;
415:
416: /*
1.10 ratchov 417: * ensure weird rates don't cause integer overflow
1.6 ratchov 418: */
419: while (iblksz > ADATA_UNIT || oblksz > ADATA_UNIT) {
420: iblksz >>= 1;
421: oblksz >>= 1;
422: }
1.1 ratchov 423:
424: p->iblksz = iblksz;
425: p->oblksz = oblksz;
426: p->diff = 0;
427: p->nch = nch;
428: p->ctx_start = 0;
1.12 ! miko 429: memset(p->ctx, 0, sizeof(p->ctx));
1.1 ratchov 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;
1.3 ratchov 567: }
1.1 ratchov 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: /*
1.10 ratchov 589: * decode "todo" frames from foreign to native encoding
1.1 ratchov 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;
1.2 ratchov 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), and maximum shift is 31
664: */
665: if (e < 127 - (ADATA_BITS - 1))
1.1 ratchov 666: y = 0;
1.2 ratchov 667: else if (e > 127)
1.1 ratchov 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
1.3 ratchov 724: dec_do_ulaw(struct conv *p, unsigned char *in,
725: unsigned char *out, int todo, int is_alaw)
1.1 ratchov 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;
1.3 ratchov 763: }
1.1 ratchov 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: /*
1.10 ratchov 831: * overwrite output with "todo" input frames with the given volume
1.1 ratchov 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: }