diff options
author | 2008-12-17 07:19:27 +0000 | |
---|---|---|
committer | 2008-12-17 07:19:27 +0000 | |
commit | dd80057d342091acb09d6f8c40eb5eb27fcf56cc (patch) | |
tree | 757ce4177d7de03e44bb11ee2fe954b7a57c0374 | |
parent | Make the "machine xir" ddb command work on machines with Tomatillo (diff) | |
download | wireguard-openbsd-dd80057d342091acb09d6f8c40eb5eb27fcf56cc.tar.xz wireguard-openbsd-dd80057d342091acb09d6f8c40eb5eb27fcf56cc.zip |
add a writable ``appbufsz'' field to the sa_par structure, containing
the program-part of the buffer size, ie the part that is subject to
underruns. Useful for apps like cdio(1) that don't have their own
rings, or to apps that have a minimum ring size constraint. Setting
the ``bufsz'' parameter becomes deprecated.
ok jakemsr
-rw-r--r-- | lib/libsndio/aucat.c | 5 | ||||
-rw-r--r-- | lib/libsndio/shlib_version | 2 | ||||
-rw-r--r-- | lib/libsndio/sio_open.3 | 50 | ||||
-rw-r--r-- | lib/libsndio/sndio.c | 10 | ||||
-rw-r--r-- | lib/libsndio/sndio.h | 37 | ||||
-rw-r--r-- | lib/libsndio/sun.c | 9 | ||||
-rw-r--r-- | regress/lib/libsndio/fd/fd.c | 2 | ||||
-rw-r--r-- | regress/lib/libsndio/play/play.c | 2 | ||||
-rw-r--r-- | regress/lib/libsndio/rec/rec.c | 1 | ||||
-rw-r--r-- | usr.bin/aucat/amsg.h | 9 | ||||
-rw-r--r-- | usr.bin/aucat/safile.c | 4 | ||||
-rw-r--r-- | usr.bin/aucat/sock.c | 54 |
12 files changed, 107 insertions, 78 deletions
diff --git a/lib/libsndio/aucat.c b/lib/libsndio/aucat.c index d3add816a06..2f373c8815f 100644 --- a/lib/libsndio/aucat.c +++ b/lib/libsndio/aucat.c @@ -1,4 +1,4 @@ -/* $OpenBSD: aucat.c,v 1.4 2008/11/17 07:04:13 ratchov Exp $ */ +/* $OpenBSD: aucat.c,v 1.5 2008/12/17 07:19:27 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * @@ -326,7 +326,7 @@ aucat_setpar(struct sio_hdl *sh, struct sio_par *par) hdl->wmsg.u.par.le = par->le; hdl->wmsg.u.par.msb = par->msb; hdl->wmsg.u.par.rate = par->rate; - hdl->wmsg.u.par.bufsz = par->bufsz; + hdl->wmsg.u.par.appbufsz = par->appbufsz; hdl->wmsg.u.par.xrun = par->xrun; hdl->wmsg.u.par.mode = hdl->sa.mode; if (hdl->sa.mode & SIO_REC) @@ -364,6 +364,7 @@ aucat_getpar(struct sio_hdl *sh, struct sio_par *par) par->msb = hdl->rmsg.u.par.msb; par->rate = hdl->rmsg.u.par.rate; par->bufsz = hdl->rmsg.u.par.bufsz; + par->appbufsz = hdl->rmsg.u.par.appbufsz; par->xrun = hdl->rmsg.u.par.xrun; par->round = hdl->rmsg.u.par.round; if (hdl->sa.mode & SIO_PLAY) diff --git a/lib/libsndio/shlib_version b/lib/libsndio/shlib_version index 3f0196ebf4a..83a67c373cc 100644 --- a/lib/libsndio/shlib_version +++ b/lib/libsndio/shlib_version @@ -1,2 +1,2 @@ major=3 -minor=1 +minor=2 diff --git a/lib/libsndio/sio_open.3 b/lib/libsndio/sio_open.3 index c194efa58d6..df0c0edf603 100644 --- a/lib/libsndio/sio_open.3 +++ b/lib/libsndio/sio_open.3 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sio_open.3,v 1.8 2008/11/17 07:49:48 jmc Exp $ +.\" $OpenBSD: sio_open.3,v 1.9 2008/12/17 07:19:27 ratchov Exp $ .\" .\" Copyright (c) 2007 Alexandre Ratchov <alex@caoua.org> .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: November 17 2008 $ +.Dd $Mdocdate: December 17 2008 $ .Dt SIO_OPEN 3 .Os .Sh NAME @@ -149,27 +149,28 @@ handle. Audio streams always use linear interleaved encoding. The set of parameters of the stream that can be controlled is given by the following structure: -.Bd -literal -offset -indent +.Bd -literal struct sio_par { - unsigned bits; /* bits per sample */ - unsigned bps; /* bytes per sample */ - unsigned sig; /* 1 = signed, 0 = unsigned */ - unsigned le; /* 1 = LE, 0 = BE byte order */ - unsigned msb; /* 1 = MSB, 0 = LSB aligned */ - unsigned rchan; /* number channels for recording */ - unsigned pchan; /* number channels for playback */ - unsigned rate; /* frames per second */ - unsigned bufsz; /* frames in the stream buffer */ - unsigned round; /* optimal buffer size divisor */ + unsigned bits; /* bits per sample */ + unsigned bps; /* bytes per sample */ + unsigned sig; /* 1 = signed, 0 = unsigned */ + unsigned le; /* 1 = LE, 0 = BE byte order */ + unsigned msb; /* 1 = MSB, 0 = LSB aligned */ + unsigned rchan; /* number channels for recording */ + unsigned pchan; /* number channels for playback */ + unsigned rate; /* frames per second */ + unsigned appbufsz; /* minimum buffer size without xruns */ + unsigned bufsz; /* end-to-end buffer size (read-only) */ + unsigned round; /* optimal buffer size divisor */ #define SIO_IGNORE 0 /* pause during xrun */ -#define SIO_SYNC 1 /* resync after xrun */ +#define SIO_SYNC 1 /* resync after xrun */ #define SIO_ERROR 2 /* terminate on xrun */ - unsigned xrun; /* what to do on overrun/underrun */ + unsigned xrun; /* what to do on overrun/underrun */ }; .Ed .Pp The parameters are as follows: -.Bl -tag -width "round" +.Bl -tag -width "appbufsz" .It Va bits Number of bits per sample: must be between 1 and 32. .It Va bps @@ -202,8 +203,19 @@ mode was selected. .It Va rate The sampling frequency in Hz. .It Va bufsz -The number of frames that will be buffered for both -play and record directions. +The maximum number of frames that may be buffered. +This parameter takes into accout any buffers, and +can be used for latency calculations. +This parameter is read-only. +.It Va appbufsz +Size of the buffer in frames the application must maintain non empty +(on the play end) or non full (on the record end) by calling +.Fn sio_write +or +.Fn sio_read +fast enough to avoid overrun or underrun conditions. +The audio subsystem may use additionnal buffering, thus this +parameter cannot be used for latency calculations .It Va round Optimal number of frames that the application buffers should be a multiple of, to get best performance. @@ -578,7 +590,7 @@ for this. .Ss Handling buffer overruns and underruns When the application cannot accept recorded data fast enough, the record buffer (of size -.Va bufsz ) +.Va appbufsz ) might overrun; in this case recorded data is lost. Similarly if the application cannot provide data to play fast enough, the play buffer underruns and silence is played diff --git a/lib/libsndio/sndio.c b/lib/libsndio/sndio.c index cccc38905ee..a849f4bf7d0 100644 --- a/lib/libsndio/sndio.c +++ b/lib/libsndio/sndio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sndio.c,v 1.7 2008/11/20 16:31:26 ratchov Exp $ */ +/* $OpenBSD: sndio.c,v 1.8 2008/12/17 07:19:27 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * @@ -266,8 +266,12 @@ sio_setpar(struct sio_hdl *hdl, struct sio_par *par) hdl->eof = 1; return 0; } - if (par->rate != (unsigned)~0 && par->bufsz == (unsigned)~0) - par->bufsz = par->rate * 200 / 1000; + if (par->bufsz != (unsigned)~0) { + fprintf(stderr, "sio_setpar: setting bufsz is deprecated\n"); + par->appbufsz = par->bufsz; + } + if (par->rate != (unsigned)~0 && par->appbufsz == (unsigned)~0) + par->appbufsz = par->rate * 200 / 1000; return hdl->ops->setpar(hdl, par); } diff --git a/lib/libsndio/sndio.h b/lib/libsndio/sndio.h index ec0afaa468d..1b3dddbb4b6 100644 --- a/lib/libsndio/sndio.h +++ b/lib/libsndio/sndio.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sndio.h,v 1.3 2008/11/11 19:39:35 ratchov Exp $ */ +/* $OpenBSD: sndio.h,v 1.4 2008/12/17 07:19:27 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * @@ -28,29 +28,30 @@ struct sio_hdl; * parameters of a full-duplex stream */ struct sio_par { - unsigned bits; /* bits per sample */ - unsigned bps; /* bytes per sample */ - unsigned sig; /* 1 = signed, 0 = unsigned */ - unsigned le; /* 1 = LE, 0 = BE byte order */ - unsigned msb; /* 1 = MSB, 0 = LSB aligned */ - unsigned rchan; /* number channels for recording direction */ - unsigned pchan; /* number channels for playback direction */ - unsigned rate; /* frames per second */ - unsigned bufsz; /* minimum buffer size */ + unsigned bits; /* bits per sample */ + unsigned bps; /* bytes per sample */ + unsigned sig; /* 1 = signed, 0 = unsigned */ + unsigned le; /* 1 = LE, 0 = BE byte order */ + unsigned msb; /* 1 = MSB, 0 = LSB aligned */ + unsigned rchan; /* number channels for recording direction */ + unsigned pchan; /* number channels for playback direction */ + unsigned rate; /* frames per second */ + unsigned bufsz; /* end-to-end buffer size */ #define SIO_IGNORE 0 /* pause during xrun */ -#define SIO_SYNC 1 /* resync after xrun */ +#define SIO_SYNC 1 /* resync after xrun */ #define SIO_ERROR 2 /* terminate on xrun */ - unsigned xrun; /* what to do on overruns/underruns */ - unsigned round; /* optimal bufsz divisor */ - int __pad[4]; /* for future use */ - int __magic; /* for internal/debug purposes only */ + unsigned xrun; /* what to do on overruns/underruns */ + unsigned round; /* optimal bufsz divisor */ + unsigned appbufsz; /* minimum buffer size */ + int __pad[3]; /* for future use */ + int __magic; /* for internal/debug purposes only */ }; /* * capabilities of a stream */ struct sio_cap { -#define SIO_NENC 8 +#define SIO_NENC 8 #define SIO_NCHAN 8 #define SIO_NRATE 16 #define SIO_NCONF 4 @@ -79,8 +80,8 @@ struct sio_cap { /* * mode bitmap */ -#define SIO_PLAY 1 -#define SIO_REC 2 +#define SIO_PLAY 1 +#define SIO_REC 2 /* * maximum size of the encording string (the longest possible diff --git a/lib/libsndio/sun.c b/lib/libsndio/sun.c index 5b4db13842b..14dbbe14400 100644 --- a/lib/libsndio/sun.c +++ b/lib/libsndio/sun.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sun.c,v 1.7 2008/11/20 16:31:26 ratchov Exp $ */ +/* $OpenBSD: sun.c,v 1.8 2008/12/17 07:19:27 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * @@ -494,7 +494,7 @@ sio_open_sun(char *path, unsigned mode, int nbio) par.rate = 48000; par.sig = 1; par.bits = 16; - par.bufsz = 1200; + par.appbufsz = 1200; if (!sio_setpar(&hdl->sa, &par)) goto bad_close; return (struct sio_hdl *)hdl; @@ -639,7 +639,7 @@ sun_setpar(struct sio_hdl *sh, struct sio_par *par) * if block size and buffer size are not both set then * set the blocksize to half the buffer size */ - bufsz = par->bufsz; + bufsz = par->appbufsz; round = par->round; if (bufsz != (unsigned)~0) { if (round == (unsigned)~0) @@ -751,7 +751,8 @@ sun_getpar(struct sio_hdl *sh, struct sio_par *par) par->round = (hdl->sa.mode & SIO_REC) ? aui.record.block_size / (par->bps * par->rchan) : aui.play.block_size / (par->bps * par->pchan); - par->bufsz = aui.hiwat * par->round; + par->appbufsz = aui.hiwat * par->round; + par->bufsz = par->appbufsz; return 1; } diff --git a/regress/lib/libsndio/fd/fd.c b/regress/lib/libsndio/fd/fd.c index 9a76946bc55..d25f32acdc2 100644 --- a/regress/lib/libsndio/fd/fd.c +++ b/regress/lib/libsndio/fd/fd.c @@ -228,7 +228,7 @@ main(int argc, char **argv) { playpath = optarg; break; case 'b': - if (sscanf(optarg, "%u", &par.bufsz) != 1) { + if (sscanf(optarg, "%u", &par.appbufsz) != 1) { fprintf(stderr, "%s: bad buf size\n", optarg); exit(1); } diff --git a/regress/lib/libsndio/play/play.c b/regress/lib/libsndio/play/play.c index a3b28b42ba3..6d85508da42 100644 --- a/regress/lib/libsndio/play/play.c +++ b/regress/lib/libsndio/play/play.c @@ -69,7 +69,7 @@ main(int argc, char **argv) { } break; case 'b': - if (sscanf(optarg, "%u", &par.bufsz) != 1) { + if (sscanf(optarg, "%u", &par.appbufsz) != 1) { fprintf(stderr, "%s: bad buf size\n", optarg); exit(1); } diff --git a/regress/lib/libsndio/rec/rec.c b/regress/lib/libsndio/rec/rec.c index e7d737e8d37..f5c908077dc 100644 --- a/regress/lib/libsndio/rec/rec.c +++ b/regress/lib/libsndio/rec/rec.c @@ -44,7 +44,6 @@ main(int argc, char **argv) { par.bits = 16; par.rchan = 2; par.rate = 44100; - par.bufsz = 0x10000; while ((ch = getopt(argc, argv, "r:c:e:b:x:")) != -1) { switch(ch) { diff --git a/usr.bin/aucat/amsg.h b/usr.bin/aucat/amsg.h index 56116c9ee2e..ee8da901165 100644 --- a/usr.bin/aucat/amsg.h +++ b/usr.bin/aucat/amsg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: amsg.h,v 1.2 2008/11/11 19:21:20 ratchov Exp $ */ +/* $OpenBSD: amsg.h,v 1.3 2008/12/17 07:19:27 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * @@ -55,13 +55,14 @@ struct amsg { uint16_t pchan; /* play channels */ uint16_t rchan; /* record channels */ uint32_t rate; /* frames per second */ - uint32_t bufsz; /* buffered frames */ + uint32_t bufsz; /* total buffered frames */ uint32_t round; - uint32_t _reserved[2]; /* for future use */ + uint32_t appbufsz; /* client side bufsz */ + uint32_t _reserved[1]; /* for future use */ } par; struct amsg_cap { uint32_t rate; /* native rate */ - uint32_t rate_div; /* divisor of emul. rates */ + uint32_t _reserved2[1]; /* for future use */ uint16_t rchan; /* native rec channels */ uint16_t pchan; /* native play channels */ uint8_t bits; /* native bits per sample */ diff --git a/usr.bin/aucat/safile.c b/usr.bin/aucat/safile.c index 775d451a6aa..f4987e7e29d 100644 --- a/usr.bin/aucat/safile.c +++ b/usr.bin/aucat/safile.c @@ -1,4 +1,4 @@ -/* $OpenBSD: safile.c,v 1.5 2008/12/07 17:10:41 ratchov Exp $ */ +/* $OpenBSD: safile.c,v 1.6 2008/12/17 07:19:27 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * @@ -125,7 +125,7 @@ safile_new(struct fileops *ops, char *path, } if (opar) par.pchan = opar->cmax - opar->cmin + 1; - par.bufsz = *bufsz; + par.appbufsz = *bufsz; par.round = *round; if (!sio_setpar(hdl, &par)) return 0; diff --git a/usr.bin/aucat/sock.c b/usr.bin/aucat/sock.c index a924bc89e01..8b86f31ce5a 100644 --- a/usr.bin/aucat/sock.c +++ b/usr.bin/aucat/sock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sock.c,v 1.9 2008/12/07 17:10:41 ratchov Exp $ */ +/* $OpenBSD: sock.c,v 1.10 2008/12/17 07:19:27 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * @@ -280,7 +280,7 @@ sock_new(struct fileops *ops, int fd, char *name, f->mode |= AMSG_PLAY; } f->xrun = AMSG_IGNORE; - f->bufsz = 2 * dev_bufsz; + f->bufsz = dev_bufsz; f->round = dev_round; f->odelta = f->idelta = 0; f->maxweight = maxweight; @@ -325,23 +325,19 @@ void sock_allocbuf(struct sock *f) { struct abuf *rbuf = NULL, *wbuf = NULL; - unsigned nfr = 0; if (f->mode & AMSG_PLAY) { - nfr = f->bufsz - dev_bufsz * f->rpar.rate / dev_rate; - rbuf = abuf_new(nfr, &f->rpar); + rbuf = abuf_new(f->bufsz, &f->rpar); aproc_setout(f->pipe.file.rproc, rbuf); f->odelta = 0; } if (f->mode & AMSG_REC) { - nfr = f->bufsz - dev_bufsz * f->wpar.rate / dev_rate; - wbuf = abuf_new(nfr, &f->wpar); + wbuf = abuf_new(f->bufsz, &f->wpar); aproc_setin(f->pipe.file.wproc, wbuf); f->idelta = 0; } - DPRINTF("sock_allocbuf: %p, using %u/%u frames buffer\n", - f, nfr, f->bufsz); + DPRINTF("sock_allocbuf: %p, using %u frames buffer\n", f, f->bufsz); f->pstate = SOCK_START; if (!(f->mode & AMSG_PLAY)) @@ -634,8 +630,10 @@ sock_setpar(struct sock *f) p->rate = RATE_MAX; f->round = dev_roundof(p->rate); f->rpar.rate = f->wpar.rate = p->rate; - if (!AMSG_ISSET(p->bufsz)) - p->bufsz = 2 * dev_bufsz / dev_round * f->round; + if (!AMSG_ISSET(p->appbufsz)) { + p->appbufsz = dev_bufsz / dev_round * f->round; + DPRINTF("sock_setpar: appbufsz -> %u\n", p->appbufsz); + } DPRINTF("sock_setpar: rate -> %u, round -> %u\n", p->rate, f->round); } @@ -650,18 +648,29 @@ sock_setpar(struct sock *f) DPRINTF("sock_setpar: xrun -> %u\n", f->xrun); } if (AMSG_ISSET(p->bufsz)) { + /* + * XXX: bufsz will become read-only, but for now + * allow old library to properly work + */ + DPRINTF("sock_setpar: bufsz: %u\n", p->bufsz); + min = (dev_bufsz / dev_round) * f->round; + if (p->bufsz < min) + p->bufsz = min; + p->appbufsz = p->bufsz - min; + } + if (AMSG_ISSET(p->appbufsz)) { rate = (f->mode & AMSG_PLAY) ? f->rpar.rate : f->wpar.rate; - min = (3 * (dev_bufsz / dev_round) + 1) / 2; - max = (dev_bufsz + rate + dev_round - 1) / dev_round; + min = 1; + max = 1 + rate / dev_round; min *= f->round; max *= f->round; - p->bufsz += f->round - 1; - p->bufsz -= p->bufsz % f->round; - if (p->bufsz < min) - p->bufsz = min; - if (p->bufsz > max) - p->bufsz = max; - f->bufsz = p->bufsz; + p->appbufsz += f->round - 1; + p->appbufsz -= p->appbufsz % f->round; + if (p->appbufsz < min) + p->appbufsz = min; + if (p->appbufsz > max) + p->appbufsz = max; + f->bufsz = p->appbufsz; DPRINTF("sock_setpar: bufsz -> %u\n", f->bufsz); } #ifdef DEBUG @@ -764,7 +773,9 @@ sock_execmsg(struct sock *f) 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.bufsz = f->bufsz; + m->u.par.appbufsz = f->bufsz; + m->u.par.bufsz = + f->bufsz + (dev_bufsz / dev_round) * f->round; m->u.par.round = f->round; f->rstate = SOCK_RRET; f->rtodo = sizeof(struct amsg); @@ -779,7 +790,6 @@ sock_execmsg(struct sock *f) AMSG_INIT(m); m->cmd = AMSG_GETCAP; m->u.cap.rate = dev_rate; - m->u.cap.rate_div = dev_rate; m->u.cap.pchan = dev_mix ? (f->templ_rpar.cmax - f->templ_rpar.cmin + 1) : 0; m->u.cap.rchan = dev_sub ? |