Source-Changes-HG archive

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

[src/trunk]: src/usr.bin/audiocfg add support for testing audio devices. the ...



details:   https://anonhg.NetBSD.org/src/rev/22d99e3b41bf
branches:  trunk
changeset: 757484:22d99e3b41bf
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Wed Sep 01 09:04:16 2010 +0000

description:
add support for testing audio devices. the usage of audiocfg changes:

  audiocfg list
  audiocfg default [index]
  audiocfg test [index]

'list' shows the available audio devices, 'default' sets the default
audio device, and 'test' will play a tone for 2 seconds on each
channel. example:

  $ ./audiocfg list
  0: [*] audio0: ICH2 AC97 (2 playback channels)
  1: [ ] audio1: Pseudo Audio (2 playback channels)
  $ ./audiocfg test 0
  testing channel 0...
  testing channel 1...
  $

diffstat:

 usr.bin/audiocfg/Makefile   |   8 ++-
 usr.bin/audiocfg/audiodev.c |  84 +++++++++++++++++++++++++++++++++++++++++++-
 usr.bin/audiocfg/audiodev.h |   5 ++-
 usr.bin/audiocfg/dtmf.c     |  75 ++++++++++++++++++++++++++++++++++++++++
 usr.bin/audiocfg/dtmf.h     |  37 +++++++++++++++++++
 usr.bin/audiocfg/main.c     |  47 ++++++++++++++++++------
 6 files changed, 237 insertions(+), 19 deletions(-)

diffs (truncated from 368 to 300 lines):

diff -r 7505195291ad -r 22d99e3b41bf usr.bin/audiocfg/Makefile
--- a/usr.bin/audiocfg/Makefile Wed Sep 01 07:50:33 2010 +0000
+++ b/usr.bin/audiocfg/Makefile Wed Sep 01 09:04:16 2010 +0000
@@ -1,9 +1,11 @@
+# $NetBSD: Makefile,v 1.3 2010/09/01 09:04:16 jmcneill Exp $
+
 PROG=  audiocfg
-SRCS=  audiodev.c drvctl.c
+SRCS=  audiodev.c drvctl.c dtmf.c
 SRCS+= main.c
 WARNS= 3
 
-LDADD+=        -lprop
-DPADD+=        $(LIBPROP)
+LDADD+=        -lprop -lm
+DPADD+=        $(LIBPROP) $(LIBM)
 
 .include <bsd.prog.mk>
diff -r 7505195291ad -r 22d99e3b41bf usr.bin/audiocfg/audiodev.c
--- a/usr.bin/audiocfg/audiodev.c       Wed Sep 01 07:50:33 2010 +0000
+++ b/usr.bin/audiocfg/audiodev.c       Wed Sep 01 09:04:16 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: audiodev.c,v 1.1.1.1 2010/08/30 02:19:47 mrg Exp $ */
+/* $NetBSD: audiodev.c,v 1.2 2010/09/01 09:04:16 jmcneill Exp $ */
 
 /*
  * Copyright (c) 2010 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -40,10 +40,42 @@
 
 #include "audiodev.h"
 #include "drvctl.h"
+#include "dtmf.h"
 
 static TAILQ_HEAD(audiodevhead, audiodev) audiodevlist =
     TAILQ_HEAD_INITIALIZER(audiodevlist);
 
+#define AUDIODEV_SAMPLE_RATE   44100
+
+static unsigned int
+audiodev_probe_pchans(struct audiodev *adev)
+{
+       audio_info_t info;
+       unsigned int nchans = 0, n;
+       int error;
+
+       AUDIO_INITINFO(&info);
+       info.play.sample_rate = AUDIODEV_SAMPLE_RATE;
+       info.play.precision = 16;
+       info.play.encoding = AUDIO_ENCODING_SLINEAR_LE;
+       info.play.channels = 1;
+       info.mode = AUMODE_PLAY;
+       error = ioctl(adev->fd, AUDIO_SETINFO, &info);
+       if (error == -1)
+               return 0;
+       nchans = 1;
+
+       for (n = 2; n <= 16; n += 2) {
+               info.play.channels = n;
+               error = ioctl(adev->fd, AUDIO_SETINFO, &info);
+               if (error == -1)
+                       break;
+               nchans = info.play.channels;
+       }
+
+       return nchans;
+}
+
 static int
 audiodev_getinfo(struct audiodev *adev)
 {
@@ -64,6 +96,8 @@
                return -1;
        }
 
+       adev->pchan = audiodev_probe_pchans(adev);
+
        return 0;
 }
 
@@ -107,7 +141,7 @@
        struct audiodev *adev;
        int fd, error;
 
-       fd = open(DRVCTLDEV, O_RDWR);
+       fd = open(DRVCTLDEV, O_RDONLY);
        if (fd == -1) {
                perror("open " DRVCTLDEV);
                return -1;
@@ -202,3 +236,49 @@
 
        return 0;
 }
+
+int
+audiodev_test(struct audiodev *adev, unsigned int chanmask)
+{
+       audio_info_t info;
+       int16_t *buf;
+       size_t buflen;
+       off_t off;
+
+       AUDIO_INITINFO(&info);
+       info.play.sample_rate = AUDIODEV_SAMPLE_RATE;
+       info.play.channels = adev->pchan;
+       info.play.precision = 16;
+       info.play.encoding = AUDIO_ENCODING_SLINEAR_LE;
+       info.mode = AUMODE_PLAY;
+       if (ioctl(adev->fd, AUDIO_SETINFO, &info) == -1) {
+               perror("ioctl AUDIO_SETINFO");
+               return -1;
+       }
+       if (ioctl(adev->fd, AUDIO_GETINFO, &info) == -1) {
+               perror("ioctl AUDIO_GETINFO");
+               return -1;
+       }
+
+       dtmf_new(&buf, &buflen, info.play.sample_rate, 2,
+           adev->pchan, chanmask, 350.0, 440.0);
+       if (buf == NULL)
+               return -1;
+
+       off = 0;
+       while (buflen > 0) {
+               size_t wlen = info.play.buffer_size;
+               if (wlen > buflen)
+                       wlen = buflen;
+               write(adev->fd, (char *)buf + off, wlen);
+               off += wlen;
+               buflen -= wlen;
+       }
+
+       if (ioctl(adev->fd, AUDIO_DRAIN) == -1)
+               perror("ioctl AUDIO_DRAIN");
+
+       free(buf);
+
+       return 0;
+}
diff -r 7505195291ad -r 22d99e3b41bf usr.bin/audiocfg/audiodev.h
--- a/usr.bin/audiocfg/audiodev.h       Wed Sep 01 07:50:33 2010 +0000
+++ b/usr.bin/audiocfg/audiodev.h       Wed Sep 01 09:04:16 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: audiodev.h,v 1.1.1.1 2010/08/30 02:19:47 mrg Exp $ */
+/* $NetBSD: audiodev.h,v 1.2 2010/09/01 09:04:16 jmcneill Exp $ */
 
 /*
  * Copyright (c) 2010 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -44,6 +44,8 @@
        dev_t dev;
        bool defaultdev;
 
+       int pchan;
+
        audio_device_t audio_device;
 
        TAILQ_ENTRY(audiodev) next;
@@ -53,5 +55,6 @@
 unsigned int           audiodev_count(void);
 struct audiodev *      audiodev_get(unsigned int);
 int                    audiodev_set_default(struct audiodev *);
+int                    audiodev_test(struct audiodev *, unsigned int);
 
 #endif /* !_HAVE_AUDIODEV_H */
diff -r 7505195291ad -r 22d99e3b41bf usr.bin/audiocfg/dtmf.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/usr.bin/audiocfg/dtmf.c   Wed Sep 01 09:04:16 2010 +0000
@@ -0,0 +1,75 @@
+/* $NetBSD: dtmf.c,v 1.1 2010/09/01 09:04:16 jmcneill Exp $ */
+
+/*
+ * Copyright (c) 2010 Jared D. McNeill <jmcneill%invisible.ca@localhost>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <fcntl.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "dtmf.h"
+
+#define        PI2     (3.14159265358979323846f * 2)
+
+static void
+dtmf_create(int16_t *buf, unsigned int sample_rate,
+    unsigned short sample_length, unsigned short channels,
+    unsigned int chanmask, float freq1, float freq2)
+{
+       int c, i;
+       size_t sample_count = sample_rate * sample_length;
+
+       for (i = 0; i < sample_count; i++) {
+               for (c = 0; c < channels; c++) {
+                       if ((chanmask & (1 << c)) == 0)
+                               continue;
+                       buf[c] = 
+                           (sin(i * PI2 * (freq1 / sample_rate)) +
+                            sin(i * PI2 * (freq2 / sample_rate))) * 16383;
+               }
+               buf += channels;
+       }
+}
+
+void
+dtmf_new(int16_t **buf, size_t *buflen, unsigned int sample_rate,
+    unsigned short sample_length, unsigned short channels,
+    unsigned int chanmask, float rate1, float rate2)
+{
+       *buflen = sample_rate * sizeof(int16_t) * sample_length * channels;
+       *buf = calloc(1, *buflen);
+       if (*buf == NULL) {
+               perror("calloc");
+               return;
+       }
+
+       dtmf_create(*buf, sample_rate, sample_length, channels, chanmask,
+           rate1, rate2);
+}
diff -r 7505195291ad -r 22d99e3b41bf usr.bin/audiocfg/dtmf.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/usr.bin/audiocfg/dtmf.h   Wed Sep 01 09:04:16 2010 +0000
@@ -0,0 +1,37 @@
+/* $NetBSD: dtmf.h,v 1.1 2010/09/01 09:04:16 jmcneill Exp $ */
+
+/*
+ * Copyright (c) 2010 Jared D. McNeill <jmcneill%invisible.ca@localhost>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _HAVE_DTMF_H
+#define _HAVE_DTMF_H
+
+#include <stdint.h>
+
+void   dtmf_new(int16_t **, size_t *, unsigned int, unsigned short,
+                unsigned short, unsigned int, float, float);
+
+#endif /* !_HAVE_DTMF_H */
diff -r 7505195291ad -r 22d99e3b41bf usr.bin/audiocfg/main.c
--- a/usr.bin/audiocfg/main.c   Wed Sep 01 07:50:33 2010 +0000
+++ b/usr.bin/audiocfg/main.c   Wed Sep 01 09:04:16 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: main.c,v 1.1.1.1 2010/08/30 02:19:47 mrg Exp $ */
+/* $NetBSD: main.c,v 1.2 2010/09/01 09:04:16 jmcneill Exp $ */
 
 /*
  * Copyright (c) 2010 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -39,7 +39,9 @@
 static void
 usage(const char *p)
 {
-       fprintf(stderr, "usage: %s [index]\n", p);
+       fprintf(stderr, "usage: %s list\n", p);
+       fprintf(stderr, "       %s default [index]\n", p);
+       fprintf(stderr, "       %s test [index]\n", p);



Home | Main Index | Thread Index | Old Index