diff options
author | Alexandre Ratchov <ratchov@cvs.openbsd.org> | 2008-12-19 08:01:07 +0000 |
---|---|---|
committer | Alexandre Ratchov <ratchov@cvs.openbsd.org> | 2008-12-19 08:01:07 +0000 |
commit | 115cced7bef29b4fe89043db1e51a1ddfeadbeb4 (patch) | |
tree | 5bf72ecc6e4a6bd3c05343a0e4e92e6c4388697c /usr.bin/aucat | |
parent | c75454f02be3fc0036cf18741387324d16c034f6 (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')
-rw-r--r-- | usr.bin/aucat/aproc.c | 56 | ||||
-rw-r--r-- | usr.bin/aucat/aproc.h | 8 |
2 files changed, 35 insertions, 29 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) diff --git a/usr.bin/aucat/aproc.h b/usr.bin/aucat/aproc.h index ffb33f93b58..910724169b4 100644 --- a/usr.bin/aucat/aproc.h +++ b/usr.bin/aucat/aproc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: aproc.h,v 1.13 2008/12/07 17:10:41 ratchov Exp $ */ +/* $OpenBSD: aproc.h,v 1.14 2008/12/19 08:01:06 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * @@ -142,9 +142,11 @@ struct aproc { int maxlat; /* max latency allowed*/ } sub; struct { - short ctx[NCHAN_MAX]; +#define RESAMP_NCTX 2 + unsigned ctx_start; + short ctx[NCHAN_MAX * RESAMP_NCTX]; unsigned iblksz, oblksz; - int ipos, opos; + int diff; int idelta, odelta; /* reminder of conv_[io]pos */ } resamp; struct { |