summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorratchov <ratchov@openbsd.org>2008-12-17 07:19:27 +0000
committerratchov <ratchov@openbsd.org>2008-12-17 07:19:27 +0000
commitdd80057d342091acb09d6f8c40eb5eb27fcf56cc (patch)
tree757ce4177d7de03e44bb11ee2fe954b7a57c0374
parentMake the "machine xir" ddb command work on machines with Tomatillo (diff)
downloadwireguard-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.c5
-rw-r--r--lib/libsndio/shlib_version2
-rw-r--r--lib/libsndio/sio_open.350
-rw-r--r--lib/libsndio/sndio.c10
-rw-r--r--lib/libsndio/sndio.h37
-rw-r--r--lib/libsndio/sun.c9
-rw-r--r--regress/lib/libsndio/fd/fd.c2
-rw-r--r--regress/lib/libsndio/play/play.c2
-rw-r--r--regress/lib/libsndio/rec/rec.c1
-rw-r--r--usr.bin/aucat/amsg.h9
-rw-r--r--usr.bin/aucat/safile.c4
-rw-r--r--usr.bin/aucat/sock.c54
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 ?