diff options
author | Jacob Meuser <jakemsr@cvs.openbsd.org> | 2007-10-03 21:49:14 +0000 |
---|---|---|
committer | Jacob Meuser <jakemsr@cvs.openbsd.org> | 2007-10-03 21:49:14 +0000 |
commit | 54eeb77f25b00ad84144dbe0edc93b29171edd2f (patch) | |
tree | 6fef7b2dd89ffe730caeb77de1b38b046acb12f7 /regress | |
parent | 631319f76280aee009fa12421aaf29432592924a (diff) |
add two new audio ioctls, AUDIO_GETPRINFO and AUDIO_GETRRINFO, and the
data structure these ioctls use, audio_bufinfo.
these ioctls return information about the play and record buffers
into the audio_bufinfo structure.
these are being added to aid in porting non-native audio applications
and libraries, and to fix issues in our OSS audio emulation. these
ioctls exist only on OpenBSD and should not be used in code intended
for distribution.
ok ratchov
Diffstat (limited to 'regress')
-rw-r--r-- | regress/sys/dev/audio_rw/Makefile | 25 | ||||
-rw-r--r-- | regress/sys/dev/audio_rw/audiotest_rw.1 | 15 | ||||
-rw-r--r-- | regress/sys/dev/audio_rw/audiotest_rw.c | 61 |
3 files changed, 83 insertions, 18 deletions
diff --git a/regress/sys/dev/audio_rw/Makefile b/regress/sys/dev/audio_rw/Makefile index 944ea6d0485..441fbe9df00 100644 --- a/regress/sys/dev/audio_rw/Makefile +++ b/regress/sys/dev/audio_rw/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.2 2007/07/31 03:14:09 jakemsr Exp $ +# $OpenBSD: Makefile,v 1.3 2007/10/03 21:49:13 jakemsr Exp $ PROG= audiotest_rw CFLAGS+=-Wall -Wstrict-prototypes -Wmissing-prototypes @@ -12,17 +12,22 @@ REGRESS_TARGETS += run-regress-record REGRESS_TARGETS += run-regress-record-duplex REGRESS_TARGETS += run-regress-record-poll REGRESS_TARGETS += run-regress-record-select +REGRESS_TARGETS += run-regress-record-bufinfo REGRESS_TARGETS += run-regress-record-poll-duplex REGRESS_TARGETS += run-regress-record-select-duplex +REGRESS_TARGETS += run-regress-record-bufinfo-duplex REGRESS_TARGETS += run-regress-play REGRESS_TARGETS += run-regress-play-duplex REGRESS_TARGETS += run-regress-play-poll REGRESS_TARGETS += run-regress-play-select +REGRESS_TARGETS += run-regress-play-bufinfo REGRESS_TARGETS += run-regress-play-poll-duplex REGRESS_TARGETS += run-regress-play-select-duplex +REGRESS_TARGETS += run-regress-play-bufinfo-duplex REGRESS_TARGETS += run-regress-duplex REGRESS_TARGETS += run-regress-duplex-poll REGRESS_TARGETS += run-regress-duplex-select +REGRESS_TARGETS += run-regress-duplex-bufinfo .endif @@ -51,6 +56,10 @@ run-regress-record-select: ${PROG} ./audiotest_rw -o test.pcm -s ${OPTS} @test -s test.pcm || (echo "no output" && false) +run-regress-record-bufinfo: ${PROG} + ./audiotest_rw -o test.pcm -n ${OPTS} + @test -s test.pcm || (echo "no output" && false) + run-regress-record-poll-duplex: ${PROG} ./audiotest_rw -o test.pcm -p -d ${OPTS} @test -s test.pcm || (echo "no output" && false) @@ -59,6 +68,10 @@ run-regress-record-select-duplex: ${PROG} ./audiotest_rw -o test.pcm -s -d ${OPTS} @test -s test.pcm || (echo "no output" && false) +run-regress-record-bufinfo-duplex: ${PROG} + ./audiotest_rw -o test.pcm -n -d ${OPTS} + @test -s test.pcm || (echo "no output" && false) + # playing tests @@ -74,12 +87,18 @@ run-regress-play-poll: ${PROG} master.pcm run-regress-play-select: ${PROG} master.pcm ./audiotest_rw -i master.pcm -s ${OPTS} +run-regress-play-bufinfo: ${PROG} master.pcm + ./audiotest_rw -i master.pcm -n ${OPTS} + run-regress-play-poll-duplex: ${PROG} master.pcm ./audiotest_rw -i master.pcm -p -d ${OPTS} run-regress-play-select-duplex: ${PROG} master.pcm ./audiotest_rw -i master.pcm -s -d ${OPTS} +run-regress-play-bufinfo-duplex: ${PROG} master.pcm + ./audiotest_rw -i master.pcm -n -d ${OPTS} + # full-duplex tests @@ -95,5 +114,9 @@ run-regress-duplex-select: ${PROG} master.pcm ./audiotest_rw -i master.pcm -o test.pcm -s ${OPTS} @test -s test.pcm || (echo "no output" && false) +run-regress-duplex-bufinfo: ${PROG} master.pcm + ./audiotest_rw -i master.pcm -o test.pcm -n ${OPTS} + @test -s test.pcm || (echo "no output" && false) + .include <bsd.regress.mk> diff --git a/regress/sys/dev/audio_rw/audiotest_rw.1 b/regress/sys/dev/audio_rw/audiotest_rw.1 index 71caa0be349..dbfa3be03ee 100644 --- a/regress/sys/dev/audio_rw/audiotest_rw.1 +++ b/regress/sys/dev/audio_rw/audiotest_rw.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: audiotest_rw.1,v 1.4 2007/07/06 15:56:15 jmc Exp $ +.\" $OpenBSD: audiotest_rw.1,v 1.5 2007/10/03 21:49:13 jakemsr Exp $ .\" .\" Copyright (c) 2007 Jacob Meuser <jakemsr@sdf.lonestar.org> .\" @@ -15,7 +15,7 @@ .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" .\" -.Dd $Mdocdate: July 6 2007 $ +.Dd $Mdocdate: October 3 2007 $ .Dt AUDIOTEST_RW 1 .Os .Sh NAME @@ -24,7 +24,7 @@ .Sh SYNOPSIS .Nm audiotest_rw .Bk -words -.Op Fl dpsv +.Op Fl dnpsv .Op Fl b Ar buffersize .Op Fl c Ar channels .Op Fl e Ar encoding @@ -157,6 +157,15 @@ The file from which raw (headerless) audio data will be read. .It Fl l Ar loops The number of times to read and/or write. It defaults to 64. +.It Fl n +Use information about the play and record buffers as reported by the +.Dv AUDIO_GETPRINFO +and +.Dv AUDIO_GETRRINFO +ioctls to wait until data may be read without blocking on each +.Xr read 2 +and to wait until data may be written without blocking on each +.Xr write 2 . .It Fl o Ar output The file to which raw (headerless) audio data will be written. .It Fl p diff --git a/regress/sys/dev/audio_rw/audiotest_rw.c b/regress/sys/dev/audio_rw/audiotest_rw.c index 6595e5f9205..cae1abeae91 100644 --- a/regress/sys/dev/audio_rw/audiotest_rw.c +++ b/regress/sys/dev/audio_rw/audiotest_rw.c @@ -1,4 +1,4 @@ -/* $OpenBSD: audiotest_rw.c,v 1.6 2007/08/26 08:37:28 jakemsr Exp $ */ +/* $OpenBSD: audiotest_rw.c,v 1.7 2007/10/03 21:49:13 jakemsr Exp $ */ /* * Copyright (c) 2007 Jacob Meuser <jakemsr@sdf.lonestar.org> @@ -37,9 +37,9 @@ void useage(void); int audio_set_duplex(int, char *, int); int audio_set_info(int, u_int, u_int, u_int, u_int, u_int); int audio_trigger_record(int); -int audio_wait_frame(int, u_int, int, int); -int audio_do_frame(int, size_t , char *, char *, u_int, int, int); -int audio_do_test(int, size_t, char *, char *, u_int, int, int, int, int); +int audio_wait_frame(int, size_t, u_int, int, int, int); +int audio_do_frame(int, size_t , char *, char *, u_int, int, int, int); +int audio_do_test(int, size_t, char *, char *, u_int, int, int, int, int, int); void useage(void) @@ -206,8 +206,10 @@ audio_info_t audio_if; /* return 0 on error, 1 if read, 2 if write, 3 if both read and write */ int -audio_wait_frame(int audio_fd, u_int mode, int use_select, int use_poll) +audio_wait_frame(int audio_fd, size_t buffer_size, u_int mode, int use_select, + int use_poll, int use_bufinfo) { +struct audio_bufinfo ab; struct pollfd pfd[1]; fd_set *sfdsr; fd_set *sfdsw; @@ -280,6 +282,29 @@ int ret; if (mode & AUMODE_PLAY) if (pfd[0].revents & POLLOUT) ret |= 2; + } else if (use_bufinfo) { +retry: + if (mode & AUMODE_RECORD) { + if (ioctl(audio_fd, AUDIO_GETRRINFO, &ab) < 0) { + warn("AUDIO_GETRRINFO"); + return 0; + } + if (ab.seek > buffer_size) + ret |= 1; + } + if (mode & AUMODE_PLAY) { + if (ioctl(audio_fd, AUDIO_GETPRINFO, &ab) < 0) { + warn("AUDIO_GETPRINFO"); + return 0; + } + if (ab.hiwat * ab.blksize - ab.seek > buffer_size) + ret |= 2; + } + if (ret == 0) { + /* 1/100th of a second */ + usleep(100000); + goto retry; + } } else { if (mode & AUMODE_RECORD) ret |= 1; @@ -294,14 +319,15 @@ int ret; /* return 0 on error, 1 if read, 2 if write, 3 if both read and write */ int audio_do_frame(int audio_fd, size_t buffer_size, char *rbuffer, char *wbuffer, - u_int mode, int use_poll, int use_select) + u_int mode, int use_poll, int use_select, int use_bufinfo) { size_t offset; size_t left; ssize_t retval; int ret; - ret = audio_wait_frame(audio_fd, mode, use_select, use_poll); + ret = audio_wait_frame(audio_fd, buffer_size, mode, use_select, + use_poll, use_bufinfo); if (ret == 0) return 0; @@ -348,8 +374,9 @@ int ret; int -audio_do_test(int audio_fd, size_t buffer_size, char *input_file, char *output_file, - u_int mode, int use_poll, int use_select, int loops, int verbose) +audio_do_test(int audio_fd, size_t buffer_size, char *input_file, + char *output_file, u_int mode, int use_poll, int use_select, + int use_bufinfo, int loops, int verbose) { FILE *fout; FILE *fin; @@ -388,7 +415,7 @@ int i, ret; } for (i = 1; mode && i <= loops; i++) { ret = audio_do_frame(audio_fd, buffer_size, rbuffer, - wbuffer, mode, use_poll, use_select); + wbuffer, mode, use_poll, use_select, use_bufinfo); if (ret == 0) return 1; if (ret & 1) { @@ -454,6 +481,7 @@ int use_duplex; int use_nonblock; int use_poll; int use_select; +int use_bufinfo; int verbose; int loops; @@ -481,10 +509,11 @@ extern int optind; use_nonblock = 0; use_select = 0; use_poll = 0; + use_bufinfo = 0; use_duplex = 0; verbose = 0; - while ((ch = getopt(argc, argv, "b:c:e:f:i:l:o:r:dpsv")) != -1) { + while ((ch = getopt(argc, argv, "b:c:e:f:i:l:o:r:dnpsv")) != -1) { switch (ch) { case 'b': buffer_size = (size_t)strtonum(optarg, 32, 65536, &errstr); @@ -515,6 +544,9 @@ extern int optind; if (errstr != NULL) errx(1, "could not grok loops: %s", errstr); break; + case 'n': + use_bufinfo = 1; + break; case 'o': output_file = optarg; break; @@ -543,8 +575,8 @@ extern int optind; argc -= optind; argv += optind; - if (use_select && use_poll) - errx(1, "can't use select and poll at the same time"); + if (use_select + use_poll + use_bufinfo > 1) + errx(1, "can only use one of select, poll or buffer info"); if ((input_file == NULL) && (output_file == NULL)) errx(1, "no input or output file specified"); @@ -607,6 +639,7 @@ extern int optind; warnx("channels: %u", channels); warnx("use_select: %d", use_select); warnx("use_poll: %d", use_poll); + warnx("use_bufinfo: %d", use_bufinfo); warnx("use_duplex: %d", use_duplex); warnx("buffer_size: %lu", (unsigned long)buffer_size); } @@ -617,7 +650,7 @@ extern int optind; exit(1); if (audio_do_test(audio_fd, buffer_size, input_file, output_file, - mode, use_poll, use_select, loops, verbose)) + mode, use_poll, use_select, use_bufinfo, loops, verbose)) exit(1); if (verbose) |