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