summaryrefslogtreecommitdiff
path: root/lib/libsndio
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libsndio')
-rw-r--r--lib/libsndio/amsg.h6
-rw-r--r--lib/libsndio/aucat.c3
-rw-r--r--lib/libsndio/aucat.h1
-rw-r--r--lib/libsndio/mio_aucat.c52
-rw-r--r--lib/libsndio/sio_aucat.c39
5 files changed, 69 insertions, 32 deletions
diff --git a/lib/libsndio/amsg.h b/lib/libsndio/amsg.h
index 585b1be8ce2..6a5664ea138 100644
--- a/lib/libsndio/amsg.h
+++ b/lib/libsndio/amsg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: amsg.h,v 1.4 2011/11/15 08:05:22 ratchov Exp $ */
+/* $OpenBSD: amsg.h,v 1.5 2012/11/02 10:24:58 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -42,7 +42,7 @@ struct amsg {
#define AMSG_START 3 /* request the server to start the stream */
#define AMSG_STOP 4 /* request the server to stop the stream */
#define AMSG_DATA 5 /* data block */
-#define AMSG_POS 6 /* initial position */
+#define AMSG_FLOWCTL 6 /* feedback about buffer usage */
#define AMSG_MOVE 7 /* position changed */
#define AMSG_SETVOL 9 /* set volume */
#define AMSG_HELLO 10 /* say hello, check versions and so ... */
@@ -80,7 +80,7 @@ struct amsg {
} vol;
struct amsg_hello {
uint16_t mode; /* bitmap of MODE_XXX */
-#define AMSG_VERSION 5
+#define AMSG_VERSION 6
uint8_t version; /* protocol version */
uint8_t devnum; /* device number */
uint32_t _reserved[1]; /* for future use */
diff --git a/lib/libsndio/aucat.c b/lib/libsndio/aucat.c
index f155c892568..e1e5211a3ea 100644
--- a/lib/libsndio/aucat.c
+++ b/lib/libsndio/aucat.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: aucat.c,v 1.54 2012/04/11 06:05:43 ratchov Exp $ */
+/* $OpenBSD: aucat.c,v 1.55 2012/11/02 10:24:58 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -463,6 +463,7 @@ aucat_open(struct aucat *hdl, const char *str, unsigned int mode,
hdl->rtodo = sizeof(struct amsg);
hdl->wstate = WSTATE_IDLE;
hdl->wtodo = 0xdeadbeef;
+ hdl->maxwrite = 0;
/*
* say hello to server
diff --git a/lib/libsndio/aucat.h b/lib/libsndio/aucat.h
index 42dc89f85e7..d7dd4d9cbf2 100644
--- a/lib/libsndio/aucat.h
+++ b/lib/libsndio/aucat.h
@@ -14,6 +14,7 @@ struct aucat {
#define WSTATE_MSG 3 /* message being transferred */
#define WSTATE_DATA 4 /* data being transferred */
unsigned wstate; /* one of above */
+ unsigned maxwrite; /* bytes we're allowed to write */
};
int aucat_rmsg(struct aucat *, int *);
diff --git a/lib/libsndio/mio_aucat.c b/lib/libsndio/mio_aucat.c
index 6f5caa8fbba..28fbd1c8154 100644
--- a/lib/libsndio/mio_aucat.c
+++ b/lib/libsndio/mio_aucat.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mio_aucat.c,v 1.8 2012/10/27 12:08:25 ratchov Exp $ */
+/* $OpenBSD: mio_aucat.c,v 1.9 2012/11/02 10:24:58 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -54,6 +54,35 @@ static struct mio_ops mio_aucat_ops = {
mio_aucat_revents
};
+/*
+ * execute the next message, return 0 if blocked
+ */
+static int
+mio_aucat_runmsg(struct mio_aucat_hdl *hdl)
+{
+ int delta;
+
+ if (!aucat_rmsg(&hdl->aucat, &hdl->mio.eof))
+ return 0;
+ switch (ntohl(hdl->aucat.rmsg.cmd)) {
+ case AMSG_DATA:
+ return 1;
+ case AMSG_FLOWCTL:
+ delta = ntohl(hdl->aucat.rmsg.u.ts.delta);
+ hdl->aucat.maxwrite += delta;
+ DPRINTF("aucat: flowctl = %d, maxwrite = %d\n",
+ delta, hdl->aucat.maxwrite);
+ break;
+ default:
+ DPRINTF("mio_aucat_runmsg: unhandled message %u\n", hdl->aucat.rmsg.cmd);
+ hdl->mio.eof = 1;
+ return 0;
+ }
+ hdl->aucat.rstate = RSTATE_MSG;
+ hdl->aucat.rtodo = sizeof(struct amsg);
+ return 1;
+}
+
struct mio_hdl *
mio_aucat_open(const char *str, unsigned int mode,
int nbio, unsigned int type)
@@ -91,7 +120,7 @@ mio_aucat_read(struct mio_hdl *sh, void *buf, size_t len)
struct mio_aucat_hdl *hdl = (struct mio_aucat_hdl *)sh;
while (hdl->aucat.rstate == RSTATE_MSG) {
- if (!aucat_rmsg(&hdl->aucat, &hdl->mio.eof))
+ if (!mio_aucat_runmsg(hdl))
return 0;
}
return aucat_rdata(&hdl->aucat, buf, len, &hdl->mio.eof);
@@ -101,8 +130,15 @@ static size_t
mio_aucat_write(struct mio_hdl *sh, const void *buf, size_t len)
{
struct mio_aucat_hdl *hdl = (struct mio_aucat_hdl *)sh;
-
- return aucat_wdata(&hdl->aucat, buf, len, 1, &hdl->mio.eof);
+ size_t n;
+
+ if (len <= 0 || hdl->aucat.maxwrite <= 0)
+ return 0;
+ if (len > hdl->aucat.maxwrite)
+ len = hdl->aucat.maxwrite;
+ n = aucat_wdata(&hdl->aucat, buf, len, 1, &hdl->mio.eof);
+ hdl->aucat.maxwrite -= n;
+ return n;
}
static int
@@ -117,6 +153,8 @@ mio_aucat_pollfd(struct mio_hdl *sh, struct pollfd *pfd, int events)
struct mio_aucat_hdl *hdl = (struct mio_aucat_hdl *)sh;
hdl->events = events;
+ if (hdl->aucat.maxwrite <= 0)
+ events &= ~POLLOUT;
return aucat_pollfd(&hdl->aucat, pfd, events);
}
@@ -128,12 +166,16 @@ mio_aucat_revents(struct mio_hdl *sh, struct pollfd *pfd)
if (revents & POLLIN) {
while (hdl->aucat.rstate == RSTATE_MSG) {
- if (!aucat_rmsg(&hdl->aucat, &hdl->mio.eof))
+ if (!mio_aucat_runmsg(hdl))
break;
}
if (hdl->aucat.rstate != RSTATE_DATA)
revents &= ~POLLIN;
}
+ if (revents & POLLOUT) {
+ if (hdl->aucat.maxwrite <= 0)
+ revents &= ~POLLOUT;
+ }
if (hdl->mio.eof)
return POLLHUP;
return revents & (hdl->events | POLLHUP);
diff --git a/lib/libsndio/sio_aucat.c b/lib/libsndio/sio_aucat.c
index bea40dce087..da2a270ac56 100644
--- a/lib/libsndio/sio_aucat.c
+++ b/lib/libsndio/sio_aucat.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sio_aucat.c,v 1.12 2012/10/27 11:56:04 ratchov Exp $ */
+/* $OpenBSD: sio_aucat.c,v 1.13 2012/11/02 10:24:58 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -35,8 +35,7 @@
struct sio_aucat_hdl {
struct sio_hdl sio;
struct aucat aucat;
- unsigned int rbpf, wbpf; /* read and write bytes-per-frame */
- int maxwrite; /* latency constraint */
+ unsigned int rbpf, wbpf; /* read and write bytes-per-frame */
int events; /* events the user requested */
unsigned int curvol, reqvol; /* current and requested volume */
int delta; /* some of received deltas */
@@ -97,23 +96,17 @@ sio_aucat_runmsg(struct sio_aucat_hdl *hdl)
return 0;
}
return 1;
- case AMSG_POS:
+ case AMSG_FLOWCTL:
delta = ntohl(hdl->aucat.rmsg.u.ts.delta);
- hdl->maxwrite += delta * (int)hdl->wbpf;
- DPRINTF("aucat: pos = %d, maxwrite = %d\n",
- delta, hdl->maxwrite);
- hdl->delta = delta;
- if (hdl->delta >= 0) {
- sio_onmove_cb(&hdl->sio, hdl->delta);
- hdl->delta = 0;
- }
+ hdl->aucat.maxwrite += delta * (int)hdl->wbpf;
+ DPRINTF("aucat: flowctl = %d, maxwrite = %d\n",
+ delta, hdl->aucat.maxwrite);
break;
case AMSG_MOVE:
delta = ntohl(hdl->aucat.rmsg.u.ts.delta);
- hdl->maxwrite += delta * hdl->wbpf;
hdl->delta += delta;
DPRINTFN(2, "aucat: move = %d, delta = %d, maxwrite = %d\n",
- delta, hdl->delta, hdl->maxwrite);
+ delta, hdl->delta, hdl->aucat.maxwrite);
if (hdl->delta >= 0) {
sio_onmove_cb(&hdl->sio, hdl->delta);
hdl->delta = 0;
@@ -196,10 +189,10 @@ sio_aucat_start(struct sio_hdl *sh)
return 0;
hdl->wbpf = par.bps * par.pchan;
hdl->rbpf = par.bps * par.rchan;
- hdl->maxwrite = hdl->wbpf * par.bufsz;
+ hdl->aucat.maxwrite = hdl->wbpf * par.bufsz;
hdl->round = par.round;
hdl->delta = 0;
- DPRINTF("aucat: start, maxwrite = %d\n", hdl->maxwrite);
+ DPRINTF("aucat: start, maxwrite = %d\n", hdl->aucat.maxwrite);
AMSG_INIT(&hdl->aucat.wmsg);
hdl->aucat.wmsg.cmd = htonl(AMSG_START);
@@ -233,7 +226,7 @@ sio_aucat_stop(struct sio_hdl *sh)
return 0;
}
if (hdl->aucat.wstate == WSTATE_DATA) {
- hdl->maxwrite = hdl->aucat.wtodo;
+ hdl->aucat.maxwrite = hdl->aucat.wtodo;
while (hdl->aucat.wstate != WSTATE_IDLE) {
count = hdl->aucat.wtodo;
if (count > ZERO_MAX)
@@ -427,14 +420,14 @@ sio_aucat_write(struct sio_hdl *sh, const void *buf, size_t len)
if (!sio_aucat_buildmsg(hdl))
break;
}
- if (len <= 0 || hdl->maxwrite <= 0)
+ if (len <= 0 || hdl->aucat.maxwrite <= 0)
return 0;
- if (len > hdl->maxwrite)
- len = hdl->maxwrite;
+ if (len > hdl->aucat.maxwrite)
+ len = hdl->aucat.maxwrite;
if (len > hdl->walign)
len = hdl->walign;
n = aucat_wdata(&hdl->aucat, buf, len, hdl->wbpf, &hdl->sio.eof);
- hdl->maxwrite -= n;
+ hdl->aucat.maxwrite -= n;
hdl->walign -= n;
if (hdl->walign == 0)
hdl->walign = hdl->round * hdl->wbpf;
@@ -453,7 +446,7 @@ sio_aucat_pollfd(struct sio_hdl *sh, struct pollfd *pfd, int events)
struct sio_aucat_hdl *hdl = (struct sio_aucat_hdl *)sh;
hdl->events = events;
- if (hdl->maxwrite <= 0)
+ if (hdl->aucat.maxwrite <= 0)
events &= ~POLLOUT;
return aucat_pollfd(&hdl->aucat, pfd, events);
}
@@ -473,7 +466,7 @@ sio_aucat_revents(struct sio_hdl *sh, struct pollfd *pfd)
revents &= ~POLLIN;
}
if (revents & POLLOUT) {
- if (hdl->maxwrite <= 0)
+ if (hdl->aucat.maxwrite <= 0)
revents &= ~POLLOUT;
}
if (hdl->sio.eof)