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