1 /*	$OpenBSD$	*/
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 const 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 const int resamp_filt[RESAMP_LENGTH / RESAMP_STEP + 1] = {
42 	      0,       0,       3,       9,      22,      42,      73,     116,
43 	    174,     248,     341,     454,     589,     749,     934,    1148,
44 	   1392,    1666,    1974,    2316,    2693,    3107,    3560,    4051,
45 	   4582,    5154,    5766,    6420,    7116,    7853,    8632,    9451,
46 	  10311,   11210,   12148,   13123,   14133,   15178,   16253,   17359,
47 	  18491,   19647,   20824,   22018,   23226,   24443,   25665,   26888,
48 	  28106,   29315,   30509,   31681,   32826,   33938,   35009,   36033,
49 	  37001,   37908,   38744,   39502,   40174,   40750,   41223,   41582,
50 	  41819,   41925,   41890,   41704,   41358,   40842,   40147,   39261,
51 	  38176,   36881,   35366,   33623,   31641,   29411,   26923,   24169,
52 	  21140,   17827,   14222,   10317,    6105,    1580,   -3267,   -8440,
53 	 -13944,  -19785,  -25967,  -32492,  -39364,  -46584,  -54153,  -62072,
54 	 -70339,  -78953,  -87911,  -97209, -106843, -116806, -127092, -137692,
55 	-148596, -159795, -171276, -183025, -195029, -207271, -219735, -232401,
56 	-245249, -258259, -271407, -284670, -298021, -311434, -324880, -338329,
57 	-351750, -365111, -378378, -391515, -404485, -417252, -429775, -442015,
58 	-453930, -465477, -476613, -487294, -497472, -507102, -516137, -524527,
59 	-532225, -539181, -545344, -550664, -555090, -558571, -561055, -562490,
60 	-562826, -562010, -559990, -556717, -552139, -546205, -538866, -530074,
61 	-519779, -507936, -494496, -479416, -462652, -444160, -423901, -401835,
62 	-377923, -352132, -324425, -294772, -263143, -229509, -193847, -156134,
63 	-116348,  -74474,  -30494,   15601,   63822,  114174,  166661,  221283,
64 	 278037,  336916,  397911,  461009,  526194,  593446,  662741,  734054,
65 	 807354,  882608,  959779, 1038826, 1119706, 1202370, 1286768, 1372846,
66 	1460546, 1549808, 1640566, 1732753, 1826299, 1921130, 2017169, 2114336,
67 	2212550, 2311723, 2411770, 2512598, 2614116, 2716228, 2818836, 2921841,
68 	3025142, 3128636, 3232218, 3335782, 3439219, 3542423, 3645282, 3747687,
69 	3849526, 3950687, 4051059, 4150530, 4248987, 4346320, 4442415, 4537163,
70 	4630453, 4722177, 4812225, 4900493, 4986873, 5071263, 5153561, 5233668,
71 	5311485, 5386917, 5459872, 5530259, 5597992, 5662986, 5725160, 5784436,
72 	5840739, 5893999, 5944148, 5991122, 6034862, 6075313, 6112422, 6146142,
73 	6176430, 6203247, 6226559, 6246335, 6262551, 6275185, 6284220, 6289647,
74 	6291456, 6289647, 6284220, 6275185, 6262551, 6246335, 6226559, 6203247,
75 	6176430, 6146142, 6112422, 6075313, 6034862, 5991122, 5944148, 5893999,
76 	5840739, 5784436, 5725160, 5662986, 5597992, 5530259, 5459872, 5386917,
77 	5311485, 5233668, 5153561, 5071263, 4986873, 4900493, 4812225, 4722177,
78 	4630453, 4537163, 4442415, 4346320, 4248987, 4150530, 4051059, 3950687,
79 	3849526, 3747687, 3645282, 3542423, 3439219, 3335782, 3232218, 3128636,
80 	3025142, 2921841, 2818836, 2716228, 2614116, 2512598, 2411770, 2311723,
81 	2212550, 2114336, 2017169, 1921130, 1826299, 1732753, 1640566, 1549808,
82 	1460546, 1372846, 1286768, 1202370, 1119706, 1038826,  959779,  882608,
83 	 807354,  734054,  662741,  593446,  526194,  461009,  397911,  336916,
84 	 278037,  221283,  166661,  114174,   63822,   15601,  -30494,  -74474,
85 	-116348, -156134, -193847, -229509, -263143, -294772, -324425, -352132,
86 	-377923, -401835, -423901, -444160, -462652, -479416, -494496, -507936,
87 	-519779, -530074, -538866, -546205, -552139, -556717, -559990, -562010,
88 	-562826, -562490, -561055, -558571, -555090, -550664, -545344, -539181,
89 	-532225, -524527, -516137, -507102, -497472, -487294, -476613, -465477,
90 	-453930, -442015, -429775, -417252, -404485, -391515, -378378, -365111,
91 	-351750, -338329, -324880, -311434, -298021, -284670, -271407, -258259,
92 	-245249, -232401, -219735, -207271, -195029, -183025, -171276, -159795,
93 	-148596, -137692, -127092, -116806, -106843,  -97209,  -87911,  -78953,
94 	 -70339,  -62072,  -54153,  -46584,  -39364,  -32492,  -25967,  -19785,
95 	 -13944,   -8440,   -3267,    1580,    6105,   10317,   14222,   17827,
96 	  21140,   24169,   26923,   29411,   31641,   33623,   35366,   36881,
97 	  38176,   39261,   40147,   40842,   41358,   41704,   41890,   41925,
98 	  41819,   41582,   41223,   40750,   40174,   39502,   38744,   37908,
99 	  37001,   36033,   35009,   33938,   32826,   31681,   30509,   29315,
100 	  28106,   26888,   25665,   24443,   23226,   22018,   20824,   19647,
101 	  18491,   17359,   16253,   15178,   14133,   13123,   12148,   11210,
102 	  10311,    9451,    8632,    7853,    7116,    6420,    5766,    5154,
103 	   4582,    4051,    3560,    3107,    2693,    2316,    1974,    1666,
104 	   1392,    1148,     934,     749,     589,     454,     341,     248,
105 	    174,     116,      73,      42,      22,       9,       3,       0,
106 	      0
107 };
108 
109 
110 /*
111  * Generate a string corresponding to the encoding in par,
112  * return the length of the resulting string.
113  */
114 int
aparams_enctostr(struct aparams * par,char * ostr)115 aparams_enctostr(struct aparams *par, char *ostr)
116 {
117 	char *p = ostr;
118 
119 	*p++ = par->sig ? 's' : 'u';
120 	if (par->bits > 9)
121 		*p++ = '0' + par->bits / 10;
122 	*p++ = '0' + par->bits % 10;
123 	if (par->bps > 1) {
124 		*p++ = par->le ? 'l' : 'b';
125 		*p++ = 'e';
126 		if (par->bps != APARAMS_BPS(par->bits) ||
127 		    par->bits < par->bps * 8) {
128 			*p++ = par->bps + '0';
129 			if (par->bits < par->bps * 8) {
130 				*p++ = par->msb ? 'm' : 'l';
131 				*p++ = 's';
132 				*p++ = 'b';
133 			}
134 		}
135 	}
136 	*p++ = '\0';
137 	return p - ostr - 1;
138 }
139 
140 /*
141  * Parse an encoding string, examples: s8, u8, s16, s16le, s24be ...
142  * set *istr to the char following the encoding. Return the number
143  * of bytes consumed.
144  */
145 int
aparams_strtoenc(struct aparams * par,char * istr)146 aparams_strtoenc(struct aparams *par, char *istr)
147 {
148 	char *p = istr;
149 	int i, sig, bits, le, bps, msb;
150 
151 #define IS_SEP(c)			\
152 	(((c) < 'a' || (c) > 'z') &&	\
153 	 ((c) < 'A' || (c) > 'Z') &&	\
154 	 ((c) < '0' || (c) > '9'))
155 
156 	/*
157 	 * get signedness
158 	 */
159 	if (*p == 's') {
160 		sig = 1;
161 	} else if (*p == 'u') {
162 		sig = 0;
163 	} else
164 		return 0;
165 	p++;
166 
167 	/*
168 	 * get number of bits per sample
169 	 */
170 	bits = 0;
171 	for (i = 0; i < 2; i++) {
172 		if (*p < '0' || *p > '9')
173 			break;
174 		bits = (bits * 10) + *p - '0';
175 		p++;
176 	}
177 	if (bits < BITS_MIN || bits > BITS_MAX)
178 		return 0;
179 	bps = APARAMS_BPS(bits);
180 	msb = 1;
181 	le = ADATA_LE;
182 
183 	/*
184 	 * get (optional) endianness
185 	 */
186 	if (p[0] == 'l' && p[1] == 'e') {
187 		le = 1;
188 		p += 2;
189 	} else if (p[0] == 'b' && p[1] == 'e') {
190 		le = 0;
191 		p += 2;
192 	} else if (IS_SEP(*p)) {
193 		goto done;
194 	} else
195 		return 0;
196 
197 	/*
198 	 * get (optional) number of bytes
199 	 */
200 	if (*p >= '0' && *p <= '9') {
201 		bps = *p - '0';
202 		if (bps < (bits + 7) / 8 ||
203 		    bps > (BITS_MAX + 7) / 8)
204 			return 0;
205 		p++;
206 
207 		/*
208 		 * get (optional) alignment
209 		 */
210 		if (p[0] == 'm' && p[1] == 's' && p[2] == 'b') {
211 			msb = 1;
212 			p += 3;
213 		} else if (p[0] == 'l' && p[1] == 's' && p[2] == 'b') {
214 			msb = 0;
215 			p += 3;
216 		} else if (IS_SEP(*p)) {
217 			goto done;
218 		} else
219 			return 0;
220 	} else if (!IS_SEP(*p))
221 		return 0;
222 
223 done:
224 	par->msb = msb;
225 	par->sig = sig;
226 	par->bits = bits;
227 	par->bps = bps;
228 	par->le = le;
229 	return p - istr;
230 }
231 
232 /*
233  * Initialise parameters structure with the defaults natively supported
234  * by the machine.
235  */
236 void
aparams_init(struct aparams * par)237 aparams_init(struct aparams *par)
238 {
239 	par->bps = sizeof(adata_t);
240 	par->bits = ADATA_BITS;
241 	par->le = ADATA_LE;
242 	par->sig = 1;
243 	par->msb = 0;
244 }
245 
246 /*
247  * log the given format/channels/encoding
248  */
249 void
aparams_log(struct aparams * par)250 aparams_log(struct aparams *par)
251 {
252 	char enc[ENCMAX];
253 
254 	aparams_enctostr(par, enc);
255 	log_puts(enc);
256 }
257 
258 /*
259  * return true if encoding corresponds to what we store in adata_t
260  */
261 int
aparams_native(struct aparams * par)262 aparams_native(struct aparams *par)
263 {
264 	return par->sig &&
265 	    par->bps == sizeof(adata_t) &&
266 	    par->bits == ADATA_BITS &&
267 	    (par->bps == 1 || par->le == ADATA_LE) &&
268 	    (par->bits == par->bps * 8 || !par->msb);
269 }
270 
271 /*
272  * resample the given number of frames
273  */
274 void
resamp_do(struct resamp * p,adata_t * in,adata_t * out,int todo)275 resamp_do(struct resamp *p, adata_t *in, adata_t *out, int todo)
276 {
277 	unsigned int nch;
278 	adata_t *idata;
279 	unsigned int oblksz;
280 	int s, ds, diff;
281 	adata_t *odata;
282 	unsigned int iblksz;
283 	unsigned int c;
284 	int64_t f[NCHAN_MAX];
285 	adata_t *ctxbuf, *ctx;
286 	unsigned int ctx_start;
287 	int q, qi, qf, n;
288 
289 #ifdef DEBUG
290 	if (todo % p->iblksz != 0) {
291 		log_puts("resamp_do: partial blocks not supported\n");
292 		panic();
293 	}
294 #endif
295 
296 	/*
297 	 * Partially copy structures into local variables, to avoid
298 	 * unnecessary indirections; this also allows the compiler to
299 	 * order local variables more "cache-friendly".
300 	 */
301 	idata = in;
302 	odata = out;
303 	diff = p->oblksz;
304 	iblksz = p->iblksz;
305 	oblksz = p->oblksz;
306 	ctxbuf = p->ctx;
307 	ctx_start = p->ctx_start;
308 	nch = p->nch;
309 
310 	for (;;) {
311 		if (diff >= oblksz) {
312 			if (todo == 0)
313 				break;
314 			ctx_start = (ctx_start - 1) & (RESAMP_NCTX - 1);
315 			ctx = ctxbuf + ctx_start;
316 			for (c = nch; c > 0; c--) {
317 				*ctx = *idata++;
318 				ctx += RESAMP_NCTX;
319 			}
320 			diff -= oblksz;
321 			todo--;
322 		} else {
323 
324 			for (c = nch; c > 0; c--)
325 				f[c] = 0;
326 
327 			q = diff * p->filt_step;
328 			n = ctx_start;
329 
330 			while (q < RESAMP_LENGTH) {
331 				qi = q >> RESAMP_STEP_BITS;
332 				qf = q & (RESAMP_STEP - 1);
333 				s = resamp_filt[qi];
334 				ds = resamp_filt[qi + 1] - s;
335 				s += (int64_t)qf * ds >> RESAMP_STEP_BITS;
336 				ctx = ctxbuf;
337 				for (c = nch; c > 0; c--) {
338 					f[c] += (int64_t)ctx[n] * s;
339 					ctx += RESAMP_NCTX;
340 				}
341 				q += p->filt_cutoff;
342 				n = (n + 1) & (RESAMP_NCTX - 1);
343 			}
344 
345 			for (c = nch; c > 0; c--) {
346 				s = f[c] >> RESAMP_BITS;
347 				s = (int64_t)s * p->filt_cutoff >> RESAMP_BITS;
348 #if ADATA_BITS == 16
349 				/*
350 				 * In 16-bit mode, we've no room for filter
351 				 * overshoots, so we need to clip the signal
352 				 * to avoid 16-bit integers to wrap around.
353 				 * In 24-bit mode, samples may exceed the
354 				 * [-1:1] range. Later, cmap_add() will clip
355 				 * them, so no need to clip them here as well.
356 				 */
357 				if (s >= ADATA_UNIT)
358 					s = ADATA_UNIT - 1;
359 				else if (s < -ADATA_UNIT)
360 					s = -ADATA_UNIT;
361 #endif
362 				*odata++ = s;
363 			}
364 			diff += iblksz;
365 		}
366 	}
367 
368 	p->ctx_start = ctx_start;
369 }
370 
371 /*
372  * initialize resampler with ibufsz/obufsz factor and "nch" channels
373  */
374 void
resamp_init(struct resamp * p,unsigned int iblksz,unsigned int oblksz,int nch)375 resamp_init(struct resamp *p, unsigned int iblksz,
376     unsigned int oblksz, int nch)
377 {
378 	p->iblksz = iblksz;
379 	p->oblksz = oblksz;
380 	p->nch = nch;
381 	p->ctx_start = 0;
382 	memset(p->ctx, 0, sizeof(p->ctx));
383 	if (p->iblksz < p->oblksz) {
384 		p->filt_cutoff = RESAMP_UNIT;
385 		p->filt_step = RESAMP_UNIT / p->oblksz;
386 	} else {
387 		p->filt_cutoff = (int64_t)RESAMP_UNIT * p->oblksz / p->iblksz;
388 		p->filt_step = RESAMP_UNIT / p->iblksz;
389 	}
390 #ifdef DEBUG
391 	if (log_level >= 3) {
392 		log_puts("resamp: ");
393 		log_putu(iblksz);
394 		log_puts("/");
395 		log_putu(oblksz);
396 		log_puts("\n");
397 	}
398 #endif
399 }
400 
401 /*
402  * encode "todo" frames from native to foreign encoding
403  */
404 void
enc_do(struct conv * p,unsigned char * in,unsigned char * out,int todo)405 enc_do(struct conv *p, unsigned char *in, unsigned char *out, int todo)
406 {
407 	unsigned int f;
408 	adata_t *idata;
409 	unsigned int s;
410 	unsigned int oshift;
411 	unsigned int obias;
412 	unsigned int obps;
413 	unsigned int i;
414 	unsigned char *odata;
415 	int obnext;
416 	int osnext;
417 
418 #ifdef DEBUG
419 	if (log_level >= 4) {
420 		log_puts("enc: copying ");
421 		log_putu(todo);
422 		log_puts(" frames\n");
423 	}
424 #endif
425 	/*
426 	 * Partially copy structures into local variables, to avoid
427 	 * unnecessary indirections; this also allows the compiler to
428 	 * order local variables more "cache-friendly".
429 	 */
430 	idata = (adata_t *)in;
431 	odata = out;
432 	oshift = p->shift;
433 	obias = p->bias;
434 	obps = p->bps;
435 	obnext = p->bnext;
436 	osnext = p->snext;
437 
438 	/*
439 	 * Start conversion.
440 	 */
441 	odata += p->bfirst;
442 	for (f = todo * p->nch; f > 0; f--) {
443 		/* convert adata to u32 */
444 		s = (int)*idata++ + ADATA_UNIT;
445 		s <<= 32 - ADATA_BITS;
446 		/* convert u32 to uN */
447 		s >>= oshift;
448 		/* convert uN to sN */
449 		s -= obias;
450 		/* packetize sN */
451 		for (i = obps; i > 0; i--) {
452 			*odata = (unsigned char)s;
453 			s >>= 8;
454 			odata += obnext;
455 		}
456 		odata += osnext;
457 	}
458 }
459 
460 /*
461  * store "todo" frames of silence in foreign encoding
462  */
463 void
enc_sil_do(struct conv * p,unsigned char * out,int todo)464 enc_sil_do(struct conv *p, unsigned char *out, int todo)
465 {
466 	unsigned int f;
467 	unsigned int s;
468 	unsigned int oshift;
469 	int obias;
470 	unsigned int obps;
471 	unsigned int i;
472 	unsigned char *odata;
473 	int obnext;
474 	int osnext;
475 
476 #ifdef DEBUG
477 	if (log_level >= 4) {
478 		log_puts("enc: silence ");
479 		log_putu(todo);
480 		log_puts(" frames\n");
481 	}
482 #endif
483 	/*
484 	 * Partially copy structures into local variables, to avoid
485 	 * unnecessary indirections; this also allows the compiler to
486 	 * order local variables more "cache-friendly".
487 	 */
488 	odata = out;
489 	oshift = p->shift;
490 	obias = p->bias;
491 	obps = p->bps;
492 	obnext = p->bnext;
493 	osnext = p->snext;
494 
495 	/*
496 	 * Start conversion.
497 	 */
498 	odata += p->bfirst;
499 	for (f = todo * p->nch; f > 0; f--) {
500 		s = ((1U << 31) >> oshift) - obias;
501 		for (i = obps; i > 0; i--) {
502 			*odata = (unsigned char)s;
503 			s >>= 8;
504 			odata += obnext;
505 		}
506 		odata += osnext;
507 	}
508 }
509 
510 /*
511  * initialize encoder from native to foreign encoding
512  */
513 void
enc_init(struct conv * p,struct aparams * par,int nch)514 enc_init(struct conv *p, struct aparams *par, int nch)
515 {
516 	p->nch = nch;
517 	p->bps = par->bps;
518 	if (par->msb) {
519 		p->shift = 32 - par->bps * 8;
520 	} else {
521 		p->shift = 32 - par->bits;
522 	}
523 	if (par->sig) {
524 		p->bias = (1U << 31) >> p->shift;
525 	} else {
526 		p->bias = 0;
527 	}
528 	if (!par->le) {
529 		p->bfirst = par->bps - 1;
530 		p->bnext = -1;
531 		p->snext = 2 * par->bps;
532 	} else {
533 		p->bfirst = 0;
534 		p->bnext = 1;
535 		p->snext = 0;
536 	}
537 #ifdef DEBUG
538 	if (log_level >= 3) {
539 		log_puts("enc: ");
540 		aparams_log(par);
541 		log_puts(", ");
542 		log_puti(p->nch);
543 		log_puts(" channels\n");
544 	}
545 #endif
546 }
547 
548 /*
549  * decode "todo" frames from foreign to native encoding
550  */
551 void
dec_do(struct conv * p,unsigned char * in,unsigned char * out,int todo)552 dec_do(struct conv *p, unsigned char *in, unsigned char *out, int todo)
553 {
554 	unsigned int f;
555 	unsigned int ibps;
556 	unsigned int i;
557 	unsigned int s = 0xdeadbeef;
558 	unsigned char *idata;
559 	int ibnext;
560 	int isnext;
561 	unsigned int ibias;
562 	unsigned int ishift;
563 	adata_t *odata;
564 
565 #ifdef DEBUG
566 	if (log_level >= 4) {
567 		log_puts("dec: copying ");
568 		log_putu(todo);
569 		log_puts(" frames\n");
570 	}
571 #endif
572 	/*
573 	 * Partially copy structures into local variables, to avoid
574 	 * unnecessary indirections; this also allows the compiler to
575 	 * order local variables more "cache-friendly".
576 	 */
577 	idata = in;
578 	odata = (adata_t *)out;
579 	ibps = p->bps;
580 	ibnext = p->bnext;
581 	ibias = p->bias;
582 	ishift = p->shift;
583 	isnext = p->snext;
584 
585 	/*
586 	 * Start conversion.
587 	 */
588 	idata += p->bfirst;
589 	for (f = todo * p->nch; f > 0; f--) {
590 		for (i = ibps; i > 0; i--) {
591 			s <<= 8;
592 			s |= *idata;
593 			idata += ibnext;
594 		}
595 		idata += isnext;
596 		s += ibias;
597 		s <<= ishift;
598 		s >>= 32 - ADATA_BITS;
599 		*odata++ = s - ADATA_UNIT;
600 	}
601 }
602 
603 /*
604  * initialize decoder from foreign to native encoding
605  */
606 void
dec_init(struct conv * p,struct aparams * par,int nch)607 dec_init(struct conv *p, struct aparams *par, int nch)
608 {
609 	p->bps = par->bps;
610 	p->nch = nch;
611 	if (par->msb) {
612 		p->shift = 32 - par->bps * 8;
613 	} else {
614 		p->shift = 32 - par->bits;
615 	}
616 	if (par->sig) {
617 		p->bias = (1U << 31) >> p->shift;
618 	} else {
619 		p->bias = 0;
620 	}
621 	if (par->le) {
622 		p->bfirst = par->bps - 1;
623 		p->bnext = -1;
624 		p->snext = 2 * par->bps;
625 	} else {
626 		p->bfirst = 0;
627 		p->bnext = 1;
628 		p->snext = 0;
629 	}
630 #ifdef DEBUG
631 	if (log_level >= 3) {
632 		log_puts("dec: ");
633 		aparams_log(par);
634 		log_puts(", ");
635 		log_puti(p->nch);
636 		log_puts(" channels\n");
637 	}
638 #endif
639 }
640 
641 /*
642  * mix "todo" input frames on the output with the given volume
643  */
644 void
cmap_add(struct cmap * p,void * in,void * out,int vol,int todo)645 cmap_add(struct cmap *p, void *in, void *out, int vol, int todo)
646 {
647 	adata_t *idata, *odata;
648 	int i, j, nch, istart, inext, onext, ostart, y, v;
649 
650 #ifdef DEBUG
651 	if (log_level >= 4) {
652 		log_puts("cmap: adding ");
653 		log_puti(todo);
654 		log_puts(" frames\n");
655 	}
656 #endif
657 	idata = in;
658 	odata = out;
659 	ostart = p->ostart;
660 	onext = p->onext;
661 	istart = p->istart;
662 	inext = p->inext;
663 	nch = p->nch;
664 	v = vol;
665 
666 	/*
667 	 * map/mix input on the output
668 	 */
669 	for (i = todo; i > 0; i--) {
670 		odata += ostart;
671 		idata += istart;
672 		for (j = nch; j > 0; j--) {
673 			y = *odata + ADATA_MUL(*idata, v);
674 			if (y >= ADATA_UNIT)
675 				y = ADATA_UNIT - 1;
676 			else if (y < -ADATA_UNIT)
677 				y = -ADATA_UNIT;
678 			*odata = y;
679 			idata++;
680 			odata++;
681 		}
682 		odata += onext;
683 		idata += inext;
684 	}
685 }
686 
687 /*
688  * overwrite output with "todo" input frames with the given volume
689  */
690 void
cmap_copy(struct cmap * p,void * in,void * out,int vol,int todo)691 cmap_copy(struct cmap *p, void *in, void *out, int vol, int todo)
692 {
693 	adata_t *idata, *odata;
694 	int i, j, nch, istart, inext, onext, ostart, v;
695 
696 #ifdef DEBUG
697 	if (log_level >= 4) {
698 		log_puts("cmap: copying ");
699 		log_puti(todo);
700 		log_puts(" frames\n");
701 	}
702 #endif
703 	idata = in;
704 	odata = out;
705 	ostart = p->ostart;
706 	onext = p->onext;
707 	istart = p->istart;
708 	inext = p->inext;
709 	nch = p->nch;
710 	v = vol;
711 
712 	/*
713 	 * copy to the output buffer
714 	 */
715 	for (i = todo; i > 0; i--) {
716 		idata += istart;
717 		odata += ostart;
718 		for (j = nch; j > 0; j--) {
719 			*odata = ADATA_MUL(*idata, v);
720 			odata++;
721 			idata++;
722 		}
723 		odata += onext;
724 		idata += inext;
725 	}
726 }
727 
728 /*
729  * initialize channel mapper, to map a subset of input channel range
730  * into a subset of the output channel range
731  */
732 void
cmap_init(struct cmap * p,int imin,int imax,int isubmin,int isubmax,int omin,int omax,int osubmin,int osubmax)733 cmap_init(struct cmap *p,
734     int imin, int imax, int isubmin, int isubmax,
735     int omin, int omax, int osubmin, int osubmax)
736 {
737 	int cmin, cmax;
738 
739 	cmin = -NCHAN_MAX;
740 	if (osubmin > cmin)
741 		cmin = osubmin;
742 	if (omin > cmin)
743 		cmin = omin;
744 	if (isubmin > cmin)
745 		cmin = isubmin;
746 	if (imin > cmin)
747 		cmin = imin;
748 
749 	cmax = NCHAN_MAX;
750 	if (osubmax < cmax)
751 		cmax = osubmax;
752 	if (omax < cmax)
753 		cmax = omax;
754 	if (isubmax < cmax)
755 		cmax = isubmax;
756 	if (imax < cmax)
757 		cmax = imax;
758 
759 	p->ostart = cmin - omin;
760 	p->onext = omax - cmax;
761 	p->istart = cmin - imin;
762 	p->inext = imax - cmax;
763 	p->nch = cmax - cmin + 1;
764 #ifdef DEBUG
765 	if (log_level >= 3) {
766 		log_puts("cmap: nch = ");
767 		log_puti(p->nch);
768 		log_puts(", ostart = ");
769 		log_puti(p->ostart);
770 		log_puts(", onext = ");
771 		log_puti(p->onext);
772 		log_puts(", istart = ");
773 		log_puti(p->istart);
774 		log_puts(", inext = ");
775 		log_puti(p->inext);
776 		log_puts("\n");
777 	}
778 #endif
779 }
780