diff options
Diffstat (limited to 'lib/libsndio/aucat.c')
-rw-r--r-- | lib/libsndio/aucat.c | 98 |
1 files changed, 75 insertions, 23 deletions
diff --git a/lib/libsndio/aucat.c b/lib/libsndio/aucat.c index 89988433f68..65cef3bb5d7 100644 --- a/lib/libsndio/aucat.c +++ b/lib/libsndio/aucat.c @@ -1,4 +1,4 @@ -/* $OpenBSD: aucat.c,v 1.34 2010/01/20 13:17:22 jakemsr Exp $ */ +/* $OpenBSD: aucat.c,v 1.35 2010/04/06 20:07:01 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * @@ -43,8 +43,6 @@ struct aucat_hdl { int maxwrite; /* latency constraint */ int events; /* events the user requested */ unsigned curvol, reqvol; /* current and requested volume */ - unsigned devbufsz; /* server side buffer size (in frames) */ - unsigned attached; /* stream attached to device */ int delta; /* some of received deltas */ }; @@ -153,14 +151,12 @@ aucat_runmsg(struct aucat_hdl *hdl) hdl->rtodo = hdl->rmsg.u.data.size; break; case AMSG_MOVE: - if (!hdl->attached) { - DPRINTF("aucat_runmsg: attached\n"); - hdl->maxwrite += hdl->devbufsz * hdl->wbpf; - hdl->attached = 1; - } + DPRINTF("aucat: tick, delta = %d\n", hdl->rmsg.u.ts.delta); + if (hdl->rmsg.u.ts.delta > 0) + hdl->maxwrite += hdl->rmsg.u.ts.delta * hdl->wbpf; hdl->delta += hdl->rmsg.u.ts.delta; if (hdl->delta >= 0) { - hdl->maxwrite += hdl->delta * hdl->wbpf; + DPRINTF("aucat: move: maxwrite = %d\n", hdl->maxwrite); sio_onmove_cb(&hdl->sio, hdl->delta); hdl->delta = 0; } @@ -316,8 +312,6 @@ aucat_start(struct sio_hdl *sh) hdl->wbpf = par.bps * par.pchan; hdl->rbpf = par.bps * par.rchan; hdl->maxwrite = hdl->wbpf * par.appbufsz; - hdl->devbufsz = par.bufsz - par.appbufsz; - hdl->attached = 0; hdl->delta = 0; AMSG_INIT(&hdl->wmsg); @@ -463,6 +457,8 @@ static int aucat_getcap(struct sio_hdl *sh, struct sio_cap *cap) { struct aucat_hdl *hdl = (struct aucat_hdl *)sh; + unsigned i, bps, le, sig, chan, rindex, rmult; + static unsigned rates[] = { 8000, 11025, 12000 }; AMSG_INIT(&hdl->wmsg); hdl->wmsg.cmd = AMSG_GETCAP; @@ -477,18 +473,70 @@ aucat_getcap(struct sio_hdl *sh, struct sio_cap *cap) hdl->sio.eof = 1; return 0; } - cap->enc[0].bits = hdl->rmsg.u.cap.bits; - cap->enc[0].bps = SIO_BPS(hdl->rmsg.u.cap.bits); - cap->enc[0].sig = 1; - cap->enc[0].le = SIO_LE_NATIVE; - cap->enc[0].msb = 1; - cap->rchan[0] = hdl->rmsg.u.cap.rchan; - cap->pchan[0] = hdl->rmsg.u.cap.pchan; - cap->rate[0] = hdl->rmsg.u.cap.rate; - cap->confs[0].enc = 1; - cap->confs[0].rchan = (hdl->rmsg.u.cap.rchan > 0) ? 1 : 0; - cap->confs[0].pchan = (hdl->rmsg.u.cap.pchan > 0) ? 1 : 0; - cap->confs[0].rate = 1; + bps = 1; + sig = le = 0; + cap->confs[0].enc = 0; + for (i = 0; i < SIO_NENC; i++) { + if (bps > 4) + break; + cap->confs[0].enc |= 1 << i; + cap->enc[i].bits = bps == 4 ? 24 : bps * 8; + cap->enc[i].bps = bps; + cap->enc[i].sig = sig ^ 1; + cap->enc[i].le = bps > 1 ? le : SIO_LE_NATIVE; + cap->enc[i].msb = 1; + le++; + if (le > 1 || bps == 1) { + le = 0; + sig++; + } + if (sig > 1 || (le == 0 && bps > 1)) { + sig = 0; + bps++; + } + } + chan = 1; + cap->confs[0].rchan = 0; + for (i = 0; i < SIO_NCHAN; i++) { + if (chan > 16) + break; + cap->confs[0].rchan |= 1 << i; + cap->rchan[i] = chan; + if (chan >= 12) { + chan += 4; + } else if (chan >= 2) { + chan += 2; + } else + chan++; + } + chan = 1; + cap->confs[0].pchan = 0; + for (i = 0; i < SIO_NCHAN; i++) { + if (chan > 16) + break; + cap->confs[0].pchan |= 1 << i; + cap->pchan[i] = chan; + if (chan >= 12) { + chan += 4; + } else if (chan >= 2) { + chan += 2; + } else + chan++; + } + rindex = 0; + rmult = 1; + cap->confs[0].rate = 0; + for (i = 0; i < SIO_NRATE; i++) { + if (rmult >= 32) + break; + cap->rate[i] = rates[rindex] * rmult; + cap->confs[0].rate |= 1 << i; + rindex++; + if (rindex == sizeof(rates) / sizeof(unsigned)) { + rindex = 0; + rmult *= 2; + } + } cap->nconf = 1; return 1; } @@ -532,6 +580,7 @@ aucat_read(struct sio_hdl *sh, void *buf, size_t len) hdl->rstate = STATE_MSG; hdl->rtodo = sizeof(struct amsg); } + DPRINTF("aucat: read: n = %zd\n", n); return n; } @@ -611,6 +660,7 @@ aucat_write(struct sio_hdl *sh, const void *buf, size_t len) return 0; } hdl->maxwrite -= n; + DPRINTF("aucat: write: n = %zd, maxwrite = %d\n", n, hdl->maxwrite); hdl->wtodo -= n; if (hdl->wtodo == 0) { hdl->wstate = STATE_IDLE; @@ -631,6 +681,7 @@ aucat_pollfd(struct sio_hdl *sh, struct pollfd *pfd, int events) events |= POLLIN; pfd->fd = hdl->fd; pfd->events = events; + DPRINTF("aucat: pollfd: %x -> %x\n", hdl->events, pfd->events); return 1; } @@ -654,6 +705,7 @@ aucat_revents(struct sio_hdl *sh, struct pollfd *pfd) } if (hdl->sio.eof) return POLLHUP; + DPRINTF("aucat: revents: %x\n", revents & hdl->events); return revents & (hdl->events | POLLHUP); } |