summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.bin/aucat/abuf.c113
-rw-r--r--usr.bin/aucat/abuf.h29
-rw-r--r--usr.bin/aucat/amsg.h5
-rw-r--r--usr.bin/aucat/aproc.c729
-rw-r--r--usr.bin/aucat/aproc.h57
-rw-r--r--usr.bin/aucat/aucat.172
-rw-r--r--usr.bin/aucat/aucat.c299
-rw-r--r--usr.bin/aucat/conf.h15
-rw-r--r--usr.bin/aucat/dev.c366
-rw-r--r--usr.bin/aucat/dev.h22
-rw-r--r--usr.bin/aucat/file.c23
-rw-r--r--usr.bin/aucat/headers.c22
-rw-r--r--usr.bin/aucat/legacy.c6
-rw-r--r--usr.bin/aucat/midi.c220
-rw-r--r--usr.bin/aucat/midi.h6
-rw-r--r--usr.bin/aucat/midicat.116
-rw-r--r--usr.bin/aucat/opt.c42
-rw-r--r--usr.bin/aucat/opt.h11
-rw-r--r--usr.bin/aucat/pipe.c51
-rw-r--r--usr.bin/aucat/pipe.h5
-rw-r--r--usr.bin/aucat/siofile.c166
-rw-r--r--usr.bin/aucat/siofile.h7
-rw-r--r--usr.bin/aucat/sock.c338
-rw-r--r--usr.bin/aucat/sock.h11
-rw-r--r--usr.bin/aucat/wav.c740
-rw-r--r--usr.bin/aucat/wav.h29
26 files changed, 1004 insertions, 2396 deletions
diff --git a/usr.bin/aucat/abuf.c b/usr.bin/aucat/abuf.c
index a206a775d0b..fcffe898b70 100644
--- a/usr.bin/aucat/abuf.c
+++ b/usr.bin/aucat/abuf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: abuf.c,v 1.19 2010/04/03 17:40:33 ratchov Exp $ */
+/* $OpenBSD: abuf.c,v 1.20 2010/04/03 17:59:17 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -105,9 +105,12 @@ abuf_new(unsigned nfr, struct aparams *par)
/*
* fill fifo pointers
*/
- buf->len = nfr;
+ buf->len = len;
buf->used = 0;
buf->start = 0;
+ buf->abspos = 0;
+ buf->silence = 0;
+ buf->drop = 0;
buf->rproc = NULL;
buf->wproc = NULL;
buf->duplex = NULL;
@@ -158,6 +161,9 @@ abuf_clear(struct abuf *buf)
#endif
buf->used = 0;
buf->start = 0;
+ buf->abspos = 0;
+ buf->silence = 0;
+ buf->drop = 0;
}
/*
@@ -185,7 +191,7 @@ abuf_rgetblk(struct abuf *buf, unsigned *rsize, unsigned ofs)
if (count > used)
count = used;
*rsize = count;
- return (unsigned char *)buf + sizeof(struct abuf) + start * buf->bpf;
+ return (unsigned char *)buf + sizeof(struct abuf) + start;
}
/*
@@ -207,6 +213,7 @@ abuf_rdiscard(struct abuf *buf, unsigned count)
buf->start += count;
if (buf->start >= buf->len)
buf->start -= buf->len;
+ buf->abspos += count;
}
/*
@@ -253,7 +260,7 @@ abuf_wgetblk(struct abuf *buf, unsigned *rsize, unsigned ofs)
if (count > avail)
count = avail;
*rsize = count;
- return (unsigned char *)buf + sizeof(struct abuf) + end * buf->bpf;
+ return (unsigned char *)buf + sizeof(struct abuf) + end;
}
/*
@@ -264,17 +271,47 @@ int
abuf_flush_do(struct abuf *buf)
{
struct aproc *p;
+ unsigned count;
- p = buf->rproc;
- if (!p)
- return 0;
+ if (buf->drop > 0) {
+ count = buf->drop;
+ if (count > buf->used)
+ count = buf->used;
+ if (count == 0) {
#ifdef DEBUG
- if (debug_level >= 4) {
- aproc_dbg(p);
- dbg_puts(": in\n");
- }
+ 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
- return p->ops->in(p, buf);
+ } 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;
+ }
+ return 1;
}
/*
@@ -285,17 +322,51 @@ int
abuf_fill_do(struct abuf *buf)
{
struct aproc *p;
-
- p = buf->wproc;
- if (!p)
- return 0;
+ unsigned char *data;
+ unsigned count;
+
+ if (buf->silence > 0) {
+ data = abuf_wgetblk(buf, &count, 0);
+ if (count >= buf->silence)
+ count = buf->silence;
+ if (count == 0) {
#ifdef DEBUG
- if (debug_level >= 4) {
- aproc_dbg(p);
- dbg_puts(": out\n");
- }
+ 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
- return p->ops->out(p, buf);
+ 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;
+ }
+ }
+ return 1;
}
/*
diff --git a/usr.bin/aucat/abuf.h b/usr.bin/aucat/abuf.h
index a69495261b0..79c5e9a773d 100644
--- a/usr.bin/aucat/abuf.h
+++ b/usr.bin/aucat/abuf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: abuf.h,v 1.20 2010/04/03 17:40:33 ratchov Exp $ */
+/* $OpenBSD: abuf.h,v 1.21 2010/04/03 17:59:17 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -39,6 +39,9 @@ struct abuf {
unsigned start; /* offset where data starts */
unsigned used; /* valid data */
unsigned len; /* size of the ring */
+ unsigned abspos; /* frame number of the start position */
+ unsigned silence; /* silence to insert on next write */
+ unsigned drop; /* bytes to drop on next read */
struct aproc *rproc; /* reader */
struct aproc *wproc; /* writer */
struct abuf *duplex; /* link to buffer of the other direction */
@@ -53,9 +56,8 @@ struct abuf {
int weight; /* dynamic range */
int maxweight; /* max dynamic range allowed */
unsigned vol; /* volume within the dynamic range */
- unsigned done; /* frames ready */
+ unsigned done; /* bytes ready */
unsigned xrun; /* underrun policy */
- int drop; /* frames to drop on next read */
} mix;
struct {
unsigned st; /* MIDI running status */
@@ -71,12 +73,11 @@ struct abuf {
*/
union {
struct {
- unsigned todo; /* frames to process */
+ unsigned todo; /* bytes to process */
} mix;
struct {
- unsigned done; /* frames copied */
+ unsigned done; /* bytes copied */
unsigned xrun; /* overrun policy */
- int silence; /* silence to add on next write */
} sub;
} w;
};
@@ -85,12 +86,12 @@ struct abuf {
* the buffer contains at least one frame. This macro should
* be used to check if the buffer can be flushed
*/
-#define ABUF_ROK(b) ((b)->used > 0)
+#define ABUF_ROK(b) ((b)->used >= (b)->bpf)
/*
* there's room for at least one frame
*/
-#define ABUF_WOK(b) ((b)->len - (b)->used > 0)
+#define ABUF_WOK(b) ((b)->len - (b)->used >= (b)->bpf)
/*
* the buffer is empty and has no writer anymore
@@ -104,6 +105,18 @@ struct abuf {
*/
#define ABUF_HUP(b) (!ABUF_WOK(b) && (b)->rproc == NULL)
+/*
+ * similar to !ABUF_WOK, but is used for file i/o, where
+ * operation may not involve an integer number of frames
+ */
+#define ABUF_FULL(b) ((b)->used == (b)->len)
+
+/*
+ * same as !ABUF_ROK, but used for files, where
+ * operations are byte orientated, not frame-oriented
+ */
+#define ABUF_EMPTY(b) ((b)->used == 0)
+
struct abuf *abuf_new(unsigned, struct aparams *);
void abuf_del(struct abuf *);
void abuf_dbg(struct abuf *);
diff --git a/usr.bin/aucat/amsg.h b/usr.bin/aucat/amsg.h
index 7da19f2e55e..c712c998ae3 100644
--- a/usr.bin/aucat/amsg.h
+++ b/usr.bin/aucat/amsg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: amsg.h,v 1.13 2010/04/03 17:40:33 ratchov Exp $ */
+/* $OpenBSD: amsg.h,v 1.14 2010/04/03 17:59:17 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -87,8 +87,7 @@ struct amsg {
#define AMSG_REC 0x2 /* audio recording */
#define AMSG_MIDIIN 0x4 /* MIDI thru input */
#define AMSG_MIDIOUT 0x8 /* MIDI thru output */
-#define AMSG_MON 0x10 /* audio monitoring */
-#define AMSG_RECMASK (AMSG_REC | AMSG_MON) /* can record ? */
+#define AMSG_MIXER 0x10 /* MIDI mixer */
uint16_t proto; /* protocol type */
#define AMSG_VERSION 1
uint8_t version; /* protocol version */
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;
-}
diff --git a/usr.bin/aucat/aproc.h b/usr.bin/aucat/aproc.h
index 6b2947c852b..7b910155d3f 100644
--- a/usr.bin/aucat/aproc.h
+++ b/usr.bin/aucat/aproc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: aproc.h,v 1.30 2010/04/03 17:40:33 ratchov Exp $ */
+/* $OpenBSD: aproc.h,v 1.31 2010/04/03 17:59:17 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -130,37 +130,26 @@ struct aproc {
union { /* follow type-specific data */
struct { /* file/device io */
struct file *file; /* file to read/write */
- unsigned partial; /* bytes of partial frame */
} io;
struct {
unsigned idle; /* frames since idleing */
- unsigned round; /* block size, for xruns */
int lat; /* current latency */
int maxlat; /* max latency allowed */
- unsigned abspos; /* frames produced */
- struct aproc *ctl; /* MIDI control/sync */
- struct aproc *mon; /* snoop output */
+ struct aproc *ctl;
} mix;
struct {
unsigned idle; /* frames since idleing */
- unsigned round; /* block size, for xruns */
int lat; /* current latency */
int maxlat; /* max latency allowed */
- unsigned abspos; /* frames consumed */
struct aproc *ctl;
} sub;
struct {
- int delta; /* time position */
- unsigned bufsz; /* buffer size (latency) */
- unsigned pending; /* uncommited samples */
- } mon;
- struct {
#define RESAMP_NCTX 2
unsigned ctx_start;
short ctx[NCHAN_MAX * RESAMP_NCTX];
unsigned iblksz, oblksz;
int diff;
- int idelta, odelta; /* remainder of resamp_xpos */
+ int idelta, odelta; /* remainder of resamp_[io]pos */
} resamp;
struct {
short ctx[NCHAN_MAX];
@@ -202,8 +191,6 @@ struct aproc {
struct ctl_ops {
void (*vol)(void *, unsigned);
void (*start)(void *);
- void (*stop)(void *);
- void (*loc)(void *, unsigned);
} *ops;
void *arg;
unsigned unit;
@@ -216,18 +203,6 @@ struct aproc {
} u;
};
-/*
- * Check if the given pointer is a valid aproc structure.
- *
- * aproc structures are not free()'d immediately, because
- * there may be pointers to them, instead the APROC_ZOMB flag
- * is set which means that they should not be used. When
- * aprocs reference counter reaches zero, they are actually
- * freed
- */
-#define APROC_OK(p) ((p) && !((p)->flags & APROC_ZOMB))
-
-
struct aproc *aproc_new(struct aproc_ops *, char *);
void aproc_del(struct aproc *);
void aproc_dbg(struct aproc *);
@@ -235,40 +210,18 @@ void aproc_setin(struct aproc *, struct abuf *);
void aproc_setout(struct aproc *, struct abuf *);
int aproc_depend(struct aproc *, struct aproc *);
-void aproc_ipos(struct aproc *, struct abuf *, int);
-void aproc_opos(struct aproc *, struct abuf *, int);
-
struct aproc *rfile_new(struct file *);
struct aproc *wfile_new(struct file *);
-struct aproc *mix_new(char *, int, unsigned, struct aproc *);
-struct aproc *sub_new(char *, int, unsigned, struct aproc *);
+struct aproc *mix_new(char *, int, struct aproc *);
+struct aproc *sub_new(char *, int, struct aproc *);
struct aproc *resamp_new(char *, unsigned, unsigned);
struct aproc *cmap_new(char *, struct aparams *, struct aparams *);
struct aproc *enc_new(char *, struct aparams *);
struct aproc *dec_new(char *, struct aparams *);
-struct aproc *mon_new(char *, unsigned);
-
-int rfile_in(struct aproc *, struct abuf *);
-int rfile_out(struct aproc *, struct abuf *);
-void rfile_eof(struct aproc *, struct abuf *);
-void rfile_hup(struct aproc *, struct abuf *);
-void rfile_done(struct aproc *);
-int rfile_do(struct aproc *, unsigned, unsigned *);
-
-int wfile_in(struct aproc *, struct abuf *);
-int wfile_out(struct aproc *, struct abuf *);
-void wfile_eof(struct aproc *, struct abuf *);
-void wfile_hup(struct aproc *, struct abuf *);
-void wfile_done(struct aproc *);
-int wfile_do(struct aproc *, unsigned, unsigned *);
void mix_setmaster(struct aproc *);
void mix_clear(struct aproc *);
void mix_prime(struct aproc *);
-void mix_drop(struct abuf *, int);
-void sub_silence(struct abuf *, int);
void sub_clear(struct aproc *);
-void mon_snoop(struct aproc *, struct abuf *, unsigned, unsigned);
-void mon_clear(struct aproc *);
#endif /* !defined(APROC_H) */
diff --git a/usr.bin/aucat/aucat.1 b/usr.bin/aucat/aucat.1
index e03e10364cc..d29af368242 100644
--- a/usr.bin/aucat/aucat.1
+++ b/usr.bin/aucat/aucat.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: aucat.1,v 1.64 2010/04/03 17:40:33 ratchov Exp $
+.\" $OpenBSD: aucat.1,v 1.65 2010/04/03 17:59:17 ratchov Exp $
.\"
.\" Copyright (c) 2006 Alexandre Ratchov <alex@caoua.org>
.\"
@@ -33,7 +33,6 @@
.Op Fl i Ar file
.Op Fl m Ar mode
.Op Fl o Ar file
-.Op Fl q Ar device
.Op Fl r Ar rate
.Op Fl s Ar name
.Op Fl t Ar mode
@@ -58,7 +57,7 @@ which does not convert on the fly and supports playback of .au files.
The options are as follows:
.Bl -tag -width Ds
.It Fl b Ar nframes
-The buffer size of the audio device in frames.
+The buffer size in frames.
A frame consists of one sample for each channel in the stream.
This is the number of frames that will be buffered before being played
and thus controls the playback latency.
@@ -106,21 +105,15 @@ but other names can be used with the
.Fl s
option.
.It Fl m Ar mode
-Set the stream mode.
+Set the server mode.
Valid modes are
.Ar play ,
.Ar rec ,
and
-.Ar mon ,
-corresponding to playback, recording and monitoring.
-A monitoring stream is a fake recording stream corresponding to
-the mix of all playback streams.
-Multiple modes can be specified, separated by commas,
-but the same stream cannot be used for both recording and monitoring.
+.Ar duplex ,
+for play-only, record-only, and full-duplex, respectively.
The default is
-.\" no spaces allowed between modes
-.Ar play,rec
-(i.e., full-duplex).
+.Ar duplex .
.It Fl n
Loopback mode.
Instead of using an audio device, send input streams
@@ -132,11 +125,6 @@ Add this file to the list of files in which to store recorded samples.
If the option argument is
.Sq -
then standard output will be used.
-.It Fl q Ar device
-The
-.Xr sndio 7
-MIDI device to use for controlling stream volumes or
-to start multiple streams synchronously.
.It Fl r Ar rate
Sample rate in Hertz of the playback or record stream.
The default is 44100Hz.
@@ -487,54 +475,6 @@ behave normally, while streams connected to
wait for the MMC start signal and start synchronously.
Regardless of which device a stream is connected to,
its playback volume knob is exposed.
-.Pp
-If
-.Nm
-is used to play and record audio files, it offers
-similar MIDI control.
-.Nm
-can open a
-.Xr sndio 7
-MIDI device allowing MIDI hardware or software
-to control playback and recording in real time.
-.Pp
-A MIDI channel is assigned to each stream, and the volume
-is changed using the standard volume controller (number 7).
-Streams created with
-.Fl t Ar slave
-are controlled by the following MMC (MIDI Machine Control) messages:
-.Bl -tag -width relocateXXX -offset -indent
-.It start
-Start all streams synchronously.
-By default, streams are created in stopped state.
-.It stop
-Playback or recording is stopped, and
-the stream is rewinded back to the starting position.
-.It relocate
-Streams are relocated to the requested time postion
-relative to the beginning of the stream, at which playback
-and recording must start.
-If the requested position is beyond the end of file,
-the stream is temporarly disabled until a valid postion is requested.
-.El
-.Pp
-For instance, the following command will play a file on the
-.Va aucat:0.mmc
-audio device, and let full control to MIDI software or hardware
-connected to the
-.Va midithru:0
-MIDI device:
-.Bd -literal -offset indent
-$ aucat -f aucat:0.mmc -t slave -q midithru:0 -i file.wav
-.Ed
-.Pp
-At this stage,
-.Nm
-will start, stop and relocate automatically following all user
-actions in the MIDI sequencer.
-Note that the sequencer must use
-.Va aucat:0
-as MTC source, i.e., the audio server, not the audio player.
.Sh LEGACY MODE
If neither
.Fl i
diff --git a/usr.bin/aucat/aucat.c b/usr.bin/aucat/aucat.c
index e2bebf47668..81093f42a4c 100644
--- a/usr.bin/aucat/aucat.c
+++ b/usr.bin/aucat/aucat.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: aucat.c,v 1.81 2010/04/03 17:40:33 ratchov Exp $ */
+/* $OpenBSD: aucat.c,v 1.82 2010/04/03 17:59:17 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -43,6 +43,9 @@
#include "dbg.h"
#endif
+#define MODE_PLAY 1
+#define MODE_REC 2
+
#define PROG_AUCAT "aucat"
#define PROG_MIDICAT "midicat"
@@ -156,33 +159,16 @@ opt_xrun(void)
errx(1, "%s: bad underrun/overrun policy", optarg);
}
-unsigned
+int
opt_mode(void)
{
- unsigned mode = 0;
- char *p = optarg;
- size_t len;
-
- for (p = optarg; *p != NULL; p++) {
- len = strcspn(p, ",");
- if (strncmp("play", p, len) == 0) {
- mode |= MODE_PLAY;
- } else if (strncmp("rec", p, len) == 0) {
- mode |= MODE_REC;
- } else if (strncmp("mon", p, len) == 0) {
- mode |= MODE_MON;
- } else if (strncmp("duplex", p, len) == 0) {
- /* XXX: backward compat, remove this */
- mode |= MODE_REC | MODE_PLAY;
- } else
- errx(1, "%s: bad mode", optarg);
- p += len;
- if (*p == '\0')
- break;
- }
- if (mode == 0)
- errx(1, "empty mode");
- return mode;
+ if (strcmp("play", optarg) == 0)
+ return MODE_PLAY;
+ if (strcmp("rec", optarg) == 0)
+ return MODE_REC;
+ if (strcmp("duplex", optarg) == 0)
+ return MODE_PLAY | MODE_REC;
+ errx(1, "%s: bad mode", optarg);
}
/*
@@ -197,7 +183,6 @@ struct farg {
int hdr; /* header format */
int xrun; /* overrun/underrun policy */
int mmc; /* MMC mode */
- unsigned mode;
};
SLIST_HEAD(farglist, farg);
@@ -209,7 +194,7 @@ SLIST_HEAD(farglist, farg);
void
farg_add(struct farglist *list,
struct aparams *ipar, struct aparams *opar, unsigned vol,
- int hdr, int xrun, int mmc, unsigned mode, char *name)
+ int hdr, int xrun, int mmc, char *name)
{
struct farg *fa;
size_t namelen;
@@ -227,15 +212,12 @@ farg_add(struct farglist *list,
}
} else
fa->hdr = hdr;
- if (mmc && xrun == XRUN_IGNORE)
- xrun = XRUN_SYNC;
fa->xrun = xrun;
fa->ipar = *ipar;
fa->opar = *opar;
fa->vol = vol;
fa->name = name;
fa->mmc = mmc;
- fa->mode = mode;
SLIST_INSERT_HEAD(list, fa, entry);
}
@@ -305,61 +287,28 @@ getbasepath(char *base, size_t size)
}
void
-stopall(char *base)
-{
- struct file *f;
-
- restart:
- LIST_FOREACH(f, &file_list, entry) {
- /*
- * skip connected streams (handled by dev_done())
- */
- if (APROC_OK(dev_mix) && f->rproc &&
- aproc_depend(dev_mix, f->rproc))
- continue;
- if (APROC_OK(dev_sub) && f->wproc &&
- aproc_depend(f->wproc, dev_sub))
- continue;
- if (APROC_OK(dev_midi)) {
- if (f->rproc && aproc_depend(dev_midi, f->rproc))
- continue;
- if (f->wproc && aproc_depend(f->wproc, dev_midi))
- continue;
- }
- /*
- * kill anything else
- */
- file_close(f);
- goto restart;
- }
-}
-
-void
aucat_usage(void)
{
(void)fputs("usage: " PROG_AUCAT " [-dlnu] [-b nframes] "
- "[-C min:max] [-c min:max] [-e enc]\n\t"
- "[-f device] [-h fmt] [-i file] [-m mode]"
- "[-o file] [-q device]\n\t"
- "[-r rate] [-s name] [-t mode] [-U unit] "
- "[-v volume] [-x policy]\n\t"
- "[-z nframes]\n",
+ "[-C min:max] [-c min:max] [-e enc] [-f device]\n"
+ "\t[-h fmt] [-i file] [-m mode] [-o file] [-r rate] [-s name]\n"
+ "\t[-t mode] [-U unit] [-v volume] [-x policy] [-z nframes]\n",
stderr);
}
int
aucat_main(int argc, char **argv)
{
- int c, u_flag, d_flag, l_flag, n_flag, hdr, xrun, unit;
+ int c, u_flag, d_flag, l_flag, n_flag, hdr, xrun, suspend = 0, unit;
struct farg *fa;
- struct farglist ifiles, ofiles, sfiles, qfiles;
+ struct farglist ifiles, ofiles, sfiles;
struct aparams ipar, opar, dipar, dopar;
char base[PATH_MAX], path[PATH_MAX], *file;
unsigned bufsz, round, mode;
char *devpath;
const char *str;
unsigned volctl;
- int mmc, autostart;
+ int mmc;
aparams_init(&ipar, 0, 1, 44100);
aparams_init(&opar, 0, 1, 44100);
@@ -373,16 +322,14 @@ aucat_main(int argc, char **argv)
SLIST_INIT(&ifiles);
SLIST_INIT(&ofiles);
SLIST_INIT(&sfiles);
- SLIST_INIT(&qfiles);
hdr = HDR_AUTO;
xrun = XRUN_IGNORE;
volctl = MIDI_MAXCTL;
- mode = MODE_PLAY | MODE_REC;
+ mode = 0;
bufsz = 0;
round = 0;
- autostart = 1;
- while ((c = getopt(argc, argv, "dnb:c:C:e:r:h:x:v:i:o:f:m:luq:s:U:t:z:")) != -1) {
+ 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
@@ -405,8 +352,6 @@ aucat_main(int argc, char **argv)
break;
case 't':
mmc = opt_mmc();
- if (mmc)
- autostart = 0;
break;
case 'c':
opt_ch(&ipar);
@@ -434,22 +379,18 @@ aucat_main(int argc, char **argv)
if (strcmp(file, "-") == 0)
file = NULL;
farg_add(&ifiles, &ipar, &opar, volctl,
- hdr, xrun, mmc, mode & MODE_PLAY, file);
+ hdr, xrun, 0, file);
break;
case 'o':
file = optarg;
if (strcmp(file, "-") == 0)
file = NULL;
farg_add(&ofiles, &ipar, &opar, volctl,
- hdr, xrun, mmc, mode & MODE_RECMASK, file);
+ hdr, xrun, 0, file);
break;
case 's':
farg_add(&sfiles, &ipar, &opar, volctl,
- hdr, xrun, mmc, mode, optarg);
- break;
- case 'q':
- farg_add(&qfiles, &aparams_none, &aparams_none,
- 0, HDR_RAW, 0, 0, 0, optarg);
+ hdr, xrun, mmc, optarg);
break;
case 'f':
if (devpath)
@@ -460,7 +401,6 @@ aucat_main(int argc, char **argv)
break;
case 'l':
l_flag = 1;
- autostart = 0;
break;
case 'u':
u_flag = 1;
@@ -511,12 +451,22 @@ aucat_main(int argc, char **argv)
if (!l_flag && (!SLIST_EMPTY(&sfiles) || unit >= 0))
errx(1, "can't use -s or -U without -l");
- if (l_flag && (!SLIST_EMPTY(&ofiles) || !SLIST_EMPTY(&ifiles)))
- errx(1, "can't use -l, and -s with -o or -i");
+ if ((l_flag || mode != 0) &&
+ (!SLIST_EMPTY(&ofiles) || !SLIST_EMPTY(&ifiles)))
+ errx(1, "can't use -l, -m and -s with -o or -i");
+ if (!mode) {
+ if (l_flag || !SLIST_EMPTY(&ifiles))
+ mode |= MODE_PLAY;
+ if (l_flag || !SLIST_EMPTY(&ofiles))
+ mode |= MODE_REC;
+ if (!mode) {
+ aucat_usage();
+ exit(1);
+ }
+ }
if (n_flag) {
- if (devpath != NULL || !SLIST_EMPTY(&qfiles) ||
- l_flag || !autostart)
- errx(1, "can't use -n with -f, -q, -t or -l");
+ if (devpath != NULL || l_flag)
+ errx(1, "can't use -n with -f or -l");
if (SLIST_EMPTY(&ifiles) || SLIST_EMPTY(&ofiles))
errx(1, "both -i and -o are required with -n");
}
@@ -526,43 +476,28 @@ aucat_main(int argc, char **argv)
*/
if (l_flag && SLIST_EMPTY(&sfiles)) {
farg_add(&sfiles, &dopar, &dipar,
- volctl, HDR_RAW, XRUN_IGNORE, mmc, mode, DEFAULT_OPT);
+ volctl, HDR_RAW, XRUN_IGNORE, mmc, DEFAULT_OPT);
}
- /*
- * Check modes and calculate "best" device parameters. Iterate over all
- * inputs and outputs and find the maximum sample rate and channel
- * number.
- */
- mode = 0;
- aparams_init(&dipar, dipar.cmin, dipar.cmax, dipar.rate);
- aparams_init(&dopar, dopar.cmin, dopar.cmax, dopar.rate);
- SLIST_FOREACH(fa, &ifiles, entry) {
- if (fa->mode == 0)
- errx(1, "%s: not in play mode", fa->name);
- mode |= fa->mode;
- if (!u_flag)
+ if (!u_flag) {
+ /*
+ * Calculate "best" device parameters. Iterate over all
+ * inputs and outputs and find the maximum sample rate
+ * and channel number.
+ */
+ aparams_init(&dipar, dipar.cmin, dipar.cmax, dipar.rate);
+ aparams_init(&dopar, dopar.cmin, dopar.cmax, dopar.rate);
+ SLIST_FOREACH(fa, &ifiles, entry) {
aparams_grow(&dopar, &fa->ipar);
- }
- SLIST_FOREACH(fa, &ofiles, entry) {
- if (fa->mode == 0)
- errx(1, "%s: not in rec/mon mode", fa->name);
- if ((fa->mode & MODE_REC) && (fa->mode & MODE_MON))
- errx(1, "%s: can't record and monitor", fa->name);
- mode |= fa->mode;
- if (!u_flag)
+ }
+ SLIST_FOREACH(fa, &ofiles, entry) {
aparams_grow(&dipar, &fa->opar);
- }
- SLIST_FOREACH(fa, &sfiles, entry) {
- if ((fa->mode & MODE_REC) && (fa->mode & MODE_MON))
- errx(1, "%s: can't record and monitor", fa->name);
- mode |= fa->mode;
- if (!u_flag) {
+ }
+ SLIST_FOREACH(fa, &sfiles, entry) {
aparams_grow(&dopar, &fa->ipar);
aparams_grow(&dipar, &fa->opar);
}
}
-
if (!round)
round = ((mode & MODE_REC) ? dipar.rate : dopar.rate) / 15;
if (!bufsz)
@@ -581,13 +516,12 @@ aucat_main(int argc, char **argv)
* the other half is for the socket/files.
*/
if (n_flag) {
- if (mode & MODE_MON)
- errx(1, "monitoring not allowed in loopback mode");
dev_loopinit(&dipar, &dopar, bufsz);
} else {
- if ((mode & MODE_MON) && !(mode & MODE_PLAY))
- errx(1, "no playback stream to monitor");
- if (!dev_init(devpath, mode, &dipar, &dopar, bufsz, round)) {
+ if (!dev_init(devpath,
+ (mode & MODE_REC) ? &dipar : NULL,
+ (mode & MODE_PLAY) ? &dopar : NULL,
+ bufsz, round)) {
errx(1, "%s: can't open device",
devpath ? devpath : "<default>");
}
@@ -596,33 +530,26 @@ aucat_main(int argc, char **argv)
/*
* Create buffers for all input and output pipes.
*/
- while (!SLIST_EMPTY(&qfiles)) {
- fa = SLIST_FIRST(&qfiles);
- SLIST_REMOVE_HEAD(&qfiles, entry);
- if (!dev_thruadd(fa->name, 1, 1))
- errx(1, "%s: can't open device", fa->name);
- free(fa);
- }
while (!SLIST_EMPTY(&ifiles)) {
fa = SLIST_FIRST(&ifiles);
SLIST_REMOVE_HEAD(&ifiles, entry);
- if (!wav_new_in(&wav_ops, fa->mode, fa->name,
- fa->hdr, &fa->ipar, fa->xrun, fa->vol, fa->mmc))
+ if (!wav_new_in(&wav_ops, fa->name,
+ fa->hdr, &fa->ipar, fa->xrun, fa->vol))
exit(1);
free(fa);
}
while (!SLIST_EMPTY(&ofiles)) {
fa = SLIST_FIRST(&ofiles);
SLIST_REMOVE_HEAD(&ofiles, entry);
- if (!wav_new_out(&wav_ops, fa->mode, fa->name,
- fa->hdr, &fa->opar, fa->xrun, fa->mmc))
+ if (!wav_new_out(&wav_ops, fa->name,
+ fa->hdr, &fa->opar, fa->xrun))
free(fa);
}
while (!SLIST_EMPTY(&sfiles)) {
fa = SLIST_FIRST(&sfiles);
SLIST_REMOVE_HEAD(&sfiles, entry);
opt_new(fa->name, &fa->opar, &fa->ipar,
- MIDI_TO_ADATA(fa->vol), fa->mmc, fa->mode);
+ MIDI_TO_ADATA(fa->vol), fa->mmc);
free(fa);
}
if (l_flag) {
@@ -632,14 +559,6 @@ aucat_main(int argc, char **argv)
if (!d_flag && daemon(0, 0) < 0)
err(1, "daemon");
}
- if (autostart) {
- /*
- * inject artificial mmc start
- */
- ctl_start(dev_midi);
- }
- if (l_flag)
- dev_prime();
/*
* Loop, start audio.
@@ -648,48 +567,57 @@ aucat_main(int argc, char **argv)
if (quit_flag) {
break;
}
- if ((APROC_OK(dev_mix) && LIST_EMPTY(&dev_mix->obuflist)) ||
- (APROC_OK(dev_sub) && LIST_EMPTY(&dev_sub->ibuflist))) {
+ if ((dev_mix && LIST_EMPTY(&dev_mix->obuflist)) ||
+ (dev_sub && LIST_EMPTY(&dev_sub->ibuflist))) {
fprintf(stderr, "device disappeared, terminating\n");
break;
}
- if (!l_flag && ctl_idle(dev_midi))
- break;
if (!file_poll())
break;
- if ((!APROC_OK(dev_mix) || dev_mix->u.mix.idle > 2 * dev_bufsz) &&
- (!APROC_OK(dev_sub) || dev_sub->u.sub.idle > 2 * dev_bufsz) &&
- (!APROC_OK(dev_submon) || dev_submon->u.sub.idle > 2 * dev_bufsz) &&
- (!APROC_OK(dev_midi) || dev_midi->u.ctl.tstate != CTL_RUN)) {
- if (dev_pstate == DEV_RUN) {
- dev_pstate = DEV_INIT;
+ if ((!dev_mix || dev_mix->u.mix.idle > 2 * dev_bufsz) &&
+ (!dev_sub || dev_sub->u.sub.idle > 2 * dev_bufsz) &&
+ ((dev_mix || dev_sub) && dev_midi->u.ctl.tstate != CTL_RUN)) {
+ if (!l_flag)
+ break;
+ if (!suspend) {
+#ifdef DEBUG
+ if (debug_level >= 2)
+ dbg_puts("suspending\n");
+#endif
+ suspend = 1;
dev_stop();
dev_clear();
- /*
- * priming buffer in non-server mode is not
- * ok, because it will insert silence and
- * break synchronization
- */
- if (l_flag)
- dev_prime();
+ dev_prime();
}
}
- /*
- * move device state machine
- * XXX: move this to dev.c
- */
- if (dev_pstate == DEV_START) {
- dev_pstate = DEV_RUN;
- dev_start();
+ if ((dev_mix && dev_mix->u.mix.idle == 0) ||
+ (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();
+ }
}
}
- stopall(base);
- dev_done();
- filelist_done();
if (l_flag) {
- if (rmdir(base) < 0 && errno != ENOTEMPTY)
+ filelist_unlisten();
+ if (rmdir(base) < 0)
warn("rmdir(\"%s\")", base);
}
+ if (suspend) {
+#ifdef DEBUG
+ if (debug_level >= 2)
+ dbg_puts("resuming to drain\n");
+#endif
+ suspend = 0;
+ dev_start();
+ }
+ dev_done();
+ filelist_done();
unsetsig();
return 0;
}
@@ -697,8 +625,8 @@ aucat_main(int argc, char **argv)
void
midicat_usage(void)
{
- (void)fputs("usage: " PROG_MIDICAT " [-dl] "
- "[-i file] [-o file] [-q device] [-U unit]\n",
+ (void)fputs("usage: " PROG_MIDICAT " [-dl] [-f device] "
+ "[-i file] [-o file] [-U unit]\n",
stderr);
}
int
@@ -720,7 +648,7 @@ midicat_main(int argc, char **argv)
SLIST_INIT(&ifiles);
SLIST_INIT(&ofiles);
- while ((c = getopt(argc, argv, "di:o:lf:q:U:")) != -1) {
+ while ((c = getopt(argc, argv, "di:o:lf:U:")) != -1) {
switch (c) {
case 'd':
#ifdef DEBUG
@@ -731,17 +659,15 @@ midicat_main(int argc, char **argv)
break;
case 'i':
farg_add(&ifiles, &aparams_none, &aparams_none,
- 0, HDR_RAW, 0, 0, 0, optarg);
+ 0, HDR_RAW, 0, 0, optarg);
break;
case 'o':
farg_add(&ofiles, &aparams_none, &aparams_none,
- 0, HDR_RAW, 0, 0, 0, optarg);
+ 0, HDR_RAW, 0, 0, optarg);
break;
- /* XXX: backward compat, remove this */
- case 'f':
- case 'q':
+ case 'f':
farg_add(&dfiles, &aparams_none, &aparams_none,
- 0, HDR_RAW, 0, 0, 0, optarg);
+ 0, HDR_RAW, 0, 0, optarg);
break;
case 'l':
l_flag = 1;
@@ -777,12 +703,12 @@ midicat_main(int argc, char **argv)
filelist_init();
dev_thruinit();
- if (!l_flag && APROC_OK(dev_midi))
+ if (!l_flag)
dev_midi->flags |= APROC_QUIT;
if ((!SLIST_EMPTY(&ifiles) || !SLIST_EMPTY(&ofiles)) &&
SLIST_EMPTY(&dfiles)) {
farg_add(&dfiles, &aparams_none, &aparams_none,
- 0, HDR_RAW, 0, 0, 0, NULL);
+ 0, HDR_RAW, 0, 0, NULL);
}
while (!SLIST_EMPTY(&dfiles)) {
fa = SLIST_FIRST(&dfiles);
@@ -841,6 +767,7 @@ midicat_main(int argc, char **argv)
dev_midiattach(NULL, buf);
free(fa);
}
+
/*
* loop, start processing
*/
@@ -851,13 +778,13 @@ midicat_main(int argc, char **argv)
if (!file_poll())
break;
}
- stopall(base);
- dev_done();
- filelist_done();
if (l_flag) {
- if (rmdir(base) < 0 && errno != ENOTEMPTY)
+ filelist_unlisten();
+ if (rmdir(base) < 0)
warn("rmdir(\"%s\")", base);
}
+ dev_done();
+ filelist_done();
unsetsig();
return 0;
}
diff --git a/usr.bin/aucat/conf.h b/usr.bin/aucat/conf.h
index 66b7b9ee2b4..47bc9ae7e11 100644
--- a/usr.bin/aucat/conf.h
+++ b/usr.bin/aucat/conf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: conf.h,v 1.13 2010/04/03 17:40:33 ratchov Exp $ */
+/* $OpenBSD: conf.h,v 1.14 2010/04/03 17:59:17 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -31,6 +31,19 @@ extern int debug_level;
#endif
/*
+ * Number of blocks in the device play/record buffers. Because Sun API
+ * cannot notify apps of the current positions, we have to use all N
+ * buffers devices blocks plus one extra block, to make write() block,
+ * so that poll() can return the exact postition.
+ */
+#define DEV_NBLK 2
+
+/*
+ * Number of blocks in the wav-file i/o buffers.
+ */
+#define WAV_NBLK 6
+
+/*
* socket and option names
*/
#define DEFAULT_MIDITHRU "midithru"
diff --git a/usr.bin/aucat/dev.c b/usr.bin/aucat/dev.c
index 683ba1b6c5a..09e97da8ea0 100644
--- a/usr.bin/aucat/dev.c
+++ b/usr.bin/aucat/dev.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dev.c,v 1.44 2010/04/03 17:40:33 ratchov Exp $ */
+/* $OpenBSD: dev.c,v 1.45 2010/04/03 17:59:17 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -27,15 +27,13 @@
#include "miofile.h"
#include "siofile.h"
#include "midi.h"
-#include "opt.h"
#ifdef DEBUG
#include "dbg.h"
#endif
-unsigned dev_pstate;
unsigned dev_bufsz, dev_round, dev_rate;
struct aparams dev_ipar, dev_opar;
-struct aproc *dev_mix, *dev_sub, *dev_rec, *dev_play, *dev_submon, *dev_mon;
+struct aproc *dev_mix, *dev_sub, *dev_rec, *dev_play;
struct aproc *dev_midi;
/*
@@ -103,14 +101,6 @@ dev_loopinit(struct aparams *dipar, struct aparams *dopar, unsigned bufsz)
struct aparams par;
unsigned cmin, cmax, rate;
- /*
- * in principle we don't need control, but the start-stop mechanism
- * depend on it and it's simpler to reuse this mechanism rather than
- * dealing with lots of special cases
- */
- dev_midi = ctl_new("ctl");
- dev_midi->refs++;
-
cmin = (dipar->cmin < dopar->cmin) ? dipar->cmin : dopar->cmin;
cmax = (dipar->cmax > dopar->cmax) ? dipar->cmax : dopar->cmax;
rate = (dipar->rate > dopar->rate) ? dipar->rate : dopar->rate;
@@ -122,14 +112,11 @@ dev_loopinit(struct aparams *dipar, struct aparams *dopar, unsigned bufsz)
dev_rate = rate;
dev_rec = NULL;
dev_play = NULL;
- dev_mon = NULL;
- dev_submon = NULL;
- dev_pstate = DEV_INIT;
buf = abuf_new(dev_bufsz, &par);
- dev_mix = mix_new("mix", dev_bufsz, 1, NULL);
+ dev_mix = mix_new("mix", dev_bufsz, NULL);
dev_mix->refs++;
- dev_sub = sub_new("sub", dev_bufsz, 1, NULL);
+ dev_sub = sub_new("sub", dev_bufsz, NULL);
dev_sub->refs++;
aproc_setout(dev_mix, buf);
aproc_setin(dev_sub, buf);
@@ -153,13 +140,14 @@ dev_roundof(unsigned newrate)
* setup.
*/
int
-dev_init(char *devpath, unsigned mode,
+dev_init(char *devpath,
struct aparams *dipar, struct aparams *dopar, unsigned bufsz, unsigned round)
{
struct file *f;
struct aparams ipar, opar;
struct aproc *conv;
struct abuf *buf;
+ unsigned nfr, ibufsz, obufsz;
dev_midi = ctl_new("ctl");
dev_midi->refs++;
@@ -169,13 +157,13 @@ dev_init(char *devpath, unsigned mode,
* limit the block size to 1/4 of the requested buffer.
*/
dev_round = round;
- dev_bufsz = bufsz;
+ dev_bufsz = (bufsz + 3) / 4 + (dev_round - 1);
+ dev_bufsz -= dev_bufsz % dev_round;
f = (struct file *)siofile_new(&siofile_ops, devpath,
- mode & (MODE_PLAY | MODE_REC), dipar, dopar,
- &dev_bufsz, &dev_round);
+ dipar, dopar, &dev_bufsz, &dev_round);
if (f == NULL)
return 0;
- if (mode & MODE_REC) {
+ if (dipar) {
#ifdef DEBUG
if (debug_level >= 2) {
dbg_puts("hw recording ");
@@ -185,7 +173,7 @@ dev_init(char *devpath, unsigned mode,
#endif
dev_rate = dipar->rate;
}
- if (mode & MODE_PLAY) {
+ if (dopar) {
#ifdef DEBUG
if (debug_level >= 2) {
dbg_puts("hw playing ");
@@ -195,19 +183,33 @@ dev_init(char *devpath, unsigned mode,
#endif
dev_rate = dopar->rate;
}
+ ibufsz = obufsz = dev_bufsz;
+ bufsz = (bufsz > dev_bufsz) ? bufsz - dev_bufsz : 0;
+
+ /*
+ * Use 1/8 of the buffer for the mixer/converters. Since we
+ * already consumed 1/4 for the device, bufsz represents the
+ * remaining 3/4. So 1/8 is 1/6 of 3/4.
+ */
+ nfr = (bufsz + 5) / 6;
+ nfr += dev_round - 1;
+ nfr -= nfr % dev_round;
+ if (nfr == 0)
+ nfr = dev_round;
/*
* Create record chain.
*/
- if (mode & MODE_REC) {
+ if (dipar) {
aparams_init(&ipar, dipar->cmin, dipar->cmax, dipar->rate);
/*
* Create the read end.
*/
- dev_rec = rsio_new(f);
+ dev_rec = rfile_new(f);
dev_rec->refs++;
- buf = abuf_new(dev_bufsz, dipar);
+ buf = abuf_new(nfr, dipar);
aproc_setout(dev_rec, buf);
+ ibufsz += nfr;
/*
* Append a converter, if needed.
@@ -215,8 +217,9 @@ dev_init(char *devpath, unsigned mode,
if (!aparams_eqenc(dipar, &ipar)) {
conv = dec_new("rec", dipar);
aproc_setin(conv, buf);
- buf = abuf_new(dev_round, &ipar);
+ buf = abuf_new(nfr, &ipar);
aproc_setout(conv, buf);
+ ibufsz += nfr;
}
dev_ipar = ipar;
@@ -224,8 +227,7 @@ dev_init(char *devpath, unsigned mode,
* Append a "sub" to which clients will connect.
* Link it to the controller only in record-only mode
*/
- dev_sub = sub_new("rec", dev_bufsz, dev_round,
- dopar ? NULL : dev_midi);
+ dev_sub = sub_new("rec", ibufsz, dopar ? NULL : dev_midi);
dev_sub->refs++;
aproc_setin(dev_sub, buf);
} else {
@@ -236,15 +238,16 @@ dev_init(char *devpath, unsigned mode,
/*
* Create play chain.
*/
- if (mode & MODE_PLAY) {
+ if (dopar) {
aparams_init(&opar, dopar->cmin, dopar->cmax, dopar->rate);
/*
* Create the write end.
*/
- dev_play = wsio_new(f);
+ dev_play = wfile_new(f);
dev_play->refs++;
- buf = abuf_new(dev_bufsz, dopar);
+ buf = abuf_new(nfr, dopar);
aproc_setin(dev_play, buf);
+ obufsz += nfr;
/*
* Append a converter, if needed.
@@ -252,50 +255,23 @@ dev_init(char *devpath, unsigned mode,
if (!aparams_eqenc(&opar, dopar)) {
conv = enc_new("play", dopar);
aproc_setout(conv, buf);
- buf = abuf_new(dev_round, &opar);
+ buf = abuf_new(nfr, &opar);
aproc_setin(conv, buf);
+ obufsz += nfr;
}
dev_opar = opar;
/*
* Append a "mix" to which clients will connect.
*/
- dev_mix = mix_new("play", dev_bufsz, dev_round, dev_midi);
+ dev_mix = mix_new("play", obufsz, dev_midi);
dev_mix->refs++;
aproc_setout(dev_mix, buf);
} else {
dev_play = NULL;
dev_mix = NULL;
}
-
- /*
- * Create monitoring chain
- */
- if (mode & MODE_MON) {
- dev_mon = mon_new("mon", dev_bufsz);
- dev_mon->refs++;
- buf = abuf_new(dev_bufsz, &dev_opar);
- aproc_setout(dev_mon, buf);
-
- /*
- * Append a "sub" to which clients will connect.
- * Link it to the controller only in record-only mode
- */
- dev_submon = sub_new("mon", dev_bufsz, dev_round, NULL);
- dev_submon->refs++;
- aproc_setin(dev_submon, buf);
-
- /*
- * Attack to the mixer
- */
- dev_mix->u.mix.mon = dev_mon;
- dev_mon->refs++;
- } else {
- dev_submon = NULL;
- if (APROC_OK(dev_mix))
- dev_mix->u.mix.mon = NULL;
- }
-
+ dev_bufsz = (dopar) ? obufsz : ibufsz;
#ifdef DEBUG
if (debug_level >= 2) {
dbg_puts("device block size is ");
@@ -305,7 +281,7 @@ dev_init(char *devpath, unsigned mode,
dbg_puts(" blocks\n");
}
#endif
- dev_pstate = DEV_INIT;
+ dev_start();
return 1;
}
@@ -334,11 +310,6 @@ dev_done(void)
* after each call to file_eof().
*/
dev_mix->flags |= APROC_QUIT;
- if (APROC_OK(dev_mix->u.mix.mon)) {
- dev_mix->u.mix.mon->refs--;
- aproc_del(dev_mix->u.mix.mon);
- dev_mix->u.mix.mon = NULL;
- }
restart_mix:
LIST_FOREACH(f, &file_list, entry) {
if (f->rproc != NULL &&
@@ -347,7 +318,7 @@ dev_done(void)
goto restart_mix;
}
}
- } else if (dev_sub || dev_submon) {
+ } else if (dev_sub) {
/*
* Same as above, but since there's no mixer,
* we generate EOF on the record-end of the
@@ -356,8 +327,7 @@ dev_done(void)
restart_sub:
LIST_FOREACH(f, &file_list, entry) {
if (f->rproc != NULL &&
- (aproc_depend(dev_sub, f->rproc) ||
- aproc_depend(dev_submon, f->rproc))) {
+ aproc_depend(dev_sub, f->rproc)) {
file_eof(f);
goto restart_sub;
}
@@ -377,37 +347,32 @@ dev_done(void)
}
}
if (dev_mix) {
- if (--dev_mix->refs == 0 && (dev_mix->flags & APROC_ZOMB))
+ dev_mix->refs--;
+ if (dev_mix->flags & APROC_ZOMB)
aproc_del(dev_mix);
dev_mix = NULL;
}
if (dev_play) {
- if (--dev_play->refs == 0 && (dev_play->flags & APROC_ZOMB))
+ dev_play->refs--;
+ if (dev_play->flags & APROC_ZOMB)
aproc_del(dev_play);
dev_play = NULL;
}
if (dev_sub) {
- if (--dev_sub->refs == 0 && (dev_sub->flags & APROC_ZOMB))
+ dev_sub->refs--;
+ if (dev_sub->flags & APROC_ZOMB)
aproc_del(dev_sub);
dev_sub = NULL;
}
if (dev_rec) {
- if (--dev_rec->refs == 0 && (dev_rec->flags & APROC_ZOMB))
+ dev_rec->refs--;
+ if (dev_rec->flags & APROC_ZOMB)
aproc_del(dev_rec);
dev_rec = NULL;
}
- if (dev_submon) {
- if (--dev_submon->refs == 0 && (dev_submon->flags & APROC_ZOMB))
- aproc_del(dev_submon);
- dev_submon = NULL;
- }
- if (dev_mon) {
- if (--dev_mon->refs == 0 && (dev_mon->flags & APROC_ZOMB))
- aproc_del(dev_mon);
- dev_mon = NULL;
- }
if (dev_midi) {
- if (--dev_midi->refs == 0 && (dev_midi->flags & APROC_ZOMB))
+ dev_midi->refs--;
+ if (dev_midi->flags & APROC_ZOMB)
aproc_del(dev_midi);
dev_midi = NULL;
}
@@ -425,64 +390,49 @@ dev_start(void)
{
struct file *f;
-#ifdef DEBUG
- if (debug_level >= 2)
- dbg_puts("starting audio device\n");
-#endif
- if (APROC_OK(dev_mix))
+ if (dev_mix)
dev_mix->flags |= APROC_DROP;
- if (APROC_OK(dev_sub))
+ if (dev_sub)
dev_sub->flags |= APROC_DROP;
- if (APROC_OK(dev_submon))
- dev_submon->flags |= APROC_DROP;
- if (APROC_OK(dev_play) && dev_play->u.io.file) {
+ if (dev_play && dev_play->u.io.file) {
f = dev_play->u.io.file;
f->ops->start(f);
- } else if (APROC_OK(dev_rec) && dev_rec->u.io.file) {
+ } else if (dev_rec && dev_rec->u.io.file) {
f = dev_rec->u.io.file;
f->ops->start(f);
}
}
/*
- * Pause the device. This may trigger context switches,
- * so it shouldn't be called from aproc methods
+ * Pause the device.
*/
void
dev_stop(void)
{
struct file *f;
- if (APROC_OK(dev_play) && dev_play->u.io.file) {
+ if (dev_play && dev_play->u.io.file) {
f = dev_play->u.io.file;
f->ops->stop(f);
- } else if (APROC_OK(dev_rec) && dev_rec->u.io.file) {
+ } else if (dev_rec && dev_rec->u.io.file) {
f = dev_rec->u.io.file;
f->ops->stop(f);
}
- if (APROC_OK(dev_mix))
+ if (dev_mix)
dev_mix->flags &= ~APROC_DROP;
- if (APROC_OK(dev_sub))
+ if (dev_sub)
dev_sub->flags &= ~APROC_DROP;
- if (APROC_OK(dev_submon))
- dev_submon->flags &= ~APROC_DROP;
-#ifdef DEBUG
- if (debug_level >= 2)
- dbg_puts("audio device stopped\n");
-#endif
}
/*
* Find the end points connected to the mix/sub.
*/
int
-dev_getep(unsigned mode, struct abuf **sibuf, struct abuf **sobuf)
+dev_getep(struct abuf **sibuf, struct abuf **sobuf)
{
struct abuf *ibuf, *obuf;
- if (mode & MODE_PLAY) {
- if (!APROC_OK(dev_mix))
- return 0;
+ if (sibuf && *sibuf) {
ibuf = *sibuf;
for (;;) {
if (!ibuf || !ibuf->rproc) {
@@ -500,9 +450,7 @@ dev_getep(unsigned mode, struct abuf **sibuf, struct abuf **sobuf)
}
*sibuf = ibuf;
}
- if (mode & MODE_REC) {
- if (!APROC_OK(dev_sub))
- return 0;
+ if (sobuf && *sobuf) {
obuf = *sobuf;
for (;;) {
if (!obuf || !obuf->wproc) {
@@ -520,26 +468,6 @@ dev_getep(unsigned mode, struct abuf **sibuf, struct abuf **sobuf)
}
*sobuf = obuf;
}
- if (mode & MODE_MON) {
- if (!APROC_OK(dev_submon))
- return 0;
- 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_submon)
- break;
- obuf = LIST_FIRST(&obuf->wproc->ibuflist);
- }
- *sobuf = obuf;
- }
return 1;
}
@@ -548,38 +476,45 @@ dev_getep(unsigned mode, struct abuf **sibuf, struct abuf **sobuf)
* them underruns/overruns).
*/
void
-dev_sync(unsigned mode, struct abuf *ibuf, struct abuf *obuf)
+dev_sync(struct abuf *ibuf, struct abuf *obuf)
{
+ struct abuf *pbuf, *rbuf;
int delta;
- if (!dev_getep(mode, &ibuf, &obuf))
+ if (!dev_mix || !dev_sub)
return;
+ pbuf = LIST_FIRST(&dev_mix->obuflist);
+ if (!pbuf)
+ return;
+ rbuf = LIST_FIRST(&dev_sub->ibuflist);
+ if (!rbuf)
+ return;
+ if (!dev_getep(&ibuf, &obuf))
+ return;
+
/*
* Calculate delta, the number of frames the play chain is ahead
* of the record chain. It's necessary to schedule silences (or
* drops) in order to start playback and record in sync.
*/
- if (APROC_OK(dev_mix) && APROC_OK(dev_sub)) {
- delta = dev_mix->u.mix.abspos - dev_sub->u.sub.abspos;
- } else if (APROC_OK(dev_mix)) {
- delta = dev_mix->u.mix.lat;
- } else
- delta = 0;
+ delta =
+ 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(" ");
- if (APROC_OK(dev_mix)) {
- aproc_dbg(dev_mix);
- dbg_puts(": abspos = ");
- dbg_putu(dev_mix->u.mix.abspos);
- }
- if (APROC_OK(dev_sub)) {
- aproc_dbg(dev_sub);
- dbg_puts(": abspos = ");
- dbg_putu(dev_sub->u.sub.abspos);
- }
+ 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
@@ -588,15 +523,19 @@ dev_sync(unsigned mode, struct abuf *ibuf, struct abuf *obuf)
* The play chain is ahead (most cases) drop some of
* the recorded input, to get both in sync.
*/
- if (mode & MODE_RECMASK)
- sub_silence(obuf, -delta);
+ if (obuf) {
+ obuf->drop += delta * obuf->bpf;
+ abuf_ipos(obuf, -delta);
+ }
} else if (delta < 0) {
/*
* The record chain is ahead (should never happen,
* right?) then insert silence to play.
*/
- if (mode & MODE_PLAY)
- mix_drop(ibuf, delta);
+ if (ibuf) {
+ ibuf->silence += -delta * ibuf->bpf;
+ abuf_opos(ibuf, delta);
+ }
}
}
@@ -611,20 +550,23 @@ dev_getpos(void)
int plat = 0, rlat = 0;
int delta;
- if (APROC_OK(dev_mix)) {
+ if (dev_mix) {
pbuf = LIST_FIRST(&dev_mix->obuflist);
if (!pbuf)
return 0;
plat = -dev_mix->u.mix.lat;
}
- if (APROC_OK(dev_sub)) {
+ if (dev_sub) {
rbuf = LIST_FIRST(&dev_sub->ibuflist);
if (!rbuf)
return 0;
rlat = -dev_sub->u.sub.lat;
}
- if (APROC_OK(dev_mix) && APROC_OK(dev_sub)) {
- delta = dev_mix->u.mix.abspos - dev_sub->u.sub.abspos;
+ if (dev_mix && dev_sub) {
+ delta =
+ rbuf->bpf * (pbuf->abspos + pbuf->used) -
+ pbuf->bpf * rbuf->abspos;
+ delta /= pbuf->bpf * rbuf->bpf;
if (delta > 0)
rlat -= delta;
else if (delta < 0)
@@ -639,7 +581,7 @@ dev_getpos(void)
}
#endif
}
- return APROC_OK(dev_mix) ? plat : rlat;
+ return dev_mix ? plat : rlat;
}
/*
@@ -649,25 +591,16 @@ dev_getpos(void)
* and rec.
*/
void
-dev_attach(char *name, unsigned mode,
- struct abuf *ibuf, struct aparams *sipar,
- struct abuf *obuf, struct aparams *sopar,
- unsigned xrun, int vol)
+dev_attach(char *name,
+ struct abuf *ibuf, struct aparams *sipar, unsigned underrun,
+ struct abuf *obuf, struct aparams *sopar, unsigned overrun, int vol)
{
struct abuf *pbuf = NULL, *rbuf = NULL;
struct aparams ipar, opar;
struct aproc *conv;
unsigned round, nblk;
-#ifdef DEBUG
- if ((!APROC_OK(dev_mix) && (mode & MODE_PLAY)) ||
- (!APROC_OK(dev_sub) && (mode & MODE_REC)) ||
- (!APROC_OK(dev_submon) && (mode & MODE_MON))) {
- dbg_puts("mode beyond device mode, not attaching\n");
- return;
- }
-#endif
- if (mode & MODE_PLAY) {
+ if (ibuf) {
ipar = *sipar;
pbuf = LIST_FIRST(&dev_mix->obuflist);
nblk = (dev_bufsz / dev_round + 3) / 4;
@@ -700,11 +633,13 @@ dev_attach(char *name, unsigned mode,
aproc_setout(conv, ibuf);
}
aproc_setin(dev_mix, ibuf);
- ibuf->r.mix.xrun = xrun;
+ if (dev_mix->u.mix.lat > 0)
+ abuf_opos(ibuf, -dev_mix->u.mix.lat);
+ ibuf->r.mix.xrun = underrun;
ibuf->r.mix.maxweight = vol;
mix_setmaster(dev_mix);
}
- if (mode & MODE_REC) {
+ if (obuf) {
opar = *sopar;
rbuf = LIST_FIRST(&dev_sub->ibuflist);
round = dev_roundof(opar.rate);
@@ -737,58 +672,19 @@ dev_attach(char *name, unsigned mode,
aproc_setin(conv, obuf);
}
aproc_setout(dev_sub, obuf);
- obuf->w.sub.xrun = xrun;
- }
- if (mode & MODE_MON) {
- opar = *sopar;
- rbuf = LIST_FIRST(&dev_submon->ibuflist);
- round = dev_roundof(opar.rate);
- nblk = (dev_bufsz / dev_round + 3) / 4;
- if (!aparams_eqenc(&opar, &dev_opar)) {
- conv = enc_new(name, &opar);
- opar.bps = dev_opar.bps;
- opar.bits = dev_opar.bits;
- opar.sig = dev_opar.sig;
- opar.le = dev_opar.le;
- opar.msb = dev_opar.msb;
- aproc_setout(conv, obuf);
- obuf = abuf_new(nblk * round, &opar);
- aproc_setin(conv, obuf);
- }
- if (!aparams_subset(&opar, &dev_opar)) {
- conv = cmap_new(name, &dev_opar, &opar);
- opar.cmin = dev_opar.cmin;
- opar.cmax = dev_opar.cmax;
- aproc_setout(conv, obuf);
- obuf = abuf_new(nblk * round, &opar);
- aproc_setin(conv, obuf);
- }
- if (!aparams_eqrate(&opar, &dev_opar)) {
- conv = resamp_new(name, dev_round, round);
- opar.rate = dev_opar.rate;
- round = dev_round;
- aproc_setout(conv, obuf);
- obuf = abuf_new(nblk * round, &opar);
- aproc_setin(conv, obuf);
- }
- aproc_setout(dev_submon, obuf);
- obuf->w.sub.xrun = xrun;
+ if (dev_sub->u.sub.lat > 0)
+ abuf_ipos(obuf, -dev_sub->u.sub.lat);
+ obuf->w.sub.xrun = overrun;
}
/*
* Sync play to record.
*/
- if ((mode & MODE_PLAY) && (mode & MODE_RECMASK)) {
+ if (ibuf && obuf) {
ibuf->duplex = obuf;
obuf->duplex = ibuf;
}
- dev_sync(mode, ibuf, obuf);
-
- /*
- * Start device if not already started
- */
- if (dev_pstate == DEV_INIT)
- dev_pstate = DEV_START;
+ dev_sync(ibuf, obuf);
}
/*
@@ -805,7 +701,7 @@ dev_setvol(struct abuf *ibuf, int vol)
dbg_puts("\n");
}
#endif
- if (!dev_getep(MODE_PLAY, &ibuf, NULL)) {
+ if (!dev_getep(&ibuf, NULL)) {
return;
}
ibuf->r.mix.vol = vol;
@@ -820,7 +716,7 @@ dev_clear(void)
{
struct abuf *buf;
- if (APROC_OK(dev_mix)) {
+ if (dev_mix) {
#ifdef DEBUG
if (!LIST_EMPTY(&dev_mix->ibuflist)) {
dbg_puts("play end not idle, can't clear device\n");
@@ -834,7 +730,7 @@ dev_clear(void)
}
mix_clear(dev_mix);
}
- if (APROC_OK(dev_sub)) {
+ if (dev_sub) {
#ifdef DEBUG
if (!LIST_EMPTY(&dev_sub->obuflist)) {
dbg_puts("record end not idle, can't clear device\n");
@@ -848,22 +744,6 @@ dev_clear(void)
}
sub_clear(dev_sub);
}
- if (APROC_OK(dev_submon)) {
-#ifdef DEBUG
- dbg_puts("clearing monitor\n");
- if (!LIST_EMPTY(&dev_submon->obuflist)) {
- dbg_puts("monitoring end not idle, can't clear device\n");
- dbg_panic();
- }
-#endif
- buf = LIST_FIRST(&dev_submon->ibuflist);
- while (buf) {
- abuf_clear(buf);
- buf = LIST_FIRST(&buf->wproc->ibuflist);
- }
- sub_clear(dev_submon);
- mon_clear(dev_mon);
- }
}
/*
@@ -873,7 +753,7 @@ dev_clear(void)
void
dev_prime(void)
{
- if (APROC_OK(dev_mix)) {
+ if (dev_mix) {
#ifdef DEBUG
if (!LIST_EMPTY(&dev_mix->ibuflist)) {
dbg_puts("play end not idle, can't prime device\n");
diff --git a/usr.bin/aucat/dev.h b/usr.bin/aucat/dev.h
index f9a97d31921..2f3195d701c 100644
--- a/usr.bin/aucat/dev.h
+++ b/usr.bin/aucat/dev.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: dev.h,v 1.18 2010/04/03 17:40:33 ratchov Exp $ */
+/* $OpenBSD: dev.h,v 1.19 2010/04/03 17:59:17 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -21,33 +21,25 @@ struct aproc;
struct aparams;
struct abuf;
-#define DEV_INIT 0
-#define DEV_START 1
-#define DEV_RUN 2
-#define DEV_STOP 3
-
-extern unsigned dev_pstate;
extern unsigned dev_bufsz, dev_round, dev_rate;
extern struct aparams dev_ipar, dev_opar;
-extern struct aproc *dev_mix, *dev_sub, *dev_midi, *dev_submon, *dev_mon;
+extern struct aproc *dev_mix, *dev_sub, *dev_midi;
void dev_thruinit(void);
int dev_thruadd(char *, int, int);
void dev_midiattach(struct abuf *, struct abuf *);
unsigned dev_roundof(unsigned);
void dev_loopinit(struct aparams *, struct aparams *, unsigned);
-int dev_init(char *, unsigned,
- struct aparams *, struct aparams *, unsigned, unsigned);
+int dev_init(char *, struct aparams *, struct aparams *, unsigned, unsigned);
void dev_start(void);
void dev_stop(void);
void dev_run(int);
void dev_done(void);
-int dev_getep(unsigned, struct abuf **, struct abuf **);
-void dev_sync(unsigned, struct abuf *, struct abuf *);
-unsigned dev_getmode(void);
+int dev_getep(struct abuf **, struct abuf **);
+void dev_sync(struct abuf *, struct abuf *);
int dev_getpos(void);
-void dev_attach(char *, unsigned,
- struct abuf *, struct aparams *,
+void dev_attach(char *,
+ struct abuf *, struct aparams *, unsigned,
struct abuf *, struct aparams *, unsigned, int);
void dev_setvol(struct abuf *, int);
void dev_clear(void);
diff --git a/usr.bin/aucat/file.c b/usr.bin/aucat/file.c
index af37e199fa0..4172325ec10 100644
--- a/usr.bin/aucat/file.c
+++ b/usr.bin/aucat/file.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: file.c,v 1.16 2010/04/03 17:40:33 ratchov Exp $ */
+/* $OpenBSD: file.c,v 1.17 2010/04/03 17:59:17 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -63,6 +63,8 @@
#define MAXFDS 100
+extern struct fileops listen_ops, pipe_ops;
+
struct timeval file_tv;
struct filelist file_list;
struct timo *timo_queue;
@@ -518,6 +520,23 @@ filelist_done(void)
timo_done();
}
+/*
+ * Close all listening sockets.
+ *
+ * XXX: remove this
+ */
+void
+filelist_unlisten(void)
+{
+ struct file *f, *fnext;
+
+ for (f = LIST_FIRST(&file_list); f != NULL; f = fnext) {
+ fnext = LIST_NEXT(f, entry);
+ if (f->ops == &listen_ops)
+ file_del(f);
+ }
+}
+
unsigned
file_read(struct file *f, unsigned char *data, unsigned count)
{
@@ -657,8 +676,6 @@ file_close(struct file *f)
dbg_puts(": closing\n");
}
#endif
- if (f->wproc == NULL && f->rproc == NULL)
- f->state |= FILE_ZOMB;
if (!(f->state & (FILE_RINUSE | FILE_WINUSE))) {
p = f->rproc;
if (p) {
diff --git a/usr.bin/aucat/headers.c b/usr.bin/aucat/headers.c
index 7859e29a436..33978d50b90 100644
--- a/usr.bin/aucat/headers.c
+++ b/usr.bin/aucat/headers.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: headers.c,v 1.11 2010/04/03 17:40:33 ratchov Exp $ */
+/* $OpenBSD: headers.c,v 1.12 2010/04/03 17:59:17 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -129,7 +129,7 @@ wav_readfmt(int fd, unsigned csize, struct aparams *par, short **map)
}
int
-wav_readhdr(int fd, struct aparams *par, off_t *startpos, off_t *datasz, short **map)
+wav_readhdr(int fd, struct aparams *par, off_t *datasz, short **map)
{
struct wavriff riff;
struct wavchunk chunk;
@@ -161,7 +161,6 @@ wav_readhdr(int fd, struct aparams *par, off_t *startpos, off_t *datasz, short *
return 0;
fmt_done = 1;
} else if (memcmp(chunk.id, wav_id_data, 4) == 0) {
- *startpos = pos;
*datasz = csize;
break;
} else {
@@ -187,12 +186,10 @@ wav_readhdr(int fd, struct aparams *par, off_t *startpos, off_t *datasz, short *
return 1;
}
-/*
- * Write header and seek to start position
- */
int
-wav_writehdr(int fd, struct aparams *par, off_t *startpos, off_t datasz)
+wav_writehdr(int fd, struct aparams *par)
{
+ off_t datasz;
unsigned nch = par->cmax - par->cmin + 1;
struct {
struct wavriff riff;
@@ -201,6 +198,16 @@ wav_writehdr(int fd, struct aparams *par, off_t *startpos, off_t datasz)
struct wavchunk data_hdr;
} hdr;
+ datasz = lseek(fd, 0, SEEK_CUR);
+ if (datasz < 0) {
+ warn("wav_writehdr: lseek(end)");
+ return 0;
+ }
+ if (datasz >= sizeof(hdr))
+ datasz -= sizeof(hdr);
+ else
+ datasz = 0;
+
/*
* Check that encoding is supported by .wav file format.
*/
@@ -246,6 +253,5 @@ wav_writehdr(int fd, struct aparams *par, off_t *startpos, off_t datasz)
warn("wav_writehdr: write");
return 0;
}
- *startpos = sizeof(hdr);
return 1;
}
diff --git a/usr.bin/aucat/legacy.c b/usr.bin/aucat/legacy.c
index 5f7a3655137..18e93c1e095 100644
--- a/usr.bin/aucat/legacy.c
+++ b/usr.bin/aucat/legacy.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: legacy.c,v 1.9 2010/04/03 17:40:33 ratchov Exp $ */
+/* $OpenBSD: legacy.c,v 1.10 2010/04/03 17:59:17 ratchov Exp $ */
/*
* Copyright (c) 1997 Kenneth Stailey. All rights reserved.
*
@@ -64,7 +64,7 @@ legacy_play(char *dev, char *aufile)
struct sio_par spar, par;
struct aparams apar;
ssize_t rd;
- off_t datasz, dummy;
+ off_t datasz;
char buf[5120];
size_t readsz;
int fd, fmt = FMT_RAW;
@@ -96,7 +96,7 @@ legacy_play(char *dev, char *aufile)
if (read(fd, &chan, sizeof(chan)) == sizeof(chan))
chan = ntohl(chan);
} else if (!strncmp(magic, "RIFF", 4) &&
- wav_readhdr(fd, &apar, &dummy, &datasz, &map)) {
+ wav_readhdr(fd, &apar, &datasz, &map)) {
fmt = FMT_WAV;
}
diff --git a/usr.bin/aucat/midi.c b/usr.bin/aucat/midi.c
index 8244a4cba3f..70d9aec2f3a 100644
--- a/usr.bin/aucat/midi.c
+++ b/usr.bin/aucat/midi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: midi.c,v 1.17 2010/04/03 17:40:33 ratchov Exp $ */
+/* $OpenBSD: midi.c,v 1.18 2010/04/03 17:59:17 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -132,7 +132,7 @@ thru_rt(struct aproc *p, struct abuf *ibuf, struct abuf *obuf, unsigned c)
if (debug_level >= 4) {
aproc_dbg(p);
dbg_puts(": ");
- dbg_putx(c);
+ dbg_putu(c);
dbg_puts(": flushing realtime message\n");
}
#endif
@@ -350,15 +350,16 @@ ctl_slotdbg(struct aproc *p, int slot)
{
struct ctl_slot *s;
+ aproc_dbg(p);
if (slot < 0) {
- dbg_puts("none");
+ dbg_puts("/none");
} else {
s = p->u.ctl.slot + slot;
dbg_puts(s->name);
dbg_putu(s->unit);
- dbg_puts("(");
+ dbg_puts("=");
dbg_putu(s->vol);
- dbg_puts(")/");
+ dbg_puts("/");
switch (s->tstate) {
case CTL_OFF:
dbg_puts("off");
@@ -393,7 +394,7 @@ ctl_sendmsg(struct aproc *p, struct abuf *ibuf, unsigned char *msg, unsigned len
for (i = LIST_FIRST(&p->obuflist); i != NULL; i = inext) {
inext = LIST_NEXT(i, oent);
- if (i->duplex && i->duplex == ibuf)
+ if (i->duplex == ibuf)
continue;
itodo = len;
idata = msg;
@@ -638,10 +639,8 @@ ctl_trystart(struct aproc *p, int caller)
if (p->u.ctl.tstate != CTL_START) {
#ifdef DEBUG
- if (debug_level >= 3) {
- ctl_slotdbg(p, caller);
- dbg_puts(": server not started, delayd\n");
- }
+ aproc_dbg(p);
+ dbg_puts(": not in starting state\n");
#endif
return 0;
}
@@ -650,10 +649,8 @@ ctl_trystart(struct aproc *p, int caller)
continue;
if (s->tstate != CTL_OFF && s->tstate != CTL_START) {
#ifdef DEBUG
- if (debug_level >= 3) {
- ctl_slotdbg(p, i);
- dbg_puts(": not ready, server delayed\n");
- }
+ ctl_slotdbg(p, i);
+ dbg_puts(": not ready to start, start delayed\n");
#endif
return 0;
}
@@ -663,10 +660,8 @@ ctl_trystart(struct aproc *p, int caller)
continue;
if (s->tstate == CTL_START) {
#ifdef DEBUG
- if (debug_level >= 3) {
- ctl_slotdbg(p, i);
- dbg_puts(": started\n");
- }
+ ctl_slotdbg(p, i);
+ dbg_puts(": started\n");
#endif
s->tstate = CTL_RUN;
s->ops->start(s->arg);
@@ -676,10 +671,10 @@ ctl_trystart(struct aproc *p, int caller)
p->u.ctl.slot[caller].tstate = CTL_RUN;
p->u.ctl.tstate = CTL_RUN;
p->u.ctl.delta = MTC_SEC * dev_getpos();
- if (dev_rate % (30 * 4 * dev_round) == 0) {
+ if (dev_rate % (30 * 4 * dev_round)) {
p->u.ctl.fps_id = MTC_FPS_30;
p->u.ctl.fps = 30;
- } else if (dev_rate % (25 * 4 * dev_round) == 0) {
+ } else if (dev_rate % (25 * 4 * dev_round)) {
p->u.ctl.fps_id = MTC_FPS_25;
p->u.ctl.fps = 25;
} else {
@@ -687,17 +682,13 @@ ctl_trystart(struct aproc *p, int caller)
p->u.ctl.fps = 24;
}
#ifdef DEBUG
- if (debug_level >= 3) {
- 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");
- }
+ 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
- if (dev_pstate == DEV_INIT)
- dev_pstate = DEV_START;
ctl_full(p);
return 1;
}
@@ -711,15 +702,8 @@ ctl_slotnew(struct aproc *p, char *who, struct ctl_ops *ops, void *arg, int tr)
int idx;
struct ctl_slot *s;
- if (!APROC_OK(p)) {
-#ifdef DEBUG
- if (debug_level >= 1) {
- dbg_puts(who);
- dbg_puts(": MIDI control not available\n");
- }
-#endif
+ if (p == NULL)
return -1;
- }
idx = ctl_getidx(p, who);
if (idx < 0)
return -1;
@@ -742,7 +726,7 @@ ctl_slotdel(struct aproc *p, int index)
unsigned i;
struct ctl_slot *s;
- if (!APROC_OK(p))
+ if (p == NULL)
return;
p->u.ctl.slot[index].ops = NULL;
if (!(p->flags & APROC_QUIT))
@@ -795,7 +779,7 @@ ctl_slotvol(struct aproc *p, int slot, unsigned vol)
{
unsigned char msg[3];
- if (!APROC_OK(p))
+ if (p == NULL)
return;
#ifdef DEBUG
if (debug_level >= 3) {
@@ -823,7 +807,7 @@ ctl_slotstart(struct aproc *p, int slot)
{
struct ctl_slot *s = p->u.ctl.slot + slot;
- if (!APROC_OK(p))
+ if (p == NULL)
return 1;
if (s->tstate == CTL_OFF || p->u.ctl.tstate == CTL_OFF)
return 1;
@@ -847,7 +831,7 @@ ctl_slotstop(struct aproc *p, int slot)
{
struct ctl_slot *s = p->u.ctl.slot + slot;
- if (!APROC_OK(p))
+ if (p == NULL)
return;
/*
* tag the stream as not trying to start,
@@ -858,118 +842,6 @@ ctl_slotstop(struct aproc *p, int slot)
}
/*
- * start all slots simultaneously
- */
-void
-ctl_start(struct aproc *p)
-{
- if (!APROC_OK(p))
- return;
- if (p->u.ctl.tstate == CTL_STOP) {
- p->u.ctl.tstate = CTL_START;
- (void)ctl_trystart(p, -1);
-#ifdef DEBUG
- } else {
- if (debug_level >= 3) {
- aproc_dbg(p);
- dbg_puts(": ignoring mmc start\n");
- }
-#endif
- }
-}
-
-/*
- * stop all slots simultaneously
- */
-void
-ctl_stop(struct aproc *p)
-{
- unsigned i;
- struct ctl_slot *s;
-
- if (!APROC_OK(p))
- return;
- switch (p->u.ctl.tstate) {
- case CTL_START:
- p->u.ctl.tstate = CTL_STOP;
- return;
- case CTL_RUN:
- p->u.ctl.tstate = CTL_STOP;
- break;
- default:
-#ifdef DEBUG
- if (debug_level >= 3) {
- aproc_dbg(p);
- dbg_puts(": ignored mmc stop\n");
- }
-#endif
- return;
- }
- for (i = 0, s = p->u.ctl.slot; i < CTL_NSLOT; i++, s++) {
- if (!s->ops)
- continue;
- if (s->tstate == CTL_RUN) {
-#ifdef DEBUG
- if (debug_level >= 3) {
- ctl_slotdbg(p, i);
- dbg_puts(": requested to stop\n");
- }
-#endif
- s->ops->stop(s->arg);
- }
- }
-}
-
-/*
- * relocate all slots simultaneously
- */
-void
-ctl_loc(struct aproc *p, unsigned origin)
-{
- unsigned i, tstate;
- struct ctl_slot *s;
-
- if (!APROC_OK(p))
- return;
-#ifdef DEBUG
- if (debug_level >= 2) {
- dbg_puts("server relocated to ");
- dbg_putu(origin);
- dbg_puts("\n");
- }
-#endif
- tstate = p->u.ctl.tstate;
- if (tstate == CTL_RUN)
- ctl_stop(p);
- p->u.ctl.origin = origin;
- for (i = 0, s = p->u.ctl.slot; i < CTL_NSLOT; i++, s++) {
- if (!s->ops)
- continue;
- s->ops->loc(s->arg, p->u.ctl.origin);
- }
- if (tstate == CTL_RUN)
- ctl_start(p);
-}
-
-/*
- * check if there are controlled streams
- */
-int
-ctl_idle(struct aproc *p)
-{
- unsigned i;
- struct ctl_slot *s;
-
- if (!APROC_OK(p))
- return 1;
- for (i = 0, s = p->u.ctl.slot; i < CTL_NSLOT; i++, s++) {
- if (s->ops)
- return 0;
- }
- return 1;
-}
-
-/*
* handle a MIDI event received from ibuf
*/
void
@@ -1011,21 +883,41 @@ ctl_ev(struct aproc *p, struct abuf *ibuf)
switch (ibuf->r.midi.msg[4]) {
case 0x01: /* mmc stop */
#ifdef DEBUG
- if (debug_level >= 3) {
+ if (debug_level >= 1) {
abuf_dbg(ibuf);
dbg_puts(": mmc stop\n");
}
#endif
- ctl_stop(p);
+ 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 >= 3) {
+ if (debug_level >= 1) {
abuf_dbg(ibuf);
dbg_puts(": mmc start\n");
}
#endif
- ctl_start(p);
+ 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;
}
}
@@ -1051,12 +943,20 @@ ctl_ev(struct aproc *p, struct abuf *ibuf)
p->u.ctl.origin = 0;
return;
}
- ctl_loc(p,
+ p->u.ctl.origin =
(ibuf->r.midi.msg[7] & 0x1f) * 3600 * MTC_SEC +
ibuf->r.midi.msg[8] * 60 * MTC_SEC +
ibuf->r.midi.msg[9] * MTC_SEC +
ibuf->r.midi.msg[10] * (MTC_SEC / fps) +
- ibuf->r.midi.msg[11] * (MTC_SEC / 100 / 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
}
}
diff --git a/usr.bin/aucat/midi.h b/usr.bin/aucat/midi.h
index 4b5cdf183df..809dc2ae90f 100644
--- a/usr.bin/aucat/midi.h
+++ b/usr.bin/aucat/midi.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: midi.h,v 1.6 2010/04/03 17:40:33 ratchov Exp $ */
+/* $OpenBSD: midi.h,v 1.7 2010/04/03 17:59:17 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -27,8 +27,4 @@ int ctl_slotstart(struct aproc *, int);
void ctl_slotstop(struct aproc *, int);
void ctl_ontick(struct aproc *, int);
-void ctl_stop(struct aproc *);
-void ctl_start(struct aproc *);
-int ctl_idle(struct aproc *);
-
#endif /* !defined(MIDI_H) */
diff --git a/usr.bin/aucat/midicat.1 b/usr.bin/aucat/midicat.1
index 3befc6a3bbf..11c828798e1 100644
--- a/usr.bin/aucat/midicat.1
+++ b/usr.bin/aucat/midicat.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: midicat.1,v 1.7 2010/04/03 17:40:33 ratchov Exp $
+.\" $OpenBSD: midicat.1,v 1.8 2010/04/03 17:59:17 ratchov Exp $
.\"
.\" Copyright (c) 2006 Alexandre Ratchov <alex@caoua.org>
.\"
@@ -23,9 +23,9 @@
.Sh SYNOPSIS
.Nm midicat
.Op Fl dl
+.Op Fl f Ar device
.Op Fl i Ar file
.Op Fl o Ar file
-.Op Fl q Ar device
.Op Fl U Ar unit
.Sh DESCRIPTION
The
@@ -45,6 +45,13 @@ If this option is specified,
.Nm
will run in the foreground and log to
.Em stderr .
+.It Fl f Ar device
+The
+.Xr midi 4
+device or
+.Nm
+socket to use for MIDI input/output.
+In server mode, devices are subscribed to the MIDI thru box.
.It Fl i Ar file
Send contents of this file to the device.
If the option argument is
@@ -64,11 +71,6 @@ Store received data from the device into this file.
If the option argument is
.Sq -
then standard output will be used.
-.It Fl q Ar device
-The
-.Xr sndio 7
-MIDI device to use for MIDI input/output.
-In server mode, devices are subscribed to the MIDI thru box.
.It Fl U Ar unit
Use the given unit number when creating a software MIDI thru box.
Only one
diff --git a/usr.bin/aucat/opt.c b/usr.bin/aucat/opt.c
index c4fd6e6c3c1..2bcaee5a3fc 100644
--- a/usr.bin/aucat/opt.c
+++ b/usr.bin/aucat/opt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: opt.c,v 1.5 2010/04/03 17:40:33 ratchov Exp $ */
+/* $OpenBSD: opt.c,v 1.6 2010/04/03 17:59:17 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -27,8 +27,8 @@
struct optlist opt_list = SLIST_HEAD_INITIALIZER(&opt_list);
void
-opt_new(char *name, struct aparams *wpar, struct aparams *rpar,
- int maxweight, int mmc, unsigned mode)
+opt_new(char *name,
+ struct aparams *wpar, struct aparams *rpar, int maxweight, int mmc)
{
struct opt *o;
unsigned len;
@@ -54,39 +54,21 @@ opt_new(char *name, struct aparams *wpar, struct aparams *rpar,
exit(1);
}
memcpy(o->name, name, len + 1);
- if (mode & MODE_RECMASK)
- o->wpar = (mode & MODE_MON) ? *rpar : *wpar;
- if (mode & MODE_PLAY)
- o->rpar = *rpar;
+ o->wpar = *wpar;
+ o->rpar = *rpar;
o->maxweight = maxweight;
o->mmc = mmc;
- o->mode = mode;
#ifdef DEBUG
if (debug_level >= 2) {
dbg_puts(o->name);
- dbg_puts(":");
- if (mode & MODE_REC) {
- dbg_puts(" rec=");
- dbg_putu(o->wpar.cmin);
- dbg_puts(":");
- dbg_putu(o->wpar.cmax);
- }
- if (mode & MODE_PLAY) {
- dbg_puts(" play=");
- dbg_putu(o->rpar.cmin);
- dbg_puts(":");
- dbg_putu(o->rpar.cmax);
- dbg_puts(" vol=");
- dbg_putu(o->maxweight);
- }
- if (mode & MODE_MON) {
- dbg_puts(" mon=");
- dbg_putu(o->wpar.cmin);
- dbg_puts(":");
- dbg_putu(o->wpar.cmax);
- }
+ 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(", mmc");
dbg_puts("\n");
}
#endif
diff --git a/usr.bin/aucat/opt.h b/usr.bin/aucat/opt.h
index 3572d560397..875f0537601 100644
--- a/usr.bin/aucat/opt.h
+++ b/usr.bin/aucat/opt.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: opt.h,v 1.3 2010/04/03 17:40:33 ratchov Exp $ */
+/* $OpenBSD: opt.h,v 1.4 2010/04/03 17:59:17 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -28,18 +28,11 @@ struct opt {
struct aparams wpar; /* template for clients write params */
struct aparams rpar; /* template for clients read params */
int mmc; /* true if MMC control enabled */
-#define MODE_PLAY 0x1 /* allowed to play */
-#define MODE_REC 0x2 /* allowed to rec */
-#define MODE_MIDIIN 0x4 /* allowed to read midi */
-#define MODE_MIDIOUT 0x8 /* allowed to write midi */
-#define MODE_MON 0x10 /* allowed to monitor */
-#define MODE_RECMASK (MODE_REC | MODE_MON)
- unsigned mode; /* bitmap of above */
};
SLIST_HEAD(optlist,opt);
-void opt_new(char *, struct aparams *, struct aparams *, int, int, unsigned);
+void opt_new(char *, struct aparams *, struct aparams *, int, int);
struct opt *opt_byname(char *);
#endif /* !defined(OPT_H) */
diff --git a/usr.bin/aucat/pipe.c b/usr.bin/aucat/pipe.c
index 065f6f0ad7a..76f98baa832 100644
--- a/usr.bin/aucat/pipe.c
+++ b/usr.bin/aucat/pipe.c
@@ -139,54 +139,3 @@ pipe_close(struct file *file)
close(f->fd);
}
-
-off_t
-pipe_endpos(struct file *file)
-{
- struct pipe *f = (struct pipe *)file;
- off_t pos;
-
- pos = lseek(f->fd, 0, SEEK_END);
- if (pos < 0) {
-#ifdef DEBUG
- file_dbg(&f->file);
- dbg_puts(": couldn't get file size\n");
-#endif
- return 0;
- }
- return pos;
-}
-
-int
-pipe_seek(struct file *file, off_t pos)
-{
- struct pipe *f = (struct pipe *)file;
- off_t newpos;
-
- newpos = lseek(f->fd, pos, SEEK_SET);
- if (newpos < 0) {
-#ifdef DEBUG
- file_dbg(&f->file);
- dbg_puts(": couldn't seek\n");
-#endif
- /* XXX: call eof() */
- return 0;
- }
- return 1;
-}
-
-int
-pipe_trunc(struct file *file, off_t pos)
-{
- struct pipe *f = (struct pipe *)file;
-
- if (ftruncate(f->fd, pos) < 0) {
-#ifdef DEBUG
- file_dbg(&f->file);
- dbg_puts(": couldn't truncate file\n");
-#endif
- /* XXX: call hup() */
- return 0;
- }
- return 1;
-}
diff --git a/usr.bin/aucat/pipe.h b/usr.bin/aucat/pipe.h
index b2f986f92bd..adcc0e89f5f 100644
--- a/usr.bin/aucat/pipe.h
+++ b/usr.bin/aucat/pipe.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pipe.h,v 1.3 2010/04/03 17:40:33 ratchov Exp $ */
+/* $OpenBSD: pipe.h,v 1.4 2010/04/03 17:59:17 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -33,8 +33,5 @@ unsigned pipe_write(struct file *, unsigned char *, unsigned);
int pipe_nfds(struct file *);
int pipe_pollfd(struct file *, struct pollfd *, int);
int pipe_revents(struct file *, struct pollfd *);
-int pipe_seek(struct file *, off_t);
-int pipe_trunc(struct file *, off_t);
-off_t pipe_endpos(struct file *);
#endif /* !defined(PIPE_H) */
diff --git a/usr.bin/aucat/siofile.c b/usr.bin/aucat/siofile.c
index ae225460bb1..f52a0c2d647 100644
--- a/usr.bin/aucat/siofile.c
+++ b/usr.bin/aucat/siofile.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: siofile.c,v 1.2 2010/04/03 17:40:33 ratchov Exp $ */
+/* $OpenBSD: siofile.c,v 1.3 2010/04/03 17:59:17 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -26,7 +26,6 @@
#include "aparams.h"
#include "aproc.h"
-#include "abuf.h"
#include "conf.h"
#include "dev.h"
#include "file.h"
@@ -38,9 +37,6 @@
struct siofile {
struct file file;
struct sio_hdl *hdl;
- unsigned wtickets, wbpf;
- unsigned rtickets, rbpf;
- unsigned bufsz;
int started;
};
@@ -66,95 +62,6 @@ struct fileops siofile_ops = {
siofile_revents
};
-int wsio_out(struct aproc *, struct abuf *);
-int rsio_in(struct aproc *, struct abuf *);
-
-struct aproc_ops rsio_ops = {
- "rsio",
- rsio_in,
- rfile_out,
- rfile_eof,
- rfile_hup,
- NULL, /* newin */
- NULL, /* newout */
- aproc_ipos,
- aproc_opos,
- rfile_done
-};
-
-struct aproc_ops wsio_ops = {
- "wsio",
- wfile_in,
- wsio_out,
- wfile_eof,
- wfile_hup,
- NULL, /* newin */
- NULL, /* newout */
- aproc_ipos,
- aproc_opos,
- wfile_done
-};
-
-struct aproc *
-rsio_new(struct file *f)
-{
- struct aproc *p;
-
- p = aproc_new(&rsio_ops, f->name);
- p->u.io.file = f;
- p->u.io.partial = 0;
- f->rproc = p;
- return p;
-}
-
-struct aproc *
-wsio_new(struct file *f)
-{
- struct aproc *p;
-
- p = aproc_new(&wsio_ops, f->name);
- p->u.io.file = f;
- p->u.io.partial = 0;
- f->wproc = p;
- return p;
-}
-
-int
-wsio_out(struct aproc *p, struct abuf *obuf)
-{
- struct siofile *f = (struct siofile *)p->u.io.file;
-
- if (f->wtickets == 0) {
-#ifdef DEBUG
- if (debug_level >= 4) {
- file_dbg(&f->file);
- dbg_puts(": no more write tickets\n");
- }
-#endif
- f->file.state &= ~FILE_WOK;
- return 0;
- }
- return wfile_out(p, obuf);
-}
-
-int
-rsio_in(struct aproc *p, struct abuf *ibuf)
-{
- struct siofile *f = (struct siofile *)p->u.io.file;
-
- if (f->rtickets == 0) {
-#ifdef DEBUG
- if (debug_level >= 4) {
- file_dbg(&f->file);
- dbg_puts(": no more read tickets\n");
- }
-#endif
- f->file.state &= ~FILE_ROK;
- return 0;
- }
- return rfile_in(p, ibuf);
-}
-
void
siofile_cb(void *addr, int delta)
{
@@ -163,18 +70,12 @@ siofile_cb(void *addr, int delta)
#ifdef DEBUG
if (delta < 0 || delta > (60 * RATE_MAX)) {
- file_dbg(&f->file);
+ dbg_puts(f->file.name);
dbg_puts(": ");
dbg_puti(delta);
dbg_puts(": bogus sndio delta");
dbg_panic();
}
- if (debug_level >= 4) {
- file_dbg(&f->file);
- dbg_puts(": tick, delta = ");
- dbg_puti(delta);
- dbg_puts("\n");
- }
#endif
if (delta != 0) {
p = f->file.wproc;
@@ -186,27 +87,31 @@ siofile_cb(void *addr, int delta)
if (p && p->ops->ipos)
p->ops->ipos(p, NULL, delta);
}
- f->wtickets += delta * f->wbpf;
- f->rtickets += delta * f->rbpf;
}
/*
* Open the device.
*/
struct siofile *
-siofile_new(struct fileops *ops, char *path, unsigned mode,
+siofile_new(struct fileops *ops, char *path,
struct aparams *ipar, struct aparams *opar,
unsigned *bufsz, unsigned *round)
{
struct sio_par par;
struct sio_hdl *hdl;
struct siofile *f;
+ int mode;
+ mode = 0;
+ if (ipar)
+ mode |= SIO_REC;
+ if (opar)
+ mode |= SIO_PLAY;
hdl = sio_open(path, mode, 1);
if (hdl == NULL)
return NULL;
sio_initpar(&par);
- if (mode & SIO_REC) {
+ if (ipar) {
par.bits = ipar->bits;
par.bps = ipar->bps;
par.sig = ipar->sig;
@@ -222,7 +127,7 @@ siofile_new(struct fileops *ops, char *path, unsigned mode,
par.msb = opar->msb;
par.rate = opar->rate;
}
- if (mode & SIO_PLAY)
+ if (opar)
par.pchan = opar->cmax - opar->cmin + 1;
par.appbufsz = *bufsz;
par.round = *round;
@@ -230,7 +135,7 @@ siofile_new(struct fileops *ops, char *path, unsigned mode,
goto bad_close;
if (!sio_getpar(hdl, &par))
goto bad_close;
- if (mode & SIO_REC) {
+ if (ipar) {
ipar->bits = par.bits;
ipar->bps = par.bps;
ipar->sig = par.sig;
@@ -239,7 +144,7 @@ siofile_new(struct fileops *ops, char *path, unsigned mode,
ipar->rate = par.rate;
ipar->cmax = ipar->cmin + par.rchan - 1;
}
- if (mode & SIO_PLAY) {
+ if (opar) {
opar->bits = par.bits;
opar->bps = par.bps;
opar->sig = par.sig;
@@ -257,11 +162,6 @@ siofile_new(struct fileops *ops, char *path, unsigned mode,
goto bad_close;
f->hdl = hdl;
f->started = 0;
- f->wtickets = 0;
- f->rtickets = 0;
- f->wbpf = par.pchan * par.bps;
- f->rbpf = par.rchan * par.bps;
- f->bufsz = par.bufsz;
sio_onmove(f->hdl, siofile_cb, f);
return f;
bad_close:
@@ -283,8 +183,6 @@ siofile_start(struct file *file)
return;
}
f->started = 1;
- f->wtickets = f->bufsz * f->wbpf;
- f->rtickets = 0;
#ifdef DEBUG
if (debug_level >= 3) {
file_dbg(&f->file);
@@ -321,14 +219,6 @@ siofile_read(struct file *file, unsigned char *data, unsigned count)
struct siofile *f = (struct siofile *)file;
unsigned n;
-#ifdef DEBUG
- if (f->rtickets == 0) {
- file_dbg(&f->file);
- dbg_puts(": called with no read tickets\n");
- }
-#endif
- if (count > f->rtickets)
- count = f->rtickets;
n = f->started ? sio_read(f->hdl, data, count) : 0;
if (n == 0) {
f->file.state &= ~FILE_ROK;
@@ -347,17 +237,6 @@ siofile_read(struct file *file, unsigned char *data, unsigned count)
#endif
}
return 0;
- } else {
- f->rtickets -= n;
- if (f->rtickets == 0) {
- f->file.state &= ~FILE_ROK;
-#ifdef DEBUG
- if (debug_level >= 4) {
- file_dbg(&f->file);
- dbg_puts(": read tickets exhausted\n");
- }
-#endif
- }
}
return n;
@@ -369,14 +248,6 @@ siofile_write(struct file *file, unsigned char *data, unsigned count)
struct siofile *f = (struct siofile *)file;
unsigned n;
-#ifdef DEBUG
- if (f->wtickets == 0) {
- file_dbg(&f->file);
- dbg_puts(": called with no write tickets\n");
- }
-#endif
- if (count > f->wtickets)
- count = f->wtickets;
n = f->started ? sio_write(f->hdl, data, count) : 0;
if (n == 0) {
f->file.state &= ~FILE_WOK;
@@ -395,17 +266,6 @@ siofile_write(struct file *file, unsigned char *data, unsigned count)
#endif
}
return 0;
- } else {
- f->wtickets -= n;
- if (f->wtickets == 0) {
- f->file.state &= ~FILE_WOK;
-#ifdef DEBUG
- if (debug_level >= 4) {
- file_dbg(&f->file);
- dbg_puts(": write tickets exhausted\n");
- }
-#endif
- }
}
return n;
}
diff --git a/usr.bin/aucat/siofile.h b/usr.bin/aucat/siofile.h
index bb8cb5dd801..b218bf1080d 100644
--- a/usr.bin/aucat/siofile.h
+++ b/usr.bin/aucat/siofile.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: siofile.h,v 1.2 2010/04/03 17:40:33 ratchov Exp $ */
+/* $OpenBSD: siofile.h,v 1.3 2010/04/03 17:59:17 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -20,12 +20,9 @@
struct fileops;
struct siofile;
struct aparams;
-struct aproc;
-struct siofile *siofile_new(struct fileops *, char *, unsigned,
+struct siofile *siofile_new(struct fileops *, char *,
struct aparams *, struct aparams *, unsigned *, unsigned *);
-struct aproc *rsio_new(struct file *f);
-struct aproc *wsio_new(struct file *f);
extern struct fileops siofile_ops;
diff --git a/usr.bin/aucat/sock.c b/usr.bin/aucat/sock.c
index 4086e1ba478..bb12d836d70 100644
--- a/usr.bin/aucat/sock.c
+++ b/usr.bin/aucat/sock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sock.c,v 1.40 2010/04/03 17:40:33 ratchov Exp $ */
+/* $OpenBSD: sock.c,v 1.41 2010/04/03 17:59:17 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -14,6 +14,12 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+/*
+ * TODO:
+ *
+ * change f->bufsz to contain only socket-side buffer,
+ * because it's less error prone
+ */
#include <stdio.h>
#include <stdlib.h>
@@ -30,7 +36,7 @@
#include "dbg.h"
#endif
-void sock_attach(struct sock *, int);
+int sock_attach(struct sock *, int);
int sock_read(struct sock *);
int sock_write(struct sock *);
int sock_execmsg(struct sock *);
@@ -53,11 +59,11 @@ struct fileops sock_ops = {
void
sock_dbg(struct sock *f)
{
- static char *pstates[] = { "hel", "ini", "sta", "rdy", "run", "mid" };
+ static char *pstates[] = { "hel", "ini", "sta", "run", "mid" };
static char *rstates[] = { "rdat", "rmsg", "rret" };
static char *wstates[] = { "widl", "wmsg", "wdat" };
- if (f->slot >= 0 && APROC_OK(dev_midi)) {
+ 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
@@ -73,14 +79,10 @@ sock_dbg(struct sock *f)
void sock_setvol(void *, unsigned);
void sock_startreq(void *);
-void sock_stopreq(void *);
-void sock_locreq(void *, unsigned);
struct ctl_ops ctl_sockops = {
sock_setvol,
- sock_startreq,
- sock_stopreq,
- sock_locreq
+ sock_startreq
};
void
@@ -156,7 +158,7 @@ rsock_opos(struct aproc *p, struct abuf *obuf, int delta)
{
struct sock *f = (struct sock *)p->u.io.file;
- if (f->mode & AMSG_RECMASK)
+ if (f->mode & AMSG_REC)
return;
f->delta += delta;
@@ -255,7 +257,7 @@ wsock_ipos(struct aproc *p, struct abuf *obuf, int delta)
{
struct sock *f = (struct sock *)p->u.io.file;
- if (!(f->mode & AMSG_RECMASK))
+ if (!(f->mode & AMSG_REC))
return;
f->delta += delta;
@@ -304,9 +306,9 @@ sock_new(struct fileops *ops, int fd)
f->mode = 0;
f->opt = opt_byname("default");
if (f->opt) {
- if (f->opt->mode & MODE_RECMASK)
+ if (dev_sub)
f->wpar = f->opt->wpar;
- if (f->opt->mode & MODE_PLAY)
+ if (dev_mix)
f->rpar = f->opt->rpar;
}
f->xrun = AMSG_IGNORE;
@@ -314,20 +316,17 @@ sock_new(struct fileops *ops, int fd)
f->round = dev_round;
f->delta = 0;
f->tickpending = 0;
- f->startpending = 0;
f->vol = f->lastvol = MIDI_MAXCTL;
f->slot = -1;
wproc = aproc_new(&wsock_ops, f->pipe.file.name);
wproc->u.io.file = &f->pipe.file;
- wproc->u.io.partial = 0;
f->pipe.file.wproc = wproc;
f->wstate = SOCK_WIDLE;
f->wtodo = 0xdeadbeef;
rproc = aproc_new(&rsock_ops, f->pipe.file.name);
rproc->u.io.file = &f->pipe.file;
- rproc->u.io.partial = 0;
f->pipe.file.rproc = rproc;
f->rstate = SOCK_RMSG;
f->rtodo = sizeof(struct amsg);
@@ -358,7 +357,6 @@ sock_freebuf(struct sock *f)
if (wbuf)
abuf_hup(wbuf);
f->tickpending = 0;
- f->startpending = 0;
}
/*
@@ -369,40 +367,28 @@ sock_allocbuf(struct sock *f)
{
struct abuf *rbuf = NULL, *wbuf = NULL;
- f->pstate = SOCK_START;
if (f->mode & AMSG_PLAY) {
rbuf = abuf_new(f->bufsz, &f->rpar);
aproc_setout(f->pipe.file.rproc, rbuf);
- if (!ABUF_WOK(rbuf) || (f->pipe.file.state & FILE_EOF))
- f->pstate = SOCK_READY;
}
- if (f->mode & AMSG_RECMASK) {
+ if (f->mode & AMSG_REC) {
wbuf = abuf_new(f->bufsz, &f->wpar);
aproc_setin(f->pipe.file.wproc, wbuf);
- f->walign = f->round;
+ f->walign = dev_round * wbuf->bpf;
}
f->delta = 0;
- f->wmax = 0;
- f->rmax = f->bufsz;
f->tickpending = 0;
- f->startpending = 0;
#ifdef DEBUG
if (debug_level >= 3) {
sock_dbg(f);
dbg_puts(": allocating ");
dbg_putu(f->bufsz);
- dbg_puts(" fr buffers, rmax = ");
- dbg_putu(f->rmax);
- dbg_puts("\n");
+ dbg_puts(" fr buffers\n");
}
#endif
- if (f->mode & AMSG_PLAY) {
- f->pstate = SOCK_START;
- } else {
- f->pstate = SOCK_READY;
- if (ctl_slotstart(dev_midi, f->slot))
- (void)sock_attach(f, 0);
- }
+ f->pstate = SOCK_START;
+ if (!(f->mode & AMSG_PLAY) && ctl_slotstart(dev_midi, f->slot))
+ (void)sock_attach(f, 0);
}
/*
@@ -437,9 +423,9 @@ sock_startreq(void *arg)
struct sock *f = (struct sock *)arg;
#ifdef DEBUG
- if (f->pstate != SOCK_READY) {
+ if (f->pstate != SOCK_START) {
sock_dbg(f);
- dbg_puts(": not in READY state\n");
+ dbg_puts(": not in START state\n");
dbg_panic();
}
#endif
@@ -447,41 +433,9 @@ sock_startreq(void *arg)
}
/*
- * Callback invoked by MMC stop
- */
-void
-sock_stopreq(void *arg)
-{
-#ifdef DEBUG
- struct sock *f = (struct sock *)arg;
-
- if (debug_level >= 3) {
- sock_dbg(f);
- dbg_puts(": ignored STOP signal\n");
- }
-#endif
-}
-
-/*
- * Callback invoked by MMC relocate, ignored
- */
-void
-sock_locreq(void *arg, unsigned mmcpos)
-{
-#ifdef DEBUG
- struct sock *f = (struct sock *)arg;
-
- if (debug_level >= 3) {
- sock_dbg(f);
- dbg_puts(": ignored RELOCATE signal\n");
- }
-#endif
-}
-
-/*
* Attach play and/or record buffers to dev_mix and/or dev_sub.
*/
-void
+int
sock_attach(struct sock *f, int force)
{
struct abuf *rbuf, *wbuf;
@@ -494,30 +448,23 @@ sock_attach(struct sock *f, int force)
* the buffer isn't completely filled.
*/
if (!force && rbuf && ABUF_WOK(rbuf))
- return;
+ return 0;
- /*
- * get the current position, the origin is when
- * the first sample is played/recorded
- */
- f->delta = dev_getpos() * (int)f->round / (int)dev_round;
- f->startpending = 1;
- f->pstate = SOCK_RUN;
#ifdef DEBUG
if (debug_level >= 3) {
sock_dbg(f);
- dbg_puts(": attaching at ");
- dbg_puti(f->delta);
- dbg_puts("\n");
+ dbg_puts(": attaching to device\n");
}
#endif
+ f->pstate = SOCK_RUN;
+
/*
- * We dont check whether the device is dying,
- * because dev_xxx() functions are supposed to
- * work (i.e., not to crash)
+ * Attach them to the device.
*/
- dev_attach(f->pipe.file.name, f->mode,
- rbuf, &f->rpar, wbuf, &f->wpar, f->xrun, f->opt->maxweight);
+ dev_attach(f->pipe.file.name,
+ (f->mode & AMSG_PLAY) ? rbuf : NULL, &f->rpar, f->xrun,
+ (f->mode & AMSG_REC) ? wbuf : NULL, &f->wpar, f->xrun,
+ f->opt->maxweight);
if (f->mode & AMSG_PLAY)
dev_setvol(rbuf, MIDI_TO_ADATA(f->vol));
@@ -528,6 +475,7 @@ sock_attach(struct sock *f, int force)
if (!sock_write(f))
break;
}
+ return 1;
}
void
@@ -535,7 +483,6 @@ sock_reset(struct sock *f)
{
switch (f->pstate) {
case SOCK_START:
- case SOCK_READY:
if (ctl_slotstart(dev_midi, f->slot)) {
(void)sock_attach(f, 1);
f->pstate = SOCK_RUN;
@@ -637,7 +584,8 @@ sock_rdata(struct sock *f)
{
struct aproc *p;
struct abuf *obuf;
- unsigned n;
+ unsigned char *data;
+ unsigned count, n;
#ifdef DEBUG
if (f->pstate != SOCK_MIDI && f->rtodo == 0) {
@@ -650,20 +598,17 @@ sock_rdata(struct sock *f)
obuf = LIST_FIRST(&p->obuflist);
if (obuf == NULL)
return 0;
- if (!ABUF_WOK(obuf) || !(f->pipe.file.state & FILE_ROK))
+ if (ABUF_FULL(obuf) || !(f->pipe.file.state & FILE_ROK))
return 0;
- if (f->pstate == SOCK_MIDI) {
- if (!rfile_do(p, obuf->len, NULL))
- return 0;
- } else {
- if (!rfile_do(p, f->rtodo, &n))
- return 0;
+ data = abuf_wgetblk(obuf, &count, 0);
+ if (f->pstate != SOCK_MIDI && count > f->rtodo)
+ count = f->rtodo;
+ n = file_read(&f->pipe.file, data, count);
+ if (n == 0)
+ return 0;
+ abuf_wcommit(obuf, n);
+ if (f->pstate != SOCK_MIDI)
f->rtodo -= n;
- if (f->pstate == SOCK_START) {
- if (!ABUF_WOK(obuf) || (f->pipe.file.state & FILE_EOF))
- f->pstate = SOCK_READY;
- }
- }
return 1;
}
@@ -676,7 +621,10 @@ sock_wdata(struct sock *f)
{
struct aproc *p;
struct abuf *ibuf;
- unsigned n;
+ unsigned char *data;
+ unsigned count, n;
+#define ZERO_MAX 0x1000
+ static unsigned char zero[ZERO_MAX];
#ifdef DEBUG
if (f->pstate != SOCK_MIDI && f->wtodo == 0) {
@@ -689,22 +637,32 @@ sock_wdata(struct sock *f)
return 0;
p = f->pipe.file.wproc;
ibuf = LIST_FIRST(&p->ibuflist);
-#ifdef DEBUG
- if (f->pstate != SOCK_MIDI && ibuf == NULL) {
- sock_dbg(f);
- dbg_puts(": attempted to write on detached buffer\n");
- dbg_panic();
- }
-#endif
- if (ibuf == NULL)
- return 0;
- if (!ABUF_ROK(ibuf))
- return 0;
- if (f->pstate == SOCK_MIDI) {
- if (!wfile_do(p, ibuf->len, NULL))
+ if (ibuf) {
+ if (ABUF_EMPTY(ibuf))
return 0;
+ data = abuf_rgetblk(ibuf, &count, 0);
+ if (f->pstate != SOCK_MIDI && count > f->wtodo)
+ count = f->wtodo;
+ n = file_write(&f->pipe.file, data, count);
+ if (n == 0)
+ return 0;
+ abuf_rdiscard(ibuf, n);
+ if (f->pstate != SOCK_MIDI)
+ f->wtodo -= n;
} else {
- if (!wfile_do(p, f->wtodo, &n))
+ if (f->pstate == SOCK_MIDI)
+ return 0;
+ /*
+ * There's no dev_detach() routine yet,
+ * so now we abruptly destroy the buffer.
+ * Until we implement dev_detach, complete
+ * the packet with zeros...
+ */
+ count = ZERO_MAX;
+ if (count > f->wtodo)
+ count = f->wtodo;
+ n = file_write(&f->pipe.file, zero, count);
+ if (n == 0)
return 0;
f->wtodo -= n;
}
@@ -762,7 +720,7 @@ sock_setpar(struct sock *f)
f->rpar.le = f->wpar.le = p->le ? 1 : 0;
if (AMSG_ISSET(p->msb))
f->rpar.msb = f->wpar.msb = p->msb ? 1 : 0;
- if (AMSG_ISSET(p->rchan) && (f->mode & AMSG_RECMASK)) {
+ if (AMSG_ISSET(p->rchan) && (f->mode & AMSG_REC)) {
if (p->rchan < 1)
p->rchan = 1;
if (p->rchan > NCHAN_MAX)
@@ -877,8 +835,8 @@ sock_setpar(struct sock *f)
}
if (AMSG_ISSET(p->appbufsz)) {
rate = (f->mode & AMSG_PLAY) ? f->rpar.rate : f->wpar.rate;
- min = 1;
- max = 1 + rate / dev_round;
+ min = 2;
+ max = 2 + rate / dev_round;
min *= f->round;
max *= f->round;
p->appbufsz += f->round - 1;
@@ -899,7 +857,7 @@ sock_setpar(struct sock *f)
}
#ifdef DEBUG
if (debug_level >= 2) {
- if (f->slot >= 0 && dev_midi) {
+ 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
@@ -910,7 +868,7 @@ sock_setpar(struct sock *f)
dbg_puts(", play = ");
aparams_dbg(&f->rpar);
}
- if (f->mode & AMSG_RECMASK) {
+ if (f->mode & AMSG_REC) {
dbg_puts(", rec:");
aparams_dbg(&f->wpar);
}
@@ -970,7 +928,7 @@ sock_hello(struct sock *f)
/*
* XXX : dev_midi can no longer be NULL, right ?
*/
- if (APROC_OK(dev_midi) && (p->proto & (AMSG_MIDIIN | AMSG_MIDIOUT))) {
+ if (dev_midi && (p->proto & (AMSG_MIDIIN | AMSG_MIDIOUT))) {
if (p->proto & ~(AMSG_MIDIIN | AMSG_MIDIOUT)) {
#ifdef DEBUG
if (debug_level >= 1) {
@@ -990,9 +948,9 @@ sock_hello(struct sock *f)
f->opt = opt_byname(p->opt);
if (f->opt == NULL)
return 0;
- if (f->opt->mode & MODE_RECMASK)
+ if (dev_sub)
f->wpar = f->opt->wpar;
- if (f->opt->mode & MODE_PLAY)
+ if (dev_mix)
f->rpar = f->opt->rpar;
if (f->opt->mmc)
f->xrun = AMSG_SYNC;
@@ -1010,7 +968,7 @@ sock_hello(struct sock *f)
}
f->mode = 0;
if (p->proto & AMSG_PLAY) {
- if (!APROC_OK(dev_mix) || !(f->opt->mode & MODE_PLAY)) {
+ if (!dev_mix) {
#ifdef DEBUG
if (debug_level >= 1) {
sock_dbg(f);
@@ -1022,8 +980,7 @@ sock_hello(struct sock *f)
f->mode |= AMSG_PLAY;
}
if (p->proto & AMSG_REC) {
- if (!(APROC_OK(dev_sub) && (f->opt->mode & MODE_REC)) &&
- !(APROC_OK(dev_submon) && (f->opt->mode & MODE_MON))) {
+ if (!dev_sub) {
#ifdef DEBUG
if (debug_level >= 1) {
sock_dbg(f);
@@ -1032,9 +989,9 @@ sock_hello(struct sock *f)
#endif
return 0;
}
- f->mode |= (f->opt->mode & MODE_MON) ? AMSG_MON : AMSG_REC;
+ f->mode |= AMSG_REC;
}
- if (APROC_OK(dev_midi)) {
+ if (dev_midi) {
f->slot = ctl_slotnew(dev_midi,
p->who, &ctl_sockops, f,
f->opt->mmc);
@@ -1060,7 +1017,6 @@ int
sock_execmsg(struct sock *f)
{
struct amsg *m = &f->rmsg;
- struct abuf *obuf;
switch (m->cmd) {
case AMSG_DATA:
@@ -1070,8 +1026,7 @@ sock_execmsg(struct sock *f)
dbg_puts(": DATA message\n");
}
#endif
- if (f->pstate != SOCK_RUN && f->pstate != SOCK_START &&
- f->pstate != SOCK_READY) {
+ if (f->pstate != SOCK_RUN && f->pstate != SOCK_START) {
#ifdef DEBUG
if (debug_level >= 1) {
sock_dbg(f);
@@ -1091,8 +1046,8 @@ sock_execmsg(struct sock *f)
aproc_del(f->pipe.file.rproc);
return 0;
}
- obuf = LIST_FIRST(&f->pipe.file.rproc->obuflist);
- if (f->pstate == SOCK_START && !ABUF_WOK(obuf)) {
+ if (f->pstate == SOCK_START &&
+ ABUF_FULL(LIST_FIRST(&f->pipe.file.rproc->obuflist))) {
#ifdef DEBUG
if (debug_level >= 1) {
sock_dbg(f);
@@ -1102,31 +1057,8 @@ sock_execmsg(struct sock *f)
aproc_del(f->pipe.file.rproc);
return 0;
}
- if (m->u.data.size % obuf->bpf != 0) {
-#ifdef DEBUG
- if (debug_level >= 1) {
- sock_dbg(f);
- dbg_puts(": unaligned data chunk\n");
- }
-#endif
- aproc_del(f->pipe.file.rproc);
- return 0;
- }
f->rstate = SOCK_RDATA;
- f->rtodo = m->u.data.size / obuf->bpf;
-#ifdef DEBUG
- if (f->rtodo > f->rmax && debug_level >= 2) {
- sock_dbg(f);
- dbg_puts(": received past current position, rtodo = ");
- dbg_putu(f->rtodo);
- dbg_puts(", rmax = ");
- dbg_putu(f->rmax);
- dbg_puts("\n");
- aproc_del(f->pipe.file.rproc);
- return 0;
- }
-#endif
- f->rmax -= f->rtodo;
+ f->rtodo = m->u.data.size;
if (f->rtodo == 0) {
#ifdef DEBUG
if (debug_level >= 1) {
@@ -1166,8 +1098,7 @@ sock_execmsg(struct sock *f)
dbg_puts(": STOP message\n");
}
#endif
- if (f->pstate != SOCK_RUN &&
- f->pstate != SOCK_START && f->pstate != SOCK_READY) {
+ if (f->pstate != SOCK_RUN && f->pstate != SOCK_START) {
#ifdef DEBUG
if (debug_level >= 1) {
sock_dbg(f);
@@ -1176,18 +1107,11 @@ sock_execmsg(struct sock *f)
#endif
aproc_del(f->pipe.file.rproc);
return 0;
- /*
- * XXX: device could have desappeared at this point,
- * see how this is fixed in wav.c
- */
}
- if ((f->pstate == SOCK_START || f->pstate == SOCK_READY) &&
+ if (f->pstate == SOCK_START &&
ctl_slotstart(dev_midi, f->slot))
(void)sock_attach(f, 1);
- if (f->wstate != SOCK_WDATA || f->wtodo == 0)
- sock_freebuf(f);
- else
- f->pstate = SOCK_STOP;
+ sock_freebuf(f);
AMSG_INIT(m);
m->cmd = AMSG_ACK;
f->rstate = SOCK_RRET;
@@ -1237,24 +1161,14 @@ sock_execmsg(struct sock *f)
AMSG_INIT(m);
m->cmd = AMSG_GETPAR;
m->u.par.legacy_mode = f->mode;
- if (f->mode & AMSG_PLAY) {
- m->u.par.bits = f->rpar.bits;
- m->u.par.bps = f->rpar.bps;
- m->u.par.sig = f->rpar.sig;
- m->u.par.le = f->rpar.le;
- m->u.par.msb = f->rpar.msb;
- m->u.par.rate = f->rpar.rate;
- m->u.par.pchan = f->rpar.cmax - f->rpar.cmin + 1;
- }
- if (f->mode & AMSG_RECMASK) {
- m->u.par.bits = f->wpar.bits;
- m->u.par.bps = f->wpar.bps;
- m->u.par.sig = f->wpar.sig;
- m->u.par.le = f->wpar.le;
- m->u.par.msb = f->wpar.msb;
- m->u.par.rate = f->wpar.rate;
- m->u.par.rchan = f->wpar.cmax - f->wpar.cmin + 1;
- }
+ m->u.par.bits = f->rpar.bits;
+ m->u.par.bps = f->rpar.bps;
+ m->u.par.sig = f->rpar.sig;
+ m->u.par.le = f->rpar.le;
+ m->u.par.msb = f->rpar.msb;
+ m->u.par.rate = f->rpar.rate;
+ m->u.par.rchan = f->wpar.cmax - f->wpar.cmin + 1;
+ m->u.par.pchan = f->rpar.cmax - f->rpar.cmin + 1;
m->u.par.appbufsz = f->bufsz;
m->u.par.bufsz =
f->bufsz + (dev_bufsz / dev_round) * f->round;
@@ -1282,9 +1196,9 @@ sock_execmsg(struct sock *f)
AMSG_INIT(m);
m->cmd = AMSG_GETCAP;
m->u.cap.rate = dev_rate;
- m->u.cap.pchan = (f->opt->mode & MODE_PLAY) ?
+ m->u.cap.pchan = dev_mix ?
(f->opt->rpar.cmax - f->opt->rpar.cmin + 1) : 0;
- m->u.cap.rchan = (f->opt->mode & (MODE_PLAY | MODE_REC)) ?
+ m->u.cap.rchan = dev_sub ?
(f->opt->wpar.cmax - f->opt->wpar.cmin + 1) : 0;
m->u.cap.bits = sizeof(short) * 8;
m->u.cap.bps = sizeof(short);
@@ -1298,8 +1212,8 @@ sock_execmsg(struct sock *f)
dbg_puts(": SETVOL message\n");
}
#endif
- if (f->pstate != SOCK_RUN && f->pstate != SOCK_START &&
- f->pstate != SOCK_INIT && f->pstate != SOCK_READY) {
+ if (f->pstate != SOCK_RUN &&
+ f->pstate != SOCK_START && f->pstate != SOCK_INIT) {
#ifdef DEBUG
if (debug_level >= 1) {
sock_dbg(f);
@@ -1407,7 +1321,7 @@ sock_buildmsg(struct sock *f)
{
struct aproc *p;
struct abuf *ibuf;
- unsigned size, max;
+ unsigned size;
if (f->pstate == SOCK_MIDI) {
#ifdef DEBUG
@@ -1424,7 +1338,7 @@ sock_buildmsg(struct sock *f)
/*
* If pos changed, build a MOVE message.
*/
- if ((f->tickpending && f->delta > 0) || f->startpending) {
+ if (f->tickpending) {
#ifdef DEBUG
if (debug_level >= 4) {
sock_dbg(f);
@@ -1433,9 +1347,6 @@ sock_buildmsg(struct sock *f)
dbg_puts("\n");
}
#endif
- f->wmax += f->delta;
- if (f->delta > 0)
- f->rmax += f->delta;
AMSG_INIT(&f->wmsg);
f->wmsg.cmd = AMSG_MOVE;
f->wmsg.u.ts.delta = f->delta;
@@ -1443,7 +1354,6 @@ sock_buildmsg(struct sock *f)
f->wstate = SOCK_WMSG;
f->delta = 0;
f->tickpending = 0;
- f->startpending = 0;
return 1;
}
@@ -1474,29 +1384,17 @@ sock_buildmsg(struct sock *f)
p = f->pipe.file.wproc;
ibuf = LIST_FIRST(&p->ibuflist);
if (ibuf && ABUF_ROK(ibuf)) {
-#ifdef DEBUG
- if (ibuf->used > f->wmax && debug_level >= 3) {
- sock_dbg(f);
- dbg_puts(": attempt to send past current position\n");
- }
-#endif
- max = AMSG_DATAMAX / ibuf->bpf;
- size = ibuf->used;
+ size = ibuf->used - (ibuf->used % ibuf->bpf);
+ if (size > AMSG_DATAMAX)
+ size = AMSG_DATAMAX - (AMSG_DATAMAX % ibuf->bpf);
if (size > f->walign)
size = f->walign;
- if (size > f->wmax)
- size = f->wmax;
- if (size > max)
- size = max;
- if (size == 0)
- return 0;
f->walign -= size;
- f->wmax -= size;
if (f->walign == 0)
- f->walign = f->round;
+ f->walign = dev_round * ibuf->bpf;
AMSG_INIT(&f->wmsg);
f->wmsg.cmd = AMSG_DATA;
- f->wmsg.u.data.size = size * ibuf->bpf;
+ f->wmsg.u.data.size = size;
f->wtodo = sizeof(struct amsg);
f->wstate = SOCK_WMSG;
return 1;
@@ -1542,11 +1440,9 @@ sock_read(struct sock *f)
f->rtodo = sizeof(struct amsg);
}
/*
- * XXX: sock_attach() may not start if there's not enough
- * samples queues, if so ctl_slotstart() will trigger
- * other streams, but this one won't start.
+ * XXX: have to way that the buffer is full before starting
*/
- if (f->pstate == SOCK_READY && ctl_slotstart(dev_midi, f->slot))
+ if (f->pstate == SOCK_START && ctl_slotstart(dev_midi, f->slot))
(void)sock_attach(f, 0);
break;
case SOCK_RRET:
@@ -1629,12 +1525,8 @@ sock_write(struct sock *f)
f->wtodo = 0xdeadbeef;
break;
}
- /*
- * XXX: why not set f->wtodo in sock_wmsg() ?
- */
f->wstate = SOCK_WDATA;
- f->wtodo = f->wmsg.u.data.size /
- LIST_FIRST(&f->pipe.file.wproc->ibuflist)->bpf;
+ f->wtodo = f->wmsg.u.data.size;
/* PASSTHROUGH */
case SOCK_WDATA:
if (!sock_wdata(f))
@@ -1643,8 +1535,6 @@ sock_write(struct sock *f)
break;
f->wstate = SOCK_WIDLE;
f->wtodo = 0xdeadbeef;
- if (f->pstate == SOCK_STOP)
- sock_freebuf(f);
/* PASSTHROUGH */
case SOCK_WIDLE:
if (!sock_return(f))
diff --git a/usr.bin/aucat/sock.h b/usr.bin/aucat/sock.h
index bc5bfa2607d..bc6e62a1da4 100644
--- a/usr.bin/aucat/sock.h
+++ b/usr.bin/aucat/sock.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sock.h,v 1.13 2010/04/03 17:40:33 ratchov Exp $ */
+/* $OpenBSD: sock.h,v 1.14 2010/04/03 17:59:17 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -30,8 +30,6 @@ struct sock {
* to decode/encode messages in the stream.
*/
struct amsg rmsg, wmsg; /* messages being sent/received */
- unsigned wmax; /* max frames we're allowed to write */
- unsigned rmax; /* max frames we're allowed to read */
unsigned rtodo; /* input bytes not read yet */
unsigned wtodo; /* output bytes not written yet */
#define SOCK_RDATA 0 /* data chunk being read */
@@ -45,17 +43,14 @@ struct sock {
#define SOCK_HELLO 0 /* waiting for HELLO message */
#define SOCK_INIT 1 /* parameter negotiation */
#define SOCK_START 2 /* filling play buffers */
-#define SOCK_READY 3 /* play buffers full */
-#define SOCK_RUN 4 /* attached to the mix / sub */
-#define SOCK_STOP 5 /* draining rec buffers */
-#define SOCK_MIDI 6 /* raw byte stream (midi) */
+#define SOCK_RUN 3 /* attached to the mix / sub */
+#define SOCK_MIDI 4 /* raw byte stream (midi) */
unsigned pstate; /* one of the above */
unsigned mode; /* a set of AMSG_PLAY, AMSG_REC */
struct aparams rpar; /* read (ie play) parameters */
struct aparams wpar; /* write (ie rec) parameters */
int delta; /* pos. change to send */
int tickpending; /* delta waiting to be transmitted */
- int startpending; /* initial delta waiting to be transmitted */
unsigned walign; /* align data packets to this */
unsigned bufsz; /* total buffer size */
unsigned round; /* block size */
diff --git a/usr.bin/aucat/wav.c b/usr.bin/aucat/wav.c
index af7a3de9982..e811c61aa6b 100644
--- a/usr.bin/aucat/wav.c
+++ b/usr.bin/aucat/wav.c
@@ -23,9 +23,7 @@
#include "aproc.h"
#include "conf.h"
#include "dev.h"
-#include "midi.h"
#include "wav.h"
-#include "opt.h"
#ifdef DEBUG
#include "dbg.h"
#endif
@@ -125,33 +123,19 @@ int rwav_out(struct aproc *, struct abuf *);
void rwav_eof(struct aproc *, struct abuf *);
void rwav_hup(struct aproc *, struct abuf *);
void rwav_done(struct aproc *);
-struct aproc *rwav_new(struct file *);
int wwav_in(struct aproc *, struct abuf *);
int wwav_out(struct aproc *, struct abuf *);
void wwav_eof(struct aproc *, struct abuf *);
void wwav_hup(struct aproc *, struct abuf *);
void wwav_done(struct aproc *);
-struct aproc *wwav_new(struct file *);
-
-void wav_setvol(void *, unsigned);
-void wav_startreq(void *);
-void wav_stopreq(void *);
-void wav_locreq(void *, unsigned);
-
-struct ctl_ops ctl_wavops = {
- wav_setvol,
- wav_startreq,
- wav_stopreq,
- wav_locreq
-};
struct aproc_ops rwav_ops = {
"rwav",
rwav_in,
rwav_out,
- rfile_eof,
- rfile_hup,
+ rwav_eof,
+ rwav_hup,
NULL, /* newin */
NULL, /* newout */
NULL, /* ipos */
@@ -163,8 +147,8 @@ struct aproc_ops wwav_ops = {
"wwav",
wwav_in,
wwav_out,
- wfile_eof,
- wfile_hup,
+ wwav_eof,
+ wwav_hup,
NULL, /* newin */
NULL, /* newout */
NULL, /* ipos */
@@ -172,466 +156,189 @@ struct aproc_ops wwav_ops = {
wwav_done
};
-#ifdef DEBUG
-/*
- * print the given wav structure
- */
-void
-wav_dbg(struct wav *f)
-{
- static char *pstates[] = { "ini", "sta", "rdy", "run", "fai" };
-
- dbg_puts("wav(");
- if (f->slot >= 0 && APROC_OK(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]);
-}
-#endif
-
-/*
- * convert ``count'' samples using the given char->short map
- */
-void
-wav_conv(unsigned char *data, unsigned count, short *map)
+struct aproc *
+rwav_new(struct file *f)
{
- unsigned i;
- unsigned char *iptr;
- short *optr;
+ struct aproc *p;
- iptr = data + count;
- optr = (short *)data + count;
- for (i = count; i > 0; i--) {
- --optr;
- --iptr;
- *optr = map[*iptr];
- }
+ p = aproc_new(&rwav_ops, f->name);
+ p->u.io.file = f;
+ f->rproc = p;
+ return p;
}
-/*
- * read method of the file structure
- */
-unsigned
-wav_read(struct file *file, unsigned char *data, unsigned count)
+int
+rwav_in(struct aproc *p, struct abuf *ibuf_dummy)
{
- struct wav *f = (struct wav *)file;
- unsigned n;
+ struct abuf *obuf = LIST_FIRST(&p->obuflist);
+ struct file *f = p->u.io.file;
+ unsigned char *data;
+ unsigned count;
- if (f->map)
- count /= sizeof(short);
- if (f->rbytes >= 0 && count > f->rbytes) {
- count = f->rbytes; /* file->rbytes fits in count */
- if (count == 0) {
-#ifdef DEBUG
- if (debug_level >= 3) {
- wav_dbg(f);
- dbg_puts(": read complete\n");
- }
-#endif
- if (!f->tr)
- file_eof(&f->pipe.file);
- return 0;
- }
- }
- n = pipe_read(file, data, count);
- if (n == 0)
+ if (ABUF_FULL(obuf) || !(f->state & FILE_ROK))
return 0;
- if (f->rbytes >= 0)
- f->rbytes -= n;
- if (f->map) {
- wav_conv(data, n, f->map);
- n *= sizeof(short);
- }
- return n;
-}
-
-/*
- * write method of the file structure
- */
-unsigned
-wav_write(struct file *file, unsigned char *data, unsigned count)
-{
- struct wav *f = (struct wav *)file;
- unsigned n;
-
- if (f->wbytes >= 0 && count > f->wbytes) {
- count = f->wbytes; /* wbytes fits in count */
- if (count == 0) {
-#ifdef DEBUG
- if (debug_level >= 3) {
- wav_dbg(f);
- dbg_puts(": write complete\n");
- }
-#endif
- file_hup(&f->pipe.file);
- return 0;
- }
- }
- n = pipe_write(file, data, count);
- if (f->wbytes >= 0)
- f->wbytes -= n;
- f->endpos += n;
- return n;
-}
-
-/*
- * close method of the file structure
- */
-void
-wav_close(struct file *file)
-{
- struct wav *f = (struct wav *)file;
-
- if (f->mode & MODE_RECMASK) {
- pipe_trunc(&f->pipe.file, f->endpos);
- if (f->hdr == HDR_WAV) {
- wav_writehdr(f->pipe.fd,
- &f->hpar,
- &f->startpos,
- f->endpos - f->startpos);
- }
- }
- pipe_close(file);
+ 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;
}
-/*
- * attach play (rec) abuf structure to the device and
- * switch to the ``RUN'' state; the play abug must not be empty
- */
int
-wav_attach(struct wav *f, int force)
+rwav_out(struct aproc *p, struct abuf *obuf)
{
- struct abuf *rbuf = NULL, *wbuf = NULL;
+ struct file *f = p->u.io.file;
+ unsigned char *data;
+ unsigned count;
- if (f->mode & MODE_PLAY)
- rbuf = LIST_FIRST(&f->pipe.file.rproc->obuflist);
- if (f->mode & MODE_RECMASK)
- wbuf = LIST_FIRST(&f->pipe.file.wproc->ibuflist);
- f->pstate = WAV_RUN;
-#ifdef DEBUG
- if (debug_level >= 3) {
- wav_dbg(f);
- dbg_puts(": attaching\n");
- }
-#endif
- dev_attach(f->pipe.file.name, f->mode,
- rbuf, &f->hpar, wbuf, &f->hpar, f->xrun, f->maxweight);
- if (f->mode & MODE_PLAY)
- dev_setvol(rbuf, MIDI_TO_ADATA(f->vol));
+ if (f->state & FILE_RINUSE)
+ return 0;
+ if (ABUF_FULL(obuf) || !(f->state & FILE_ROK))
+ return 0;
+ data = abuf_wgetblk(obuf, &count, 0);
+ count = file_read(f, data, count);
+ if (count == 0)
+ return 0;
+ abuf_wcommit(obuf, count);
return 1;
}
-/*
- * allocate the play (rec) abuf structure; if this is a
- * file to record, then attach it to the device
- *
- * XXX: buffer size should be larger than dev_bufsz, because
- * in non-server mode we don't prime play buffers with
- * silence
- */
void
-wav_allocbuf(struct wav *f)
+rwav_done(struct aproc *p)
{
- struct abuf *buf;
- unsigned nfr;
+ struct file *f = p->u.io.file;
+ struct abuf *obuf;
- f->pstate = WAV_START;
- if (f->mode & MODE_PLAY) {
- nfr = 2 * dev_bufsz * f->hpar.rate / dev_rate;
- buf = abuf_new(nfr, &f->hpar);
- aproc_setout(f->pipe.file.rproc, buf);
- abuf_fill(buf);
- if (!ABUF_WOK(buf) || (f->pipe.file.state & FILE_EOF))
- f->pstate = WAV_READY;
- }
- if (f->mode & MODE_RECMASK) {
- nfr = 2 * dev_bufsz * f->hpar.rate / dev_rate;
- buf = abuf_new(nfr, &f->hpar);
- aproc_setin(f->pipe.file.wproc, buf);
- f->pstate = WAV_READY;
- }
-#ifdef DEBUG
- if (debug_level >= 3) {
- wav_dbg(f);
- dbg_puts(": allocating buffers\n");
- }
-#endif
- if (f->pstate == WAV_READY && ctl_slotstart(dev_midi, f->slot))
- (void)wav_attach(f, 0);
+ if (f == NULL)
+ return;
+ /*
+ * all buffers must be detached before deleting f->wproc,
+ * because otherwise it could trigger this code again
+ */
+ obuf = LIST_FIRST(&p->obuflist);
+ if (obuf)
+ abuf_eof(obuf);
+ if (f->wproc) {
+ f->rproc = NULL;
+ aproc_del(f->wproc);
+ } else
+ file_del(f);
+ p->u.io.file = NULL;
}
-/*
- * free abuf structure and switch to the ``INIT'' state
- */
void
-wav_freebuf(struct wav *f)
+rwav_eof(struct aproc *p, struct abuf *ibuf_dummy)
{
- struct abuf *rbuf = NULL, *wbuf = NULL;
-
- if (f->mode & MODE_PLAY)
- rbuf = LIST_FIRST(&f->pipe.file.rproc->obuflist);
- if (f->mode & MODE_RECMASK)
- wbuf = LIST_FIRST(&f->pipe.file.wproc->ibuflist);
- f->pstate = WAV_INIT;
-#ifdef DEBUG
- if (debug_level >= 3) {
- wav_dbg(f);
- dbg_puts(": freeing buffers\n");
- }
-#endif
- if (rbuf || wbuf)
- ctl_slotstop(dev_midi, f->slot);
- if (rbuf)
- abuf_eof(rbuf);
- if (wbuf)
- abuf_hup(wbuf);
+ aproc_del(p);
}
-/*
- * switch to the ``INIT'' state performing
- * necessary actions to reach it
- */
void
-wav_reset(struct wav *f)
+rwav_hup(struct aproc *p, struct abuf *obuf)
{
- switch (f->pstate) {
- case WAV_START:
- case WAV_READY:
- if (ctl_slotstart(dev_midi, f->slot))
- (void)wav_attach(f, 1);
- /* PASSTHROUGH */
- case WAV_RUN:
- wav_freebuf(f);
- f->pstate = WAV_INIT;
- /* PASSTHROUGH */
- case WAV_INIT:
- case WAV_FAILED:
- /* nothing yet */
- break;
- }
+ aproc_del(p);
}
-/*
- * terminate the wav reader/writer
- */
-void
-wav_exit(struct wav *f)
+struct aproc *
+wwav_new(struct file *f)
{
- if (f->mode & MODE_PLAY) {
- aproc_del(f->pipe.file.rproc);
- } else if (f->mode & MODE_RECMASK) {
- aproc_del(f->pipe.file.wproc);
- }
+ struct aproc *p;
+
+ p = aproc_new(&wwav_ops, f->name);
+ p->u.io.file = f;
+ f->wproc = p;
+ return p;
}
-/*
- * seek to f->mmcpos and prepare to start, close
- * the file on error.
- */
-int
-wav_seekmmc(struct wav *f)
+void
+wwav_done(struct aproc *p)
{
+ struct file *f = p->u.io.file;
+ struct abuf *ibuf;
+
+ if (f == NULL)
+ return;
/*
- * don't go beyond the end-of-file, if so
- * put it in INIT state so it dosn't start
+ * all buffers must be detached before deleting f->rproc,
+ * because otherwise it could trigger this code again
*/
- if (f->mmcpos > f->endpos) {
- wav_reset(f);
- f->pstate = WAV_FAILED;
- /*
- * don't make other stream wait for us
- */
- if (f->slot >= 0)
- ctl_slotstart(dev_midi, f->slot);
- return 0;
- }
- if (!pipe_seek(&f->pipe.file, f->mmcpos)) {
- wav_exit(f);
- return 0;
- }
- if (f->hdr == HDR_WAV)
- f->wbytes = WAV_DATAMAX - f->mmcpos;
- f->rbytes = f->endpos - f->mmcpos;
- wav_reset(f);
- wav_allocbuf(f);
- return 1;
+ ibuf = LIST_FIRST(&p->ibuflist);
+ if (ibuf)
+ abuf_hup(ibuf);
+ if (f->rproc) {
+ f->wproc = NULL;
+ aproc_del(f->rproc);
+ } else
+ file_del(f);
+ p->u.io.file = NULL;
}
-/*
- * read samples from the file and possibly start it
- */
int
-wav_rdata(struct wav *f)
+wwav_in(struct aproc *p, struct abuf *ibuf)
{
- struct aproc *p;
- struct abuf *obuf;
+ struct file *f = p->u.io.file;
+ unsigned char *data;
+ unsigned count;
- p = f->pipe.file.rproc;
- obuf = LIST_FIRST(&p->obuflist);
- if (obuf == NULL)
+ if (f->state & FILE_WINUSE)
return 0;
- if (!ABUF_WOK(obuf) || !(f->pipe.file.state & FILE_ROK))
+ if (ABUF_EMPTY(ibuf) || !(f->state & FILE_WOK))
return 0;
- if (!rfile_do(p, obuf->len, NULL))
+ data = abuf_rgetblk(ibuf, &count, 0);
+ count = file_write(f, data, count);
+ if (count == 0)
return 0;
- switch (f->pstate) {
- case WAV_START:
- if (!ABUF_WOK(obuf) || (f->pipe.file.state & FILE_EOF))
- f->pstate = WAV_READY;
- /* PASSTHROUGH */
- case WAV_READY:
- if (ctl_slotstart(dev_midi, f->slot))
- (void)wav_attach(f, 0);
- break;
-#ifdef DEBUG
- case WAV_RUN:
- break;
- default:
- wav_dbg(f);
- dbg_puts(": bad state\n");
- dbg_panic();
-#endif
- }
- if (f->rbytes == 0 && f->tr) {
-#ifdef DEBUG
- if (debug_level >= 3) {
- wav_dbg(f);
- dbg_puts(": trying to restart\n");
- }
-#endif
- if (!wav_seekmmc(f))
- return 0;
- }
+ abuf_rdiscard(ibuf, count);
return 1;
}
int
-wav_wdata(struct wav *f)
+wwav_out(struct aproc *p, struct abuf *obuf_dummy)
{
- struct aproc *p;
- struct abuf *ibuf;
+ struct abuf *ibuf = LIST_FIRST(&p->ibuflist);
+ struct file *f = p->u.io.file;
+ unsigned char *data;
+ unsigned count;
- if (!(f->pipe.file.state & FILE_WOK))
+ if (!abuf_fill(ibuf))
return 0;
- p = f->pipe.file.wproc;
- ibuf = LIST_FIRST(&p->ibuflist);
- if (ibuf == NULL)
+ if (ABUF_EMPTY(ibuf) || !(f->state & FILE_WOK))
return 0;
- if (!ABUF_ROK(ibuf))
+ 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;
}
-/*
- * callback to set the volume, invoked by the MIDI control code
- */
-void
-wav_setvol(void *arg, unsigned vol)
-{
- struct wav *f = (struct wav *)arg;
- struct abuf *rbuf;
-
- f->vol = vol;
- if ((f->mode & MODE_PLAY) && f->pstate == WAV_RUN) {
- rbuf = LIST_FIRST(&f->pipe.file.rproc->obuflist);
- dev_setvol(rbuf, MIDI_TO_ADATA(vol));
- }
-}
-
-/*
- * callback to start the stream, invoked by the MIDI control code
- */
-void
-wav_startreq(void *arg)
-{
- struct wav *f = (struct wav *)arg;
-
- switch (f->pstate) {
- case WAV_FAILED:
-#ifdef DEBUG
- if (debug_level >= 2) {
- wav_dbg(f);
- dbg_puts(": skipped (failed to seek)\n");
- }
-#endif
- return;
- case WAV_READY:
- if (f->mode & MODE_RECMASK)
- f->endpos = f->startpos;
- (void)wav_attach(f, 0);
- break;
-#ifdef DEBUG
- default:
- wav_dbg(f);
- dbg_puts(": not in READY state\n");
- dbg_panic();
- break;
-#endif
- }
-}
-
-/*
- * callback to stop the stream, invoked by the MIDI control code
- */
void
-wav_stopreq(void *arg)
+wwav_eof(struct aproc *p, struct abuf *ibuf)
{
- struct wav *f = (struct wav *)arg;
-
-#ifdef DEBUG
- if (debug_level >= 2) {
- wav_dbg(f);
- dbg_puts(": stopping");
- if (f->pstate != WAV_FAILED && (f->mode & MODE_RECMASK)) {
- dbg_puts(", ");
- dbg_putu(f->endpos);
- dbg_puts(" bytes recorded");
- }
- dbg_puts("\n");
- }
-#endif
- if (!f->tr) {
- wav_exit(f);
- return;
- }
- (void)wav_seekmmc(f);
+ aproc_del(p);
}
-/*
- * callback to relocate the stream, invoked by the MIDI control code
- * on a stopped stream
- */
void
-wav_locreq(void *arg, unsigned mmc)
+wwav_hup(struct aproc *p, struct abuf *obuf_dummy)
{
- struct wav *f = (struct wav *)arg;
-
-#ifdef DEBUG
- if (f->pstate == WAV_RUN) {
- wav_dbg(f);
- dbg_puts(": in RUN state\n");
- dbg_panic();
- }
-#endif
- f->mmcpos = f->startpos +
- ((off_t)mmc * f->hpar.rate / MTC_SEC) * aparams_bpf(&f->hpar);
- (void)wav_seekmmc(f);
+ aproc_del(p);
}
-/*
- * create a file reader in the ``INIT'' state
- */
struct wav *
-wav_new_in(struct fileops *ops, unsigned mode, char *name, unsigned hdr,
- struct aparams *par, unsigned xrun, unsigned volctl, int tr)
+wav_new_in(struct fileops *ops, char *name, unsigned hdr,
+ struct aparams *par, unsigned xrun, unsigned volctl)
{
int fd;
struct wav *f;
+ struct aproc *p;
+ struct abuf *buf;
+ unsigned nfr;
if (name != NULL) {
fd = open(name, O_RDONLY | O_NONBLOCK, 0666);
@@ -649,59 +356,43 @@ wav_new_in(struct fileops *ops, unsigned mode, char *name, unsigned hdr,
if (f == NULL)
return NULL;
if (hdr == HDR_WAV) {
- if (!wav_readhdr(f->pipe.fd, par, &f->startpos, &f->rbytes, &f->map)) {
+ if (!wav_readhdr(f->pipe.fd, par, &f->rbytes, &f->map)) {
file_del((struct file *)f);
return NULL;
}
- f->endpos = f->startpos + f->rbytes;
+ f->hpar = *par;
} else {
- f->startpos = 0;
- f->endpos = pipe_endpos(&f->pipe.file);
- if (f->endpos > 0) {
- if (!pipe_seek(&f->pipe.file, 0)) {
- file_del((struct file *)f);
- return NULL;
- }
- f->rbytes = f->endpos;
- } else
- f->rbytes = -1;
+ f->rbytes = -1;
f->map = NULL;
}
- f->tr = tr;
- f->mode = mode;
- f->hpar = *par;
f->hdr = 0;
- f->xrun = xrun;
- f->maxweight = MIDI_TO_ADATA(volctl);
- f->slot = ctl_slotnew(dev_midi, "play", &ctl_wavops, f, 1);
- rwav_new((struct file *)f);
- wav_allocbuf(f);
+ nfr = dev_bufsz * par->rate / dev_rate;
+ buf = abuf_new(nfr, par);
+ p = rwav_new((struct file *)f);
+ aproc_setout(p, buf);
+ abuf_fill(buf); /* XXX: move this in dev_attach() ? */
+ dev_attach(name, buf, par, xrun, NULL, NULL, 0, ADATA_UNIT);
+ dev_setvol(buf, MIDI_TO_ADATA(volctl));
#ifdef DEBUG
if (debug_level >= 2) {
dbg_puts(name);
dbg_puts(": playing ");
- dbg_putu(f->startpos);
- dbg_puts("..");
- dbg_putu(f->endpos);
- dbg_puts(": playing ");
aparams_dbg(par);
- if (f->tr)
- dbg_puts(", mmc");
dbg_puts("\n");
}
#endif
return f;
}
-/*
- * create a file writer in the ``INIT'' state
- */
struct wav *
-wav_new_out(struct fileops *ops, unsigned mode, char *name, unsigned hdr,
- struct aparams *par, unsigned xrun, int tr)
+wav_new_out(struct fileops *ops, char *name, unsigned hdr,
+ struct aparams *par, unsigned xrun)
{
int fd;
struct wav *f;
+ struct aproc *p;
+ struct abuf *buf;
+ unsigned nfr;
if (name == NULL) {
name = "stdout";
@@ -723,24 +414,20 @@ wav_new_out(struct fileops *ops, unsigned mode, char *name, unsigned hdr,
par->le = 1;
par->sig = (par->bits <= 8) ? 0 : 1;
par->bps = (par->bits + 7) / 8;
- if (!wav_writehdr(f->pipe.fd, par, &f->startpos, 0)) {
+ if (!wav_writehdr(f->pipe.fd, par)) {
file_del((struct file *)f);
return NULL;
}
+ f->hpar = *par;
f->wbytes = WAV_DATAMAX;
- f->endpos = f->startpos;
- } else {
+ } else
f->wbytes = -1;
- f->startpos = f->endpos = 0;
- }
- f->tr = tr;
- f->mode = mode;
- f->hpar = *par;
f->hdr = hdr;
- f->xrun = xrun;
- f->slot = ctl_slotnew(dev_midi, "rec", &ctl_wavops, f, 1);
- wwav_new((struct file *)f);
- wav_allocbuf(f);
+ nfr = dev_bufsz * par->rate / dev_rate;
+ p = wwav_new((struct file *)f);
+ buf = abuf_new(nfr, par);
+ aproc_setin(p, buf);
+ dev_attach(name, NULL, NULL, 0, buf, par, xrun, 0);
#ifdef DEBUG
if (debug_level >= 2) {
dbg_puts(name);
@@ -753,107 +440,86 @@ wav_new_out(struct fileops *ops, unsigned mode, char *name, unsigned hdr,
}
void
-rwav_done(struct aproc *p)
-{
- struct wav *f = (struct wav *)p->u.io.file;
-
- if (f->slot >= 0)
- ctl_slotdel(dev_midi, f->slot);
- f->slot = -1;
- rfile_done(p);
-}
-
-int
-rwav_in(struct aproc *p, struct abuf *ibuf_dummy)
+wav_conv(unsigned char *data, unsigned count, short *map)
{
- struct wav *f = (struct wav *)p->u.io.file;
- struct abuf *obuf;
+ unsigned i;
+ unsigned char *iptr;
+ short *optr;
- if (!wav_rdata(f))
- return 0;
- obuf = LIST_FIRST(&p->obuflist);
- if (obuf && f->pstate >= WAV_RUN) {
- if (!abuf_flush(obuf))
- return 0;
+ iptr = data + count;
+ optr = (short *)data + count;
+ for (i = count; i > 0; i--) {
+ --optr;
+ --iptr;
+ *optr = map[*iptr];
}
- return 1;
}
-int
-rwav_out(struct aproc *p, struct abuf *obuf)
+unsigned
+wav_read(struct file *file, unsigned char *data, unsigned count)
{
- struct wav *f = (struct wav *)p->u.io.file;
+ struct wav *f = (struct wav *)file;
+ unsigned n;
- if (f->pipe.file.state & FILE_RINUSE)
- return 0;
- for (;;) {
- if (!wav_rdata(f))
+ if (f->map)
+ count /= sizeof(short);
+ 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;
+ }
}
- return 1;
-}
-
-struct aproc *
-rwav_new(struct file *f)
-{
- struct aproc *p;
-
- p = aproc_new(&rwav_ops, f->name);
- p->u.io.file = f;
- p->u.io.partial = 0;;
- f->rproc = p;
- return p;
-}
-
-void
-wwav_done(struct aproc *p)
-{
- struct wav *f = (struct wav *)p->u.io.file;
-
- if (f->slot >= 0)
- ctl_slotdel(dev_midi, f->slot);
- f->slot = -1;
- wfile_done(p);
-}
-
-int
-wwav_in(struct aproc *p, struct abuf *ibuf)
-{
- struct wav *f = (struct wav *)p->u.io.file;
-
- if (f->pipe.file.state & FILE_WINUSE)
+ n = pipe_read(file, data, count);
+ if (n == 0)
return 0;
- for (;;) {
- if (!wav_wdata(f))
- return 0;
+ if (f->rbytes >= 0)
+ f->rbytes -= n;
+ if (f->map) {
+ wav_conv(data, n, f->map);
+ n *= sizeof(short);
}
- return 1;
+ return n;
}
-int
-wwav_out(struct aproc *p, struct abuf *obuf_dummy)
+unsigned
+wav_write(struct file *file, unsigned char *data, unsigned count)
{
- struct abuf *ibuf = LIST_FIRST(&p->ibuflist);
- struct wav *f = (struct wav *)p->u.io.file;
+ struct wav *f = (struct wav *)file;
+ unsigned n;
- if (ibuf && f->pstate == WAV_RUN) {
- if (!abuf_fill(ibuf))
+ 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;
+ }
}
- if (!wav_wdata(f))
- return 0;
- return 1;
+ n = pipe_write(file, data, count);
+ if (f->wbytes >= 0)
+ f->wbytes -= n;
+ return n;
}
-struct aproc *
-wwav_new(struct file *f)
+void
+wav_close(struct file *file)
{
- struct aproc *p;
+ struct wav *f = (struct wav *)file;
- p = aproc_new(&wwav_ops, f->name);
- p->u.io.file = f;
- p->u.io.partial = 0;;
- f->wproc = p;
- return p;
+ if (f->hdr == HDR_WAV)
+ wav_writehdr(f->pipe.fd, &f->hpar);
+ pipe_close(file);
}
diff --git a/usr.bin/aucat/wav.h b/usr.bin/aucat/wav.h
index 4543d1a89da..8e8288cdecd 100644
--- a/usr.bin/aucat/wav.h
+++ b/usr.bin/aucat/wav.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: wav.h,v 1.6 2010/04/03 17:40:33 ratchov Exp $ */
+/* $OpenBSD: wav.h,v 1.7 2010/04/03 17:59:17 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -28,38 +28,23 @@ struct wav {
#define HDR_RAW 1 /* no headers, ie openbsd native ;-) */
#define HDR_WAV 2 /* microsoft riff wave */
unsigned hdr; /* HDR_RAW or HDR_WAV */
- unsigned xrun; /* xrun policy */
struct aparams hpar; /* parameters to write on the header */
off_t rbytes; /* bytes to read, -1 if no limit */
off_t wbytes; /* bytes to write, -1 if no limit */
- off_t startpos; /* beginning of the data chunk */
- off_t endpos; /* end of the data chunk */
- off_t mmcpos; /* play/rec start point set by MMC */
short *map; /* mulaw/alaw -> s16 conversion table */
- int slot; /* mixer ctl slot number */
- int tr; /* use MMC control */
- unsigned vol; /* current volume */
- unsigned maxweight; /* dynamic range when vol == 127 */
-#define WAV_INIT 0 /* not trying to do anything */
-#define WAV_START 1 /* buffer allocated */
-#define WAV_READY 2 /* buffer filled enough */
-#define WAV_RUN 3 /* buffer attached to device */
-#define WAV_FAILED 4 /* failed to seek */
- unsigned pstate; /* one of above */
- unsigned mode; /* bitmap of MODE_* */
};
extern struct fileops wav_ops;
-struct wav *wav_new_in(struct fileops *, unsigned, char *, unsigned,
- struct aparams *, unsigned, unsigned, int);
-struct wav *wav_new_out(struct fileops *, unsigned, char *, unsigned,
- struct aparams *, unsigned, int);
+struct wav *wav_new_in(struct fileops *, char *, unsigned,
+ struct aparams *, unsigned, unsigned);
+struct wav *wav_new_out(struct fileops *, char *, unsigned,
+ struct aparams *, unsigned);
unsigned wav_read(struct file *, unsigned char *, unsigned);
unsigned wav_write(struct file *, unsigned char *, unsigned);
void wav_close(struct file *);
-int wav_readhdr(int, struct aparams *, off_t *, off_t *, short **);
-int wav_writehdr(int, struct aparams *, off_t *, off_t);
+int wav_readhdr(int, struct aparams *, off_t *, short **);
+int wav_writehdr(int, struct aparams *);
void wav_conv(unsigned char *, unsigned, short *);
/* legacy */