Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/tests/dev/audio tests: Add tests for AUDIO_GET[IO]OFFS ioctls.



details:   https://anonhg.NetBSD.org/src/rev/d856420df14c
branches:  trunk
changeset: 365750:d856420df14c
user:      isaki <isaki%NetBSD.org@localhost>
date:      Sat Apr 23 07:47:42 2022 +0000

description:
tests: Add tests for AUDIO_GET[IO]OFFS ioctls.
- AUDIO_GETIOFFS_one_{RDONLY,RDWR,WRONLY}
- AUDIO_GETOOFFS_one_{RDONLY,RDWR,WRONLY}
- AUDIO_GETOOFFS_wrap_{RDONLY,RDWR,WRONLY}
- AUDIO_GETOOFFS_flush_{RDONLY,RDWR,WRONLY}
- AUDIO_GETOOFFS_set_{RDONLY,RDWR,WRONLY}

diffstat:

 tests/dev/audio/audiotest.c |  571 +++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 569 insertions(+), 2 deletions(-)

diffs (truncated from 606 to 300 lines):

diff -r 9be759540864 -r d856420df14c tests/dev/audio/audiotest.c
--- a/tests/dev/audio/audiotest.c       Sat Apr 23 07:43:16 2022 +0000
+++ b/tests/dev/audio/audiotest.c       Sat Apr 23 07:47:42 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: audiotest.c,v 1.18 2021/12/10 20:36:05 andvar Exp $    */
+/*     $NetBSD: audiotest.c,v 1.19 2022/04/23 07:47:42 isaki Exp $     */
 
 /*
  * Copyright (C) 2019 Tetsuya Isaki. All rights reserved.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: audiotest.c,v 1.18 2021/12/10 20:36:05 andvar Exp $");
+__RCSID("$NetBSD: audiotest.c,v 1.19 2022/04/23 07:47:42 isaki Exp $");
 
 #include <errno.h>
 #include <fcntl.h>
@@ -1395,6 +1395,11 @@
 void xp_getenc(int[][5], int, int, int, struct audio_prinfo *);
 void getenc_check_encodings(int, int[][5]);
 void test_AUDIO_ERROR(int);
+void test_AUDIO_GETIOFFS_one(int);
+void test_AUDIO_GETOOFFS_one(int);
+void test_AUDIO_GETOOFFS_wrap(int);
+void test_AUDIO_GETOOFFS_flush(int);
+void test_AUDIO_GETOOFFS_set(int);
 void test_audioctl_open_1(int, int);
 void test_audioctl_open_2(int, int);
 void try_audioctl_open_multiuser(const char *, const char *);
@@ -6175,6 +6180,553 @@
 DEF(AUDIO_ERROR_RDWR)  { test_AUDIO_ERROR(O_RDWR); }
 
 /*
+ * AUDIO_GETIOFFS at least one block.
+ */
+void
+test_AUDIO_GETIOFFS_one(int openmode)
+{
+       struct audio_info ai;
+       audio_offset_t o;
+       int fd;
+       int r;
+       u_int blocksize;
+       u_int blk_ms;
+
+       TEST("AUDIO_GETIOFFS_one_%s", openmode_str[openmode] + 2);
+       if (mode2aumode(openmode) == 0) {
+               XP_SKIP("Operation not allowed on this hardware property");
+               return;
+       }
+
+       fd = OPEN(devaudio, openmode);
+       REQUIRED_SYS_OK(fd);
+
+#if 0
+       /*
+        * On NetBSD7/8, native encodings and emulated encodings behave
+        * differently.  But it's hard to identify which encoding is native.
+        * If you try other encodings, edit these parameters manually.
+        */
+       AUDIO_INITINFO(&ai);
+       ai.record.encoding = AUDIO_ENCODING_SLINEAR_NE;
+       ai.record.precision = 16;
+       ai.record.channels = 2;
+       ai.record.sample_rate = 48000;
+       /* ai.blocksize is shared by play and record, so set both the same. */
+       *ai.play = *ai.record;
+       r = IOCTL(fd, AUDIO_SETINFO, &ai, "");
+       REQUIRED_SYS_EQ(0, r);
+#endif
+
+       /* Get blocksize to calc blk_ms. */
+       r = IOCTL(fd, AUDIO_GETBUFINFO, &ai, "");
+       REQUIRED_SYS_EQ(0, r);
+       blocksize = ai.blocksize;
+       if (netbsd < 9) {
+               blk_ms = 0;
+       } else {
+               /* On NetBSD9, blocktime can always be calculated. */
+               blk_ms = blocksize * 1000 /
+                   (ai.play.precision / 8 * ai.play.channels *
+                    ai.play.sample_rate);
+       }
+       if (blk_ms == 0)
+               blk_ms = 50;
+       DPRINTF("  > blocksize=%u, estimated blk_ms=%u\n", blocksize, blk_ms);
+
+       /*
+        * Even when just opened, recording counters will start.
+        * Wait a moment, about one block time.
+        */
+       usleep(blk_ms * 1000);
+
+       r = IOCTL(fd, AUDIO_GETIOFFS, &o, "");
+       XP_SYS_EQ(0, r);
+       if (mode2rec(openmode)) {
+               /*
+                * It's difficult to know exact values.
+                * But at least these should not be zero.
+                */
+               DPRINTF("  > %d: samples=%u deltablks=%u offset=%u\n",
+                   __LINE__, o.samples, o.deltablks, o.offset);
+               XP_NE(0, o.samples);
+               XP_NE(0, o.deltablks);
+               XP_NE(0, o.offset);
+       } else {
+               /* All are zero on playback track. */
+               XP_EQ(0, o.samples);
+               XP_EQ(0, o.deltablks);
+               XP_EQ(0, o.offset);
+       }
+
+       r = CLOSE(fd);
+       XP_SYS_EQ(0, r);
+}
+DEF(AUDIO_GETIOFFS_one_RDONLY) { test_AUDIO_GETIOFFS_one(O_RDONLY); }
+DEF(AUDIO_GETIOFFS_one_WRONLY) { test_AUDIO_GETIOFFS_one(O_WRONLY); }
+DEF(AUDIO_GETIOFFS_one_RDWR)   { test_AUDIO_GETIOFFS_one(O_RDWR); }
+
+/*
+ * AUDIO_GETOOFFS for one block.
+ */
+void
+test_AUDIO_GETOOFFS_one(int openmode)
+{
+       struct audio_info ai;
+       audio_offset_t o;
+       char *buf;
+       int fd;
+       int r;
+       u_int blocksize;
+       u_int initial_offset;
+       u_int blk_ms;
+
+       TEST("AUDIO_GETOOFFS_one_%s", openmode_str[openmode] + 2);
+       if (mode2aumode(openmode) == 0) {
+               XP_SKIP("Operation not allowed on this hardware property");
+               return;
+       }
+
+       fd = OPEN(devaudio, openmode);
+       REQUIRED_SYS_OK(fd);
+
+#if 0
+       /*
+        * On NetBSD7/8, native encodings and emulated encodings behave
+        * differently.  But it's hard to identify which encoding is native.
+        * If you try other encodings, edit these parameters manually.
+        */
+       AUDIO_INITINFO(&ai);
+       ai.play.encoding = AUDIO_ENCODING_SLINEAR_NE;
+       ai.play.precision = 16;
+       ai.play.channels = 2;
+       ai.play.sample_rate = 48000;
+       /* ai.blocksize is shared by play and record, so set both the same. */
+       *ai.record = *ai.play;
+       r = IOCTL(fd, AUDIO_SETINFO, &ai, "slinear16/2ch/48000");
+       REQUIRED_SYS_EQ(0, r);
+#endif
+
+       /* Get blocksize to calc blk_ms. */
+       r = IOCTL(fd, AUDIO_GETBUFINFO, &ai, "");
+       REQUIRED_SYS_EQ(0, r);
+       blocksize = ai.blocksize;
+       if (netbsd < 9) {
+               blk_ms = 0;
+       } else {
+               /* On NetBSD9, blocktime can always be calculated. */
+               blk_ms = blocksize * 1000 /
+                   (ai.play.precision / 8 * ai.play.channels *
+                    ai.play.sample_rate);
+       }
+       if (blk_ms == 0)
+               blk_ms = 50;
+       DPRINTF("  > blocksize=%u, estimated blk_ms=%u\n", blocksize, blk_ms);
+
+       buf = (char *)malloc(blocksize);
+       REQUIRED_IF(buf != NULL);
+       memset(buf, 0xff, blocksize);
+
+       /*
+        * On NetBSD7, .offset starts from one block.  What is the block??
+        * On NetBSD9, .offset starts from zero.
+        */
+       if (netbsd < 9) {
+               initial_offset = blocksize;
+       } else {
+               initial_offset = 0;
+       }
+
+       /* When just opened, all are zero. */
+       r = IOCTL(fd, AUDIO_GETOOFFS, &o, "");
+       XP_SYS_EQ(0, r);
+       XP_EQ(0, o.samples);
+       XP_EQ(0, o.deltablks);
+       XP_EQ(initial_offset, o.offset);
+
+       /* Even if wait (at least) one block, these remain unchanged. */
+       usleep(blk_ms * 1000);
+       r = IOCTL(fd, AUDIO_GETOOFFS, &o, "");
+       XP_SYS_EQ(0, r);
+       XP_EQ(0, o.samples);
+       XP_EQ(0, o.deltablks);
+       XP_EQ(initial_offset, o.offset);
+
+       /* Write one block. */
+       r = WRITE(fd, buf, blocksize);
+       if (mode2play(openmode)) {
+               XP_SYS_EQ(blocksize, r);
+       } else {
+               XP_SYS_NG(EBADF, r);
+       }
+       r = IOCTL(fd, AUDIO_DRAIN, NULL, "");
+       REQUIRED_SYS_EQ(0, r);
+
+       r = IOCTL(fd, AUDIO_GETOOFFS, &o, "");
+       XP_SYS_EQ(0, r);
+       if (mode2play(openmode)) {
+               /* All advance one block. */
+               XP_EQ(blocksize, o.samples);
+               XP_EQ(1, o.deltablks);
+               XP_EQ(initial_offset + blocksize, o.offset);
+       } else {
+               /*
+                * All are zero on non-play track.
+                * On NetBSD7, the rec track has play buffer, too.
+                */
+               XP_EQ(0, o.samples);
+               XP_EQ(0, o.deltablks);
+               XP_EQ(initial_offset, o.offset);
+       }
+
+       r = CLOSE(fd);
+       XP_SYS_EQ(0, r);
+
+       free(buf);
+}
+DEF(AUDIO_GETOOFFS_one_RDONLY) { test_AUDIO_GETOOFFS_one(O_RDONLY); }
+DEF(AUDIO_GETOOFFS_one_WRONLY) { test_AUDIO_GETOOFFS_one(O_WRONLY); }
+DEF(AUDIO_GETOOFFS_one_RDWR)   { test_AUDIO_GETOOFFS_one(O_RDWR); }
+
+/*
+ * AUDIO_GETOOFFS when wrap around buffer.
+ */
+void
+test_AUDIO_GETOOFFS_wrap(int openmode)
+{
+       struct audio_info ai;
+       audio_offset_t o;
+       char *buf;
+       int fd;
+       int r;
+       u_int blocksize;
+       u_int buffer_size;
+       u_int initial_offset;
+       u_int nblks;
+
+       TEST("AUDIO_GETOOFFS_wrap_%s", openmode_str[openmode] + 2);
+       if (mode2aumode(openmode) == 0) {
+               XP_SKIP("Operation not allowed on this hardware property");
+               return;
+       }
+
+       fd = OPEN(devaudio, openmode);
+       REQUIRED_SYS_OK(fd);
+
+#if 1
+       /* To save test time, use larger format if possible. */
+       AUDIO_INITINFO(&ai);
+       ai.play.encoding = AUDIO_ENCODING_SLINEAR_NE;
+       ai.play.precision = 16;
+       ai.play.channels = 2;
+       ai.play.sample_rate = 48000;
+       r = IOCTL(fd, AUDIO_SETINFO, &ai, "slinear16/2/48000");
+       if (r != 0)
+#endif
+       {
+               /*
+                * If it cannot be set, use common format instead.
+                * May be happened on NetBSD7/8.
+                */
+               AUDIO_INITINFO(&ai);
+               ai.play.encoding = AUDIO_ENCODING_ULAW;
+               ai.play.precision = 8;
+               ai.play.channels = 1;
+               ai.play.sample_rate = 8000;
+               r = IOCTL(fd, AUDIO_SETINFO, &ai, "ulaw/1/8000");
+       }
+       REQUIRED_SYS_EQ(0, r);
+
+       /* Get buffer_size and blocksize. */
+       r = IOCTL(fd, AUDIO_GETBUFINFO, &ai, "");
+       REQUIRED_SYS_EQ(0, r);
+       buffer_size = ai.play.buffer_size;
+       blocksize = ai.blocksize;
+       nblks = buffer_size / blocksize;
+       DPRINTF("  > buffer_size=%u blocksize=%u nblks=%u\n",
+           buffer_size, blocksize, nblks);
+



Home | Main Index | Thread Index | Old Index