Re: audioctl: display variables periodically
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
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
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
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
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
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
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':