diff options
author | Alexandre Ratchov <ratchov@cvs.openbsd.org> | 2015-07-28 20:45:03 +0000 |
---|---|---|
committer | Alexandre Ratchov <ratchov@cvs.openbsd.org> | 2015-07-28 20:45:03 +0000 |
commit | c3bbe3df2251d73b764b62936861513c64399db7 (patch) | |
tree | bac685f9086c2d03ce61eea79ae7f6e31f70dccc | |
parent | 17682997ea03cb4ca482d8a4d16de1c373425bcd (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.4 | 37 | ||||
-rw-r--r-- | sys/dev/audio.c | 18 | ||||
-rw-r--r-- | sys/sys/audioio.h | 10 |
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 |