summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorAlexandre Ratchov <ratchov@cvs.openbsd.org>2010-01-10 21:47:42 +0000
committerAlexandre Ratchov <ratchov@cvs.openbsd.org>2010-01-10 21:47:42 +0000
commit37e6be3704bca205ce132f6b272639465cd841f4 (patch)
tree2a923a2c6b2319e21c555333db83e091842af53a /usr.bin
parentb039c5e2f74be6a127e392ec2effc1aebc324126 (diff)
Add traces to help tracking subtle timing bugs often causing
underuns and overruns; such bugs are hard to debug with ktrace or a debugger. They are also handy to debug or monitor code using aucat. To enable traces, compile aucat with ``make DEBUG=-DDEBUG'' and use the -d option multiple times. ok jakemsr
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/aucat/Makefile4
-rw-r--r--usr.bin/aucat/abuf.c246
-rw-r--r--usr.bin/aucat/aparams.c24
-rw-r--r--usr.bin/aucat/aproc.c368
-rw-r--r--usr.bin/aucat/aucat.c63
-rw-r--r--usr.bin/aucat/conf.h14
-rw-r--r--usr.bin/aucat/dbg.c153
-rw-r--r--usr.bin/aucat/dbg.h45
-rw-r--r--usr.bin/aucat/dev.c90
-rw-r--r--usr.bin/aucat/file.c264
-rw-r--r--usr.bin/aucat/headers.c6
-rw-r--r--usr.bin/aucat/midi.c210
-rw-r--r--usr.bin/aucat/miofile.c25
-rw-r--r--usr.bin/aucat/opt.c31
-rw-r--r--usr.bin/aucat/pipe.c15
-rw-r--r--usr.bin/aucat/safile.c45
-rw-r--r--usr.bin/aucat/sock.c497
-rw-r--r--usr.bin/aucat/wav.c15
18 files changed, 2100 insertions, 15 deletions
diff --git a/usr.bin/aucat/Makefile b/usr.bin/aucat/Makefile
index 5aad09ff145..f652c247fed 100644
--- a/usr.bin/aucat/Makefile
+++ b/usr.bin/aucat/Makefile
@@ -1,8 +1,8 @@
-# $OpenBSD: Makefile,v 1.10 2009/09/27 11:51:20 ratchov Exp $
+# $OpenBSD: Makefile,v 1.11 2010/01/10 21:47:41 ratchov Exp $
PROG= aucat
SRCS= aucat.c abuf.c aparams.c aproc.c dev.c midi.c file.c headers.c \
- safile.c miofile.c sock.c pipe.c listen.c opt.c wav.c legacy.c
+ safile.c miofile.c sock.c pipe.c listen.c opt.c wav.c legacy.c dbg.c
MAN= aucat.1 midicat.1
LINKS= ${BINDIR}/aucat ${BINDIR}/midicat
CFLAGS+= -Wall -Wstrict-prototypes -Wundef
diff --git a/usr.bin/aucat/abuf.c b/usr.bin/aucat/abuf.c
index 54f2436c21b..9c39c470dea 100644
--- a/usr.bin/aucat/abuf.c
+++ b/usr.bin/aucat/abuf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: abuf.c,v 1.16 2009/10/09 16:49:48 ratchov Exp $ */
+/* $OpenBSD: abuf.c,v 1.17 2010/01/10 21:47:41 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -41,7 +41,40 @@
#include "aparams.h"
#include "aproc.h"
#include "conf.h"
+#ifdef DEBUG
+#include "dbg.h"
+#endif
+#ifdef DEBUG
+void
+abuf_dbg(struct abuf *buf)
+{
+ if (buf->wproc) {
+ aproc_dbg(buf->wproc);
+ } else {
+ dbg_puts("none");
+ }
+ dbg_puts(buf->inuse ? "=>" : "->");
+ if (buf->rproc) {
+ aproc_dbg(buf->rproc);
+ } else {
+ dbg_puts("none");
+ }
+}
+
+void
+abuf_dump(struct abuf *buf)
+{
+ abuf_dbg(buf);
+ dbg_puts(": used = ");
+ dbg_putu(buf->used);
+ dbg_puts("/");
+ dbg_putu(buf->len);
+ dbg_puts(" start = ");
+ dbg_putu(buf->start);
+ dbg_puts("\n");
+}
+#endif
struct abuf *
abuf_new(unsigned nfr, struct aparams *par)
@@ -53,7 +86,16 @@ abuf_new(unsigned nfr, struct aparams *par)
len = nfr * bpf;
buf = malloc(sizeof(struct abuf) + len);
if (buf == NULL) {
+#ifdef DEBUG
+ dbg_puts("couldn't allocate abuf of ");
+ dbg_putu(nfr);
+ dbg_puts("fr * ");
+ dbg_putu(bpf);
+ dbg_puts("bpf\n");
+ dbg_panic();
+#else
err(1, "malloc");
+#endif
}
buf->bpf = bpf;
buf->cmin = par->cmin;
@@ -80,6 +122,28 @@ abuf_del(struct abuf *buf)
{
if (buf->duplex)
buf->duplex->duplex = NULL;
+#ifdef DEBUG
+ if (buf->rproc || buf->wproc) {
+ abuf_dbg(buf);
+ dbg_puts(": can't delete referenced buffer\n");
+ dbg_panic();
+ }
+ if (ABUF_ROK(buf)) {
+ /*
+ * XXX : we should call abort(), here.
+ * However, poll() doesn't seem to return POLLHUP,
+ * so the reader is never destroyed; instead it appears
+ * as blocked. Fix file_poll(), if fixable, and add
+ * a call to abord() here.
+ */
+ if (debug_level >= 3) {
+ abuf_dbg(buf);
+ dbg_puts(": deleting non-empty buffer, used = ");
+ dbg_putu(buf->used);
+ dbg_puts("\n");
+ }
+ }
+#endif
free(buf);
}
@@ -89,6 +153,12 @@ abuf_del(struct abuf *buf)
void
abuf_clear(struct abuf *buf)
{
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ abuf_dbg(buf);
+ dbg_puts(": cleared\n");
+ }
+#endif
buf->used = 0;
buf->start = 0;
buf->abspos = 0;
@@ -108,6 +178,15 @@ abuf_rgetblk(struct abuf *buf, unsigned *rsize, unsigned ofs)
used = buf->used - ofs;
if (start >= buf->len)
start -= buf->len;
+#ifdef DEBUG
+ if (start >= buf->len || used > buf->used) {
+ abuf_dump(buf);
+ dbg_puts(": rgetblk: bad ofs = ");
+ dbg_putu(ofs);
+ dbg_puts("\n");
+ dbg_panic();
+ }
+#endif
count = buf->len - start;
if (count > used)
count = used;
@@ -121,6 +200,15 @@ abuf_rgetblk(struct abuf *buf, unsigned *rsize, unsigned ofs)
void
abuf_rdiscard(struct abuf *buf, unsigned count)
{
+#ifdef DEBUG
+ if (count > buf->used) {
+ abuf_dump(buf);
+ dbg_puts(": rdiscard: bad count = ");
+ dbg_putu(count);
+ dbg_puts("\n");
+ dbg_panic();
+ }
+#endif
buf->used -= count;
buf->start += count;
if (buf->start >= buf->len)
@@ -134,6 +222,15 @@ abuf_rdiscard(struct abuf *buf, unsigned count)
void
abuf_wcommit(struct abuf *buf, unsigned count)
{
+#ifdef DEBUG
+ if (count > (buf->len - buf->used)) {
+ abuf_dump(buf);
+ dbg_puts(": rdiscard: bad count = ");
+ dbg_putu(count);
+ dbg_puts("\n");
+ dbg_panic();
+ }
+#endif
buf->used += count;
}
@@ -149,6 +246,15 @@ abuf_wgetblk(struct abuf *buf, unsigned *rsize, unsigned ofs)
end = buf->start + buf->used + ofs;
if (end >= buf->len)
end -= buf->len;
+#ifdef DEBUG
+ if (end >= buf->len) {
+ abuf_dump(buf);
+ dbg_puts(": rgetblk: bad ofs = ");
+ dbg_putu(ofs);
+ dbg_puts("\n");
+ dbg_panic();
+ }
+#endif
avail = buf->len - (buf->used + ofs);
count = buf->len - end;
if (count > avail)
@@ -172,14 +278,36 @@ abuf_flush_do(struct abuf *buf)
if (count > buf->used)
count = buf->used;
if (count == 0) {
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ abuf_dbg(buf);
+ dbg_puts(": flush: no data to drop\n");
+ }
+#endif
return 0;
}
abuf_rdiscard(buf, count);
buf->drop -= count;
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ abuf_dbg(buf);
+ dbg_puts(": flush: dropped ");
+ dbg_putu(count);
+ dbg_puts(", to drop = ");
+ dbg_putu(buf->drop);
+ dbg_puts("\n");
+ }
+#endif
} else {
p = buf->rproc;
if (!p)
return 0;
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ aproc_dbg(p);
+ dbg_puts(": in\n");
+ }
+#endif
if (!p->ops->in(p, buf))
return 0;
}
@@ -202,16 +330,38 @@ abuf_fill_do(struct abuf *buf)
if (count >= buf->silence)
count = buf->silence;
if (count == 0) {
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ abuf_dbg(buf);
+ dbg_puts(": fill: no space for silence\n");
+ }
+#endif
return 0;
}
memset(data, 0, count);
abuf_wcommit(buf, count);
buf->silence -= count;
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ abuf_dbg(buf);
+ dbg_puts(": fill: inerted ");
+ dbg_putu(count);
+ dbg_puts(", remaining silence = ");
+ dbg_putu(buf->silence);
+ dbg_puts("\n");
+ }
+#endif
p = buf->wproc;
} else {
p = buf->wproc;
if (!p)
return 0;
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ aproc_dbg(p);
+ dbg_puts(": out\n");
+ }
+#endif
if (!p->ops->out(p, buf)) {
return 0;
}
@@ -233,6 +383,12 @@ abuf_eof_do(struct abuf *buf)
buf->rproc = NULL;
LIST_REMOVE(buf, ient);
buf->inuse++;
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ aproc_dbg(p);
+ dbg_puts(": eof\n");
+ }
+#endif
p->ops->eof(p, buf);
buf->inuse--;
}
@@ -249,6 +405,14 @@ abuf_hup_do(struct abuf *buf)
struct aproc *p;
if (ABUF_ROK(buf)) {
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ abuf_dbg(buf);
+ dbg_puts(": hup: lost ");
+ dbg_putu(buf->used);
+ dbg_puts(" bytes\n");
+ }
+#endif
buf->used = 0;
}
p = buf->wproc;
@@ -256,6 +420,12 @@ abuf_hup_do(struct abuf *buf)
buf->wproc = NULL;
LIST_REMOVE(buf, oent);
buf->inuse++;
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ aproc_dbg(p);
+ dbg_puts(": hup\n");
+ }
+#endif
p->ops->hup(p, buf);
buf->inuse--;
}
@@ -270,6 +440,12 @@ int
abuf_flush(struct abuf *buf)
{
if (buf->inuse) {
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ abuf_dbg(buf);
+ dbg_puts(": flush blocked (inuse)\n");
+ }
+#endif
} else {
buf->inuse++;
for (;;) {
@@ -298,6 +474,12 @@ int
abuf_fill(struct abuf *buf)
{
if (buf->inuse) {
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ abuf_dbg(buf);
+ dbg_puts(": fill blocked (inuse)\n");
+ }
+#endif
} else {
buf->inuse++;
for (;;) {
@@ -327,6 +509,12 @@ abuf_run(struct abuf *buf)
int canfill = 1, canflush = 1;
if (buf->inuse) {
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ abuf_dbg(buf);
+ dbg_puts(": run blocked (inuse)\n");
+ }
+#endif
return;
}
buf->inuse++;
@@ -363,6 +551,17 @@ abuf_run(struct abuf *buf)
void
abuf_eof(struct abuf *buf)
{
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ abuf_dbg(buf);
+ dbg_puts(": eof requested\n");
+ }
+ if (buf->wproc == NULL) {
+ abuf_dbg(buf);
+ dbg_puts(": eof, no writer\n");
+ dbg_panic();
+ }
+#endif
LIST_REMOVE(buf, oent);
buf->wproc = NULL;
if (buf->rproc != NULL) {
@@ -373,10 +572,22 @@ abuf_eof(struct abuf *buf)
* Could not flush everything, the reader will
* have a chance to delete the abuf later.
*/
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ abuf_dbg(buf);
+ dbg_puts(": eof, blocked (drain)\n");
+ }
+#endif
return;
}
}
if (buf->inuse) {
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ abuf_dbg(buf);
+ dbg_puts(": eof, blocked (inuse)\n");
+ }
+#endif
return;
}
abuf_eof_do(buf);
@@ -389,10 +600,27 @@ abuf_eof(struct abuf *buf)
void
abuf_hup(struct abuf *buf)
{
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ abuf_dbg(buf);
+ dbg_puts(": hup requested\n");
+ }
+ if (buf->rproc == NULL) {
+ abuf_dbg(buf);
+ dbg_puts(": hup, no reader\n");
+ dbg_panic();
+ }
+#endif
buf->rproc = NULL;
LIST_REMOVE(buf, ient);
if (buf->wproc != NULL) {
if (buf->inuse) {
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ abuf_dbg(buf);
+ dbg_puts(": eof, blocked (inuse)\n");
+ }
+#endif
return;
}
}
@@ -409,6 +637,14 @@ abuf_ipos(struct abuf *buf, int delta)
if (p && p->ops->ipos) {
buf->inuse++;
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ aproc_dbg(p);
+ dbg_puts(": ipos delta = ");
+ dbg_puti(delta);
+ dbg_puts("\n");
+ }
+#endif
p->ops->ipos(p, buf, delta);
buf->inuse--;
}
@@ -426,6 +662,14 @@ abuf_opos(struct abuf *buf, int delta)
if (p && p->ops->opos) {
buf->inuse++;
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ aproc_dbg(p);
+ dbg_puts(": opos delta = ");
+ dbg_puti(delta);
+ dbg_puts("\n");
+ }
+#endif
p->ops->opos(p, buf, delta);
buf->inuse--;
}
diff --git a/usr.bin/aucat/aparams.c b/usr.bin/aucat/aparams.c
index eabdd0a80f4..ad3c2a1abda 100644
--- a/usr.bin/aucat/aparams.c
+++ b/usr.bin/aucat/aparams.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: aparams.c,v 1.9 2009/09/27 11:51:20 ratchov Exp $ */
+/* $OpenBSD: aparams.c,v 1.10 2010/01/10 21:47:41 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -16,6 +16,9 @@
*/
#include "aparams.h"
+#ifdef DEBUG
+#include "dbg.h"
+#endif
int aparams_ctltovol[128] = {
0,
@@ -181,6 +184,25 @@ aparams_init(struct aparams *par, unsigned cmin, unsigned cmax, unsigned rate)
par->rate = rate;
}
+#ifdef DEBUG
+/*
+ * Print the format/channels/encoding on stderr.
+ */
+void
+aparams_dbg(struct aparams *par)
+{
+ char enc[ENCMAX];
+
+ aparams_enctostr(par, enc);
+ dbg_puts(enc);
+ dbg_puts(",");
+ dbg_putu(par->cmin);
+ dbg_puts(":");
+ dbg_putu(par->cmax);
+ dbg_puts(",");
+ dbg_putu(par->rate);
+}
+#endif
/*
* Return true if both encodings are the same.
diff --git a/usr.bin/aucat/aproc.c b/usr.bin/aucat/aproc.c
index 1e53a8f6c4d..c0a6010bfb4 100644
--- a/usr.bin/aucat/aproc.c
+++ b/usr.bin/aucat/aproc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: aproc.c,v 1.41 2010/01/05 10:18:12 ratchov Exp $ */
+/* $OpenBSD: aproc.c,v 1.42 2010/01/10 21:47:41 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -44,7 +44,100 @@
#include "conf.h"
#include "file.h"
#include "midi.h"
+#ifdef DEBUG
+#include "dbg.h"
+#endif
+#ifdef DEBUG
+void
+aproc_dbg(struct aproc *p)
+{
+ dbg_puts(p->ops->name);
+ dbg_puts("(");
+ dbg_puts(p->name);
+ dbg_puts(")");
+}
+
+int
+zomb_in(struct aproc *p, struct abuf *ibuf)
+{
+ aproc_dbg(p);
+ dbg_puts(": in: terminated\n");
+ dbg_panic();
+ return 0;
+}
+
+
+int
+zomb_out(struct aproc *p, struct abuf *obuf)
+{
+ aproc_dbg(p);
+ dbg_puts(": out: terminated\n");
+ dbg_panic();
+ return 0;
+}
+
+void
+zomb_eof(struct aproc *p, struct abuf *ibuf)
+{
+ aproc_dbg(p);
+ dbg_puts(": eof: terminated\n");
+ dbg_panic();
+}
+
+void
+zomb_hup(struct aproc *p, struct abuf *obuf)
+{
+ aproc_dbg(p);
+ dbg_puts(": hup: terminated\n");
+ dbg_panic();
+}
+
+void
+zomb_newin(struct aproc *p, struct abuf *ibuf)
+{
+ aproc_dbg(p);
+ dbg_puts(": newin: terminated\n");
+ dbg_panic();
+}
+
+void
+zomb_newout(struct aproc *p, struct abuf *obuf)
+{
+ aproc_dbg(p);
+ dbg_puts(": newout: terminated\n");
+ dbg_panic();
+}
+
+void
+zomb_ipos(struct aproc *p, struct abuf *ibuf, int delta)
+{
+ aproc_dbg(p);
+ dbg_puts(": ipos: terminated\n");
+ dbg_panic();
+}
+
+void
+zomb_opos(struct aproc *p, struct abuf *obuf, int delta)
+{
+ aproc_dbg(p);
+ dbg_puts(": opos: terminated\n");
+ dbg_panic();
+}
+
+struct aproc_ops zomb_ops = {
+ "zomb",
+ zomb_in,
+ zomb_out,
+ zomb_eof,
+ zomb_hup,
+ zomb_newin,
+ zomb_newout,
+ zomb_ipos,
+ zomb_opos,
+ NULL
+};
+#endif
struct aproc *
aproc_new(struct aproc_ops *ops, char *name)
@@ -69,7 +162,19 @@ aproc_del(struct aproc *p)
struct abuf *i;
if (!(p->flags & APROC_ZOMB)) {
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ aproc_dbg(p);
+ dbg_puts(": terminating...\n");
+ }
+#endif
if (p->ops->done) {
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ aproc_dbg(p);
+ dbg_puts(": done\n");
+ }
+#endif
p->ops->done(p);
}
while (!LIST_EMPTY(&p->ibuflist)) {
@@ -83,8 +188,21 @@ aproc_del(struct aproc *p)
p->flags |= APROC_ZOMB;
}
if (p->refs > 0) {
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ aproc_dbg(p);
+ dbg_puts(": free delayed\n");
+ p->ops = &zomb_ops;
+ }
+#endif
return;
}
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ aproc_dbg(p);
+ dbg_puts(": freed\n");
+ }
+#endif
free(p);
}
@@ -366,6 +484,14 @@ mix_bzero(struct abuf *obuf, unsigned zcount)
short *odata;
unsigned ocount;
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ abuf_dbg(obuf);
+ dbg_puts(": bzero(");
+ dbg_putu(zcount);
+ dbg_puts(")\n");
+ }
+#endif
odata = (short *)abuf_wgetblk(obuf, &ocount, obuf->w.mix.todo);
ocount -= ocount % obuf->bpf;
if (ocount > zcount)
@@ -385,6 +511,16 @@ mix_badd(struct abuf *ibuf, struct abuf *obuf)
unsigned scount, icount, ocount, zcount;
int vol;
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ abuf_dbg(ibuf);
+ dbg_puts(": badd: todo = ");
+ dbg_putu(obuf->w.mix.todo);
+ dbg_puts("/");
+ dbg_putu(ibuf->r.mix.done);
+ dbg_puts("\n");
+ }
+#endif
/*
* Calculate the maximum we can read.
*/
@@ -425,6 +561,18 @@ mix_badd(struct abuf *ibuf, struct abuf *obuf)
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
}
/*
@@ -443,12 +591,28 @@ mix_xrun(struct abuf *i, struct abuf *obuf)
}
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->drop / i->bpf);
+ dbg_puts("\n");
+ }
+#endif
i->r.mix.done += fdrop * obuf->bpf;
if (i->r.mix.xrun == XRUN_SYNC)
i->drop += fdrop * i->bpf;
else {
abuf_opos(i, -(int)fdrop);
if (i->duplex) {
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ abuf_dbg(i->duplex);
+ dbg_puts(": full-duplex resync\n");
+ }
+#endif
i->duplex->drop += fdrop * i->duplex->bpf;
abuf_ipos(i->duplex, -(int)fdrop);
}
@@ -462,6 +626,20 @@ mix_in(struct aproc *p, struct abuf *ibuf)
struct abuf *i, *inext, *obuf = LIST_FIRST(&p->obuflist);
unsigned odone;
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ aproc_dbg(p);
+ dbg_puts(": used = ");
+ dbg_putu(ibuf->used);
+ dbg_puts("/");
+ dbg_putu(ibuf->len);
+ dbg_puts(", todo = ");
+ dbg_putu(obuf->w.mix.todo);
+ dbg_puts("/");
+ dbg_putu(ibuf->r.mix.done);
+ dbg_puts("\n");
+ }
+#endif
if (!ABUF_ROK(ibuf))
return 0;
odone = obuf->len;
@@ -492,6 +670,20 @@ mix_out(struct aproc *p, struct abuf *obuf)
struct abuf *i, *inext;
unsigned odone;
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ aproc_dbg(p);
+ dbg_puts(": used = ");
+ dbg_putu(obuf->used);
+ dbg_puts("/");
+ dbg_putu(obuf->len);
+ dbg_puts(", todo = ");
+ dbg_putu(obuf->w.mix.todo);
+ dbg_puts("/");
+ dbg_putu(obuf->len);
+ dbg_puts("\n");
+ }
+#endif
if (!ABUF_WOK(obuf))
return 0;
odone = obuf->len;
@@ -540,6 +732,12 @@ mix_eof(struct aproc *p, struct abuf *ibuf)
mix_setmaster(p);
if (!aproc_inuse(p)) {
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ aproc_dbg(p);
+ dbg_puts(": running other streams\n");
+ }
+#endif
/*
* Find a blocked input.
*/
@@ -569,6 +767,14 @@ mix_hup(struct aproc *p, struct abuf *obuf)
void
mix_newin(struct aproc *p, struct abuf *ibuf)
{
+#ifdef DEBUG
+ struct abuf *obuf = LIST_FIRST(&p->obuflist);
+
+ if (!obuf || ibuf->cmin < obuf->cmin || ibuf->cmax > obuf->cmax) {
+ dbg_puts("newin: channel ranges mismatch\n");
+ dbg_panic();
+ }
+#endif
p->u.mix.idle = 0;
ibuf->r.mix.done = 0;
ibuf->r.mix.vol = ADATA_UNIT;
@@ -580,12 +786,30 @@ mix_newin(struct aproc *p, struct abuf *ibuf)
void
mix_newout(struct aproc *p, struct abuf *obuf)
{
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ aproc_dbg(p);
+ dbg_puts(": newin, will use ");
+ dbg_putu(obuf->len / obuf->bpf);
+ dbg_puts(" fr\n");
+ }
+#endif
obuf->w.mix.todo = 0;
}
void
mix_opos(struct aproc *p, struct abuf *obuf, int delta)
{
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ aproc_dbg(p);
+ dbg_puts(": opos: lat = ");
+ dbg_puti(p->u.mix.lat);
+ dbg_puts("/");
+ dbg_puti(p->u.mix.maxlat);
+ dbg_puts(" fr\n");
+ }
+#endif
p->u.mix.lat -= delta;
if (p->u.mix.ctl)
ctl_ontick(p->u.mix.ctl, delta);
@@ -652,6 +876,16 @@ mix_setmaster(struct aproc *p)
if (weight > i->r.mix.maxweight)
weight = i->r.mix.maxweight;
i->r.mix.weight = weight;
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ abuf_dbg(i);
+ dbg_puts(": setmaster: ");
+ dbg_puti(i->r.mix.weight);
+ dbg_puts("/");
+ dbg_puti(i->r.mix.maxweight);
+ dbg_puts("\n");
+ }
+#endif
}
}
@@ -697,6 +931,14 @@ sub_bcopy(struct abuf *ibuf, struct abuf *obuf)
}
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(" fr\n");
+ }
+#endif
}
/*
@@ -714,11 +956,27 @@ sub_xrun(struct abuf *ibuf, struct abuf *i)
return 0;
}
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->silence / i->bpf);
+ dbg_puts("\n");
+ }
+#endif
if (i->w.sub.xrun == XRUN_SYNC)
i->silence += fdrop * i->bpf;
else {
abuf_ipos(i, -(int)fdrop);
if (i->duplex) {
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ abuf_dbg(i->duplex);
+ dbg_puts(": full-duplex resync\n");
+ }
+#endif
i->duplex->silence += fdrop * i->duplex->bpf;
abuf_opos(i->duplex, -(int)fdrop);
}
@@ -813,6 +1071,12 @@ sub_hup(struct aproc *p, struct abuf *obuf)
unsigned idone;
if (!aproc_inuse(p)) {
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ aproc_dbg(p);
+ dbg_puts(": running other streams\n");
+ }
+#endif
/*
* Find a blocked output.
*/
@@ -836,6 +1100,14 @@ sub_hup(struct aproc *p, struct abuf *obuf)
void
sub_newout(struct aproc *p, struct abuf *obuf)
{
+#ifdef DEBUG
+ struct abuf *ibuf = LIST_FIRST(&p->ibuflist);
+
+ if (!ibuf || obuf->cmin < ibuf->cmin || obuf->cmax > ibuf->cmax) {
+ dbg_puts("newout: channel ranges mismatch\n");
+ dbg_panic();
+ }
+#endif
p->u.sub.idle = 0;
obuf->w.sub.done = 0;
obuf->w.sub.xrun = XRUN_IGNORE;
@@ -845,6 +1117,16 @@ void
sub_ipos(struct aproc *p, struct abuf *ibuf, int delta)
{
p->u.sub.lat += delta;
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ aproc_dbg(p);
+ dbg_puts(": ipos: lat = ");
+ dbg_puti(p->u.sub.lat);
+ dbg_puts("/");
+ dbg_puti(p->u.sub.maxlat);
+ dbg_puts(" fr\n");
+ }
+#endif
if (p->u.sub.ctl)
ctl_ontick(p->u.sub.ctl, delta);
aproc_ipos(p, ibuf, delta);
@@ -929,6 +1211,16 @@ resamp_bcopy(struct aproc *p, struct abuf *ibuf, struct abuf *obuf)
/*
* Start conversion.
*/
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ aproc_dbg(p);
+ dbg_puts(": resamp starting ifr = ");
+ dbg_putu(ifr);
+ dbg_puts(", ofr = ");
+ dbg_puti(ofr);
+ dbg_puts(" fr\n");
+ }
+#endif
for (;;) {
if (diff < 0) {
if (ifr == 0)
@@ -957,6 +1249,16 @@ resamp_bcopy(struct aproc *p, struct abuf *ibuf, struct abuf *obuf)
}
p->u.resamp.diff = diff;
p->u.resamp.ctx_start = ctx_start;
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ aproc_dbg(p);
+ dbg_puts(": resamp done ifr = ");
+ dbg_putu(ifr);
+ dbg_puts(", ofr = ");
+ dbg_puti(ofr);
+ dbg_puts(" fr\n");
+ }
+#endif
/*
* Update FIFO pointers.
*/
@@ -1062,6 +1364,16 @@ resamp_new(char *name, unsigned iblksz, unsigned oblksz)
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 >= 3) {
+ aproc_dbg(p);
+ dbg_puts(": new ");
+ dbg_putu(iblksz);
+ dbg_puts("/");
+ dbg_putu(oblksz);
+ dbg_puts("\n");
+ }
+#endif
return p;
}
@@ -1109,6 +1421,14 @@ cmap_bcopy(struct aproc *p, struct abuf *ibuf, struct abuf *obuf)
ctx++;
}
}
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ aproc_dbg(p);
+ dbg_puts(": bcopy ");
+ dbg_putu(scount);
+ dbg_puts(" fr\n");
+ }
+#endif
abuf_rdiscard(ibuf, scount * ibuf->bpf);
abuf_wcommit(obuf, scount * obuf->bpf);
}
@@ -1173,6 +1493,16 @@ cmap_new(char *name, struct aparams *ipar, struct aparams *opar)
p = aproc_new(&cmap_ops, name);
for (i = 0; i < NCHAN_MAX; i++)
p->u.cmap.ctx[i] = 0;
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ aproc_dbg(p);
+ dbg_puts(": new ");
+ aparams_dbg(ipar);
+ dbg_puts(" -> ");
+ aparams_dbg(opar);
+ dbg_puts("\n");
+ }
+#endif
return p;
}
@@ -1207,6 +1537,16 @@ enc_bcopy(struct aproc *p, struct abuf *ibuf, struct abuf *obuf)
return;
scount = (icount < ocount) ? icount : ocount;
nch = ibuf->cmax - ibuf->cmin + 1;
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ aproc_dbg(p);
+ dbg_puts(": bcopy ");
+ dbg_putu(scount);
+ dbg_puts(" fr * ");
+ dbg_putu(nch);
+ dbg_puts(" ch\n");
+ }
+#endif
/*
* Partially copy structures into local variables, to avoid
* unnecessary indirections; this also allows the compiler to
@@ -1315,6 +1655,14 @@ enc_new(char *name, struct aparams *par)
p->u.conv.bnext = 1;
p->u.conv.snext = 0;
}
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ aproc_dbg(p);
+ dbg_puts(": new ");
+ aparams_dbg(par);
+ dbg_puts("\n");
+ }
+#endif
return p;
}
@@ -1349,6 +1697,16 @@ dec_bcopy(struct aproc *p, struct abuf *ibuf, struct abuf *obuf)
return;
scount = (icount < ocount) ? icount : ocount;
nch = obuf->cmax - obuf->cmin + 1;
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ aproc_dbg(p);
+ dbg_puts(": bcopy ");
+ dbg_putu(scount);
+ dbg_puts(" fr * ");
+ dbg_putu(nch);
+ dbg_puts(" ch\n");
+ }
+#endif
/*
* Partially copy structures into local variables, to avoid
* unnecessary indirections; this also allows the compiler to
@@ -1457,5 +1815,13 @@ dec_new(char *name, struct aparams *par)
p->u.conv.bnext = 1;
p->u.conv.snext = 0;
}
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ aproc_dbg(p);
+ dbg_puts(": new ");
+ aparams_dbg(par);
+ dbg_puts("\n");
+ }
+#endif
return p;
}
diff --git a/usr.bin/aucat/aucat.c b/usr.bin/aucat/aucat.c
index 6f0861cdd6a..873cd4771ef 100644
--- a/usr.bin/aucat/aucat.c
+++ b/usr.bin/aucat/aucat.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: aucat.c,v 1.77 2010/01/05 10:18:12 ratchov Exp $ */
+/* $OpenBSD: aucat.c,v 1.78 2010/01/10 21:47:41 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -39,6 +39,9 @@
#include "midi.h"
#include "opt.h"
#include "wav.h"
+#ifdef DEBUG
+#include "dbg.h"
+#endif
#define MODE_PLAY 1
#define MODE_REC 2
@@ -46,6 +49,9 @@
#define PROG_AUCAT "aucat"
#define PROG_MIDICAT "midicat"
+#ifdef DEBUG
+int debug_level = 0;
+#endif
volatile int quit_flag = 0;
/*
@@ -61,6 +67,27 @@ sigint(int s)
quit_flag = 1;
}
+#ifdef DEBUG
+/*
+ * Increase debug level on SIGUSR1.
+ */
+void
+sigusr1(int s)
+{
+ if (debug_level < 4)
+ debug_level++;
+}
+
+/*
+ * Decrease debug level on SIGUSR2.
+ */
+void
+sigusr2(int s)
+{
+ if (debug_level > 0)
+ debug_level--;
+}
+#endif
void
opt_ch(struct aparams *par)
@@ -209,6 +236,14 @@ setsig(void)
err(1, "sigaction(term) failed");
if (sigaction(SIGHUP, &sa, NULL) < 0)
err(1, "sigaction(hup) failed");
+#ifdef DEBUG
+ sa.sa_handler = sigusr1;
+ if (sigaction(SIGUSR1, &sa, NULL) < 0)
+ err(1, "sigaction(usr1) failed");
+ sa.sa_handler = sigusr2;
+ if (sigaction(SIGUSR2, &sa, NULL) < 0)
+ err(1, "sigaction(usr2) failed1n");
+#endif
}
void
@@ -219,6 +254,12 @@ unsetsig(void)
sigfillset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
sa.sa_handler = SIG_DFL;
+#ifdef DEBUG
+ if (sigaction(SIGUSR2, &sa, NULL) < 0)
+ err(1, "unsetsig(usr2): sigaction failed");
+ if (sigaction(SIGUSR1, &sa, NULL) < 0)
+ err(1, "unsetsig(usr1): sigaction failed");
+#endif
if (sigaction(SIGHUP, &sa, NULL) < 0)
err(1, "unsetsig(hup): sigaction failed\n");
if (sigaction(SIGTERM, &sa, NULL) < 0)
@@ -291,6 +332,10 @@ aucat_main(int argc, char **argv)
while ((c = getopt(argc, argv, "dnb:c:C:e:r:h:x:v:i:o:f:m:lus:U:t:z:")) != -1) {
switch (c) {
case 'd':
+#ifdef DEBUG
+ if (d_flag)
+ debug_level++;
+#endif
d_flag = 1;
break;
case 'n':
@@ -535,6 +580,10 @@ aucat_main(int argc, char **argv)
if (!l_flag)
break;
if (!suspend) {
+#ifdef DEBUG
+ if (debug_level >= 2)
+ dbg_puts("suspending\n");
+#endif
suspend = 1;
dev_stop();
dev_clear();
@@ -544,6 +593,10 @@ aucat_main(int argc, char **argv)
(dev_sub && dev_sub->u.sub.idle == 0) ||
((dev_mix || dev_sub) && dev_midi->u.ctl.tstate == CTL_RUN)) {
if (suspend) {
+#ifdef DEBUG
+ if (debug_level >= 2)
+ dbg_puts("resuming\n");
+#endif
suspend = 0;
dev_start();
}
@@ -555,6 +608,10 @@ aucat_main(int argc, char **argv)
warn("rmdir(\"%s\")", base);
}
if (suspend) {
+#ifdef DEBUG
+ if (debug_level >= 2)
+ dbg_puts("resuming to drain\n");
+#endif
suspend = 0;
dev_start();
}
@@ -593,6 +650,10 @@ midicat_main(int argc, char **argv)
while ((c = getopt(argc, argv, "di:o:lf:U:")) != -1) {
switch (c) {
case 'd':
+#ifdef DEBUG
+ if (d_flag)
+ debug_level++;
+#endif
d_flag = 1;
break;
case 'i':
diff --git a/usr.bin/aucat/conf.h b/usr.bin/aucat/conf.h
index 00515460cfc..9f23921c760 100644
--- a/usr.bin/aucat/conf.h
+++ b/usr.bin/aucat/conf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: conf.h,v 1.11 2009/11/03 21:31:37 ratchov Exp $ */
+/* $OpenBSD: conf.h,v 1.12 2010/01/10 21:47:41 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -17,6 +17,18 @@
#ifndef CONF_H
#define CONF_H
+#ifdef DEBUG
+/*
+ * Debug trace levels:
+ *
+ * 0 - fatal errors: bugs, asserts, internal errors.
+ * 1 - warnings: bugs in clients, failed allocations, non-fatal errors.
+ * 2 - misc information (hardware parameters, incoming clients)
+ * 3 - structural changes (new aproc structures and files stream params changes)
+ * 4 - data blocks and messages
+ */
+extern int debug_level;
+#endif
/*
* Number of blocks in the device play/record buffers. Because Sun API
diff --git a/usr.bin/aucat/dbg.c b/usr.bin/aucat/dbg.c
new file mode 100644
index 00000000000..10cbcd7fff9
--- /dev/null
+++ b/usr.bin/aucat/dbg.c
@@ -0,0 +1,153 @@
+#ifdef DEBUG
+/*
+ * Copyright (c) 2003-2007 Alexandre Ratchov <alex@caoua.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * dbg_xxx() routines are used to quickly store traces into a trace buffer.
+ * This allows trances to be collected during time sensitive operations without
+ * disturbing them. The buffer can be flushed on standard error later, when
+ * slow syscalls are no longer disruptive, e.g. at the end of the poll() loop.
+ */
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include "dbg.h"
+
+/*
+ * size of the buffer where traces are stored
+ */
+#define DBG_BUFSZ 8192
+
+/*
+ * store a character in the trace buffer
+ */
+#define DBG_PUTC(c) do { \
+ if (dbg_used < DBG_BUFSZ) \
+ dbg_buf[dbg_used++] = (c); \
+} while (0)
+
+char dbg_buf[DBG_BUFSZ]; /* buffer where traces are stored */
+unsigned dbg_used = 0; /* bytes used in the buffer */
+unsigned dbg_sync = 1; /* if true, flush after each '\n' */
+
+/*
+ * write debug info buffer on stderr
+ */
+void
+dbg_flush(void)
+{
+ if (dbg_used == 0)
+ return;
+ write(STDERR_FILENO, dbg_buf, dbg_used);
+ dbg_used = 0;
+}
+
+/*
+ * store a string in the debug buffer
+ */
+void
+dbg_puts(char *msg)
+{
+ char *p = msg;
+ int c;
+
+ while ((c = *p++) != '\0') {
+ DBG_PUTC(c);
+ if (dbg_sync && c == '\n')
+ dbg_flush();
+ }
+}
+
+/*
+ * store a hex in the debug buffer
+ */
+void
+dbg_putx(unsigned long num)
+{
+ char dig[sizeof(num) * 2], *p = dig, c;
+ unsigned ndig;
+
+ if (num != 0) {
+ for (ndig = 0; num != 0; ndig++) {
+ *p++ = num & 0xf;
+ num >>= 4;
+ }
+ for (; ndig != 0; ndig--) {
+ c = *(--p);
+ c += (c < 10) ? '0' : 'a' - 10;
+ DBG_PUTC(c);
+ }
+ } else
+ DBG_PUTC('0');
+}
+
+/*
+ * store a decimal in the debug buffer
+ */
+void
+dbg_putu(unsigned long num)
+{
+ char dig[sizeof(num) * 3], *p = dig;
+ unsigned ndig;
+
+ if (num != 0) {
+ for (ndig = 0; num != 0; ndig++) {
+ *p++ = num % 10;
+ num /= 10;
+ }
+ for (; ndig != 0; ndig--)
+ DBG_PUTC(*(--p) + '0');
+ } else
+ DBG_PUTC('0');
+}
+
+/*
+ * store a signed integer in the trace buffer
+ */
+void
+dbg_puti(long num)
+{
+ if (num < 0) {
+ DBG_PUTC('-');
+ num = -num;
+ }
+ dbg_putu(num);
+}
+
+/*
+ * abort program execution after a fatal error, we should
+ * put code here to backup user data
+ */
+void
+dbg_panic(void)
+{
+ dbg_flush();
+ abort();
+}
+#endif
diff --git a/usr.bin/aucat/dbg.h b/usr.bin/aucat/dbg.h
new file mode 100644
index 00000000000..119aa5d546a
--- /dev/null
+++ b/usr.bin/aucat/dbg.h
@@ -0,0 +1,45 @@
+#ifdef DEBUG
+/*
+ * Copyright (c) 2003-2007 Alexandre Ratchov <alex@caoua.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MIDISH_DBG_H
+#define MIDISH_DBG_H
+
+void dbg_puts(char *);
+void dbg_putx(unsigned long);
+void dbg_putu(unsigned long);
+void dbg_puti(long);
+void dbg_panic(void);
+void dbg_flush(void);
+
+extern unsigned dbg_sync;
+
+#endif /* MIDISH_DBG_H */
+#endif /* DEBUG */
diff --git a/usr.bin/aucat/dev.c b/usr.bin/aucat/dev.c
index bdd6366235a..e749531d742 100644
--- a/usr.bin/aucat/dev.c
+++ b/usr.bin/aucat/dev.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dev.c,v 1.38 2010/01/05 10:18:12 ratchov Exp $ */
+/* $OpenBSD: dev.c,v 1.39 2010/01/10 21:47:41 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -27,6 +27,9 @@
#include "miofile.h"
#include "safile.h"
#include "midi.h"
+#ifdef DEBUG
+#include "dbg.h"
+#endif
unsigned dev_bufsz, dev_round, dev_rate;
struct aparams dev_ipar, dev_opar;
@@ -161,9 +164,23 @@ dev_init(char *devpath,
if (f == NULL)
return 0;
if (dipar) {
+#ifdef DEBUG
+ if (debug_level >= 2) {
+ dbg_puts("hw recording ");
+ aparams_dbg(dipar);
+ dbg_puts("\n");
+ }
+#endif
dev_rate = dipar->rate;
}
if (dopar) {
+#ifdef DEBUG
+ if (debug_level >= 2) {
+ dbg_puts("hw playing ");
+ aparams_dbg(dopar);
+ dbg_puts("\n");
+ }
+#endif
dev_rate = dopar->rate;
}
ibufsz = obufsz = dev_bufsz;
@@ -255,6 +272,15 @@ dev_init(char *devpath,
dev_mix = NULL;
}
dev_bufsz = (dopar) ? obufsz : ibufsz;
+#ifdef DEBUG
+ if (debug_level >= 2) {
+ dbg_puts("device block size is ");
+ dbg_putu(dev_round);
+ dbg_puts(" frames, using ");
+ dbg_putu(dev_bufsz / dev_round);
+ dbg_puts(" blocks\n");
+ }
+#endif
dev_start();
return 1;
}
@@ -268,6 +294,10 @@ dev_done(void)
{
struct file *f;
+#ifdef DEBUG
+ if (debug_level >= 2)
+ dbg_puts("closing audio device\n");
+#endif
if (dev_mix) {
/*
* Put the mixer in ``autoquit'' state and generate
@@ -404,6 +434,12 @@ dev_getep(struct abuf **sibuf, struct abuf **sobuf)
ibuf = *sibuf;
for (;;) {
if (!ibuf || !ibuf->rproc) {
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ abuf_dbg(*sibuf);
+ dbg_puts(": not connected to device\n");
+ }
+#endif
return 0;
}
if (ibuf->rproc == dev_mix)
@@ -416,6 +452,12 @@ dev_getep(struct abuf **sibuf, struct abuf **sobuf)
obuf = *sobuf;
for (;;) {
if (!obuf || !obuf->wproc) {
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ abuf_dbg(*sobuf);
+ dbg_puts(": not connected to device\n");
+ }
+#endif
return 0;
}
if (obuf->wproc == dev_sub)
@@ -457,6 +499,23 @@ dev_sync(struct abuf *ibuf, struct abuf *obuf)
rbuf->bpf * (pbuf->abspos + pbuf->used) -
pbuf->bpf * rbuf->abspos;
delta /= pbuf->bpf * rbuf->bpf;
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ dbg_puts("syncing device, delta = ");
+ dbg_putu(delta);
+ dbg_puts(": ");
+ abuf_dbg(pbuf);
+ dbg_puts(" abspos = ");
+ dbg_putu(pbuf->abspos);
+ dbg_puts(" used = ");
+ dbg_putu(pbuf->used);
+ dbg_puts(" <---> ");
+ abuf_dbg(rbuf);
+ dbg_puts(" abspos = ");
+ dbg_putu(rbuf->abspos);
+ dbg_puts("\n");
+ }
+#endif
if (delta > 0) {
/*
* The play chain is ahead (most cases) drop some of
@@ -510,6 +569,15 @@ dev_getpos(void)
rlat -= delta;
else if (delta < 0)
plat += delta;
+#ifdef DEBUG
+ if (rlat != plat) {
+ dbg_puts("dev_getpos: play/rec out of sync: plat = ");
+ dbg_puti(plat);
+ dbg_puts(", rlat = ");
+ dbg_puti(rlat);
+ dbg_puts("\n");
+ }
+#endif
}
return dev_mix ? plat : rlat;
}
@@ -621,6 +689,14 @@ dev_attach(char *name,
void
dev_setvol(struct abuf *ibuf, int vol)
{
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ abuf_dbg(ibuf);
+ dbg_puts(": setting volume to ");
+ dbg_putu(vol);
+ dbg_puts("\n");
+ }
+#endif
if (!dev_getep(&ibuf, NULL)) {
return;
}
@@ -637,6 +713,12 @@ dev_clear(void)
struct abuf *buf;
if (dev_mix) {
+#ifdef DEBUG
+ if (!LIST_EMPTY(&dev_mix->ibuflist)) {
+ dbg_puts("play end not idle, can't clear device\n");
+ dbg_panic();
+ }
+#endif
buf = LIST_FIRST(&dev_mix->obuflist);
while (buf) {
abuf_clear(buf);
@@ -645,6 +727,12 @@ dev_clear(void)
mix_clear(dev_mix);
}
if (dev_sub) {
+#ifdef DEBUG
+ if (!LIST_EMPTY(&dev_sub->obuflist)) {
+ dbg_puts("record end not idle, can't clear device\n");
+ dbg_panic();
+ }
+#endif
buf = LIST_FIRST(&dev_sub->ibuflist);
while (buf) {
abuf_clear(buf);
diff --git a/usr.bin/aucat/file.c b/usr.bin/aucat/file.c
index 100e597a630..e60f1154e15 100644
--- a/usr.bin/aucat/file.c
+++ b/usr.bin/aucat/file.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: file.c,v 1.14 2009/09/27 11:51:20 ratchov Exp $ */
+/* $OpenBSD: file.c,v 1.15 2010/01/10 21:47:41 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -57,6 +57,9 @@
#include "aproc.h"
#include "conf.h"
#include "file.h"
+#ifdef DEBUG
+#include "dbg.h"
+#endif
#define MAXFDS 100
@@ -90,6 +93,16 @@ timo_add(struct timo *o, unsigned delta)
unsigned val;
int diff;
+#ifdef DEBUG
+ if (o->set) {
+ dbg_puts("timo_set: already set\n");
+ dbg_panic();
+ }
+ if (delta == 0) {
+ dbg_puts("timo_set: zero timeout is evil\n");
+ dbg_panic();
+ }
+#endif
val = timo_abstime + delta;
for (i = &timo_queue; *i != NULL; i = &(*i)->next) {
diff = (*i)->val - val;
@@ -118,6 +131,10 @@ timo_del(struct timo *o)
return;
}
}
+#ifdef DEBUG
+ if (debug_level >= 4)
+ dbg_puts("timo_del: not found\n");
+#endif
}
/*
@@ -171,9 +188,40 @@ timo_init(void)
void
timo_done(void)
{
+#ifdef DEBUG
+ if (timo_queue != NULL) {
+ dbg_puts("timo_done: timo_queue not empty!\n");
+ dbg_panic();
+ }
+#endif
timo_queue = (struct timo *)0xdeadbeef;
}
+#ifdef DEBUG
+void
+file_dbg(struct file *f)
+{
+ dbg_puts(f->ops->name);
+ dbg_puts("(");
+ dbg_puts(f->name);
+ dbg_puts("|");
+ if (f->state & FILE_ROK)
+ dbg_puts("r");
+ if (f->state & FILE_RINUSE)
+ dbg_puts("R");
+ if (f->state & FILE_WOK)
+ dbg_puts("w");
+ if (f->state & FILE_WINUSE)
+ dbg_puts("W");
+ if (f->state & FILE_EOF)
+ dbg_puts("e");
+ if (f->state & FILE_HUP)
+ dbg_puts("h");
+ if (f->state & FILE_ZOMB)
+ dbg_puts("Z");
+ dbg_puts(")");
+}
+#endif
struct file *
file_new(struct fileops *ops, char *name, unsigned nfds)
@@ -183,6 +231,12 @@ file_new(struct fileops *ops, char *name, unsigned nfds)
LIST_FOREACH(f, &file_list, entry)
nfds += f->ops->nfds(f);
if (nfds > MAXFDS) {
+#ifdef DEBUG
+ if (debug_level >= 1) {
+ dbg_puts(name);
+ dbg_puts(": too many polled files\n");
+ }
+#endif
return NULL;
}
f = malloc(ops->size);
@@ -194,16 +248,34 @@ file_new(struct fileops *ops, char *name, unsigned nfds)
f->rproc = NULL;
f->wproc = NULL;
LIST_INSERT_HEAD(&file_list, f, entry);
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ file_dbg(f);
+ dbg_puts(": created\n");
+ }
+#endif
return f;
}
void
file_del(struct file *f)
{
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ file_dbg(f);
+ dbg_puts(": terminating...\n");
+ }
+#endif
if (f->state & (FILE_RINUSE | FILE_WINUSE)) {
f->state |= FILE_ZOMB;
} else {
LIST_REMOVE(f, entry);
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ file_dbg(f);
+ dbg_puts(": destroyed\n");
+ }
+#endif
f->ops->close(f);
free(f);
}
@@ -225,6 +297,11 @@ file_poll(void)
* Fill the pfds[] array with files that are blocked on reading
* and/or writing, skipping those that are just waiting.
*/
+#ifdef DEBUG
+ dbg_flush();
+ if (debug_level >= 4)
+ dbg_puts("poll:");
+#endif
nfds = 0;
LIST_FOREACH(f, &file_list, entry) {
events = 0;
@@ -232,6 +309,12 @@ file_poll(void)
events |= POLLIN;
if (f->wproc && !(f->state & FILE_WOK))
events |= POLLOUT;
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ dbg_puts(" ");
+ file_dbg(f);
+ }
+#endif
n = f->ops->pollfd(f, pfds + nfds, events);
if (n == 0) {
f->pfd = NULL;
@@ -240,7 +323,21 @@ file_poll(void)
f->pfd = pfds + nfds;
nfds += n;
}
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ dbg_puts("\npfds[] =");
+ for (n = 0; n < nfds; n++) {
+ dbg_puts(" ");
+ dbg_putx(pfds[n].events);
+ }
+ dbg_puts("\n");
+ }
+#endif
if (LIST_EMPTY(&file_list)) {
+#ifdef DEBUG
+ if (debug_level >= 3)
+ dbg_puts("nothing to do...\n");
+#endif
return 0;
}
if (nfds > 0) {
@@ -272,12 +369,24 @@ file_poll(void)
revents = f->ops->revents(f, f->pfd);
if (!(f->state & FILE_ZOMB) && (revents & POLLIN)) {
revents &= ~POLLIN;
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ file_dbg(f);
+ dbg_puts(": rok\n");
+ }
+#endif
f->state |= FILE_ROK;
f->state |= FILE_RINUSE;
for (;;) {
p = f->rproc;
if (!p)
break;
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ aproc_dbg(p);
+ dbg_puts(": in\n");
+ }
+#endif
if (!p->ops->in(p, NULL))
break;
}
@@ -285,33 +394,75 @@ file_poll(void)
}
if (!(f->state & FILE_ZOMB) && (revents & POLLOUT)) {
revents &= ~POLLOUT;
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ file_dbg(f);
+ dbg_puts(": wok\n");
+ }
+#endif
f->state |= FILE_WOK;
f->state |= FILE_WINUSE;
for (;;) {
p = f->wproc;
if (!p)
break;
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ aproc_dbg(p);
+ dbg_puts(": out\n");
+ }
+#endif
if (!p->ops->out(p, NULL))
break;
}
f->state &= ~FILE_WINUSE;
}
if (!(f->state & FILE_ZOMB) && (revents & POLLHUP)) {
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ file_dbg(f);
+ dbg_puts(": disconnected\n");
+ }
+#endif
f->state |= (FILE_EOF | FILE_HUP);
}
if (!(f->state & FILE_ZOMB) && (f->state & FILE_EOF)) {
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ file_dbg(f);
+ dbg_puts(": eof\n");
+ }
+#endif
p = f->rproc;
if (p) {
f->state |= FILE_RINUSE;
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ aproc_dbg(p);
+ dbg_puts(": eof\n");
+ }
+#endif
p->ops->eof(p, NULL);
f->state &= ~FILE_RINUSE;
}
f->state &= ~FILE_EOF;
}
if (!(f->state & FILE_ZOMB) && (f->state & FILE_HUP)) {
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ file_dbg(f);
+ dbg_puts(": hup\n");
+ }
+#endif
p = f->wproc;
if (p) {
f->state |= FILE_WINUSE;
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ aproc_dbg(p);
+ dbg_puts(": hup\n");
+ }
+#endif
p->ops->hup(p, NULL);
f->state &= ~FILE_WINUSE;
}
@@ -323,6 +474,10 @@ file_poll(void)
f = fnext;
}
if (LIST_EMPTY(&file_list)) {
+#ifdef DEBUG
+ if (debug_level >= 3)
+ dbg_puts("no files anymore...\n");
+#endif
return 0;
}
return 1;
@@ -340,11 +495,28 @@ filelist_init(void)
LIST_INIT(&file_list);
timo_init();
gettimeofday(&file_tv, NULL);
+#ifdef DEBUG
+ dbg_sync = 0;
+#endif
}
void
filelist_done(void)
{
+#ifdef DEBUG
+ struct file *f;
+
+ if (!LIST_EMPTY(&file_list)) {
+ LIST_FOREACH(f, &file_list, entry) {
+ dbg_puts("\t");
+ file_dbg(f);
+ dbg_puts("\n");
+ }
+ dbg_panic();
+ }
+ dbg_sync = 1;
+ dbg_flush();
+#endif
timo_done();
}
@@ -369,7 +541,31 @@ unsigned
file_read(struct file *f, unsigned char *data, unsigned count)
{
unsigned n;
+#ifdef DEBUG
+ struct timeval tv0, tv1, dtv;
+ unsigned us;
+
+ gettimeofday(&tv0, NULL);
+ if (!(f->state & FILE_ROK)) {
+ file_dbg(f);
+ dbg_puts(": read: bad state\n");
+ dbg_panic();
+ }
+#endif
n = f->ops->read(f, data, count);
+#ifdef DEBUG
+ gettimeofday(&tv1, NULL);
+ timersub(&tv1, &tv0, &dtv);
+ us = dtv.tv_sec * 1000000 + dtv.tv_usec;
+ if (debug_level >= 4 || (debug_level >= 1 && us >= 5000)) {
+ dbg_puts(f->name);
+ dbg_puts(": read ");
+ dbg_putu(n);
+ dbg_puts(" bytes in ");
+ dbg_putu(us);
+ dbg_puts("us\n");
+ }
+#endif
return n;
}
@@ -377,7 +573,31 @@ unsigned
file_write(struct file *f, unsigned char *data, unsigned count)
{
unsigned n;
+#ifdef DEBUG
+ struct timeval tv0, tv1, dtv;
+ unsigned us;
+
+ if (!(f->state & FILE_WOK)) {
+ file_dbg(f);
+ dbg_puts(": write: bad state\n");
+ dbg_panic();
+ }
+ gettimeofday(&tv0, NULL);
+#endif
n = f->ops->write(f, data, count);
+#ifdef DEBUG
+ gettimeofday(&tv1, NULL);
+ timersub(&tv1, &tv0, &dtv);
+ us = dtv.tv_sec * 1000000 + dtv.tv_usec;
+ if (debug_level >= 4 || (debug_level >= 1 && us >= 5000)) {
+ dbg_puts(f->name);
+ dbg_puts(": wrote ");
+ dbg_putu(n);
+ dbg_puts(" bytes in ");
+ dbg_putu(us);
+ dbg_puts("us\n");
+ }
+#endif
return n;
}
@@ -386,10 +606,22 @@ file_eof(struct file *f)
{
struct aproc *p;
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ file_dbg(f);
+ dbg_puts(": eof requested\n");
+ }
+#endif
if (!(f->state & (FILE_RINUSE | FILE_WINUSE))) {
p = f->rproc;
if (p) {
f->state |= FILE_RINUSE;
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ aproc_dbg(p);
+ dbg_puts(": eof\n");
+ }
+#endif
p->ops->eof(p, NULL);
f->state &= ~FILE_RINUSE;
}
@@ -406,10 +638,22 @@ file_hup(struct file *f)
{
struct aproc *p;
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ file_dbg(f);
+ dbg_puts(": hup requested\n");
+ }
+#endif
if (!(f->state & (FILE_RINUSE | FILE_WINUSE))) {
p = f->wproc;
if (p) {
f->state |= FILE_WINUSE;
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ aproc_dbg(p);
+ dbg_puts(": hup\n");
+ }
+#endif
p->ops->hup(p, NULL);
f->state &= ~FILE_WINUSE;
}
@@ -426,16 +670,34 @@ file_close(struct file *f)
{
struct aproc *p;
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ file_dbg(f);
+ dbg_puts(": closing\n");
+ }
+#endif
if (!(f->state & (FILE_RINUSE | FILE_WINUSE))) {
p = f->rproc;
if (p) {
f->state |= FILE_RINUSE;
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ aproc_dbg(p);
+ dbg_puts(": eof\n");
+ }
+#endif
p->ops->eof(p, NULL);
f->state &= ~FILE_RINUSE;
}
p = f->wproc;
if (p) {
f->state |= FILE_WINUSE;
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ aproc_dbg(p);
+ dbg_puts(": hup\n");
+ }
+#endif
p->ops->hup(p, NULL);
f->state &= ~FILE_WINUSE;
}
diff --git a/usr.bin/aucat/headers.c b/usr.bin/aucat/headers.c
index 20f68d01436..e9a8ed256dc 100644
--- a/usr.bin/aucat/headers.c
+++ b/usr.bin/aucat/headers.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: headers.c,v 1.9 2009/12/12 15:15:34 ratchov Exp $ */
+/* $OpenBSD: headers.c,v 1.10 2010/01/10 21:47:41 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -164,6 +164,10 @@ wav_readhdr(int fd, struct aparams *par, off_t *datasz, short **map)
*datasz = csize;
break;
} else {
+#ifdef DEBUG
+ if (debug_level >= 1)
+ warnx("ignoring chuck <%.4s>\n", chunk.id);
+#endif
}
/*
diff --git a/usr.bin/aucat/midi.c b/usr.bin/aucat/midi.c
index 8c8a80698cf..352dcab7543 100644
--- a/usr.bin/aucat/midi.c
+++ b/usr.bin/aucat/midi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: midi.c,v 1.13 2009/11/03 21:31:37 ratchov Exp $ */
+/* $OpenBSD: midi.c,v 1.14 2010/01/10 21:47:41 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -32,6 +32,9 @@
#include "conf.h"
#include "dev.h"
#include "midi.h"
+#ifdef DEBUG
+#include "dbg.h"
+#endif
/*
* input data rate is XFER / TIMO (in bytes per microsecond),
@@ -80,8 +83,24 @@ thru_flush(struct aproc *p, struct abuf *ibuf, struct abuf *obuf)
itodo = ibuf->r.midi.used;
idata = ibuf->r.midi.msg;
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ aproc_dbg(p);
+ dbg_puts(": flushing ");
+ dbg_putu(itodo);
+ dbg_puts(" byte message\n");
+ }
+#endif
while (itodo > 0) {
if (!ABUF_WOK(obuf)) {
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ aproc_dbg(p);
+ dbg_puts(": overrun, discarding ");
+ dbg_putu(obuf->used);
+ dbg_puts(" bytes\n");
+ }
+#endif
abuf_rdiscard(obuf, obuf->used);
if (p->u.thru.owner == ibuf)
p->u.thru.owner = NULL;
@@ -108,7 +127,23 @@ thru_rt(struct aproc *p, struct abuf *ibuf, struct abuf *obuf, unsigned c)
unsigned ocount;
unsigned char *odata;
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ aproc_dbg(p);
+ dbg_puts(": ");
+ dbg_putu(c);
+ dbg_puts(": flushing realtime message\n");
+ }
+#endif
if (!ABUF_WOK(obuf)) {
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ aproc_dbg(p);
+ dbg_puts(": overrun, discarding ");
+ dbg_putu(obuf->used);
+ dbg_puts(" bytes\n");
+ }
+#endif
abuf_rdiscard(obuf, obuf->used);
if (p->u.thru.owner == ibuf)
p->u.thru.owner = NULL;
@@ -199,6 +234,12 @@ thru_in(struct aproc *p, struct abuf *ibuf)
if (!ABUF_ROK(ibuf))
return 0;
if (ibuf->tickets == 0) {
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ abuf_dbg(ibuf);
+ dbg_puts(": out of tickets, blocking\n");
+ }
+#endif
return 0;
}
todo = ibuf->used;
@@ -304,6 +345,42 @@ thru_new(char *name)
return p;
}
+#ifdef DEBUG
+void
+ctl_slotdbg(struct aproc *p, int slot)
+{
+ struct ctl_slot *s;
+
+ aproc_dbg(p);
+ if (slot < 0) {
+ dbg_puts("/none");
+ } else {
+ s = p->u.ctl.slot + slot;
+ dbg_puts(s->name);
+ dbg_putu(s->unit);
+ dbg_puts("=");
+ dbg_putu(s->vol);
+ dbg_puts("/");
+ switch (s->tstate) {
+ case CTL_OFF:
+ dbg_puts("off");
+ break;
+ case CTL_RUN:
+ dbg_puts("run");
+ break;
+ case CTL_START:
+ dbg_puts("sta");
+ break;
+ case CTL_STOP:
+ dbg_puts("stp");
+ break;
+ default:
+ dbg_puts("unk");
+ break;
+ }
+ }
+}
+#endif
/*
* broadcast a message to all output buffers on the behalf of ibuf.
@@ -324,11 +401,27 @@ ctl_sendmsg(struct aproc *p, struct abuf *ibuf, unsigned char *msg, unsigned len
idata = msg;
while (itodo > 0) {
if (!ABUF_WOK(i)) {
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ abuf_dbg(i);
+ dbg_puts(": overrun, discarding ");
+ dbg_putu(i->used);
+ dbg_puts(" bytes\n");
+ }
+#endif
abuf_rdiscard(i, i->used);
}
odata = abuf_wgetblk(i, &ocount, 0);
if (ocount > itodo)
ocount = itodo;
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ abuf_dbg(i);
+ dbg_puts(": stored ");
+ dbg_putu(ocount);
+ dbg_puts(" bytes\n");
+ }
+#endif
memcpy(odata, idata, ocount);
abuf_wcommit(i, ocount);
itodo -= ocount;
@@ -474,6 +567,15 @@ ctl_getidx(struct aproc *p, char *who)
if ((umap & (1 << unit)) == 0)
break;
}
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ aproc_dbg(p);
+ dbg_puts(": new control name is ");
+ dbg_puts(name);
+ dbg_putu(unit);
+ dbg_puts("\n");
+ }
+#endif
/*
* find a free controller slot with the same name/unit
*/
@@ -481,6 +583,14 @@ ctl_getidx(struct aproc *p, char *who)
if (slot->ops == NULL &&
strcmp(slot->name, name) == 0 &&
slot->unit == unit) {
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ aproc_dbg(p);
+ dbg_puts(": found slot ");
+ dbg_putu(i);
+ dbg_puts("\n");
+ }
+#endif
return i;
}
}
@@ -507,6 +617,14 @@ ctl_getidx(struct aproc *p, char *who)
slot->serial = p->u.ctl.serial++;
slot->unit = unit;
slot->vol = MIDI_MAXCTL;
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ aproc_dbg(p);
+ dbg_puts(": overwritten slot ");
+ dbg_putu(bestidx);
+ dbg_puts("\n");
+ }
+#endif
return bestidx;
}
@@ -521,12 +639,20 @@ ctl_trystart(struct aproc *p, int caller)
struct ctl_slot *s;
if (p->u.ctl.tstate != CTL_START) {
+#ifdef DEBUG
+ aproc_dbg(p);
+ dbg_puts(": not in starting state\n");
+#endif
return 0;
}
for (i = 0, s = p->u.ctl.slot; i < CTL_NSLOT; i++, s++) {
if (!s->ops || i == caller)
continue;
if (s->tstate != CTL_OFF && s->tstate != CTL_START) {
+#ifdef DEBUG
+ ctl_slotdbg(p, i);
+ dbg_puts(": not ready to start, start delayed\n");
+#endif
return 0;
}
}
@@ -534,6 +660,10 @@ ctl_trystart(struct aproc *p, int caller)
if (!s->ops || i == caller)
continue;
if (s->tstate == CTL_START) {
+#ifdef DEBUG
+ ctl_slotdbg(p, i);
+ dbg_puts(": started\n");
+#endif
s->tstate = CTL_RUN;
s->ops->start(s->arg);
}
@@ -552,6 +682,14 @@ ctl_trystart(struct aproc *p, int caller)
p->u.ctl.fps_id = MTC_FPS_24;
p->u.ctl.fps = 24;
}
+#ifdef DEBUG
+ ctl_slotdbg(p, caller);
+ dbg_puts(": started server at ");
+ dbg_puti(p->u.ctl.delta);
+ dbg_puts(", ");
+ dbg_puti(p->u.ctl.fps);
+ dbg_puts(" mtc fps\n");
+#endif
ctl_full(p);
return 1;
}
@@ -644,6 +782,14 @@ ctl_slotvol(struct aproc *p, int slot, unsigned vol)
if (p == NULL)
return;
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ ctl_slotdbg(p, slot);
+ dbg_puts(": changing volume to ");
+ dbg_putu(vol);
+ dbg_puts("\n");
+ }
+#endif
p->u.ctl.slot[slot].vol = vol;
msg[0] = MIDI_CTL | slot;
msg[1] = MIDI_CTLVOL;
@@ -705,6 +851,19 @@ ctl_ev(struct aproc *p, struct abuf *ibuf)
unsigned chan;
struct ctl_slot *slot;
unsigned fps;
+#ifdef DEBUG
+ unsigned i;
+
+ if (debug_level >= 3) {
+ abuf_dbg(ibuf);
+ dbg_puts(": got event:");
+ for (i = 0; i < ibuf->r.midi.idx; i++) {
+ dbg_puts(" ");
+ dbg_putx(ibuf->r.midi.msg[i]);
+ }
+ dbg_puts("\n");
+ }
+#endif
if ((ibuf->r.midi.msg[0] & MIDI_CMDMASK) == MIDI_CTL &&
ibuf->r.midi.msg[1] == MIDI_CTLVOL) {
chan = ibuf->r.midi.msg[0] & MIDI_CHANMASK;
@@ -724,14 +883,41 @@ ctl_ev(struct aproc *p, struct abuf *ibuf)
ibuf->r.midi.msg[5] == 0xf7) { /* subtype is mmc */
switch (ibuf->r.midi.msg[4]) {
case 0x01: /* mmc stop */
+#ifdef DEBUG
+ if (debug_level >= 1) {
+ abuf_dbg(ibuf);
+ dbg_puts(": mmc stop\n");
+ }
+#endif
if (p->u.ctl.tstate == CTL_RUN ||
p->u.ctl.tstate == CTL_START)
p->u.ctl.tstate = CTL_STOP;
+#ifdef DEBUG
+ else {
+ if (debug_level >= 1) {
+ aproc_dbg(p);
+ dbg_puts(": ignored mmc stop\n");
+ }
+ }
+#endif
break;
case 0x02: /* mmc start */
+#ifdef DEBUG
+ if (debug_level >= 1) {
+ abuf_dbg(ibuf);
+ dbg_puts(": mmc start\n");
+ }
+#endif
if (p->u.ctl.tstate == CTL_STOP) {
p->u.ctl.tstate = CTL_START;
(void)ctl_trystart(p, -1);
+#ifdef DEBUG
+ } else {
+ if (debug_level >= 1) {
+ abuf_dbg(ibuf);
+ dbg_puts(": ignoring mmc start\n");
+ }
+#endif
}
break;
}
@@ -764,6 +950,14 @@ ctl_ev(struct aproc *p, struct abuf *ibuf)
ibuf->r.midi.msg[9] * MTC_SEC +
ibuf->r.midi.msg[10] * (MTC_SEC / fps) +
ibuf->r.midi.msg[11] * (MTC_SEC / 100 / fps);
+#ifdef DEBUG
+ if (debug_level >= 1) {
+ aproc_dbg(p);
+ dbg_puts(": relocated to ");
+ dbg_putu(p->u.ctl.origin);
+ dbg_puts("\n");
+ }
+#endif
}
}
@@ -862,6 +1056,20 @@ ctl_newin(struct aproc *p, struct abuf *ibuf)
void
ctl_done(struct aproc *p)
{
+#ifdef DEBUG
+ unsigned i;
+ struct ctl_slot *s;
+
+ for (i = 0, s = p->u.ctl.slot; i < CTL_NSLOT; i++, s++) {
+ /*
+ * XXX: shouldn't we abord() here ?
+ */
+ if (s->ops != NULL) {
+ ctl_slotdbg(p, i);
+ dbg_puts(": still in use\n");
+ }
+ }
+#endif
}
struct aproc_ops ctl_ops = {
diff --git a/usr.bin/aucat/miofile.c b/usr.bin/aucat/miofile.c
index d8c45125113..f3038c88b47 100644
--- a/usr.bin/aucat/miofile.c
+++ b/usr.bin/aucat/miofile.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: miofile.c,v 1.3 2009/11/05 08:36:48 ratchov Exp $ */
+/* $OpenBSD: miofile.c,v 1.4 2010/01/10 21:47:41 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -27,6 +27,9 @@
#include "conf.h"
#include "file.h"
#include "miofile.h"
+#ifdef DEBUG
+#include "dbg.h"
+#endif
struct miofile {
struct file file;
@@ -94,8 +97,18 @@ miofile_read(struct file *file, unsigned char *data, unsigned count)
if (n == 0) {
f->file.state &= ~FILE_ROK;
if (mio_eof(f->hdl)) {
+#ifdef DEBUG
+ dbg_puts(f->file.name);
+ dbg_puts(": failed to read from device\n");
+#endif
file_eof(&f->file);
} else {
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ file_dbg(&f->file);
+ dbg_puts(": reading blocked\n");
+ }
+#endif
}
return 0;
}
@@ -113,8 +126,18 @@ miofile_write(struct file *file, unsigned char *data, unsigned count)
if (n == 0) {
f->file.state &= ~FILE_WOK;
if (mio_eof(f->hdl)) {
+#ifdef DEBUG
+ dbg_puts(f->file.name);
+ dbg_puts(": failed to write on device\n");
+#endif
file_hup(&f->file);
} else {
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ file_dbg(&f->file);
+ dbg_puts(": writing blocked\n");
+ }
+#endif
}
return 0;
}
diff --git a/usr.bin/aucat/opt.c b/usr.bin/aucat/opt.c
index 83dd689bf8e..3c7e8959765 100644
--- a/usr.bin/aucat/opt.c
+++ b/usr.bin/aucat/opt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: opt.c,v 1.3 2009/11/03 21:31:37 ratchov Exp $ */
+/* $OpenBSD: opt.c,v 1.4 2010/01/10 21:47:41 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -20,6 +20,9 @@
#include "conf.h"
#include "opt.h"
+#ifdef DEBUG
+#include "dbg.h"
+#endif
struct optlist opt_list = SLIST_HEAD_INITIALIZER(&opt_list);
@@ -55,6 +58,20 @@ opt_new(char *name,
o->rpar = *rpar;
o->maxweight = maxweight;
o->mmc = mmc;
+#ifdef DEBUG
+ if (debug_level >= 2) {
+ dbg_puts(o->name);
+ dbg_puts(": rec ");
+ aparams_dbg(&o->wpar);
+ dbg_puts(", play ");
+ aparams_dbg(&o->rpar);
+ dbg_puts(", vol ");
+ dbg_putu(o->maxweight);
+ if (o->mmc)
+ dbg_puts(", mmc");
+ dbg_puts("\n");
+ }
+#endif
SLIST_INSERT_HEAD(&opt_list, o, entry);
}
@@ -65,9 +82,21 @@ opt_byname(char *name)
SLIST_FOREACH(o, &opt_list, entry) {
if (strcmp(name, o->name) == 0) {
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ dbg_puts(o->name);
+ dbg_puts(": option found\n");
+ }
+#endif
return o;
}
}
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ dbg_puts(name);
+ dbg_puts(": option not found\n");
+ }
+#endif
return NULL;
}
diff --git a/usr.bin/aucat/pipe.c b/usr.bin/aucat/pipe.c
index d95afdb4e77..76f98baa832 100644
--- a/usr.bin/aucat/pipe.c
+++ b/usr.bin/aucat/pipe.c
@@ -27,6 +27,9 @@
#include "conf.h"
#include "pipe.h"
+#ifdef DEBUG
+#include "dbg.h"
+#endif
struct fileops pipe_ops = {
"pipe",
@@ -62,6 +65,12 @@ pipe_read(struct file *file, unsigned char *data, unsigned count)
while ((n = read(f->fd, data, count)) < 0) {
f->file.state &= ~FILE_ROK;
if (errno == EAGAIN) {
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ file_dbg(&f->file);
+ dbg_puts(": reading blocked\n");
+ }
+#endif
} else {
warn("%s", f->file.name);
file_eof(&f->file);
@@ -86,6 +95,12 @@ pipe_write(struct file *file, unsigned char *data, unsigned count)
while ((n = write(f->fd, data, count)) < 0) {
f->file.state &= ~FILE_WOK;
if (errno == EAGAIN) {
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ file_dbg(&f->file);
+ dbg_puts(": writing blocked\n");
+ }
+#endif
} else {
if (errno != EPIPE)
warn("%s", f->file.name);
diff --git a/usr.bin/aucat/safile.c b/usr.bin/aucat/safile.c
index 425c44cec5e..2d5b5516261 100644
--- a/usr.bin/aucat/safile.c
+++ b/usr.bin/aucat/safile.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: safile.c,v 1.19 2009/11/05 08:36:48 ratchov Exp $ */
+/* $OpenBSD: safile.c,v 1.20 2010/01/10 21:47:41 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -30,6 +30,9 @@
#include "dev.h"
#include "file.h"
#include "safile.h"
+#ifdef DEBUG
+#include "dbg.h"
+#endif
struct safile {
struct file file;
@@ -163,10 +166,20 @@ safile_start(struct file *file)
struct safile *f = (struct safile *)file;
if (!sio_start(f->hdl)) {
+#ifdef DEBUG
+ dbg_puts(f->file.name);
+ dbg_puts(": failed to start device\n");
+#endif
file_close(file);
return;
}
f->started = 1;
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ file_dbg(&f->file);
+ dbg_puts(": started\n");
+ }
+#endif
}
void
@@ -176,9 +189,19 @@ safile_stop(struct file *file)
f->started = 0;
if (!sio_eof(f->hdl) && !sio_stop(f->hdl)) {
+#ifdef DEBUG
+ dbg_puts(f->file.name);
+ dbg_puts(": failed to stop device\n");
+#endif
file_close(file);
return;
}
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ file_dbg(&f->file);
+ dbg_puts(": stopped\n");
+ }
+#endif
}
unsigned
@@ -191,8 +214,18 @@ safile_read(struct file *file, unsigned char *data, unsigned count)
if (n == 0) {
f->file.state &= ~FILE_ROK;
if (sio_eof(f->hdl)) {
+#ifdef DEBUG
+ dbg_puts(f->file.name);
+ dbg_puts(": failed to read from device\n");
+#endif
file_eof(&f->file);
} else {
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ file_dbg(&f->file);
+ dbg_puts(": reading blocked\n");
+ }
+#endif
}
return 0;
}
@@ -210,8 +243,18 @@ safile_write(struct file *file, unsigned char *data, unsigned count)
if (n == 0) {
f->file.state &= ~FILE_WOK;
if (sio_eof(f->hdl)) {
+#ifdef DEBUG
+ dbg_puts(f->file.name);
+ dbg_puts(": failed to write on device\n");
+#endif
file_hup(&f->file);
} else {
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ file_dbg(&f->file);
+ dbg_puts(": writing blocked\n");
+ }
+#endif
}
return 0;
}
diff --git a/usr.bin/aucat/sock.c b/usr.bin/aucat/sock.c
index 2fa277bca53..d11ffe0b8ed 100644
--- a/usr.bin/aucat/sock.c
+++ b/usr.bin/aucat/sock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sock.c,v 1.36 2010/01/05 10:18:12 ratchov Exp $ */
+/* $OpenBSD: sock.c,v 1.37 2010/01/10 21:47:41 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -32,6 +32,9 @@
#include "midi.h"
#include "opt.h"
#include "sock.h"
+#ifdef DEBUG
+#include "dbg.h"
+#endif
int sock_attach(struct sock *, int);
int sock_read(struct sock *);
@@ -52,6 +55,27 @@ struct fileops sock_ops = {
pipe_revents
};
+#ifdef DEBUG
+void
+sock_dbg(struct sock *f)
+{
+ static char *pstates[] = { "hel", "ini", "sta", "run", "mid" };
+ static char *rstates[] = { "rdat", "rmsg", "rret" };
+ static char *wstates[] = { "widl", "wmsg", "wdat" };
+
+ if (f->slot >= 0 && dev_midi) {
+ dbg_puts(dev_midi->u.ctl.slot[f->slot].name);
+ dbg_putu(dev_midi->u.ctl.slot[f->slot].unit);
+ } else
+ dbg_puts(f->pipe.file.name);
+ dbg_puts("/");
+ dbg_puts(pstates[f->pstate]);
+ dbg_puts("|");
+ dbg_puts(rstates[f->rstate]);
+ dbg_puts("|");
+ dbg_puts(wstates[f->wstate]);
+}
+#endif
void sock_setvol(void *, unsigned);
void sock_startreq(void *);
@@ -138,6 +162,14 @@ rsock_opos(struct aproc *p, struct abuf *obuf, int delta)
return;
f->delta += delta;
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ aproc_dbg(p);
+ dbg_puts(": moved to delta = ");
+ dbg_puti(f->delta);
+ dbg_puts("\n");
+ }
+#endif
f->tickpending++;
for (;;) {
if (!sock_write(f))
@@ -229,6 +261,14 @@ wsock_ipos(struct aproc *p, struct abuf *obuf, int delta)
return;
f->delta += delta;
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ aproc_dbg(p);
+ dbg_puts(": moved to delta = ");
+ dbg_puti(f->delta);
+ dbg_puts("\n");
+ }
+#endif
f->tickpending++;
for (;;) {
if (!sock_write(f))
@@ -302,6 +342,12 @@ sock_freebuf(struct sock *f)
struct abuf *rbuf, *wbuf;
f->pstate = SOCK_INIT;
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ sock_dbg(f);
+ dbg_puts(": freeing buffers\n");
+ }
+#endif
wbuf = LIST_FIRST(&f->pipe.file.wproc->ibuflist);
rbuf = LIST_FIRST(&f->pipe.file.rproc->obuflist);
if (rbuf || wbuf)
@@ -331,6 +377,14 @@ sock_allocbuf(struct sock *f)
}
f->delta = 0;
f->tickpending = 0;
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ sock_dbg(f);
+ dbg_puts(": allocating ");
+ dbg_putu(f->bufsz);
+ dbg_puts(" fr buffers\n");
+ }
+#endif
f->pstate = SOCK_START;
if (!(f->mode & AMSG_PLAY) && ctl_slotstart(dev_midi, f->slot))
(void)sock_attach(f, 0);
@@ -348,6 +402,12 @@ sock_setvol(void *arg, unsigned vol)
f->vol = vol;
rbuf = LIST_FIRST(&f->pipe.file.rproc->obuflist);
if (!rbuf) {
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ sock_dbg(f);
+ dbg_puts(": no read buffer to set volume yet\n");
+ }
+#endif
return;
}
dev_setvol(rbuf, MIDI_TO_ADATA(vol));
@@ -361,6 +421,13 @@ sock_startreq(void *arg)
{
struct sock *f = (struct sock *)arg;
+#ifdef DEBUG
+ if (f->pstate != SOCK_START) {
+ sock_dbg(f);
+ dbg_puts(": not in START state\n");
+ dbg_panic();
+ }
+#endif
(void)sock_attach(f, 0);
}
@@ -382,6 +449,12 @@ sock_attach(struct sock *f, int force)
if (!force && rbuf && ABUF_WOK(rbuf))
return 0;
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ sock_dbg(f);
+ dbg_puts(": attaching to device\n");
+ }
+#endif
f->pstate = SOCK_RUN;
/*
@@ -436,6 +509,14 @@ sock_rmsg(struct sock *f)
while (f->rtodo > 0) {
if (!(f->pipe.file.state & FILE_ROK)) {
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ sock_dbg(f);
+ dbg_puts(": reading message blocked, ");
+ dbg_putu(f->rtodo);
+ dbg_puts(" bytes remaining\n");
+ }
+#endif
return 0;
}
data = (unsigned char *)&f->rmsg;
@@ -445,6 +526,12 @@ sock_rmsg(struct sock *f)
return 0;
f->rtodo -= count;
}
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ sock_dbg(f);
+ dbg_puts(": read full message\n");
+ }
+#endif
return 1;
}
@@ -461,6 +548,14 @@ sock_wmsg(struct sock *f, struct amsg *m, unsigned *ptodo)
while (*ptodo > 0) {
if (!(f->pipe.file.state & FILE_WOK)) {
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ sock_dbg(f);
+ dbg_puts(": writing message blocked, ");
+ dbg_putu(*ptodo);
+ dbg_puts(" bytes remaining\n");
+ }
+#endif
return 0;
}
data = (unsigned char *)m;
@@ -470,6 +565,12 @@ sock_wmsg(struct sock *f, struct amsg *m, unsigned *ptodo)
return 0;
*ptodo -= count;
}
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ sock_dbg(f);
+ dbg_puts(": wrote full message\n");
+ }
+#endif
return 1;
}
@@ -485,6 +586,13 @@ sock_rdata(struct sock *f)
unsigned char *data;
unsigned count, n;
+#ifdef DEBUG
+ if (f->pstate != SOCK_MIDI && f->rtodo == 0) {
+ sock_dbg(f);
+ dbg_puts(": data block already read\n");
+ dbg_panic();
+ }
+#endif
p = f->pipe.file.rproc;
obuf = LIST_FIRST(&p->obuflist);
if (obuf == NULL)
@@ -517,6 +625,13 @@ sock_wdata(struct sock *f)
#define ZERO_MAX 0x1000
static unsigned char zero[ZERO_MAX];
+#ifdef DEBUG
+ if (f->pstate != SOCK_MIDI && f->wtodo == 0) {
+ sock_dbg(f);
+ dbg_puts(": attempted to write zero-sized data block\n");
+ dbg_panic();
+ }
+#endif
if (!(f->pipe.file.state & FILE_WOK))
return 0;
p = f->pipe.file.wproc;
@@ -561,16 +676,42 @@ sock_setpar(struct sock *f)
if (AMSG_ISSET(p->bits)) {
if (p->bits < BITS_MIN || p->bits > BITS_MAX) {
+#ifdef DEBUG
+ if (debug_level >= 1) {
+ sock_dbg(f);
+ dbg_puts(": ");
+ dbg_putu(p->bits);
+ dbg_puts(": bits out of bounds\n");
+ }
+#endif
return 0;
}
if (AMSG_ISSET(p->bps)) {
if (p->bps < ((p->bits + 7) / 8) || p->bps > 4) {
+#ifdef DEBUG
+ if (debug_level >= 1) {
+ sock_dbg(f);
+ dbg_puts(": ");
+ dbg_putu(p->bps);
+ dbg_puts(": wrong bytes per sample\n");
+ }
+#endif
return 0;
}
} else
p->bps = APARAMS_BPS(p->bits);
f->rpar.bits = f->wpar.bits = p->bits;
f->rpar.bps = f->wpar.bps = p->bps;
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ sock_dbg(f);
+ dbg_puts(": using ");
+ dbg_putu(p->bits);
+ dbg_puts("bits, ");
+ dbg_putu(p->bps);
+ dbg_puts(" bytes per sample\n");
+ }
+#endif
}
if (AMSG_ISSET(p->sig))
f->rpar.sig = f->wpar.sig = p->sig ? 1 : 0;
@@ -587,6 +728,16 @@ sock_setpar(struct sock *f)
f->wpar.cmax = f->opt->wpar.cmin + p->rchan - 1;
if (f->wpar.cmax > f->opt->wpar.cmax)
f->wpar.cmax = f->opt->wpar.cmax;
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ sock_dbg(f);
+ dbg_puts(": using recording channels ");
+ dbg_putu(f->wpar.cmin);
+ dbg_puts("..");
+ dbg_putu(f->wpar.cmax);
+ dbg_puts("\n");
+ }
+#endif
}
if (AMSG_ISSET(p->pchan) && (f->mode & AMSG_PLAY)) {
if (p->pchan < 1)
@@ -597,6 +748,16 @@ sock_setpar(struct sock *f)
f->rpar.cmax = f->opt->rpar.cmin + p->pchan - 1;
if (f->rpar.cmax > f->opt->rpar.cmax)
f->rpar.cmax = f->opt->rpar.cmax;
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ sock_dbg(f);
+ dbg_puts(": using playback channels ");
+ dbg_putu(f->rpar.cmin);
+ dbg_puts("..");
+ dbg_putu(f->rpar.cmax);
+ dbg_puts("\n");
+ }
+#endif
}
if (AMSG_ISSET(p->rate)) {
if (p->rate < RATE_MIN)
@@ -607,23 +768,65 @@ sock_setpar(struct sock *f)
f->rpar.rate = f->wpar.rate = p->rate;
if (!AMSG_ISSET(p->appbufsz)) {
p->appbufsz = dev_bufsz / dev_round * f->round;
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ sock_dbg(f);
+ dbg_puts(": using ");
+ dbg_putu(p->appbufsz);
+ dbg_puts(" fr app buffer size\n");
+ }
+#endif
}
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ sock_dbg(f);
+ dbg_puts(": using ");
+ dbg_putu(p->rate);
+ dbg_puts("Hz sample rate, ");
+ dbg_putu(f->round);
+ dbg_puts(" fr block size\n");
+ }
+#endif
}
if (AMSG_ISSET(p->xrun)) {
if (p->xrun != AMSG_IGNORE &&
p->xrun != AMSG_SYNC &&
p->xrun != AMSG_ERROR) {
+#ifdef DEBUG
+ if (debug_level >= 1) {
+ sock_dbg(f);
+ dbg_puts(": ");
+ dbg_putx(p->xrun);
+ dbg_puts(": bad xrun policy\n");
+ }
+#endif
return 0;
}
f->xrun = p->xrun;
if (f->opt->mmc && f->xrun == AMSG_IGNORE)
f->xrun = AMSG_SYNC;
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ sock_dbg(f);
+ dbg_puts(": using 0x");
+ dbg_putx(f->xrun);
+ dbg_puts(" xrun policy\n");
+ }
+#endif
}
if (AMSG_ISSET(p->bufsz)) {
/*
* XXX: bufsz will become read-only, but for now
* allow old library to properly work
*/
+#ifdef DEBUG
+ if (debug_level >= 1) {
+ sock_dbg(f);
+ dbg_puts(": legacy client using ");
+ dbg_putx(p->bufsz);
+ dbg_puts("fr total buffer size\n");
+ }
+#endif
min = (dev_bufsz / dev_round) * f->round;
if (p->bufsz < min)
p->bufsz = min;
@@ -642,7 +845,35 @@ sock_setpar(struct sock *f)
if (p->appbufsz > max)
p->appbufsz = max;
f->bufsz = p->appbufsz;
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ sock_dbg(f);
+ dbg_puts(": using ");
+ dbg_putu(f->bufsz);
+ dbg_puts(" buffer size\n");
+ }
+#endif
}
+#ifdef DEBUG
+ if (debug_level >= 2) {
+ if (f->slot >= -1 && dev_midi) {
+ dbg_puts(dev_midi->u.ctl.slot[f->slot].name);
+ dbg_putu(dev_midi->u.ctl.slot[f->slot].unit);
+ } else
+ dbg_puts(f->pipe.file.name);
+ dbg_puts(": buffer size = ");
+ dbg_putu(f->bufsz);
+ if (f->mode & AMSG_PLAY) {
+ dbg_puts(", play = ");
+ aparams_dbg(&f->rpar);
+ }
+ if (f->mode & AMSG_REC) {
+ dbg_puts(", rec:");
+ aparams_dbg(&f->wpar);
+ }
+ dbg_puts("\n");
+ }
+#endif
return 1;
}
@@ -670,7 +901,27 @@ sock_hello(struct sock *f)
{
struct amsg_hello *p = &f->rmsg.u.hello;
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ sock_dbg(f);
+ dbg_puts(": hello from <");
+ dbg_puts(p->who);
+ dbg_puts(">, proto = ");
+ dbg_putx(p->proto);
+ dbg_puts(", ver ");
+ dbg_putu(p->version);
+ dbg_puts("\n");
+ }
+#endif
if (p->version != AMSG_VERSION) {
+#ifdef DEBUG
+ if (debug_level >= 1) {
+ sock_dbg(f);
+ dbg_puts(": ");
+ dbg_putu(p->version);
+ dbg_puts(": bad version\n");
+ }
+#endif
return 0;
}
/*
@@ -678,6 +929,14 @@ sock_hello(struct sock *f)
*/
if (dev_midi && (p->proto & (AMSG_MIDIIN | AMSG_MIDIOUT))) {
if (p->proto & ~(AMSG_MIDIIN | AMSG_MIDIOUT)) {
+#ifdef DEBUG
+ if (debug_level >= 1) {
+ sock_dbg(f);
+ dbg_puts(": ");
+ dbg_putx(p->proto);
+ dbg_puts(": bad hello protocol\n");
+ }
+#endif
return 0;
}
f->mode = p->proto;
@@ -696,17 +955,37 @@ sock_hello(struct sock *f)
f->xrun = AMSG_SYNC;
if ((p->proto & ~(AMSG_PLAY | AMSG_REC)) != 0 ||
(p->proto & (AMSG_PLAY | AMSG_REC)) == 0) {
+#ifdef DEBUG
+ if (debug_level >= 1) {
+ sock_dbg(f);
+ dbg_puts(": ");
+ dbg_putx(p->proto);
+ dbg_puts(": unsupported hello protocol\n");
+ }
+#endif
return 0;
}
f->mode = 0;
if (p->proto & AMSG_PLAY) {
if (!dev_mix) {
+#ifdef DEBUG
+ if (debug_level >= 1) {
+ sock_dbg(f);
+ dbg_puts(": playback not available\n");
+ }
+#endif
return 0;
}
f->mode |= AMSG_PLAY;
}
if (p->proto & AMSG_REC) {
if (!dev_sub) {
+#ifdef DEBUG
+ if (debug_level >= 1) {
+ sock_dbg(f);
+ dbg_puts(": recording not available\n");
+ }
+#endif
return 0;
}
f->mode |= AMSG_REC;
@@ -716,6 +995,12 @@ sock_hello(struct sock *f)
p->who, &ctl_sockops, f,
f->opt->mmc);
if (f->slot < 0) {
+#ifdef DEBUG
+ if (debug_level >= 1) {
+ sock_dbg(f);
+ dbg_puts(": out of mixer slots\n");
+ }
+#endif
return 0;
}
}
@@ -734,28 +1019,70 @@ sock_execmsg(struct sock *f)
switch (m->cmd) {
case AMSG_DATA:
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ sock_dbg(f);
+ dbg_puts(": DATA message\n");
+ }
+#endif
if (f->pstate != SOCK_RUN && f->pstate != SOCK_START) {
+#ifdef DEBUG
+ if (debug_level >= 1) {
+ sock_dbg(f);
+ dbg_puts(": DATA, bad state\n");
+ }
+#endif
aproc_del(f->pipe.file.rproc);
return 0;
}
if (!(f->mode & AMSG_PLAY)) {
+#ifdef DEBUG
+ if (debug_level >= 1) {
+ sock_dbg(f);
+ dbg_puts(": DATA not allowed in record-only mode\n");
+ }
+#endif
aproc_del(f->pipe.file.rproc);
return 0;
}
if (f->pstate == SOCK_START &&
ABUF_FULL(LIST_FIRST(&f->pipe.file.rproc->obuflist))) {
+#ifdef DEBUG
+ if (debug_level >= 1) {
+ sock_dbg(f);
+ dbg_puts(": DATA client violates flow control\n");
+ }
+#endif
aproc_del(f->pipe.file.rproc);
return 0;
}
f->rstate = SOCK_RDATA;
f->rtodo = m->u.data.size;
if (f->rtodo == 0) {
+#ifdef DEBUG
+ if (debug_level >= 1) {
+ sock_dbg(f);
+ dbg_puts(": zero-length data chunk\n");
+ }
+#endif
aproc_del(f->pipe.file.rproc);
return 0;
}
break;
case AMSG_START:
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ sock_dbg(f);
+ dbg_puts(": START message\n");
+ }
+#endif
if (f->pstate != SOCK_INIT) {
+#ifdef DEBUG
+ if (debug_level >= 1) {
+ sock_dbg(f);
+ dbg_puts(": START, bad state\n");
+ }
+#endif
aproc_del(f->pipe.file.rproc);
return 0;
}
@@ -764,7 +1091,19 @@ sock_execmsg(struct sock *f)
f->rtodo = sizeof(struct amsg);
break;
case AMSG_STOP:
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ sock_dbg(f);
+ dbg_puts(": STOP message\n");
+ }
+#endif
if (f->pstate != SOCK_RUN && f->pstate != SOCK_START) {
+#ifdef DEBUG
+ if (debug_level >= 1) {
+ sock_dbg(f);
+ dbg_puts(": STOP, bad state\n");
+ }
+#endif
aproc_del(f->pipe.file.rproc);
return 0;
}
@@ -778,7 +1117,19 @@ sock_execmsg(struct sock *f)
f->rtodo = sizeof(struct amsg);
break;
case AMSG_SETPAR:
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ sock_dbg(f);
+ dbg_puts(": SETPAR message\n");
+ }
+#endif
if (f->pstate != SOCK_INIT) {
+#ifdef DEBUG
+ if (debug_level >= 1) {
+ sock_dbg(f);
+ dbg_puts(": SETPAR, bad state\n");
+ }
+#endif
aproc_del(f->pipe.file.rproc);
return 0;
}
@@ -790,7 +1141,19 @@ sock_execmsg(struct sock *f)
f->rstate = SOCK_RMSG;
break;
case AMSG_GETPAR:
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ sock_dbg(f);
+ dbg_puts(": GETPAR message\n");
+ }
+#endif
if (f->pstate != SOCK_INIT) {
+#ifdef DEBUG
+ if (debug_level >= 1) {
+ sock_dbg(f);
+ dbg_puts(": GETPAR, bad state\n");
+ }
+#endif
aproc_del(f->pipe.file.rproc);
return 0;
}
@@ -813,7 +1176,19 @@ sock_execmsg(struct sock *f)
f->rtodo = sizeof(struct amsg);
break;
case AMSG_GETCAP:
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ sock_dbg(f);
+ dbg_puts(": GETCAP message\n");
+ }
+#endif
if (f->pstate != SOCK_INIT) {
+#ifdef DEBUG
+ if (debug_level >= 1) {
+ sock_dbg(f);
+ dbg_puts(": GETCAP, bad state\n");
+ }
+#endif
aproc_del(f->pipe.file.rproc);
return 0;
}
@@ -830,12 +1205,30 @@ sock_execmsg(struct sock *f)
f->rtodo = sizeof(struct amsg);
break;
case AMSG_SETVOL:
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ sock_dbg(f);
+ dbg_puts(": SETVOL message\n");
+ }
+#endif
if (f->pstate != SOCK_RUN &&
f->pstate != SOCK_START && f->pstate != SOCK_INIT) {
+#ifdef DEBUG
+ if (debug_level >= 1) {
+ sock_dbg(f);
+ dbg_puts(": SETVOL, bad state\n");
+ }
+#endif
aproc_del(f->pipe.file.rproc);
return 0;
}
if (m->u.vol.ctl > MIDI_MAXCTL) {
+#ifdef DEBUG
+ if (debug_level >= 1) {
+ sock_dbg(f);
+ dbg_puts(": SETVOL, volume out of range\n");
+ }
+#endif
aproc_del(f->pipe.file.rproc);
return 0;
}
@@ -846,7 +1239,19 @@ sock_execmsg(struct sock *f)
f->rstate = SOCK_RMSG;
break;
case AMSG_HELLO:
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ sock_dbg(f);
+ dbg_puts(": HELLO message\n");
+ }
+#endif
if (f->pstate != SOCK_HELLO) {
+#ifdef DEBUG
+ if (debug_level >= 1) {
+ sock_dbg(f);
+ dbg_puts(": HELLO, bad state\n");
+ }
+#endif
aproc_del(f->pipe.file.rproc);
return 0;
}
@@ -860,11 +1265,29 @@ sock_execmsg(struct sock *f)
f->rtodo = sizeof(struct amsg);
break;
case AMSG_BYE:
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ sock_dbg(f);
+ dbg_puts(": BYE message\n");
+ }
+#endif
if (f->pstate != SOCK_INIT) {
+#ifdef DEBUG
+ if (debug_level >= 1) {
+ sock_dbg(f);
+ dbg_puts(": BYE, bad state\n");
+ }
+#endif
}
aproc_del(f->pipe.file.rproc);
return 0;
default:
+#ifdef DEBUG
+ if (debug_level >= 1) {
+ sock_dbg(f);
+ dbg_puts(": unknown command in message\n");
+ }
+#endif
aproc_del(f->pipe.file.rproc);
return 0;
}
@@ -872,6 +1295,12 @@ sock_execmsg(struct sock *f)
if (f->wstate != SOCK_WIDLE ||
!sock_wmsg(f, &f->rmsg, &f->rtodo))
return 0;
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ sock_dbg(f);
+ dbg_puts(": RRET done\n");
+ }
+#endif
if (f->pstate == SOCK_MIDI && (f->mode & AMSG_MIDIOUT)) {
f->rstate = SOCK_RDATA;
f->rtodo = 0;
@@ -893,6 +1322,12 @@ sock_buildmsg(struct sock *f)
struct abuf *ibuf;
if (f->pstate == SOCK_MIDI) {
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ sock_dbg(f);
+ dbg_puts(": switching to MIDI mode\n");
+ }
+#endif
f->wstate = SOCK_WDATA;
f->wtodo = 0;
return 1;
@@ -902,6 +1337,14 @@ sock_buildmsg(struct sock *f)
* If pos changed, build a MOVE message.
*/
if (f->tickpending) {
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ sock_dbg(f);
+ dbg_puts(": building POS message, delta = ");
+ dbg_puti(f->delta);
+ dbg_puts("\n");
+ }
+#endif
AMSG_INIT(&f->wmsg);
f->wmsg.cmd = AMSG_MOVE;
f->wmsg.u.ts.delta = f->delta;
@@ -916,6 +1359,14 @@ sock_buildmsg(struct sock *f)
* if volume changed build a SETVOL message
*/
if (f->pstate >= SOCK_START && f->vol != f->lastvol) {
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ sock_dbg(f);
+ dbg_puts(": building SETVOL message, vol = ");
+ dbg_puti(f->vol);
+ dbg_puts("\n");
+ }
+#endif
AMSG_INIT(&f->wmsg);
f->wmsg.cmd = AMSG_SETVOL;
f->wmsg.u.vol.ctl = f->vol;
@@ -941,6 +1392,12 @@ sock_buildmsg(struct sock *f)
f->wstate = SOCK_WMSG;
return 1;
}
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ sock_dbg(f);
+ dbg_puts(": no messages to build anymore, idling...\n");
+ }
+#endif
f->wstate = SOCK_WIDLE;
return 0;
}
@@ -953,6 +1410,16 @@ sock_buildmsg(struct sock *f)
int
sock_read(struct sock *f)
{
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ sock_dbg(f);
+ dbg_puts(": reading, state = ");
+ dbg_putu(f->rstate);
+ dbg_puts(", todo = ");
+ dbg_putu(f->rtodo);
+ dbg_puts("\n");
+ }
+#endif
switch (f->rstate) {
case SOCK_RMSG:
if (!sock_rmsg(f))
@@ -974,6 +1441,12 @@ sock_read(struct sock *f)
(void)sock_attach(f, 0);
break;
case SOCK_RRET:
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ sock_dbg(f);
+ dbg_puts(": blocked by pending RRET message\n");
+ }
+#endif
return 0;
}
return 1;
@@ -990,6 +1463,12 @@ sock_return(struct sock *f)
while (f->rstate == SOCK_RRET) {
if (!sock_wmsg(f, &f->rmsg, &f->rtodo))
return 0;
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ sock_dbg(f);
+ dbg_puts(": sent RRET message\n");
+ }
+#endif
if (f->pstate == SOCK_MIDI && (f->mode & AMSG_MIDIOUT)) {
f->rstate = SOCK_RDATA;
f->rtodo = 0;
@@ -1024,6 +1503,16 @@ sock_return(struct sock *f)
int
sock_write(struct sock *f)
{
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ sock_dbg(f);
+ dbg_puts(": writing, state = ");
+ dbg_putu(f->wstate);
+ dbg_puts(", todo = ");
+ dbg_putu(f->wtodo);
+ dbg_puts("\n");
+ }
+#endif
switch (f->wstate) {
case SOCK_WMSG:
if (!sock_wmsg(f, &f->wmsg, &f->wtodo))
@@ -1050,6 +1539,12 @@ sock_write(struct sock *f)
if (!sock_buildmsg(f))
return 0;
break;
+#ifdef DEBUG
+ default:
+ sock_dbg(f);
+ dbg_puts(": bad writing end state\n");
+ dbg_panic();
+#endif
}
return 1;
}
diff --git a/usr.bin/aucat/wav.c b/usr.bin/aucat/wav.c
index 48563ed0ba1..aa6c7670341 100644
--- a/usr.bin/aucat/wav.c
+++ b/usr.bin/aucat/wav.c
@@ -24,6 +24,9 @@
#include "conf.h"
#include "dev.h"
#include "wav.h"
+#ifdef DEBUG
+#include "dbg.h"
+#endif
short wav_ulawmap[256] = {
-32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
@@ -447,6 +450,12 @@ wav_read(struct file *file, unsigned char *data, unsigned count)
if (f->rbytes >= 0 && count > f->rbytes) {
count = f->rbytes; /* file->rbytes fits in count */
if (count == 0) {
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ file_dbg(&f->pipe.file);
+ dbg_puts(": read complete\n");
+ }
+#endif
file_eof(&f->pipe.file);
return 0;
}
@@ -472,6 +481,12 @@ wav_write(struct file *file, unsigned char *data, unsigned count)
if (f->wbytes >= 0 && count > f->wbytes) {
count = f->wbytes; /* wbytes fits in count */
if (count == 0) {
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ file_dbg(&f->pipe.file);
+ dbg_puts(": write complete\n");
+ }
+#endif
file_hup(&f->pipe.file);
return 0;
}