summaryrefslogtreecommitdiff
path: root/usr.bin/aucat/aproc.c
diff options
context:
space:
mode:
authorAlexandre Ratchov <ratchov@cvs.openbsd.org>2008-12-19 08:01:07 +0000
committerAlexandre Ratchov <ratchov@cvs.openbsd.org>2008-12-19 08:01:07 +0000
commit115cced7bef29b4fe89043db1e51a1ddfeadbeb4 (patch)
tree5bf72ecc6e4a6bd3c05343a0e4e92e6c4388697c /usr.bin/aucat/aproc.c
parentc75454f02be3fc0036cf18741387324d16c034f6 (diff)
use simple linear interpolation in the resampling code.
This partially removes the ``metallic'' noise audible especially when upsampling 8k -> 44.1k.
Diffstat (limited to 'usr.bin/aucat/aproc.c')
-rw-r--r--usr.bin/aucat/aproc.c56
1 files changed, 30 insertions, 26 deletions
diff --git a/usr.bin/aucat/aproc.c b/usr.bin/aucat/aproc.c
index 794a2b130b4..0474fdeb73c 100644
--- a/usr.bin/aucat/aproc.c
+++ b/usr.bin/aucat/aproc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: aproc.c,v 1.26 2008/12/07 17:10:41 ratchov Exp $ */
+/* $OpenBSD: aproc.c,v 1.27 2008/12/19 08:01:06 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -831,14 +831,16 @@ resamp_bcopy(struct aproc *p, struct abuf *ibuf, struct abuf *obuf)
{
unsigned inch;
short *idata;
- unsigned ipos, oblksz;
+ unsigned oblksz;
unsigned ifr;
unsigned onch;
+ int s1, s2, diff;
short *odata;
- unsigned opos, iblksz;
+ unsigned iblksz;
unsigned ofr;
unsigned c;
- short *ctxbuf, *ctx;
+ short *ctxbuf, *ctx;
+ unsigned ctx_start;
unsigned icount, ocount;
/*
@@ -857,45 +859,47 @@ resamp_bcopy(struct aproc *p, struct abuf *ibuf, struct abuf *obuf)
* unnecessary indirections; this also allows the compiler to
* order local variables more "cache-friendly".
*/
+ diff = p->u.resamp.diff;
inch = ibuf->cmax - ibuf->cmin + 1;
- ipos = p->u.resamp.ipos;
iblksz = p->u.resamp.iblksz;
onch = obuf->cmax - obuf->cmin + 1;
- opos = p->u.resamp.opos;
oblksz = p->u.resamp.oblksz;
ctxbuf = p->u.resamp.ctx;
+ ctx_start = p->u.resamp.ctx_start;
/*
* Start conversion.
*/
DPRINTFN(4, "resamp_bcopy: ifr=%d ofr=%d\n", ifr, ofr);
for (;;) {
- if ((int)(ipos - opos) > 0) {
- if (ofr == 0)
- break;
- ctx = ctxbuf;
- for (c = onch; c > 0; c--) {
- *odata = *ctx;
- odata++;
- ctx++;
- }
- opos += iblksz;
- ofr--;
- } else {
+ if (diff < 0) {
if (ifr == 0)
break;
- ctx = ctxbuf;
+ ctx_start ^= 1;
+ ctx = ctxbuf + ctx_start;
for (c = inch; c > 0; c--) {
*ctx = *idata;
idata++;
- ctx++;
+ ctx += RESAMP_NCTX;
}
- ipos += oblksz;
+ diff += oblksz;
ifr--;
+ } else {
+ if (ofr == 0)
+ break;
+ ctx = ctxbuf;
+ for (c = onch; c > 0; c--) {
+ s1 = ctxbuf[ctx_start];
+ s2 = ctxbuf[ctx_start ^ 1];
+ ctx += RESAMP_NCTX;
+ *odata++ = s1 + (s2 - s1) * diff / (int)oblksz;
+ }
+ diff -= iblksz;
+ ofr--;
}
}
- p->u.resamp.ipos = ipos;
- p->u.resamp.opos = opos;
+ p->u.resamp.diff = diff;
+ p->u.resamp.ctx_start = ctx_start;
DPRINTFN(4, "resamp_bcopy: done, ifr=%d ofr=%d\n", ifr, ofr);
/*
@@ -1009,11 +1013,11 @@ resamp_new(char *name, unsigned iblksz, unsigned oblksz)
p = aproc_new(&resamp_ops, name);
p->u.resamp.iblksz = iblksz;
p->u.resamp.oblksz = oblksz;
- p->u.resamp.ipos = 0;
- p->u.resamp.opos = 0;
+ p->u.resamp.diff = 0;
p->u.resamp.idelta = 0;
p->u.resamp.odelta = 0;
- for (i = 0; i < NCHAN_MAX; i++)
+ p->u.resamp.ctx_start = 0;
+ for (i = 0; i < NCHAN_MAX * RESAMP_NCTX; i++)
p->u.resamp.ctx[i] = 0;
#ifdef DEBUG
if (debug_level > 0)