-.\" $OpenBSD: audioctl.8,v 1.4 2020/04/23 00:16:59 schwarze Exp $
+.\" $OpenBSD: audioctl.8,v 1.5 2023/01/08 06:58:07 ratchov Exp $
.\" $NetBSD: audioctl.1,v 1.7 1998/04/27 16:55:23 augustss Exp $
.\" Copyright (c) 1997 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd $Mdocdate: April 23 2020 $
+.Dd $Mdocdate: January 8 2023 $
.Dt AUDIOCTL 8
.Os
.Sh NAME
.Sh SYNOPSIS
.Nm audioctl
.Op Fl f Ar file
+.Op Fl w Ar wait
.Nm audioctl
.Op Fl n
.Op Fl f Ar file
+.Op Fl w Ar wait
.Ar name ...
.Nm audioctl
.Op Fl nq
Suppress printing of the variable name.
.It Fl q
Suppress all output when setting a variable.
+.It Fl w Ar wait
+Pause
+.Ar wait
+seconds between each display.
+.Nm
+will display variables forever.
.It Ar name Ns = Ns Ar value
Attempt to set the specified variable
.Ar name
audio devices
.El
.Sh EXAMPLES
-Display the number of bytes of silence inserted during play buffer
-underruns since device started:
+Once per-second, display the number of bytes of silence inserted due to buffer
+underruns (since the device started playback):
.Bd -literal -offset indent
-# audioctl play.errors
+# audioctl -w 1 play.errors
.Ed
.Pp
Use signed 24-bit samples and 44100Hz sample rate:
-/* $OpenBSD: audioctl.c,v 1.44 2022/12/26 19:16:00 jmc Exp $ */
+/* $OpenBSD: audioctl.c,v 1.45 2023/01/08 06:58:07 ratchov Exp $ */
/*
* Copyright (c) 2016 Alexandre Ratchov <alex@caoua.org>
*
#define STR 2
#define ENC 3
int type;
+ int show;
int set;
} fields[] = {
{"name", &rname.name, NULL, STR},
};
const char usagestr[] =
- "usage: audioctl [-f file]\n"
- " audioctl [-n] [-f file] name ...\n"
+ "usage: audioctl [-f file] [-w wait_sec]\n"
+ " audioctl [-n] [-f file] [-w wait_sec] name ...\n"
" audioctl [-nq] [-f file] name=value ...\n";
-int fd, show_names = 1, quiet = 0;
+int fd, show_names = 1, quiet = 0, wait_sec = 0;
/*
* parse encoding string (examples: s8, u8, s16, s16le, s24be ...)
char *lhs, *rhs;
int set = 0;
- if (ioctl(fd, AUDIO_GETSTATUS, &rstatus) == -1)
- err(1, "AUDIO_GETSTATUS");
- if (ioctl(fd, AUDIO_GETDEV, &rname) == -1)
- err(1, "AUDIO_GETDEV");
- if (ioctl(fd, AUDIO_GETPAR, &rpar) == -1)
- err(1, "AUDIO_GETPAR");
- if (ioctl(fd, AUDIO_GETPOS, &rpos) == -1)
- err(1, "AUDIO_GETPOS");
if (argc == 0) {
- for (f = fields; f->name != NULL; f++) {
- printf("%s=", f->name);
- print_field(f, f->raddr);
- printf("\n");
- }
+ for (f = fields; f->name != NULL; f++)
+ f->show = 1;
}
AUDIO_INITPAR(&wpar);
for (; argc > 0; argc--, argv++) {
parse_field(f, f->waddr, rhs);
f->set = 1;
set = 1;
- } else {
+ } else
+ f->show = 1;
+ }
+
+ if (set && wait_sec)
+ errx(1, "Can't set variables wait_secically");
+
+ while (1) {
+ if (ioctl(fd, AUDIO_GETSTATUS, &rstatus) == -1)
+ err(1, "AUDIO_GETSTATUS");
+ if (ioctl(fd, AUDIO_GETDEV, &rname) == -1)
+ err(1, "AUDIO_GETDEV");
+ if (ioctl(fd, AUDIO_GETPAR, &rpar) == -1)
+ err(1, "AUDIO_GETPAR");
+ if (ioctl(fd, AUDIO_GETPOS, &rpos) == -1)
+ err(1, "AUDIO_GETPOS");
+ for (f = fields; f->name != NULL; f++) {
+ if (!f->show)
+ continue;
if (show_names)
printf("%s=", f->name);
print_field(f, f->raddr);
printf("\n");
}
+
+ if (wait_sec == 0)
+ break;
+
+ /* ioctls are fast, we neglect drift from real-time clock */
+ sleep(wait_sec);
}
+
if (!set)
return;
+
if (ioctl(fd, AUDIO_SETPAR, &wpar) == -1)
err(1, "AUDIO_SETPAR");
if (ioctl(fd, AUDIO_GETPAR, &wpar) == -1)
main(int argc, char **argv)
{
char *path = "/dev/audioctl0";
+ const char *errstr;
int c;
- while ((c = getopt(argc, argv, "anf:q")) != -1) {
+ while ((c = getopt(argc, argv, "anf:qw:")) != -1) {
switch (c) {
case 'a': /* ignored, compat */
break;
case 'q':
quiet = 1;
break;
+ case 'w':
+ wait_sec = strtonum(optarg, 1, INT_MAX, &errstr);
+ if (errstr != NULL)
+ errx(1, "wait is %s: %s", errstr, optarg);
+ break;
default:
fputs(usagestr, stderr);
return 1;