Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.bin/audiocfg Update respond to isaki-audio2 branch.
details: https://anonhg.NetBSD.org/src/rev/f9ac97a43f87
branches: trunk
changeset: 451173:f9ac97a43f87
user: isaki <isaki%NetBSD.org@localhost>
date: Wed May 08 14:36:12 2019 +0000
description:
Update respond to isaki-audio2 branch.
- Extend list command to display supported hardware formats.
- Add set command to set hardware format.
- Use correct /dev/audioctl instead of /dev/audio.
diffstat:
usr.bin/audiocfg/audiocfg.1 | 29 ++++++-
usr.bin/audiocfg/audiodev.c | 178 ++++++++++++++++++++++++++++++-------------
usr.bin/audiocfg/audiodev.h | 18 +++-
usr.bin/audiocfg/main.c | 144 ++++++++++++++++++++++++++++++++++-
4 files changed, 304 insertions(+), 65 deletions(-)
diffs (truncated from 591 to 300 lines):
diff -r 475fd2777afb -r f9ac97a43f87 usr.bin/audiocfg/audiocfg.1
--- a/usr.bin/audiocfg/audiocfg.1 Wed May 08 14:25:38 2019 +0000
+++ b/usr.bin/audiocfg/audiocfg.1 Wed May 08 14:36:12 2019 +0000
@@ -1,4 +1,4 @@
-.\" $NetBSD: audiocfg.1,v 1.3 2010/09/01 09:17:31 wiz Exp $
+.\" $NetBSD: audiocfg.1,v 1.4 2019/05/08 14:36:12 isaki Exp $
.\"
.\" Copyright (c) 2010 The NetBSD Foundation, Inc.
.\" All rights reserved.
@@ -40,6 +40,14 @@
.Cm default
.Ar index
.Nm
+.Cm set
+.Ar index
+.Ar direction
+.Ar encoding
+.Ar precision
+.Ar channels
+.Ar sample_rate
+.Nm
.Cm test
.Ar index
.Sh DESCRIPTION
@@ -51,6 +59,25 @@
.Dq Cm list ,
it lists the available audio devices and shows the currently selected
default audio device.
+.Pp
+Run with
+.Dq Cm set ,
+if sets the hardware format.
+The
+.Ar direction
+is represented by either of 'p'(playback) or 'r'(record), or both of them,
+indicates direction you want to set to.
+The remaining parameters
+.Ar encoding ,
+.Ar precision ,
+.Ar channels
+and
+.Ar sample_rate
+indicate the hardware format you want to set to.
+These parameters must be selected from the candidates displayed by
+.Nm
+.Cm list .
+.Pp
Called with
.Dq Cm test ,
it plays a tone of 2 seconds for each channel of the device with the index
diff -r 475fd2777afb -r f9ac97a43f87 usr.bin/audiocfg/audiodev.c
--- a/usr.bin/audiocfg/audiodev.c Wed May 08 14:25:38 2019 +0000
+++ b/usr.bin/audiocfg/audiodev.c Wed May 08 14:36:12 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: audiodev.c,v 1.6 2016/03/05 22:10:39 mrg Exp $ */
+/* $NetBSD: audiodev.c,v 1.7 2019/05/08 14:36:12 isaki Exp $ */
/*
* Copyright (c) 2010 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -31,6 +31,7 @@
#include <sys/stat.h>
#include <sys/drvctlio.h>
+#include <errno.h>
#include <fcntl.h>
#include <paths.h>
#include <stdio.h>
@@ -47,51 +48,23 @@
#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)
{
struct stat st;
+ struct audiofmt *f;
+ audio_format_query_t query;
+ int i;
- if (stat(adev->path, &st) == -1)
+ if (stat(adev->ctlpath, &st) == -1)
return -1;
adev->dev = st.st_rdev;
- if (stat(_PATH_AUDIO, &st) != -1 && st.st_rdev == adev->dev)
+ if (stat(_PATH_AUDIOCTL, &st) != -1 && st.st_rdev == adev->dev)
adev->defaultdev = true;
- adev->fd = open(adev->path, O_RDWR);
+ adev->fd = open(adev->ctlpath, O_RDONLY);
if (adev->fd == -1) {
- adev->fd = open(adev->path, O_WRONLY);
- if (adev->fd == -1)
return -1;
}
if (ioctl(adev->fd, AUDIO_GETDEV, &adev->audio_device) == -1) {
@@ -99,7 +72,29 @@
return -1;
}
- adev->pchan = audiodev_probe_pchans(adev);
+ for (i = 0; ;i++) {
+ memset(&query, 0, sizeof(query));
+ query.index = i;
+ if (ioctl(adev->fd, AUDIO_QUERYFORMAT, &query) == -1) {
+ if (errno == ENODEV) {
+ /* QUERYFORMAT not supported. */
+ break;
+ }
+ if (errno == EINVAL)
+ break;
+ close(adev->fd);
+ return -1;
+ }
+
+ f = calloc(1, sizeof(*f));
+ f->fmt = query.fmt;
+ TAILQ_INSERT_TAIL(&adev->formats, f, next);
+ }
+
+ if (ioctl(adev->fd, AUDIO_GETFORMAT, &adev->info) == -1) {
+ close(adev->fd);
+ return -1;
+ }
return 0;
}
@@ -115,8 +110,10 @@
strlcpy(adev->pxname, pdev, sizeof(adev->pxname));
strlcpy(adev->xname, dev, sizeof(adev->xname));
- snprintf(adev->path, sizeof(adev->path) - 1, "/dev/%s", dev);
+ snprintf(adev->path, sizeof(adev->path), "/dev/%s", dev);
+ snprintf(adev->ctlpath, sizeof(adev->ctlpath), "/dev/audioctl%d", unit);
adev->unit = unit;
+ TAILQ_INIT(&adev->formats);
if (audiodev_getinfo(adev) == -1) {
free(adev);
@@ -124,8 +121,16 @@
}
#ifdef DEBUG
- printf("[%c] %s: %s\n", adev->defaultdev ? '*' : ' ',
- adev->path, adev->audio_device.name);
+ printf("DEBUG: [%c] %s(%s): %s\n", adev->defaultdev ? '*' : ' ',
+ adev->path, adev->ctlpath, adev->audio_device.name);
+ struct audiofmt *f;
+ TAILQ_FOREACH(f, &adev->formats, next) {
+ printf("DEBUG: enc%d, %d/%d, %dch\n",
+ f->fmt.encoding,
+ f->fmt.validbits,
+ f->fmt.precision,
+ f->fmt.channels);
+ }
#endif
TAILQ_INSERT_TAIL(&audiodevlist, adev, next);
@@ -207,13 +212,13 @@
char audioctlpath[PATH_MAX+1];
char mixerpath[PATH_MAX+1];
- snprintf(audiopath, sizeof(audiopath) - 1,
+ snprintf(audiopath, sizeof(audiopath),
_PATH_AUDIO "%u", adev->unit);
- snprintf(soundpath, sizeof(soundpath) - 1,
+ snprintf(soundpath, sizeof(soundpath),
_PATH_SOUND "%u", adev->unit);
- snprintf(audioctlpath, sizeof(audioctlpath) - 1,
+ snprintf(audioctlpath, sizeof(audioctlpath),
_PATH_AUDIOCTL "%u", adev->unit);
- snprintf(mixerpath, sizeof(mixerpath) - 1,
+ snprintf(mixerpath, sizeof(mixerpath),
_PATH_MIXER "%u", adev->unit);
unlink(_PATH_AUDIO);
@@ -242,33 +247,92 @@
}
int
+audiodev_set_param(struct audiodev *adev, int mode,
+ const char *encname, unsigned int prec, unsigned int ch, unsigned int freq)
+{
+ struct audio_info ai;
+ int setmode;
+ u_int enc;
+
+ setmode = 0;
+ ai = adev->info;
+
+ for (enc = 0; enc < encoding_max; enc++) {
+ if (strcmp(encname, encoding_names[enc]) == 0)
+ break;
+ }
+ if (enc >= encoding_max) {
+ fprintf(stderr, "unknown encoding name: %s\n", encname);
+ errno = EINVAL;
+ return -1;
+ }
+
+ if ((ai.mode & mode & AUMODE_PLAY)) {
+ setmode |= AUMODE_PLAY;
+ ai.play.encoding = enc;
+ ai.play.precision = prec;
+ ai.play.channels = ch;
+ ai.play.sample_rate = freq;
+ }
+ if ((ai.mode & mode & AUMODE_RECORD)) {
+ setmode |= AUMODE_RECORD;
+ ai.record.encoding = enc;
+ ai.record.precision = prec;
+ ai.record.channels = ch;
+ ai.record.sample_rate = freq;
+ }
+
+ if (setmode == 0) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ ai.mode = setmode;
+ printf("setting %s to %s:%u, %uch, %uHz\n",
+ adev->xname, encname, prec, ch, freq);
+ if (ioctl(adev->fd, AUDIO_SETFORMAT, &ai) == -1) {
+ perror("ioctl AUDIO_SETFORMAT");
+ return -1;
+ }
+ return 0;
+}
+
+int
audiodev_test(struct audiodev *adev, unsigned int chanmask)
{
audio_info_t info;
int16_t *buf;
size_t buflen;
off_t off;
- int rv = 0;
+ int fd;
+ int rv = -1;
+
+ fd = open(adev->path, O_WRONLY);
+ if (fd == -1) {
+ perror("open");
+ return -1;
+ }
AUDIO_INITINFO(&info);
info.play.sample_rate = AUDIODEV_SAMPLE_RATE;
- info.play.channels = adev->pchan;
+ info.play.channels = adev->info.play.channels;
info.play.precision = 16;
info.play.encoding = AUDIO_ENCODING_SLINEAR_LE;
info.mode = AUMODE_PLAY;
- if (ioctl(adev->fd, AUDIO_SETINFO, &info) == -1) {
+ if (ioctl(fd, AUDIO_SETINFO, &info) == -1) {
perror("ioctl AUDIO_SETINFO");
- return -1;
+ goto abort;
}
- if (ioctl(adev->fd, AUDIO_GETINFO, &info) == -1) {
+ if (ioctl(fd, AUDIO_GETINFO, &info) == -1) {
perror("ioctl AUDIO_GETINFO");
- return -1;
+ goto abort;
}
dtmf_new(&buf, &buflen, info.play.sample_rate, 2,
- adev->pchan, chanmask, 350.0, 440.0);
- if (buf == NULL)
- return -1;
Home |
Main Index |
Thread Index |
Old Index