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