GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/aucat/dsp.c Lines: 0 350 0.0 %
Date: 2017-11-13 Branches: 0 206 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: dsp.c,v 1.11 2016/09/30 08:43:23 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 "dsp.h"
18
#include "utils.h"
19
20
int aparams_ctltovol[128] = {
21
	    0,
22
	  256,	  266,	  276,	  287,	  299,	  310,	  323,	  335,
23
	  348,	  362,	  376,	  391,	  406,	  422,	  439,	  456,
24
	  474,	  493,	  512,	  532,	  553,	  575,	  597,	  621,
25
	  645,	  670,	  697,	  724,	  753,	  782,	  813,	  845,
26
	  878,	  912,	  948,	  985,	 1024,	 1064,	 1106,	 1149,
27
	 1195,	 1241,	 1290,	 1341,	 1393,	 1448,	 1505,	 1564,
28
	 1625,	 1689,	 1756,	 1825,	 1896,	 1971,	 2048,	 2128,
29
	 2212,	 2299,	 2389,	 2483,	 2580,	 2682,	 2787,	 2896,
30
	 3010,	 3128,	 3251,	 3379,	 3511,	 3649,	 3792,	 3941,
31
	 4096,	 4257,	 4424,	 4598,	 4778,	 4966,	 5161,	 5363,
32
	 5574,	 5793,	 6020,	 6256,	 6502,	 6757,	 7023,	 7298,
33
	 7585,	 7883,	 8192,	 8514,	 8848,	 9195,	 9556,	 9931,
34
	10321,	10726,	11148,	11585,	12040,	12513,	13004,	13515,
35
	14045,	14596,	15170,	15765,	16384,	17027,	17696,	18390,
36
	19112,	19863,	20643,	21453,	22295,	23170,	24080,	25025,
37
	26008,	27029,	28090,	29193,	30339,	31530,	32768
38
};
39
40
short dec_ulawmap[256] = {
41
	-32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
42
	-23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
43
	-15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
44
	-11900, -11388, -10876, -10364,  -9852,  -9340,  -8828,  -8316,
45
	 -7932,  -7676,  -7420,  -7164,  -6908,  -6652,  -6396,  -6140,
46
	 -5884,  -5628,  -5372,  -5116,  -4860,  -4604,  -4348,  -4092,
47
	 -3900,  -3772,  -3644,  -3516,  -3388,  -3260,  -3132,  -3004,
48
	 -2876,  -2748,  -2620,  -2492,  -2364,  -2236,  -2108,  -1980,
49
	 -1884,  -1820,  -1756,  -1692,  -1628,  -1564,  -1500,  -1436,
50
	 -1372,  -1308,  -1244,  -1180,  -1116,  -1052,   -988,   -924,
51
	  -876,   -844,   -812,   -780,   -748,   -716,   -684,   -652,
52
	  -620,   -588,   -556,   -524,   -492,   -460,   -428,   -396,
53
	  -372,   -356,   -340,   -324,   -308,   -292,   -276,   -260,
54
	  -244,   -228,   -212,   -196,   -180,   -164,   -148,   -132,
55
	  -120,   -112,   -104,    -96,    -88,    -80,    -72,    -64,
56
	   -56,    -48,    -40,    -32,    -24,    -16,     -8,      0,
57
	 32124,  31100,  30076,  29052,  28028,  27004,  25980,  24956,
58
	 23932,  22908,  21884,  20860,  19836,  18812,  17788,  16764,
59
	 15996,  15484,  14972,  14460,  13948,  13436,  12924,  12412,
60
	 11900,  11388,  10876,  10364,   9852,   9340,   8828,   8316,
61
	  7932,   7676,   7420,   7164,   6908,   6652,   6396,   6140,
62
	  5884,   5628,   5372,   5116,   4860,   4604,   4348,   4092,
63
	  3900,   3772,   3644,   3516,   3388,   3260,   3132,   3004,
64
	  2876,   2748,   2620,   2492,   2364,   2236,   2108,   1980,
65
	  1884,   1820,   1756,   1692,   1628,   1564,   1500,   1436,
66
	  1372,   1308,   1244,   1180,   1116,   1052,    988,    924,
67
	   876,    844,    812,    780,    748,    716,    684,    652,
68
	   620,    588,    556,    524,    492,    460,    428,    396,
69
	   372,    356,    340,    324,    308,    292,    276,    260,
70
	   244,    228,    212,    196,    180,    164,    148,    132,
71
	   120,    112,    104,     96,     88,     80,     72,     64,
72
	    56,     48,     40,     32,     24,     16,      8,      0
73
};
74
75
short dec_alawmap[256] = {
76
	 -5504,  -5248,  -6016,  -5760,  -4480,  -4224,  -4992,  -4736,
77
	 -7552,  -7296,  -8064,  -7808,  -6528,  -6272,  -7040,  -6784,
78
	 -2752,  -2624,  -3008,  -2880,  -2240,  -2112,  -2496,  -2368,
79
	 -3776,  -3648,  -4032,  -3904,  -3264,  -3136,  -3520,  -3392,
80
	-22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944,
81
	-30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136,
82
	-11008, -10496, -12032, -11520,  -8960,  -8448,  -9984,  -9472,
83
	-15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568,
84
	  -344,   -328,   -376,   -360,   -280,   -264,   -312,   -296,
85
	  -472,   -456,   -504,   -488,   -408,   -392,   -440,   -424,
86
	   -88,    -72,   -120,   -104,    -24,     -8,    -56,    -40,
87
	  -216,   -200,   -248,   -232,   -152,   -136,   -184,   -168,
88
	 -1376,  -1312,  -1504,  -1440,  -1120,  -1056,  -1248,  -1184,
89
	 -1888,  -1824,  -2016,  -1952,  -1632,  -1568,  -1760,  -1696,
90
	  -688,   -656,   -752,   -720,   -560,   -528,   -624,   -592,
91
	  -944,   -912,  -1008,   -976,   -816,   -784,   -880,   -848,
92
	  5504,   5248,   6016,   5760,   4480,   4224,   4992,   4736,
93
	  7552,   7296,   8064,   7808,   6528,   6272,   7040,   6784,
94
	  2752,   2624,   3008,   2880,   2240,   2112,   2496,   2368,
95
	  3776,   3648,   4032,   3904,   3264,   3136,   3520,   3392,
96
	 22016,  20992,  24064,  23040,  17920,  16896,  19968,  18944,
97
	 30208,  29184,  32256,  31232,  26112,  25088,  28160,  27136,
98
	 11008,  10496,  12032,  11520,   8960,   8448,   9984,   9472,
99
	 15104,  14592,  16128,  15616,  13056,  12544,  14080,  13568,
100
	   344,    328,    376,    360,    280,    264,    312,    296,
101
	   472,    456,    504,    488,    408,    392,    440,    424,
102
	    88,     72,    120,    104,     24,      8,     56,     40,
103
	   216,    200,    248,    232,    152,    136,    184,    168,
104
	  1376,   1312,   1504,   1440,   1120,   1056,   1248,   1184,
105
	  1888,   1824,   2016,   1952,   1632,   1568,   1760,   1696,
106
	   688,    656,    752,    720,    560,    528,    624,    592,
107
	   944,    912,   1008,    976,    816,    784,    880,    848
108
};
109
110
/*
111
 * Generate a string corresponding to the encoding in par,
112
 * return the length of the resulting string.
113
 */
114
int
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
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
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
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
262
aparams_native(struct aparams *par)
263
{
264
	return par->bps == sizeof(adata_t) && par->bits == ADATA_BITS &&
265
	    (par->bps == 1 || par->le == ADATA_LE) &&
266
	    (par->bits == par->bps * 8 || !par->msb);
267
}
268
269
/*
270
 * Return the number of input and output frame that would be consumed
271
 * by resamp_do(p, *icnt, *ocnt).
272
 */
273
void
274
resamp_getcnt(struct resamp *p, int *icnt, int *ocnt)
275
{
276
	long long idiff, odiff;
277
	int cdiff;
278
279
	cdiff = p->oblksz - p->diff;
280
	idiff = (long long)*icnt * p->oblksz;
281
	odiff = (long long)*ocnt * p->iblksz;
282
	if (odiff - idiff >= cdiff)
283
		*ocnt = (idiff + cdiff + p->iblksz - 1) / p->iblksz;
284
	else
285
		*icnt = (odiff + p->diff) / p->oblksz;
286
}
287
288
/*
289
 * Resample the given number of frames. The number of output frames
290
 * must match the coresponding number of input frames. Either always
291
 * use icnt and ocnt such that:
292
 *
293
 *	 icnt * oblksz = ocnt * iblksz
294
 *
295
 * or use resamp_getcnt() to calculate the proper numbers.
296
 */
297
void
298
resamp_do(struct resamp *p, adata_t *in, adata_t *out, int icnt, int ocnt)
299
{
300
	unsigned int nch;
301
	adata_t *idata;
302
	unsigned int oblksz;
303
	unsigned int ifr;
304
	int s, ds, diff;
305
	adata_t *odata;
306
	unsigned int iblksz;
307
	unsigned int ofr;
308
	unsigned int c;
309
	adata_t *ctxbuf, *ctx;
310
	unsigned int ctx_start;
311
312
	/*
313
	 * Partially copy structures into local variables, to avoid
314
	 * unnecessary indirections; this also allows the compiler to
315
	 * order local variables more "cache-friendly".
316
	 */
317
	idata = in;
318
	odata = out;
319
	diff = p->diff;
320
	iblksz = p->iblksz;
321
	oblksz = p->oblksz;
322
	ctxbuf = p->ctx;
323
	ctx_start = p->ctx_start;
324
	nch = p->nch;
325
	ifr = icnt;
326
	ofr = ocnt;
327
328
	/*
329
	 * Start conversion.
330
	 */
331
#ifdef DEBUG
332
	if (log_level >= 4) {
333
		log_puts("resamp: copying ");
334
		log_puti(ifr);
335
		log_puts(" -> ");
336
		log_putu(ofr);
337
		log_puts(" frames, diff = ");
338
		log_puti(diff);
339
		log_puts("\n");
340
	}
341
#endif
342
	for (;;) {
343
		if (diff >= oblksz) {
344
			if (ifr == 0)
345
				break;
346
			ctx_start ^= 1;
347
			ctx = ctxbuf + ctx_start;
348
			for (c = nch; c > 0; c--) {
349
				*ctx = *idata++;
350
				ctx += RESAMP_NCTX;
351
			}
352
			diff -= oblksz;
353
			ifr--;
354
		} else {
355
			if (ofr == 0)
356
				break;
357
			ctx = ctxbuf;
358
			for (c = nch; c > 0; c--) {
359
				s = ctx[ctx_start ^ 1];
360
				ds = ctx[ctx_start] - s;
361
				ctx += RESAMP_NCTX;
362
				*odata++ = s + ADATA_MULDIV(ds, diff, oblksz);
363
			}
364
			diff += iblksz;
365
			ofr--;
366
		}
367
	}
368
	p->diff = diff;
369
	p->ctx_start = ctx_start;
370
#ifdef DEBUG
371
	if (ifr != 0) {
372
		log_puts("resamp_do: ");
373
		log_puti(ifr);
374
		log_puts(": too many input frames\n");
375
		panic();
376
	}
377
	if (ofr != 0) {
378
		log_puts("resamp_do: ");
379
		log_puti(ofr);
380
		log_puts(": too many output frames\n");
381
		panic();
382
	}
383
#endif
384
}
385
386
static unsigned int
387
uint_gcd(unsigned int a, unsigned int b)
388
{
389
	unsigned int r;
390
391
	while (b > 0) {
392
		r = a % b;
393
		a = b;
394
		b = r;
395
	}
396
	return a;
397
}
398
399
/*
400
 * initialize resampler with ibufsz/obufsz factor and "nch" channels
401
 */
402
void
403
resamp_init(struct resamp *p, unsigned int iblksz,
404
    unsigned int oblksz, int nch)
405
{
406
	unsigned int i, g;
407
408
	/*
409
	 * reduce iblksz/oblksz fraction
410
	 */
411
	g = uint_gcd(iblksz, oblksz);
412
	iblksz /= g;
413
	oblksz /= g;
414
415
	/*
416
	 * ensure weird rates don't cause integer overflow
417
	 */
418
	while (iblksz > ADATA_UNIT || oblksz > ADATA_UNIT) {
419
		iblksz >>= 1;
420
		oblksz >>= 1;
421
	}
422
423
	p->iblksz = iblksz;
424
	p->oblksz = oblksz;
425
	p->diff = 0;
426
	p->nch = nch;
427
	p->ctx_start = 0;
428
	for (i = 0; i < NCHAN_MAX * RESAMP_NCTX; i++)
429
		p->ctx[i] = 0;
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), 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
}