summaryrefslogtreecommitdiff
path: root/usr.bin/aucat/aproc.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/aucat/aproc.c')
-rw-r--r--usr.bin/aucat/aproc.c729
1 files changed, 157 insertions, 572 deletions
diff --git a/usr.bin/aucat/aproc.c b/usr.bin/aucat/aproc.c
index 4f71392a335..318326bbb42 100644
--- a/usr.bin/aucat/aproc.c
+++ b/usr.bin/aucat/aproc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: aproc.c,v 1.49 2010/04/03 17:40:33 ratchov Exp $ */
+/* $OpenBSD: aproc.c,v 1.50 2010/04/03 17:59:17 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -48,18 +48,6 @@
#include "dbg.h"
#endif
-/*
- * Same as ABUF_ROK(), but consider that a buffer is
- * readable if there's silence pending to be inserted
- */
-#define MIX_ROK(buf) (ABUF_ROK(buf) || (buf)->r.mix.drop < 0)
-
-/*
- * Same as ABUF_WOK(), but consider that a buffer is
- * writeable if there are samples to drop
- */
-#define SUB_WOK(buf) (ABUF_WOK(buf) || (buf)->w.sub.silence < 0)
-
#ifdef DEBUG
void
aproc_dbg(struct aproc *p)
@@ -287,40 +275,20 @@ aproc_depend(struct aproc *p, struct aproc *dep)
}
int
-rfile_do(struct aproc *p, unsigned todo, unsigned *done)
-{
- struct abuf *obuf = LIST_FIRST(&p->obuflist);
- struct file *f = p->u.io.file;
- unsigned char *data;
- unsigned n, count, off;
-
- off = p->u.io.partial;
- data = abuf_wgetblk(obuf, &count, 0);
- if (count > todo)
- count = todo;
- n = file_read(f, data + off, count * obuf->bpf - off);
- if (n == 0)
- return 0;
- n += off;
- p->u.io.partial = n % obuf->bpf;
- count = n / obuf->bpf;
- if (count > 0)
- abuf_wcommit(obuf, count);
- if (done)
- *done = count;
- return 1;
-}
-
-int
rfile_in(struct aproc *p, struct abuf *ibuf_dummy)
{
struct abuf *obuf = LIST_FIRST(&p->obuflist);
struct file *f = p->u.io.file;
+ unsigned char *data;
+ unsigned count;
- if (!ABUF_WOK(obuf) || !(f->state & FILE_ROK))
+ if (ABUF_FULL(obuf) || !(f->state & FILE_ROK))
return 0;
- if (!rfile_do(p, obuf->len, NULL))
+ data = abuf_wgetblk(obuf, &count, 0);
+ count = file_read(f, data, count);
+ if (count == 0)
return 0;
+ abuf_wcommit(obuf, count);
if (!abuf_flush(obuf))
return 0;
return 1;
@@ -330,13 +298,18 @@ int
rfile_out(struct aproc *p, struct abuf *obuf)
{
struct file *f = p->u.io.file;
+ unsigned char *data;
+ unsigned count;
if (f->state & FILE_RINUSE)
return 0;
- if (!ABUF_WOK(obuf) || !(f->state & FILE_ROK))
+ if (ABUF_FULL(obuf) || !(f->state & FILE_ROK))
return 0;
- if (!rfile_do(p, obuf->len, NULL))
+ data = abuf_wgetblk(obuf, &count, 0);
+ count = file_read(f, data, count);
+ if (count == 0)
return 0;
+ abuf_wcommit(obuf, count);
return 1;
}
@@ -349,12 +322,6 @@ rfile_done(struct aproc *p)
if (f == NULL)
return;
/*
- * disconnect from file structure
- */
- f->rproc = NULL;
- p->u.io.file = NULL;
-
- /*
* all buffers must be detached before deleting f->wproc,
* because otherwise it could trigger this code again
*/
@@ -362,18 +329,11 @@ rfile_done(struct aproc *p)
if (obuf)
abuf_eof(obuf);
if (f->wproc) {
+ f->rproc = NULL;
aproc_del(f->wproc);
} else
file_del(f);
-
-#ifdef DEBUG
- if (debug_level >= 2 && p->u.io.partial > 0) {
- aproc_dbg(p);
- dbg_puts(": ");
- dbg_putu(p->u.io.partial);
- dbg_puts(" bytes lost in partial read\n");
- }
-#endif
+ p->u.io.file = NULL;
}
void
@@ -408,7 +368,6 @@ rfile_new(struct file *f)
p = aproc_new(&rfile_ops, f->name);
p->u.io.file = f;
- p->u.io.partial = 0;
f->rproc = p;
return p;
}
@@ -422,12 +381,6 @@ wfile_done(struct aproc *p)
if (f == NULL)
return;
/*
- * disconnect from file structure
- */
- f->wproc = NULL;
- p->u.io.file = NULL;
-
- /*
* all buffers must be detached before deleting f->rproc,
* because otherwise it could trigger this code again
*/
@@ -435,54 +388,29 @@ wfile_done(struct aproc *p)
if (ibuf)
abuf_hup(ibuf);
if (f->rproc) {
+ f->wproc = NULL;
aproc_del(f->rproc);
} else
file_del(f);
-#ifdef DEBUG
- if (debug_level >= 2 && p->u.io.partial > 0) {
- aproc_dbg(p);
- dbg_puts(": ");
- dbg_putu(p->u.io.partial);
- dbg_puts(" bytes lost in partial write\n");
- }
-#endif
+ p->u.io.file = NULL;
}
int
-wfile_do(struct aproc *p, unsigned todo, unsigned *done)
-{
- struct abuf *ibuf = LIST_FIRST(&p->ibuflist);
- struct file *f = p->u.io.file;
- unsigned char *data;
- unsigned n, count, off;
-
- off = p->u.io.partial;
- data = abuf_rgetblk(ibuf, &count, 0);
- if (count > todo)
- count = todo;
- n = file_write(f, data + off, count * ibuf->bpf - off);
- if (n == 0)
- return 0;
- n += off;
- p->u.io.partial = n % ibuf->bpf;
- count = n / ibuf->bpf;
- if (count > 0)
- abuf_rdiscard(ibuf, count);
- if (done)
- *done = count;
- return 1;
-}
-int
wfile_in(struct aproc *p, struct abuf *ibuf)
{
struct file *f = p->u.io.file;
+ unsigned char *data;
+ unsigned count;
if (f->state & FILE_WINUSE)
return 0;
- if (!ABUF_ROK(ibuf) || !(f->state & FILE_WOK))
+ if (ABUF_EMPTY(ibuf) || !(f->state & FILE_WOK))
return 0;
- if (!wfile_do(p, ibuf->len, NULL))
+ data = abuf_rgetblk(ibuf, &count, 0);
+ count = file_write(f, data, count);
+ if (count == 0)
return 0;
+ abuf_rdiscard(ibuf, count);
return 1;
}
@@ -491,13 +419,22 @@ wfile_out(struct aproc *p, struct abuf *obuf_dummy)
{
struct abuf *ibuf = LIST_FIRST(&p->ibuflist);
struct file *f = p->u.io.file;
+ unsigned char *data;
+ unsigned count;
if (!abuf_fill(ibuf))
return 0;
- if (!ABUF_ROK(ibuf) || !(f->state & FILE_WOK))
+ if (ABUF_EMPTY(ibuf) || !(f->state & FILE_WOK))
+ return 0;
+ data = abuf_rgetblk(ibuf, &count, 0);
+ if (count == 0) {
+ /* XXX: this can't happen, right ? */
return 0;
- if (!wfile_do(p, ibuf->len, NULL))
+ }
+ count = file_write(f, data, count);
+ if (count == 0)
return 0;
+ abuf_rdiscard(ibuf, count);
return 1;
}
@@ -533,83 +470,45 @@ wfile_new(struct file *f)
p = aproc_new(&wfile_ops, f->name);
p->u.io.file = f;
- p->u.io.partial = 0;
f->wproc = p;
return p;
}
/*
- * Drop as much as possible samples from the reader end,
- * negative values mean ``insert silence''.
- */
-void
-mix_drop(struct abuf *buf, int extra)
-{
- unsigned count;
-
- buf->r.mix.drop += extra;
- while (buf->r.mix.drop > 0) {
- count = buf->r.mix.drop;
- if (count > buf->used)
- count = buf->used;
- if (count == 0) {
-#ifdef DEBUG
- if (debug_level >= 4) {
- abuf_dbg(buf);
- dbg_puts(": drop: no data\n");
- }
-#endif
- return;
- }
- abuf_rdiscard(buf, count);
- buf->r.mix.drop -= count;
-#ifdef DEBUG
- if (debug_level >= 4) {
- abuf_dbg(buf);
- dbg_puts(": dropped ");
- dbg_putu(count);
- dbg_puts(", to drop = ");
- dbg_putu(buf->r.mix.drop);
- dbg_puts("\n");
- }
-#endif
- }
-}
-
-/*
* Append the given amount of silence (or less if there's not enough
- * space), and crank w.mix.todo accordingly.
+ * space), and crank mixitodo accordingly.
*/
void
-mix_bzero(struct abuf *obuf)
+mix_bzero(struct abuf *obuf, unsigned zcount)
{
short *odata;
unsigned ocount;
- odata = (short *)abuf_wgetblk(obuf, &ocount, obuf->w.mix.todo);
- if (ocount == 0)
- return;
- memset(odata, 0, ocount * obuf->bpf);
- obuf->w.mix.todo += ocount;
#ifdef DEBUG
if (debug_level >= 4) {
abuf_dbg(obuf);
dbg_puts(": bzero(");
- dbg_putu(obuf->w.mix.todo);
+ dbg_putu(zcount);
dbg_puts(")\n");
}
#endif
+ odata = (short *)abuf_wgetblk(obuf, &ocount, obuf->w.mix.todo);
+ ocount -= ocount % obuf->bpf;
+ if (ocount > zcount)
+ ocount = zcount;
+ memset(odata, 0, ocount);
+ obuf->w.mix.todo += ocount;
}
/*
* Mix an input block over an output block.
*/
-unsigned
+void
mix_badd(struct abuf *ibuf, struct abuf *obuf)
{
short *idata, *odata;
unsigned i, j, icnt, onext, ostart;
- unsigned scount, icount, ocount;
+ unsigned scount, icount, ocount, zcount;
int vol;
#ifdef DEBUG
@@ -619,37 +518,31 @@ mix_badd(struct abuf *ibuf, struct abuf *obuf)
dbg_putu(ibuf->r.mix.done);
dbg_puts("/");
dbg_putu(obuf->w.mix.todo);
- dbg_puts(", drop = ");
- dbg_puti(ibuf->r.mix.drop);
dbg_puts("\n");
}
#endif
/*
- * Insert silence for xrun correction
- */
- if (ibuf->r.mix.drop < 0) {
- icount = -ibuf->r.mix.drop;
- ocount = obuf->len - obuf->used;
- if (ocount > obuf->w.mix.todo)
- ocount = obuf->w.mix.todo;
- scount = (icount < ocount) ? icount : ocount;
- ibuf->r.mix.done += scount;
- ibuf->r.mix.drop += scount;
- }
-
- /*
* Calculate the maximum we can read.
*/
idata = (short *)abuf_rgetblk(ibuf, &icount, 0);
+ icount /= ibuf->bpf;
if (icount == 0)
- return 0;
+ return;
+
+ /*
+ * Zero-fill if necessary.
+ */
+ zcount = ibuf->r.mix.done + icount * obuf->bpf;
+ if (zcount > obuf->w.mix.todo)
+ mix_bzero(obuf, zcount - obuf->w.mix.todo);
/*
* Calculate the maximum we can write.
*/
odata = (short *)abuf_wgetblk(obuf, &ocount, ibuf->r.mix.done);
+ ocount /= obuf->bpf;
if (ocount == 0)
- return 0;
+ return;
vol = (ibuf->r.mix.weight * ibuf->r.mix.vol) >> ADATA_SHIFT;
ostart = ibuf->cmin - obuf->cmin;
@@ -665,30 +558,30 @@ mix_badd(struct abuf *ibuf, struct abuf *obuf)
}
odata += onext;
}
- abuf_rdiscard(ibuf, scount);
- ibuf->r.mix.done += scount;
+ abuf_rdiscard(ibuf, scount * ibuf->bpf);
+ ibuf->r.mix.done += scount * obuf->bpf;
#ifdef DEBUG
if (debug_level >= 4) {
abuf_dbg(ibuf);
dbg_puts(": badd: done = ");
+ dbg_putu(scount);
+ dbg_puts(", todo = ");
dbg_putu(ibuf->r.mix.done);
dbg_puts("/");
dbg_putu(obuf->w.mix.todo);
dbg_puts("\n");
}
#endif
- return scount;
}
/*
* Handle buffer underrun, return 0 if stream died.
*/
int
-mix_xrun(struct aproc *p, struct abuf *i)
+mix_xrun(struct abuf *i, struct abuf *obuf)
{
- struct abuf *obuf = LIST_FIRST(&p->obuflist);
- unsigned fdrop, remain;
+ unsigned fdrop;
if (i->r.mix.done > 0)
return 1;
@@ -696,34 +589,22 @@ mix_xrun(struct aproc *p, struct abuf *i)
abuf_hup(i);
return 0;
}
- fdrop = obuf->w.mix.todo;
+ mix_bzero(obuf, obuf->len);
+ fdrop = obuf->w.mix.todo / obuf->bpf;
#ifdef DEBUG
if (debug_level >= 3) {
abuf_dbg(i);
dbg_puts(": underrun, dropping ");
dbg_putu(fdrop);
dbg_puts(" + ");
- dbg_putu(i->r.mix.drop);
+ dbg_putu(i->drop / i->bpf);
dbg_puts("\n");
}
#endif
- i->r.mix.done += fdrop;
+ i->r.mix.done += fdrop * obuf->bpf;
if (i->r.mix.xrun == XRUN_SYNC)
- mix_drop(i, fdrop);
+ i->drop += fdrop * i->bpf;
else {
- remain = fdrop % p->u.mix.round;
- if (remain)
- remain = p->u.mix.round - remain;
- mix_drop(i, -(int)remain);
- fdrop += remain;
-#ifdef DEBUG
- if (debug_level >= 3) {
- abuf_dbg(i);
- dbg_puts(": underrun, adding ");
- dbg_putu(remain);
- dbg_puts("\n");
- }
-#endif
abuf_opos(i, -(int)fdrop);
if (i->duplex) {
#ifdef DEBUG
@@ -732,7 +613,7 @@ mix_xrun(struct aproc *p, struct abuf *i)
dbg_puts(": full-duplex resync\n");
}
#endif
- sub_silence(i->duplex, -(int)fdrop);
+ i->duplex->drop += fdrop * i->duplex->bpf;
abuf_ipos(i->duplex, -(int)fdrop);
}
}
@@ -744,8 +625,6 @@ mix_in(struct aproc *p, struct abuf *ibuf)
{
struct abuf *i, *inext, *obuf = LIST_FIRST(&p->obuflist);
unsigned odone;
- unsigned maxwrite;
- unsigned scount;
#ifdef DEBUG
if (debug_level >= 4) {
@@ -761,50 +640,27 @@ mix_in(struct aproc *p, struct abuf *ibuf)
dbg_puts("\n");
}
#endif
- if (!MIX_ROK(ibuf))
+ if (!ABUF_ROK(ibuf))
return 0;
- mix_bzero(obuf);
- scount = 0;
- odone = obuf->w.mix.todo;
+ odone = obuf->len;
for (i = LIST_FIRST(&p->ibuflist); i != NULL; i = inext) {
inext = LIST_NEXT(i, ient);
- if (i->r.mix.drop >= 0 && !abuf_fill(i))
+ if (!abuf_fill(i))
continue; /* eof */
- mix_drop(i, 0);
- scount += mix_badd(i, obuf);
+ mix_badd(i, obuf);
if (odone > i->r.mix.done)
odone = i->r.mix.done;
}
- if (LIST_EMPTY(&p->ibuflist) || scount == 0)
+ if (LIST_EMPTY(&p->ibuflist) || odone == 0)
return 0;
-#ifdef DEBUG
- if (debug_level >= 4) {
- aproc_dbg(p);
- dbg_puts(": maxwrite = ");
- dbg_putu(p->u.mix.maxlat);
- dbg_puts(" - ");
- dbg_putu(p->u.mix.lat);
- dbg_puts(" = ");
- dbg_putu(p->u.mix.maxlat - p->u.mix.lat);
- dbg_puts("\n");
- }
-#endif
- maxwrite = p->u.mix.maxlat - p->u.mix.lat;
- if (maxwrite > 0) {
- if (odone > maxwrite)
- odone = maxwrite;
- p->u.mix.lat += odone;
- p->u.mix.abspos += odone;
- LIST_FOREACH(i, &p->ibuflist, ient) {
- i->r.mix.done -= odone;
- }
- abuf_wcommit(obuf, odone);
- obuf->w.mix.todo -= odone;
- if (APROC_OK(p->u.mix.mon))
- mon_snoop(p->u.mix.mon, obuf, obuf->used - odone, odone);
- if (!abuf_flush(obuf))
- return 0; /* hup */
+ p->u.mix.lat += odone / obuf->bpf;
+ LIST_FOREACH(i, &p->ibuflist, ient) {
+ i->r.mix.done -= odone;
}
+ abuf_wcommit(obuf, odone);
+ obuf->w.mix.todo -= odone;
+ if (!abuf_flush(obuf))
+ return 0; /* hup */
return 1;
}
@@ -813,8 +669,6 @@ mix_out(struct aproc *p, struct abuf *obuf)
{
struct abuf *i, *inext;
unsigned odone;
- unsigned maxwrite;
- unsigned scount;
#ifdef DEBUG
if (debug_level >= 4) {
@@ -832,34 +686,18 @@ mix_out(struct aproc *p, struct abuf *obuf)
#endif
if (!ABUF_WOK(obuf))
return 0;
-#ifdef DEBUG
- if (debug_level >= 4) {
- aproc_dbg(p);
- dbg_puts(": maxwrite = ");
- dbg_putu(p->u.mix.maxlat);
- dbg_puts(" - ");
- dbg_putu(p->u.mix.lat);
- dbg_puts(" = ");
- dbg_putu(p->u.mix.maxlat - p->u.mix.lat);
- dbg_puts("\n");
- }
-#endif
- maxwrite = p->u.mix.maxlat - p->u.mix.lat;
- mix_bzero(obuf);
- scount = 0;
odone = obuf->len;
for (i = LIST_FIRST(&p->ibuflist); i != NULL; i = inext) {
inext = LIST_NEXT(i, ient);
- if (i->r.mix.drop >= 0 && !abuf_fill(i))
+ if (!abuf_fill(i))
continue; /* eof */
- mix_drop(i, 0);
- if (maxwrite > 0 && !MIX_ROK(i)) {
+ if (!ABUF_ROK(i)) {
if (p->flags & APROC_DROP) {
- if (!mix_xrun(p, i))
+ if (!mix_xrun(i, obuf))
continue;
}
} else
- scount += mix_badd(i, obuf);
+ mix_badd(i, obuf);
if (odone > i->r.mix.done)
odone = i->r.mix.done;
}
@@ -870,31 +708,25 @@ mix_out(struct aproc *p, struct abuf *obuf)
}
if (!(p->flags & APROC_DROP))
return 0;
+ mix_bzero(obuf, obuf->len);
odone = obuf->w.mix.todo;
- p->u.mix.idle += odone;
- }
- if (maxwrite > 0) {
- if (odone > maxwrite)
- odone = maxwrite;
- p->u.mix.lat += odone;
- p->u.mix.abspos += odone;
- LIST_FOREACH(i, &p->ibuflist, ient) {
- i->r.mix.done -= odone;
- }
- abuf_wcommit(obuf, odone);
- obuf->w.mix.todo -= odone;
- if (APROC_OK(p->u.mix.mon))
- mon_snoop(p->u.mix.mon, obuf, obuf->used - odone, odone);
+ p->u.mix.idle += odone / obuf->bpf;
}
- if (scount == 0)
+ if (odone == 0)
return 0;
+ p->u.mix.lat += odone / obuf->bpf;
+ LIST_FOREACH(i, &p->ibuflist, ient) {
+ i->r.mix.done -= odone;
+ }
+ abuf_wcommit(obuf, odone);
+ obuf->w.mix.todo -= odone;
return 1;
}
void
mix_eof(struct aproc *p, struct abuf *ibuf)
{
- struct abuf *i, *inext, *obuf = LIST_FIRST(&p->obuflist);
+ struct abuf *i, *obuf = LIST_FIRST(&p->obuflist);
unsigned odone;
mix_setmaster(p);
@@ -910,11 +742,8 @@ mix_eof(struct aproc *p, struct abuf *ibuf)
* Find a blocked input.
*/
odone = obuf->len;
- for (i = LIST_FIRST(&p->ibuflist); i != NULL; i = inext) {
- inext = LIST_NEXT(i, ient);
- if (!abuf_fill(i))
- continue;
- if (MIX_ROK(i) && i->r.mix.done < obuf->w.mix.todo) {
+ LIST_FOREACH(i, &p->ibuflist, ient) {
+ if (ABUF_ROK(i) && i->r.mix.done < obuf->w.mix.todo) {
abuf_run(i);
return;
}
@@ -952,7 +781,6 @@ mix_newin(struct aproc *p, struct abuf *ibuf)
ibuf->r.mix.weight = ADATA_UNIT;
ibuf->r.mix.maxweight = ADATA_UNIT;
ibuf->r.mix.xrun = XRUN_IGNORE;
- ibuf->r.mix.drop = 0;
}
void
@@ -962,8 +790,8 @@ mix_newout(struct aproc *p, struct abuf *obuf)
if (debug_level >= 3) {
aproc_dbg(p);
dbg_puts(": newin, will use ");
- dbg_putu(obuf->len);
- dbg_puts("\n");
+ dbg_putu(obuf->len / obuf->bpf);
+ dbg_puts(" fr\n");
}
#endif
obuf->w.mix.todo = 0;
@@ -972,7 +800,6 @@ mix_newout(struct aproc *p, struct abuf *obuf)
void
mix_opos(struct aproc *p, struct abuf *obuf, int delta)
{
- p->u.mix.lat -= delta;
#ifdef DEBUG
if (debug_level >= 4) {
aproc_dbg(p);
@@ -980,14 +807,13 @@ mix_opos(struct aproc *p, struct abuf *obuf, int delta)
dbg_puti(p->u.mix.lat);
dbg_puts("/");
dbg_puti(p->u.mix.maxlat);
- dbg_puts("\n");
+ dbg_puts(" fr\n");
}
#endif
- if (APROC_OK(p->u.mix.ctl))
+ p->u.mix.lat -= delta;
+ if (p->u.mix.ctl)
ctl_ontick(p->u.mix.ctl, delta);
aproc_opos(p, obuf, delta);
- if (APROC_OK(p->u.mix.mon))
- p->u.mix.mon->ops->ipos(p->u.mix.mon, NULL, delta);
}
struct aproc_ops mix_ops = {
@@ -1004,16 +830,14 @@ struct aproc_ops mix_ops = {
};
struct aproc *
-mix_new(char *name, int maxlat, unsigned round, struct aproc *ctl)
+mix_new(char *name, int maxlat, struct aproc *ctl)
{
struct aproc *p;
p = aproc_new(&mix_ops, name);
p->u.mix.idle = 0;
p->u.mix.lat = 0;
- p->u.mix.round = round;
p->u.mix.maxlat = maxlat;
- p->u.mix.abspos = 0;
p->u.mix.ctl = ctl;
return p;
}
@@ -1071,7 +895,6 @@ mix_clear(struct aproc *p)
struct abuf *obuf = LIST_FIRST(&p->obuflist);
p->u.mix.lat = 0;
- p->u.mix.abspos = 0;
obuf->w.mix.todo = 0;
}
@@ -1084,19 +907,16 @@ mix_prime(struct aproc *p)
for (;;) {
if (!ABUF_WOK(obuf))
break;
- todo = p->u.mix.maxlat - p->u.mix.lat;
+ todo = (p->u.mix.maxlat - p->u.mix.lat) * obuf->bpf;
if (todo == 0)
break;
- mix_bzero(obuf);
+ mix_bzero(obuf, obuf->len);
count = obuf->w.mix.todo;
if (count > todo)
count = todo;
obuf->w.mix.todo -= count;
- p->u.mix.lat += count;
- p->u.mix.abspos += count;
+ p->u.mix.lat += count / obuf->bpf;
abuf_wcommit(obuf, count);
- if (APROC_OK(p->u.mix.mon))
- mon_snoop(p->u.mix.mon, obuf, 0, count);
abuf_flush(obuf);
}
#ifdef DEBUG
@@ -1112,45 +932,6 @@ mix_prime(struct aproc *p)
}
/*
- * Append as much as possible silence on the writer end
- */
-void
-sub_silence(struct abuf *buf, int extra)
-{
- unsigned char *data;
- unsigned count;
-
- buf->w.sub.silence += extra;
- if (buf->w.sub.silence > 0) {
- data = abuf_wgetblk(buf, &count, 0);
- if (count >= buf->w.sub.silence)
- count = buf->w.sub.silence;
- if (count == 0) {
-#ifdef DEBUG
- if (debug_level >= 4) {
- abuf_dbg(buf);
- dbg_puts(": no space for silence\n");
- }
-#endif
- return;
- }
- memset(data, 0, count * buf->bpf);
- abuf_wcommit(buf, count);
- buf->w.sub.silence -= count;
-#ifdef DEBUG
- if (debug_level >= 4) {
- abuf_dbg(buf);
- dbg_puts(": appended ");
- dbg_putu(count);
- dbg_puts(", remaining silence = ");
- dbg_putu(buf->w.sub.silence);
- dbg_puts("\n");
- }
-#endif
- }
-}
-
-/*
* Copy data from ibuf to obuf.
*/
void
@@ -1160,21 +941,12 @@ sub_bcopy(struct abuf *ibuf, struct abuf *obuf)
unsigned i, j, ocnt, inext, istart;
unsigned icount, ocount, scount;
- /*
- * Drop samples for xrun correction
- */
- if (obuf->w.sub.silence < 0) {
- scount = -obuf->w.sub.silence;
- if (scount > ibuf->used)
- scount = ibuf->used;
- obuf->w.sub.done += scount;
- obuf->w.sub.silence += scount;
- }
-
idata = (short *)abuf_rgetblk(ibuf, &icount, obuf->w.sub.done);
+ icount /= ibuf->bpf;
if (icount == 0)
return;
odata = (short *)abuf_wgetblk(obuf, &ocount, 0);
+ ocount /= obuf->bpf;
if (ocount == 0)
return;
istart = obuf->cmin - ibuf->cmin;
@@ -1190,14 +962,14 @@ sub_bcopy(struct abuf *ibuf, struct abuf *obuf)
}
idata += inext;
}
- abuf_wcommit(obuf, scount);
- obuf->w.sub.done += scount;
+ abuf_wcommit(obuf, scount * obuf->bpf);
+ obuf->w.sub.done += scount * ibuf->bpf;
#ifdef DEBUG
if (debug_level >= 4) {
abuf_dbg(obuf);
dbg_puts(": bcopy ");
dbg_putu(scount);
- dbg_puts("\n");
+ dbg_puts(" fr\n");
}
#endif
}
@@ -1206,10 +978,9 @@ sub_bcopy(struct abuf *ibuf, struct abuf *obuf)
* Handle buffer overruns. Return 0 if the stream died.
*/
int
-sub_xrun(struct aproc *p, struct abuf *i)
+sub_xrun(struct abuf *ibuf, struct abuf *i)
{
- struct abuf *ibuf = LIST_FIRST(&p->ibuflist);
- unsigned fdrop, remain;
+ unsigned fdrop;
if (i->w.sub.done > 0)
return 1;
@@ -1217,35 +988,20 @@ sub_xrun(struct aproc *p, struct abuf *i)
abuf_eof(i);
return 0;
}
- fdrop = ibuf->used;
+ fdrop = ibuf->used / ibuf->bpf;
#ifdef DEBUG
if (debug_level >= 3) {
abuf_dbg(i);
dbg_puts(": overrun, silence ");
dbg_putu(fdrop);
dbg_puts(" + ");
- dbg_putu(i->w.sub.silence);
+ dbg_putu(i->silence / i->bpf);
dbg_puts("\n");
}
#endif
- i->w.sub.done += fdrop;
if (i->w.sub.xrun == XRUN_SYNC)
- sub_silence(i, fdrop);
+ i->silence += fdrop * i->bpf;
else {
- remain = fdrop % p->u.sub.round;
- if (remain)
- remain = p->u.sub.round - remain;
- sub_silence(i, -(int)remain);
- fdrop += remain;
-#ifdef DEBUG
- if (debug_level >= 3) {
- abuf_dbg(i);
- dbg_puts(": overrun, adding ");
- dbg_putu(remain);
- dbg_puts("\n");
- }
-#endif
-
abuf_ipos(i, -(int)fdrop);
if (i->duplex) {
#ifdef DEBUG
@@ -1254,10 +1010,11 @@ sub_xrun(struct aproc *p, struct abuf *i)
dbg_puts(": full-duplex resync\n");
}
#endif
- mix_drop(i->duplex, -(int)fdrop);
+ i->duplex->silence += fdrop * i->duplex->bpf;
abuf_opos(i->duplex, -(int)fdrop);
}
}
+ i->w.sub.done += fdrop * ibuf->bpf;
return 1;
}
@@ -1272,10 +1029,9 @@ sub_in(struct aproc *p, struct abuf *ibuf)
idone = ibuf->len;
for (i = LIST_FIRST(&p->obuflist); i != NULL; i = inext) {
inext = LIST_NEXT(i, oent);
- sub_silence(i, 0);
- if (!SUB_WOK(i)) {
+ if (!ABUF_WOK(i)) {
if (p->flags & APROC_DROP) {
- if (!sub_xrun(p, i))
+ if (!sub_xrun(ibuf, i))
continue;
}
} else
@@ -1293,7 +1049,7 @@ sub_in(struct aproc *p, struct abuf *ibuf)
if (!(p->flags & APROC_DROP))
return 0;
idone = ibuf->used;
- p->u.sub.idle += idone;
+ p->u.sub.idle += idone / ibuf->bpf;
}
if (idone == 0)
return 0;
@@ -1301,9 +1057,7 @@ sub_in(struct aproc *p, struct abuf *ibuf)
i->w.sub.done -= idone;
}
abuf_rdiscard(ibuf, idone);
- abuf_opos(ibuf, idone);
- p->u.sub.lat -= idone;
- p->u.sub.abspos += idone;
+ p->u.sub.lat -= idone / ibuf->bpf;
return 1;
}
@@ -1314,14 +1068,13 @@ sub_out(struct aproc *p, struct abuf *obuf)
struct abuf *i, *inext;
unsigned idone;
- if (!SUB_WOK(obuf))
+ if (!ABUF_WOK(obuf))
return 0;
if (!abuf_fill(ibuf))
return 0; /* eof */
idone = ibuf->len;
for (i = LIST_FIRST(&p->obuflist); i != NULL; i = inext) {
inext = LIST_NEXT(i, oent);
- sub_silence(i, 0);
sub_bcopy(ibuf, i);
if (idone > i->w.sub.done)
idone = i->w.sub.done;
@@ -1334,9 +1087,7 @@ sub_out(struct aproc *p, struct abuf *obuf)
i->w.sub.done -= idone;
}
abuf_rdiscard(ibuf, idone);
- abuf_opos(ibuf, idone);
- p->u.sub.lat -= idone;
- p->u.sub.abspos += idone;
+ p->u.sub.lat -= idone / ibuf->bpf;
return 1;
}
@@ -1349,7 +1100,7 @@ sub_eof(struct aproc *p, struct abuf *ibuf)
void
sub_hup(struct aproc *p, struct abuf *obuf)
{
- struct abuf *i, *inext, *ibuf = LIST_FIRST(&p->ibuflist);
+ struct abuf *i, *ibuf = LIST_FIRST(&p->ibuflist);
unsigned idone;
if (!aproc_inuse(p)) {
@@ -1363,11 +1114,8 @@ sub_hup(struct aproc *p, struct abuf *obuf)
* Find a blocked output.
*/
idone = ibuf->len;
- for (i = LIST_FIRST(&p->obuflist); i != NULL; i = inext) {
- inext = LIST_NEXT(i, oent);
- if (!abuf_flush(i))
- continue;
- if (SUB_WOK(i) && i->w.sub.done < ibuf->used) {
+ LIST_FOREACH(i, &p->obuflist, oent) {
+ if (ABUF_WOK(i) && i->w.sub.done < ibuf->used) {
abuf_run(i);
return;
}
@@ -1396,7 +1144,6 @@ sub_newout(struct aproc *p, struct abuf *obuf)
p->u.sub.idle = 0;
obuf->w.sub.done = 0;
obuf->w.sub.xrun = XRUN_IGNORE;
- obuf->w.sub.silence = 0;
}
void
@@ -1410,10 +1157,10 @@ sub_ipos(struct aproc *p, struct abuf *ibuf, int delta)
dbg_puti(p->u.sub.lat);
dbg_puts("/");
dbg_puti(p->u.sub.maxlat);
- dbg_puts("\n");
+ dbg_puts(" fr\n");
}
#endif
- if (APROC_OK(p->u.sub.ctl))
+ if (p->u.sub.ctl)
ctl_ontick(p->u.sub.ctl, delta);
aproc_ipos(p, ibuf, delta);
}
@@ -1432,16 +1179,14 @@ struct aproc_ops sub_ops = {
};
struct aproc *
-sub_new(char *name, int maxlat, unsigned round, struct aproc *ctl)
+sub_new(char *name, int maxlat, struct aproc *ctl)
{
struct aproc *p;
p = aproc_new(&sub_ops, name);
p->u.sub.idle = 0;
p->u.sub.lat = 0;
- p->u.sub.round = round;
p->u.sub.maxlat = maxlat;
- p->u.sub.abspos = 0;
p->u.sub.ctl = ctl;
return p;
}
@@ -1449,8 +1194,7 @@ sub_new(char *name, int maxlat, unsigned round, struct aproc *ctl)
void
sub_clear(struct aproc *p)
{
- p->u.sub.lat = 0;
- p->u.sub.abspos = 0;
+ p->u.mix.lat = 0;
}
/*
@@ -1477,10 +1221,12 @@ resamp_bcopy(struct aproc *p, struct abuf *ibuf, struct abuf *obuf)
* Calculate max frames readable at once from the input buffer.
*/
idata = (short *)abuf_rgetblk(ibuf, &icount, 0);
- ifr = icount;
+ ifr = icount / ibuf->bpf;
+ icount = ifr * ibuf->bpf;
odata = (short *)abuf_wgetblk(obuf, &ocount, 0);
- ofr = ocount;
+ ofr = ocount / obuf->bpf;
+ ocount = ofr * obuf->bpf;
/*
* Partially copy structures into local variables, to avoid
@@ -1512,8 +1258,6 @@ resamp_bcopy(struct aproc *p, struct abuf *ibuf, struct abuf *obuf)
#endif
for (;;) {
if (diff < 0) {
- if (ifr == 0)
- break;
ctx_start ^= 1;
ctx = ctxbuf + ctx_start;
for (c = inch; c > 0; c--) {
@@ -1521,10 +1265,9 @@ resamp_bcopy(struct aproc *p, struct abuf *ibuf, struct abuf *obuf)
ctx += RESAMP_NCTX;
}
diff += oblksz;
- ifr--;
- } else {
- if (ofr == 0)
+ if (--ifr == 0)
break;
+ } else {
ctx = ctxbuf;
for (c = onch; c > 0; c--) {
s1 = ctx[ctx_start];
@@ -1533,7 +1276,8 @@ resamp_bcopy(struct aproc *p, struct abuf *ibuf, struct abuf *obuf)
*odata++ = s1 + (s2 - s1) * diff / (int)oblksz;
}
diff -= iblksz;
- ofr--;
+ if (--ofr == 0)
+ break;
}
}
p->u.resamp.diff = diff;
@@ -1553,8 +1297,8 @@ resamp_bcopy(struct aproc *p, struct abuf *ibuf, struct abuf *obuf)
/*
* Update FIFO pointers.
*/
- icount -= ifr;
- ocount -= ofr;
+ icount -= ifr * ibuf->bpf;
+ ocount -= ofr * obuf->bpf;
abuf_rdiscard(ibuf, icount);
abuf_wcommit(obuf, ocount);
}
@@ -1677,9 +1421,11 @@ cmap_bcopy(struct aproc *p, struct abuf *ibuf, struct abuf *obuf)
* Calculate max frames readable at once from the input buffer.
*/
idata = (short *)abuf_rgetblk(ibuf, &icount, 0);
+ icount /= ibuf->bpf;
if (icount == 0)
return;
odata = (short *)abuf_wgetblk(obuf, &ocount, 0);
+ ocount /= obuf->bpf;
if (ocount == 0)
return;
scount = icount < ocount ? icount : ocount;
@@ -1710,8 +1456,8 @@ cmap_bcopy(struct aproc *p, struct abuf *ibuf, struct abuf *obuf)
dbg_puts(" fr\n");
}
#endif
- abuf_rdiscard(ibuf, scount);
- abuf_wcommit(obuf, scount);
+ abuf_rdiscard(ibuf, scount * ibuf->bpf);
+ abuf_wcommit(obuf, scount * obuf->bpf);
}
int
@@ -1809,9 +1555,11 @@ enc_bcopy(struct aproc *p, struct abuf *ibuf, struct abuf *obuf)
* Calculate max frames readable at once from the input buffer.
*/
idata = (short *)abuf_rgetblk(ibuf, &icount, 0);
+ icount /= ibuf->bpf;
if (icount == 0)
return;
odata = abuf_wgetblk(obuf, &ocount, 0);
+ ocount /= obuf->bpf;
if (ocount == 0)
return;
scount = (icount < ocount) ? icount : ocount;
@@ -1821,7 +1569,7 @@ enc_bcopy(struct aproc *p, struct abuf *ibuf, struct abuf *obuf)
aproc_dbg(p);
dbg_puts(": bcopy ");
dbg_putu(scount);
- dbg_puts(" fr / ");
+ dbg_puts(" fr * ");
dbg_putu(nch);
dbg_puts(" ch\n");
}
@@ -1857,8 +1605,8 @@ enc_bcopy(struct aproc *p, struct abuf *ibuf, struct abuf *obuf)
/*
* Update FIFO pointers.
*/
- abuf_rdiscard(ibuf, scount);
- abuf_wcommit(obuf, scount);
+ abuf_rdiscard(ibuf, scount * ibuf->bpf);
+ abuf_wcommit(obuf, scount * obuf->bpf);
}
int
@@ -1967,9 +1715,11 @@ dec_bcopy(struct aproc *p, struct abuf *ibuf, struct abuf *obuf)
* Calculate max frames readable at once from the input buffer.
*/
idata = abuf_rgetblk(ibuf, &icount, 0);
+ icount /= ibuf->bpf;
if (icount == 0)
return;
odata = (short *)abuf_wgetblk(obuf, &ocount, 0);
+ ocount /= obuf->bpf;
if (ocount == 0)
return;
scount = (icount < ocount) ? icount : ocount;
@@ -1979,7 +1729,7 @@ dec_bcopy(struct aproc *p, struct abuf *ibuf, struct abuf *obuf)
aproc_dbg(p);
dbg_puts(": bcopy ");
dbg_putu(scount);
- dbg_puts(" fr / ");
+ dbg_puts(" fr * ");
dbg_putu(nch);
dbg_puts(" ch\n");
}
@@ -2015,8 +1765,8 @@ dec_bcopy(struct aproc *p, struct abuf *ibuf, struct abuf *obuf)
/*
* Update FIFO pointers.
*/
- abuf_rdiscard(ibuf, scount);
- abuf_wcommit(obuf, scount);
+ abuf_rdiscard(ibuf, scount * ibuf->bpf);
+ abuf_wcommit(obuf, scount * obuf->bpf);
}
int
@@ -2102,168 +1852,3 @@ dec_new(char *name, struct aparams *par)
#endif
return p;
}
-
-/*
- * Commit and flush part of the output buffer
- */
-void
-mon_flush(struct aproc *p)
-{
- struct abuf *obuf = LIST_FIRST(&p->obuflist);
- unsigned count;
-
-#ifdef DEBUG
- if (debug_level >= 4) {
- aproc_dbg(p);
- dbg_puts(": delta = ");
- dbg_puti(p->u.mon.delta);
- dbg_puts("/");
- dbg_putu(p->u.mon.bufsz);
- dbg_puts(" pending = ");
- dbg_puti(p->u.mon.pending);
- dbg_puts("\n");
- }
-#endif
- if (p->u.mon.delta <= 0 || p->u.mon.pending == 0)
- return;
- count = p->u.mon.delta;
- if (count > p->u.mon.pending)
- count = p->u.mon.pending;
- abuf_wcommit(obuf, count);
- p->u.mon.pending -= count;
- p->u.mon.delta -= count;
- abuf_flush(obuf);
-}
-
-/*
- * Copy one block.
- */
-void
-mon_snoop(struct aproc *p, struct abuf *ibuf, unsigned pos, unsigned todo)
-{
- struct abuf *obuf = LIST_FIRST(&p->obuflist);
- unsigned scount, icount, ocount;
- short *idata, *odata;
-
-#ifdef DEBUG
- if (debug_level >= 4) {
- aproc_dbg(p);
- dbg_puts(": snoop ");
- dbg_putu(pos);
- dbg_puts("..");
- dbg_putu(todo);
- dbg_puts("\n");
- }
-#endif
- if (!abuf_flush(obuf))
- return;
-
- while (todo > 0) {
- /*
- * Calculate max frames readable at once from the input buffer.
- */
- idata = (short *)abuf_rgetblk(ibuf, &icount, pos);
- odata = (short *)abuf_wgetblk(obuf, &ocount, p->u.mon.pending);
- scount = (icount < ocount) ? icount : ocount;
-#ifdef DEBUG
- if (debug_level >= 4) {
- aproc_dbg(p);
- dbg_puts(": snooping ");
- dbg_putu(scount);
- dbg_puts(" fr\n");
- }
- if (scount == 0) {
- dbg_puts("monitor xrun, not allowed\n");
- dbg_panic();
- }
-#endif
- memcpy(odata, idata, scount * obuf->bpf);
- p->u.mon.pending += scount;
- todo -= scount;
- pos += scount;
- }
- mon_flush(p);
-}
-
-int
-mon_in(struct aproc *p, struct abuf *ibuf)
-{
-#ifdef DEBUG
- dbg_puts("monitor can't have inputs to read\n");
- dbg_panic();
-#endif
- return 0;
-}
-
-/*
- * put the monitor into ``empty'' state
- */
-void
-mon_clear(struct aproc *p)
-{
- p->u.mon.pending = 0;
- p->u.mon.delta = 0;
-}
-
-int
-mon_out(struct aproc *p, struct abuf *obuf)
-{
- /*
- * can't trigger monitored stream to produce data
- */
- return 0;
-}
-
-void
-mon_eof(struct aproc *p, struct abuf *ibuf)
-{
-#ifdef DEBUG
- dbg_puts("monitor can't have inputs to eof\n");
- dbg_panic();
-#endif
-}
-
-void
-mon_hup(struct aproc *p, struct abuf *obuf)
-{
- aproc_del(p);
-}
-
-void
-mon_ipos(struct aproc *p, struct abuf *ibuf, int delta)
-{
- aproc_ipos(p, ibuf, delta);
- p->u.mon.delta += delta;
- mon_flush(p);
-}
-
-struct aproc_ops mon_ops = {
- "mon",
- mon_in,
- mon_out,
- mon_eof,
- mon_hup,
- NULL,
- NULL,
- mon_ipos,
- aproc_opos,
- NULL
-};
-
-struct aproc *
-mon_new(char *name, unsigned bufsz)
-{
- struct aproc *p;
-
- p = aproc_new(&mon_ops, name);
- p->u.mon.pending = 0;
- p->u.mon.delta = 0;
- p->u.mon.bufsz = bufsz;
-#ifdef DEBUG
- if (debug_level >= 3) {
- aproc_dbg(p);
- dbg_puts(": new\n");
- }
-#endif
- return p;
-}