GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/aucat/dsp.c Lines: 0 374 0.0 %
Date: 2016-12-06 Branches: 0 192 0.0 %

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