summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/aucat/abuf.c73
-rw-r--r--usr.bin/aucat/abuf.h8
-rw-r--r--usr.bin/aucat/aproc.c50
3 files changed, 72 insertions, 59 deletions
diff --git a/usr.bin/aucat/abuf.c b/usr.bin/aucat/abuf.c
index a3143d9ac18..a6f2ebc1bc9 100644
--- a/usr.bin/aucat/abuf.c
+++ b/usr.bin/aucat/abuf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: abuf.c,v 1.3 2008/08/14 09:39:16 ratchov Exp $ */
+/* $OpenBSD: abuf.c,v 1.4 2008/08/14 09:44:15 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -36,6 +36,7 @@
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include "conf.h"
#include "aproc.h"
@@ -60,6 +61,8 @@ abuf_new(unsigned nfr, unsigned bpf)
buf->len = len;
buf->used = 0;
buf->start = 0;
+ buf->silence = 0;
+ buf->drop = 0;
buf->rproc = NULL;
buf->wproc = NULL;
buf->data = (unsigned char *)buf + sizeof(*buf);
@@ -151,23 +154,73 @@ abuf_wgetblk(struct abuf *buf, unsigned *rsize, unsigned ofs)
}
/*
+ * flush buffer either by dropping samples or by calling the aproc
+ * call-back to consume data. Return 0 if blocked, 1 otherwise
+ */
+int
+abuf_flush_do(struct abuf *buf)
+{
+ struct aproc *p;
+ unsigned count;
+
+ if (buf->drop > 0) {
+ count = buf->drop;
+ if (count > buf->used)
+ count = buf->used;
+ abuf_rdiscard(buf, count);
+ buf->drop -= count;
+ DPRINTF("abuf_flush_do: drop = %u\n", buf->drop);
+ } else {
+ p = buf->rproc;
+ if (p == NULL || !p->ops->in(p, buf))
+ return 0;
+ }
+ return 1;
+}
+
+/*
* Notify the read end of the buffer that there is input available
* and that data can be processed again.
*/
void
abuf_flush(struct abuf *buf)
{
- struct aproc *p = buf->rproc;
-
for (;;) {
if (!ABUF_ROK(buf))
break;
- if (p == NULL || !p->ops->in(p, buf))
+ if (!abuf_flush_do(buf))
break;
}
}
/*
+ * fill the buffer either by generating silence or by calling the aproc
+ * call-back to provide data. Return 0 if blocked, 1 otherwise
+ */
+int
+abuf_fill_do(struct abuf *buf)
+{
+ struct aproc *p;
+ unsigned char *data;
+ unsigned count;
+
+ if (buf->silence > 0) {
+ data = abuf_wgetblk(buf, &count, 0);
+ if (count >= buf->silence)
+ count = buf->silence;
+ memset(data, 0, count);
+ abuf_wcommit(buf, count);
+ buf->silence -= count;
+ DPRINTF("abuf_fill_do: silence = %u\n", buf->silence);
+ } else {
+ p = buf->wproc;
+ if (p == NULL || !p->ops->out(p, buf))
+ return 0;
+ }
+ return 1;
+}
+
+/*
* Notify the write end of the buffer that there is room and data can be
* written again. This routine can only be called from the out()
* call-back of the reader.
@@ -178,12 +231,10 @@ abuf_flush(struct abuf *buf)
void
abuf_fill(struct abuf *buf)
{
- struct aproc *p = buf->wproc;
-
for (;;) {
if (!ABUF_WOK(buf))
break;
- if (p == NULL || !p->ops->out(p, buf))
+ if (!abuf_fill_do(buf))
break;
}
}
@@ -211,12 +262,10 @@ abuf_run(struct abuf *buf)
abuf_del(buf);
return;
}
- if (ABUF_WOK(buf) && canfill && buf->wproc) {
- p = buf->wproc;
- canfill = p->ops->out(p, buf);
+ if (ABUF_WOK(buf) && canfill) {
+ canfill = abuf_fill_do(buf);
} else if (ABUF_ROK(buf) && canflush) {
- p = buf->rproc;
- canflush = p->ops->in(p, buf);
+ canflush = abuf_flush_do(buf);
} else
break; /* can neither read nor write */
}
diff --git a/usr.bin/aucat/abuf.h b/usr.bin/aucat/abuf.h
index d7345e0dcd5..860a6c5be6b 100644
--- a/usr.bin/aucat/abuf.h
+++ b/usr.bin/aucat/abuf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: abuf.h,v 1.5 2008/08/14 09:39:16 ratchov Exp $ */
+/* $OpenBSD: abuf.h,v 1.6 2008/08/14 09:44:15 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -34,9 +34,7 @@ struct abuf {
int mixvol; /* input gain */
unsigned mixdone; /* input of mixer */
unsigned mixtodo; /* output of mixer */
- unsigned mixdrop; /* frames mix_in() will discard */
unsigned subdone; /* output if sub */
- unsigned subdrop; /* silence frames sub_out() will insert */
#define XRUN_IGNORE 0 /* on xrun silently insert/discard samples */
#define XRUN_SYNC 1 /* catchup to sync to the mix/sub */
#define XRUN_ERROR 2 /* xruns are errors, eof/hup buffer */
@@ -51,9 +49,11 @@ struct abuf {
unsigned start; /* offset where data starts */
unsigned used; /* valid data */
unsigned len; /* size of the ring */
+ unsigned silence; /* silence to insert on next write */
+ unsigned drop; /* frames to drop on next read */
struct aproc *rproc; /* reader */
struct aproc *wproc; /* writer */
- unsigned char *data; /* pointer to actual data (immediately following) */
+ unsigned char *data; /* actual data (immediately following) */
};
/*
diff --git a/usr.bin/aucat/aproc.c b/usr.bin/aucat/aproc.c
index b938bb6907d..b98959069b8 100644
--- a/usr.bin/aucat/aproc.c
+++ b/usr.bin/aucat/aproc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: aproc.c,v 1.6 2008/08/14 09:39:16 ratchov Exp $ */
+/* $OpenBSD: aproc.c,v 1.7 2008/08/14 09:44:15 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -320,25 +320,10 @@ int
mix_in(struct aproc *p, struct abuf *ibuf)
{
struct abuf *i, *inext, *obuf = LIST_FIRST(&p->obuflist);
- unsigned icount, ocount;
+ unsigned ocount;
- DPRINTFN(4, "mix_in: used = %u, done = %u, zero = %u\n",
+ DPRINTFN(4, "mix_in: used = %u, done = %u, todo = %u\n",
ibuf->used, ibuf->mixdone, obuf->mixtodo);
-
- /*
- * discard data already sent as silence
- */
- if (ibuf->mixdrop > 0) {
- icount = ibuf->mixdrop;
- if (icount > ibuf->used)
- icount = ibuf->used;
- ibuf->used -= icount;
- ibuf->start += icount;
- if (ibuf->start >= ibuf->len)
- ibuf->start -= ibuf->len;
- ibuf->mixdrop -= icount;
- DPRINTF("mix_in: catched xruns, drop = %u\n", ibuf->mixdrop);
- }
if (ibuf->mixdone >= obuf->mixtodo)
return 0;
@@ -394,9 +379,8 @@ mix_out(struct aproc *p, struct abuf *obuf)
drop = obuf->mixtodo;
i->mixdone += drop;
if (i->xrun == XRUN_SYNC)
- i->mixdrop += drop;
- DPRINTF("mix_out: xrun, drop = %u\n",
- i->mixdrop);
+ i->drop += drop;
+ DPRINTF("mix_out: drop = %u\n", i->drop);
}
} else
mix_badd(i, obuf);
@@ -458,7 +442,6 @@ void
mix_newin(struct aproc *p, struct abuf *ibuf)
{
ibuf->mixdone = 0;
- ibuf->mixdrop = 0;
ibuf->mixvol = ADATA_UNIT;
ibuf->xrun = XRUN_IGNORE;
}
@@ -539,10 +522,9 @@ sub_in(struct aproc *p, struct abuf *ibuf)
}
drop = ibuf->used;
if (i->xrun == XRUN_SYNC)
- i->subdrop += drop;
+ i->silence += drop;
i->subdone += drop;
- DPRINTF("sub_in: xrun, drop = %u\n",
- i->subdrop);
+ DPRINTF("sub_in: silence = %u\n", i->silence);
}
} else {
sub_bcopy(ibuf, i);
@@ -565,25 +547,8 @@ sub_out(struct aproc *p, struct abuf *obuf)
{
struct abuf *ibuf = LIST_FIRST(&p->ibuflist);
struct abuf *i, *inext;
- unsigned char *odata;
- unsigned ocount;
unsigned done;
- /*
- * generate silence for dropped samples
- */
- while (obuf->subdrop > 0) {
- odata = abuf_wgetblk(obuf, &ocount, 0);
- if (ocount >= obuf->subdrop)
- ocount = obuf->subdrop;
- if (ocount == 0)
- break;
- memset(odata, 0, ocount);
- obuf->used += ocount;
- obuf->subdrop -= ocount;
- DPRINTF("sub_out: catch, drop = %u\n", obuf->subdrop);
- }
-
if (obuf->subdone >= ibuf->used)
return 0;
@@ -653,7 +618,6 @@ void
sub_newout(struct aproc *p, struct abuf *obuf)
{
obuf->subdone = 0;
- obuf->subdrop = 0;
obuf->xrun = XRUN_IGNORE;
}