Re: audioctl: display variables periodically

2023-01-03 Thread Alexandre Ratchov
On Sat, Dec 10, 2022 at 09:39:41AM +, Edd Barrett wrote:
> I agree with ratchov that in this instance, precise timing isn't important.
> 

So, are we OK with this or there are still objections?



Re: audioctl: display variables periodically

2022-12-10 Thread Edd Barrett
I agree with ratchov that in this instance, precise timing isn't important.

10 Dec 2022 05:53:48 Alexandre Ratchov :

> On Fri, Dec 09, 2022 at 12:43:31PM -0600, Scott Cheloha wrote:
>> On Fri, Dec 09, 2022 at 12:10:59PM +0100, Alexandre Ratchov wrote:
>>> This diff adds an option to display variables periodically. Basically
>>> it replaces this usage:
>>> 
>>>     while sleep 1; do audioctl play.errors; done
>>> 
>>> by
>>> 
>>>     audioctl -w 1 play.errors
>>> 
>>> The purpose of above audioctl commands is to debug underruns, so we
>>> don't want to fork a new process and reopen the device. This would
>>> trigger longer kernel code-paths and may cause additional underruns
>>> than the ones being investigated.
>>> 
>>> OK?
>> 
>> I like the idea, but I would like to tweak some things.
>> 
>> - Add [-w wait] to the first synoptic form in the manpage.  It's legal
>>   to do e.g.
>> 
>>     # audioctl -w 1
>> 
> 
> done
> 
>> - Call the variable "wait" in audioctl.c to match the manpage.
>> 
> 
> done (used wait_sec, as there's a global wait() symbol).
> 
>> - Update usagestr to mention [-w wait].
>> 
> 
> done
> 
>> - When polling variables periodically, it's better to use setitimer(2)
>>   and sigsuspend(2) instead of sleep(3).  setitimer(2) keeps the period
>>   from drifting.
>> 
>> - Let the user SIGINT (^C) out of the program without returning an
>>   error to the shell.
>> 
>>   I'm unsure about this one, but it seems logical to give the user a
>>   way to gracefully terminate the program.  You say in the manpage that
>>   the program will continue printing until it is interrupted.
>> 
> 
> I just tried these. Synchronizing the display to a clock might make
> sense if it was the sound card's clock, but here the result was boiler
> with no benefit. The intent of -w is to just show the variables from
> time to time, so keeping the code trivial is more important,
> IMHO. I've added a comment to say so.
> 
> About ^C, I've changed the man page text to "audioctl will display
> variables forever." which implies that ^C is out of the scope.
> 
> Index: audioctl.8
> ===
> RCS file: /cvs/src/usr.bin/audioctl/audioctl.8,v
> retrieving revision 1.4
> diff -u -p -r1.4 audioctl.8
> --- audioctl.8  23 Apr 2020 00:16:59 -  1.4
> +++ audioctl.8  10 Dec 2022 05:50:05 -
> @@ -35,9 +35,11 @@
> .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
> @@ -59,6 +61,12 @@ The default is
> 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
> @@ -130,10 +138,10 @@ audio control devices
> 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:
> Index: audioctl.c
> ===
> RCS file: /cvs/src/usr.bin/audioctl/audioctl.c,v
> retrieving revision 1.43
> diff -u -p -r1.43 audioctl.c
> --- audioctl.c  12 Jul 2021 15:09:19 -  1.43
> +++ audioctl.c  10 Dec 2022 05:50:05 -
> @@ -43,6 +43,7 @@ struct field {
> #define STR    2
> #define ENC    3
>     int type;
> +   int show;
>     int set;
> } fields[] = {
>     {"name",    ,    NULL,   STR},
> @@ -63,11 +64,11 @@ struct field {
> };
> 
> 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 ...)
> @@ -198,20 +199,9 @@ audio_main(int argc, char **argv)
>     char *lhs, *rhs;
>     int set = 0;
> 
> -   if (ioctl(fd, AUDIO_GETSTATUS, ) == -1)
> -   err(1, "AUDIO_GETSTATUS");
> -   if (ioctl(fd, AUDIO_GETDEV, ) == -1)
> -   err(1, "AUDIO_GETDEV");
> -   if (ioctl(fd, AUDIO_GETPAR, ) == -1)
> -   err(1, "AUDIO_GETPAR");
> -   if (ioctl(fd, AUDIO_GETPOS, ) == -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; 

Re: audioctl: display variables periodically

2022-12-09 Thread Alexandre Ratchov
On Fri, Dec 09, 2022 at 12:43:31PM -0600, Scott Cheloha wrote:
> On Fri, Dec 09, 2022 at 12:10:59PM +0100, Alexandre Ratchov wrote:
> > This diff adds an option to display variables periodically. Basically
> > it replaces this usage:
> > 
> > while sleep 1; do audioctl play.errors; done
> > 
> > by
> > 
> > audioctl -w 1 play.errors
> > 
> > The purpose of above audioctl commands is to debug underruns, so we
> > don't want to fork a new process and reopen the device. This would
> > trigger longer kernel code-paths and may cause additional underruns
> > than the ones being investigated.
> > 
> > OK?
> 
> I like the idea, but I would like to tweak some things.
> 
> - Add [-w wait] to the first synoptic form in the manpage.  It's legal
>   to do e.g.
> 
>   # audioctl -w 1
> 

done

> - Call the variable "wait" in audioctl.c to match the manpage.
>

done (used wait_sec, as there's a global wait() symbol).

> - Update usagestr to mention [-w wait].
>

done

> - When polling variables periodically, it's better to use setitimer(2)
>   and sigsuspend(2) instead of sleep(3).  setitimer(2) keeps the period
>   from drifting.
> 
> - Let the user SIGINT (^C) out of the program without returning an
>   error to the shell.
> 
>   I'm unsure about this one, but it seems logical to give the user a
>   way to gracefully terminate the program.  You say in the manpage that
>   the program will continue printing until it is interrupted.
> 

I just tried these. Synchronizing the display to a clock might make
sense if it was the sound card's clock, but here the result was boiler
with no benefit. The intent of -w is to just show the variables from
time to time, so keeping the code trivial is more important,
IMHO. I've added a comment to say so.

About ^C, I've changed the man page text to "audioctl will display
variables forever." which implies that ^C is out of the scope.

Index: audioctl.8
===
RCS file: /cvs/src/usr.bin/audioctl/audioctl.8,v
retrieving revision 1.4
diff -u -p -r1.4 audioctl.8
--- audioctl.8  23 Apr 2020 00:16:59 -  1.4
+++ audioctl.8  10 Dec 2022 05:50:05 -
@@ -35,9 +35,11 @@
 .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
@@ -59,6 +61,12 @@ The default is
 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
@@ -130,10 +138,10 @@ audio control devices
 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:
Index: audioctl.c
===
RCS file: /cvs/src/usr.bin/audioctl/audioctl.c,v
retrieving revision 1.43
diff -u -p -r1.43 audioctl.c
--- audioctl.c  12 Jul 2021 15:09:19 -  1.43
+++ audioctl.c  10 Dec 2022 05:50:05 -
@@ -43,6 +43,7 @@ struct field {
 #define STR2
 #define ENC3
int type;
+   int show;
int set;
 } fields[] = {
{"name",,NULL,   STR},
@@ -63,11 +64,11 @@ struct field {
 };
 
 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 ...)
@@ -198,20 +199,9 @@ audio_main(int argc, char **argv)
char *lhs, *rhs;
int set = 0;
 
-   if (ioctl(fd, AUDIO_GETSTATUS, ) == -1)
-   err(1, "AUDIO_GETSTATUS");
-   if (ioctl(fd, AUDIO_GETDEV, ) == -1)
-   err(1, "AUDIO_GETDEV");
-   if (ioctl(fd, AUDIO_GETPAR, ) == -1)
-   err(1, "AUDIO_GETPAR");
-   if (ioctl(fd, AUDIO_GETPOS, ) == -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();
for (; argc > 0; argc--, argv++) {
@@ -231,15 +221,41 @@ 

Re: audioctl: display variables periodically

2022-12-09 Thread Scott Cheloha
On Fri, Dec 09, 2022 at 12:10:59PM +0100, Alexandre Ratchov wrote:
> This diff adds an option to display variables periodically. Basically
> it replaces this usage:
> 
>   while sleep 1; do audioctl play.errors; done
> 
> by
> 
>   audioctl -w 1 play.errors
> 
> The purpose of above audioctl commands is to debug underruns, so we
> don't want to fork a new process and reopen the device. This would
> trigger longer kernel code-paths and may cause additional underruns
> than the ones being investigated.
> 
> OK?

I like the idea, but I would like to tweak some things.

- Add [-w wait] to the first synoptic form in the manpage.  It's legal
  to do e.g.

# audioctl -w 1

- Call the variable "wait" in audioctl.c to match the manpage.

- Update usagestr to mention [-w wait].

- When polling variables periodically, it's better to use setitimer(2)
  and sigsuspend(2) instead of sleep(3).  setitimer(2) keeps the period
  from drifting.

- Let the user SIGINT (^C) out of the program without returning an
  error to the shell.

  I'm unsure about this one, but it seems logical to give the user a
  way to gracefully terminate the program.  You say in the manpage that
  the program will continue printing until it is interrupted.

Index: audioctl.8
===
RCS file: /cvs/src/usr.bin/audioctl/audioctl.8,v
retrieving revision 1.4
diff -u -p -r1.4 audioctl.8
--- audioctl.8  23 Apr 2020 00:16:59 -  1.4
+++ audioctl.8  9 Dec 2022 18:41:45 -
@@ -35,8 +35,10 @@
 .Sh SYNOPSIS
 .Nm audioctl
 .Op Fl f Ar file
+.Op Fl w wait
 .Nm audioctl
 .Op Fl n
+.Op Fl w wait
 .Op Fl f Ar file
 .Ar name ...
 .Nm audioctl
@@ -59,6 +61,12 @@ The default is
 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 until it is interrupted.
 .It Ar name Ns = Ns Ar value
 Attempt to set the specified variable
 .Ar name
@@ -130,10 +138,10 @@ audio control devices
 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
+during play buffer underruns since device started:
 .Bd -literal -offset indent
-# audioctl play.errors
+# audioctl -w 1 play.errors
 .Ed
 .Pp
 Use signed 24-bit samples and 44100Hz sample rate:
Index: audioctl.c
===
RCS file: /cvs/src/usr.bin/audioctl/audioctl.c,v
retrieving revision 1.43
diff -u -p -r1.43 audioctl.c
--- audioctl.c  12 Jul 2021 15:09:19 -  1.43
+++ audioctl.c  9 Dec 2022 18:41:45 -
@@ -16,9 +16,11 @@
  */
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -43,6 +45,7 @@ struct field {
 #define STR2
 #define ENC3
int type;
+   int show;
int set;
 } fields[] = {
{"name",,NULL,   STR},
@@ -63,11 +66,24 @@ struct field {
 };
 
 const char usagestr[] =
-   "usage: audioctl [-f file]\n"
-   "   audioctl [-n] [-f file] name ...\n"
+   "usage: audioctl [-f file] [-w wait]\n"
+   "   audioctl [-n] [-f file] [-w wait] name ...\n"
"   audioctl [-nq] [-f file] name=value ...\n";
 
 int fd, show_names = 1, quiet = 0;
+unsigned int wait;
+volatile sig_atomic_t uninterrupted = 1;
+
+void
+handle_alrm(int signo)
+{
+}
+
+void
+handle_int(int signo)
+{
+   uninterrupted = 0;
+}
 
 /*
  * parse encoding string (examples: s8, u8, s16, s16le, s24be ...)
@@ -194,24 +210,15 @@ parse_field(struct field *f, void *addr,
 void
 audio_main(int argc, char **argv)
 {
+   struct itimerval itv;
struct field *f;
char *lhs, *rhs;
+   sigset_t empty;
int set = 0;
 
-   if (ioctl(fd, AUDIO_GETSTATUS, ) == -1)
-   err(1, "AUDIO_GETSTATUS");
-   if (ioctl(fd, AUDIO_GETDEV, ) == -1)
-   err(1, "AUDIO_GETDEV");
-   if (ioctl(fd, AUDIO_GETPAR, ) == -1)
-   err(1, "AUDIO_GETPAR");
-   if (ioctl(fd, AUDIO_GETPOS, ) == -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();
for (; argc > 0; argc--, argv++) {
@@ -231,15 +238,51 @@ audio_main(int argc, char **argv)
parse_field(f, f->waddr, rhs);
f->set = 1;
set = 1;
-   } else {
+   } else
+   f->show = 1;
+   }
+
+   if (set && wait)
+   

Re: audioctl: display variables periodically

2022-12-09 Thread Alexandre Ratchov
On Fri, Dec 09, 2022 at 04:24:03PM +, Edd Barrett wrote:
> On Fri, Dec 09, 2022 at 12:10:59PM +0100, Alexandre Ratchov wrote:
> > -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
> > +during play buffer underruns since device started:
> 
> Would it read better as:
> 
> "Once per-second, display the number of bytes of silence inserted due to 
> buffer
> underruns (since the device started playback):"
> 
> And don't forget to update the usage message too :)
> 

Thanks. New diff, with above suggestions plus the fix for the missing
Ar tag in the synopsis.

Index: audioctl.8
===
RCS file: /cvs/src/usr.bin/audioctl/audioctl.8,v
retrieving revision 1.4
diff -u -p -u -p -r1.4 audioctl.8
--- audioctl.8  23 Apr 2020 00:16:59 -  1.4
+++ audioctl.8  9 Dec 2022 17:40:21 -
@@ -37,6 +37,7 @@
 .Op Fl f Ar file
 .Nm audioctl
 .Op Fl n
+.Op Fl w Ar wait
 .Op Fl f Ar file
 .Ar name ...
 .Nm audioctl
@@ -59,6 +60,12 @@ The default is
 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 until it is interrupted.
 .It Ar name Ns = Ns Ar value
 Attempt to set the specified variable
 .Ar name
@@ -130,10 +137,10 @@ audio control devices
 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:
Index: audioctl.c
===
RCS file: /cvs/src/usr.bin/audioctl/audioctl.c,v
retrieving revision 1.43
diff -u -p -u -p -r1.43 audioctl.c
--- audioctl.c  12 Jul 2021 15:09:19 -  1.43
+++ audioctl.c  9 Dec 2022 17:40:21 -
@@ -43,6 +43,7 @@ struct field {
 #define STR2
 #define ENC3
int type;
+   int show;
int set;
 } fields[] = {
{"name",,NULL,   STR},
@@ -64,10 +65,10 @@ struct field {
 
 const char usagestr[] =
"usage: audioctl [-f file]\n"
-   "   audioctl [-n] [-f file] name ...\n"
+   "   audioctl [-n] [-w wait] [-f file] name ...\n"
"   audioctl [-nq] [-f file] name=value ...\n";
 
-int fd, show_names = 1, quiet = 0;
+int fd, show_names = 1, quiet = 0, period = 0;
 
 /*
  * parse encoding string (examples: s8, u8, s16, s16le, s24be ...)
@@ -198,20 +199,9 @@ audio_main(int argc, char **argv)
char *lhs, *rhs;
int set = 0;
 
-   if (ioctl(fd, AUDIO_GETSTATUS, ) == -1)
-   err(1, "AUDIO_GETSTATUS");
-   if (ioctl(fd, AUDIO_GETDEV, ) == -1)
-   err(1, "AUDIO_GETDEV");
-   if (ioctl(fd, AUDIO_GETPAR, ) == -1)
-   err(1, "AUDIO_GETPAR");
-   if (ioctl(fd, AUDIO_GETPOS, ) == -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();
for (; argc > 0; argc--, argv++) {
@@ -231,15 +221,38 @@ audio_main(int argc, char **argv)
parse_field(f, f->waddr, rhs);
f->set = 1;
set = 1;
-   } else {
+   } else
+   f->show = 1;
+   }
+
+   if (set && period)
+   errx(1, "Can't set variables periodically");
+
+   while (1) {
+   if (ioctl(fd, AUDIO_GETSTATUS, ) == -1)
+   err(1, "AUDIO_GETSTATUS");
+   if (ioctl(fd, AUDIO_GETDEV, ) == -1)
+   err(1, "AUDIO_GETDEV");
+   if (ioctl(fd, AUDIO_GETPAR, ) == -1)
+   err(1, "AUDIO_GETPAR");
+   if (ioctl(fd, AUDIO_GETPOS, ) == -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 (period == 0)
+   break;
+   sleep(period);
}
+
if (!set)
return;
+
if (ioctl(fd, AUDIO_SETPAR, ) == -1)
  

Re: audioctl: display variables periodically

2022-12-09 Thread Edd Barrett
On Fri, Dec 09, 2022 at 12:10:59PM +0100, Alexandre Ratchov wrote:
> -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
> +during play buffer underruns since device started:

Would it read better as:

"Once per-second, display the number of bytes of silence inserted due to buffer
underruns (since the device started playback):"

And don't forget to update the usage message too :)

-- 
Best Regards
Edd Barrett

https://www.theunixzoo.co.uk



audioctl: display variables periodically

2022-12-09 Thread Alexandre Ratchov
This diff adds an option to display variables periodically. Basically
it replaces this usage:

while sleep 1; do audioctl play.errors; done

by

audioctl -w 1 play.errors

The purpose of above audioctl commands is to debug underruns, so we
don't want to fork a new process and reopen the device. This would
trigger longer kernel code-paths and may cause additional underruns
than the ones being investigated.

OK?

Index: audioctl.8
===
RCS file: /cvs/src/usr.bin/audioctl/audioctl.8,v
retrieving revision 1.4
diff -u -p -r1.4 audioctl.8
--- audioctl.8  23 Apr 2020 00:16:59 -  1.4
+++ audioctl.8  9 Dec 2022 10:57:05 -
@@ -37,6 +37,7 @@
 .Op Fl f Ar file
 .Nm audioctl
 .Op Fl n
+.Op Fl w wait
 .Op Fl f Ar file
 .Ar name ...
 .Nm audioctl
@@ -59,6 +60,12 @@ The default is
 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 until it is interrupted.
 .It Ar name Ns = Ns Ar value
 Attempt to set the specified variable
 .Ar name
@@ -130,10 +137,10 @@ audio control devices
 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
+during play buffer underruns since device started:
 .Bd -literal -offset indent
-# audioctl play.errors
+# audioctl -w 1 play.errors
 .Ed
 .Pp
 Use signed 24-bit samples and 44100Hz sample rate:
Index: audioctl.c
===
RCS file: /cvs/src/usr.bin/audioctl/audioctl.c,v
retrieving revision 1.43
diff -u -p -r1.43 audioctl.c
--- audioctl.c  12 Jul 2021 15:09:19 -  1.43
+++ audioctl.c  9 Dec 2022 10:57:05 -
@@ -43,6 +43,7 @@ struct field {
 #define STR2
 #define ENC3
int type;
+   int show;
int set;
 } fields[] = {
{"name",,NULL,   STR},
@@ -67,7 +68,7 @@ const char usagestr[] =
"   audioctl [-n] [-f file] name ...\n"
"   audioctl [-nq] [-f file] name=value ...\n";
 
-int fd, show_names = 1, quiet = 0;
+int fd, show_names = 1, quiet = 0, period = 0;
 
 /*
  * parse encoding string (examples: s8, u8, s16, s16le, s24be ...)
@@ -198,20 +199,9 @@ audio_main(int argc, char **argv)
char *lhs, *rhs;
int set = 0;
 
-   if (ioctl(fd, AUDIO_GETSTATUS, ) == -1)
-   err(1, "AUDIO_GETSTATUS");
-   if (ioctl(fd, AUDIO_GETDEV, ) == -1)
-   err(1, "AUDIO_GETDEV");
-   if (ioctl(fd, AUDIO_GETPAR, ) == -1)
-   err(1, "AUDIO_GETPAR");
-   if (ioctl(fd, AUDIO_GETPOS, ) == -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();
for (; argc > 0; argc--, argv++) {
@@ -231,15 +221,38 @@ audio_main(int argc, char **argv)
parse_field(f, f->waddr, rhs);
f->set = 1;
set = 1;
-   } else {
+   } else
+   f->show = 1;
+   }
+
+   if (set && period)
+   errx(1, "Can't set variables periodically");
+
+   while (1) {
+   if (ioctl(fd, AUDIO_GETSTATUS, ) == -1)
+   err(1, "AUDIO_GETSTATUS");
+   if (ioctl(fd, AUDIO_GETDEV, ) == -1)
+   err(1, "AUDIO_GETDEV");
+   if (ioctl(fd, AUDIO_GETPAR, ) == -1)
+   err(1, "AUDIO_GETPAR");
+   if (ioctl(fd, AUDIO_GETPOS, ) == -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 (period == 0)
+   break;
+   sleep(period);
}
+
if (!set)
return;
+
if (ioctl(fd, AUDIO_SETPAR, ) == -1)
err(1, "AUDIO_SETPAR");
if (ioctl(fd, AUDIO_GETPAR, ) == -1)
@@ -261,9 +274,10 @@ int
 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':