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