summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandre Ratchov <ratchov@cvs.openbsd.org>2015-07-28 20:45:03 +0000
committerAlexandre Ratchov <ratchov@cvs.openbsd.org>2015-07-28 20:45:03 +0000
commitc3bbe3df2251d73b764b62936861513c64399db7 (patch)
treebac685f9086c2d03ce61eea79ae7f6e31f70dccc
parent17682997ea03cb4ca482d8a4d16de1c373425bcd (diff)
Add the AUDIO_GETPOS ioctl() to fetch a snapshot of the 4 counters
returned by AUDIO_GETxOFFS and AUDIO_xERROR ioctls. ok deraadt
-rw-r--r--share/man/man4/audio.437
-rw-r--r--sys/dev/audio.c18
-rw-r--r--sys/sys/audioio.h10
3 files changed, 58 insertions, 7 deletions
diff --git a/share/man/man4/audio.4 b/share/man/man4/audio.4
index 2d8179a74c8..ae30267fc85 100644
--- a/share/man/man4/audio.4
+++ b/share/man/man4/audio.4
@@ -1,4 +1,4 @@
-.\" $OpenBSD: audio.4,v 1.67 2015/07/27 06:10:22 ratchov Exp $
+.\" $OpenBSD: audio.4,v 1.68 2015/07/28 20:45:02 ratchov Exp $
.\" $NetBSD: audio.4,v 1.20 1998/05/28 17:27:15 augustss Exp $
.\"
.\" Copyright (c) 1996 The NetBSD Foundation, Inc.
@@ -28,7 +28,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd $Mdocdate: July 27 2015 $
+.Dd $Mdocdate: July 28 2015 $
.Dt AUDIO 4
.Os
.Sh NAME
@@ -129,6 +129,7 @@ commands are supported on the sample devices:
.Bl -tag -width Ds -compact
.It Dv AUDIO_RERROR Fa "int *"
.It Dv AUDIO_PERROR Fa "int *"
+Obsolete.
These commands fetch the count of dropped input or output samples into
the
.Vt int *
@@ -194,6 +195,7 @@ The device can set playing and recording channel counts independently.
.Pp
.It Dv AUDIO_GETIOFFS Fa "audio_offset_t *"
.It Dv AUDIO_GETOOFFS Fa "audio_offset_t *"
+Obsolete.
These commands fetch the number of bytes played or recorded.
The information is returned in the
.Vt audio_offset
@@ -332,6 +334,37 @@ if the pause value is specified it will either pause
or unpause the particular direction.
In full-duplex the pause values for both directions must
be equal.
+.Pp
+.It Dv AUDIO_GETPOS Fa "struct audio_pos *"
+Fetch an atomic snapshot of device timing information in the
+.Vt audio_pos
+structure.
+.Bd -literal
+struct audio_pos {
+ unsigned int play_pos; /* total bytes played */
+ unsigned int play_xrun; /* bytes of silence inserted */
+ unsigned int rec_pos; /* total bytes recorded */
+ unsigned int rec_xrun; /* bytes dropped */
+};
+.Ed
+.Pp
+The properties have the following meaning:
+.Bl -tag -width "play_xrun"
+.It Va play_pos
+Total number of bytes played by the device since playback started
+(a.k.a the device wall clock).
+.It Va play_xrun
+The number of bytes corresponding to silence played because
+.Xr write 2
+wasn't called fast enough.
+.It Va rec_pos
+Total number of bytes recorded by the device since recording started
+(a.k.a the device wall clock).
+.It Va rec_xrun
+The number of bytes dropped because
+.Xr read 2
+wasn't called fast enough.
+.El
.El
.Sh MIXER DEVICE
The
diff --git a/sys/dev/audio.c b/sys/dev/audio.c
index 8506f88b0ee..29550f2be88 100644
--- a/sys/dev/audio.c
+++ b/sys/dev/audio.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: audio.c,v 1.134 2015/07/24 08:56:45 ratchov Exp $ */
+/* $OpenBSD: audio.c,v 1.135 2015/07/28 20:45:02 ratchov Exp $ */
/*
* Copyright (c) 2015 Alexandre Ratchov <alex@caoua.org>
*
@@ -66,9 +66,9 @@ struct audio_buf {
size_t start; /* first byte used in the FIFO */
size_t used; /* bytes used in the FIFO */
size_t blksz; /* DMA block size */
- unsigned long pos; /* bytes transferred */
- unsigned long xrun; /* bytes lost by xruns */
struct selinfo sel; /* to record & wakeup poll(2) */
+ unsigned int pos; /* bytes transferred */
+ unsigned int xrun; /* bytes lost by xruns */
int blocking; /* read/write blocking */
};
@@ -1298,7 +1298,7 @@ audio_drain(struct audio_softc *sc)
xrun = sc->play.xrun;
while (sc->play.xrun == xrun) {
- DPRINTF("%s: drain: used = %zu, xrun = %ld\n",
+ DPRINTF("%s: drain: used = %zu, xrun = %d\n",
DEVNAME(sc), sc->play.used, sc->play.xrun);
/*
@@ -1486,6 +1486,7 @@ int
audio_ioctl(struct audio_softc *sc, unsigned long cmd, void *addr)
{
struct audio_offset *ao;
+ struct audio_pos *ap;
int error = 0, fd;
/* block if quiesced */
@@ -1518,6 +1519,15 @@ audio_ioctl(struct audio_softc *sc, unsigned long cmd, void *addr)
ao->samples = sc->rec.pos;
mtx_leave(&audio_lock);
break;
+ case AUDIO_GETPOS:
+ mtx_enter(&audio_lock);
+ ap = (struct audio_pos *)addr;
+ ap->play_pos = sc->play.pos;
+ ap->play_xrun = sc->play.xrun;
+ ap->rec_pos = sc->rec.pos;
+ ap->rec_xrun = sc->rec.xrun;
+ mtx_leave(&audio_lock);
+ break;
case AUDIO_SETINFO:
error = audio_setinfo(sc, (struct audio_info *)addr);
break;
diff --git a/sys/sys/audioio.h b/sys/sys/audioio.h
index afbdd7a7a19..f93c1c45e56 100644
--- a/sys/sys/audioio.h
+++ b/sys/sys/audioio.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: audioio.h,v 1.22 2015/06/25 06:43:46 ratchov Exp $ */
+/* $OpenBSD: audioio.h,v 1.23 2015/07/28 20:45:02 ratchov Exp $ */
/* $NetBSD: audioio.h,v 1.24 1998/08/13 06:28:41 mrg Exp $ */
/*
@@ -92,6 +92,13 @@ typedef struct audio_offset {
u_int unused[2];
} audio_offset_t;
+struct audio_pos {
+ unsigned int play_pos; /* total bytes played */
+ unsigned int play_xrun; /* bytes of silence inserted */
+ unsigned int rec_pos; /* total bytes recorded */
+ unsigned int rec_xrun; /* bytes dropped */
+};
+
/*
* Supported audio encodings
*/
@@ -141,6 +148,7 @@ typedef struct audio_encoding {
#define AUDIO_GETIOFFS _IOR('A', 32, struct audio_offset)
#define AUDIO_GETOOFFS _IOR('A', 33, struct audio_offset)
#define AUDIO_GETPROPS _IOR('A', 34, int)
+#define AUDIO_GETPOS _IOR('A', 35, struct audio_pos)
#define AUDIO_PROP_FULLDUPLEX 0x01
#define AUDIO_PROP_MMAP 0x02
#define AUDIO_PROP_INDEPENDENT 0x04