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