diff options
Diffstat (limited to 'lib/libsndio')
-rw-r--r-- | lib/libsndio/amsg.h | 6 | ||||
-rw-r--r-- | lib/libsndio/aucat.c | 3 | ||||
-rw-r--r-- | lib/libsndio/aucat.h | 1 | ||||
-rw-r--r-- | lib/libsndio/mio_aucat.c | 52 | ||||
-rw-r--r-- | lib/libsndio/sio_aucat.c | 39 |
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) |