Add audio utility programs.
The audio device can be inspected and changed by audioctl, and the mixer device by mixerctl. The command syntax was inspired by sysctl.
This commit is contained in:
parent
1aa91b893d
commit
9d5e7c9a4c
@ -1,18 +1,18 @@
|
||||
# $NetBSD: Makefile,v 1.70 1997/04/19 05:17:45 thorpej Exp $
|
||||
# $NetBSD: Makefile,v 1.71 1997/05/13 17:35:50 augustss Exp $
|
||||
# from: @(#)Makefile 8.3 (Berkeley) 1/7/94
|
||||
|
||||
.include <bsd.own.mk> # for EXPORTABLE_SYSTEM definition
|
||||
|
||||
SUBDIR= apply apropos asa at banner basename bdes biff cal calendar \
|
||||
SUBDIR= apply apropos asa at audioctl banner basename bdes biff cal calendar \
|
||||
cap_mkdb checknr chflags chpass cksum cmp col colcrt colrm column \
|
||||
comm compress crontab ctags cut dirname du \
|
||||
eject env error expand false file find finger fmt fold fpr from \
|
||||
fsplit fstat ftp gencat getconf getopt head hexdump id indent \
|
||||
ipcrm ipcs join jot kdump ktrace lam last lastcomm leave less lex \
|
||||
locate lock logger login logname look lorder m4 machine mail make man \
|
||||
mesg mkdep mkfifo mkstr modstat msgs netstat newsyslog nfsstat nice \
|
||||
nohup pagesize passwd paste patch pr printenv printf quota \
|
||||
rdist renice rev rlogin rpcgen rpcinfo rs \
|
||||
mesg mixerctl mkdep mkfifo mkstr modstat msgs netstat newsyslog \
|
||||
nfsstat nice nohup pagesize passwd paste patch pr printenv printf \
|
||||
quota rdist renice rev rlogin rpcgen rpcinfo rs \
|
||||
rsh rup ruptime rusers rwall rwho \
|
||||
script sed shar showmount skey skeyinit soelim split strings \
|
||||
su systat tail talk tcopy tee tftp time \
|
||||
|
100
usr.bin/audio/ctl/audioctl.1
Normal file
100
usr.bin/audio/ctl/audioctl.1
Normal file
@ -0,0 +1,100 @@
|
||||
.\" $NetBSD: audioctl.1,v 1.1 1997/05/13 17:35:52 augustss Exp $
|
||||
.\" Copyright (c) 1997 The NetBSD Foundation, Inc.
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Author: Lennart Augustsson
|
||||
.\"
|
||||
.\" 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.
|
||||
.\" 3. All advertising materials mentioning features or use of this software
|
||||
.\" must display the following acknowledgement:
|
||||
.\" This product includes software developed by the NetBSD
|
||||
.\" Foundation, Inc. and its contributors.
|
||||
.\" 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
.\" contributors may be used to endorse or promote products derived
|
||||
.\" from this software without specific prior written permission.
|
||||
.\"
|
||||
.\" 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 REGENTS 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.
|
||||
.\"
|
||||
.Dd May 4, 1997
|
||||
.Dt AUDIOCTL 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm audioctl
|
||||
.Nd control audio device
|
||||
.Sh SYNOPSIS
|
||||
.Nm audioctl
|
||||
.Op Fl f Ar file
|
||||
.Op Fl n
|
||||
.Fl a
|
||||
.Nm audioctl
|
||||
.Op Fl f Ar file
|
||||
.Op Fl n
|
||||
.Ar name ...
|
||||
.Nm audioctl
|
||||
.Op Fl f Ar file
|
||||
.Op Fl n
|
||||
.Fl w
|
||||
.Ar name=value ...
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm audioctl
|
||||
command displays or sets various audio system driver variables.
|
||||
If a list of variables is present on the command line, then
|
||||
.Nm audioctl
|
||||
prints the current value of those variables for the specified device.
|
||||
If the
|
||||
.Fl a
|
||||
flag is specified, all variables for the device are printed.
|
||||
If the
|
||||
.Fl w
|
||||
flag is specified
|
||||
.Nm audioctl
|
||||
attempts to set the specified variables to the given values.
|
||||
.Pp
|
||||
The
|
||||
.Fl f
|
||||
flag can be used to give an alternative sound device, the default is
|
||||
.Pa /dev/sound.
|
||||
.Pp
|
||||
The
|
||||
.Fl n
|
||||
flag suppresses printing of the variable name.
|
||||
.Sh EXAMPLES
|
||||
To set the playing sampling rate to 11025 you can enter
|
||||
.Dl audioctl -w play.sample_rate=11025
|
||||
Note that many of the variables that can be inspected and changed
|
||||
with
|
||||
.Nm audioctl
|
||||
are reset when the device is opened. This can be circumvented
|
||||
like this
|
||||
.Dl (cat file.au; audioctl -f /dev/stdout -a) > /dev/audio
|
||||
or
|
||||
.Dl (audioctl -f /dev/stdout -w blocksize=1024; cat file.au) > /dev/audio
|
||||
.Sh FILES
|
||||
.Bl -tag -width /dev/sound
|
||||
.It Pa /dev/sound
|
||||
audio device
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr mixerctl 1 ,
|
||||
.Xr audio 4 ,
|
||||
.Xr sysctl 8
|
||||
.Sh AUTHOR
|
||||
Lennart Augustsson, augustss@cs.chalmers.se
|
351
usr.bin/audio/ctl/ctl.c
Normal file
351
usr.bin/audio/ctl/ctl.c
Normal file
@ -0,0 +1,351 @@
|
||||
/* $NetBSD: ctl.c,v 1.1 1997/05/13 17:35:53 augustss Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Lennart Augustsson
|
||||
*
|
||||
* 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.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* 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 REGENTS 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 <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <err.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/audioio.h>
|
||||
|
||||
FILE *out = stdout;
|
||||
|
||||
char *prog;
|
||||
|
||||
audio_device_t adev;
|
||||
|
||||
audio_info_t info;
|
||||
|
||||
char encbuf[1000];
|
||||
|
||||
int fullduplex, rerror;
|
||||
|
||||
struct field {
|
||||
char *name;
|
||||
void *valp;
|
||||
int format;
|
||||
#define STRING 1
|
||||
#define INT 2
|
||||
#define UINT 3
|
||||
#define P_R 4
|
||||
#define ULONG 5
|
||||
#define UCHAR 6
|
||||
#define ENC 7
|
||||
char readonly;
|
||||
} fields[] = {
|
||||
{ "name", &adev.name, STRING, 1 },
|
||||
{ "version", &adev.version, STRING, 1 },
|
||||
{ "config", &adev.config, STRING, 1 },
|
||||
{ "encodings", encbuf, STRING, 1 },
|
||||
{ "full_duplex", &fullduplex, INT, 0 },
|
||||
{ "blocksize", &info.blocksize, UINT, 0 },
|
||||
{ "hiwat", &info.hiwat, UINT, 0 },
|
||||
{ "lowat", &info.lowat, UINT, 0 },
|
||||
{ "backlog", &info.backlog, UINT, 0 },
|
||||
{ "mode", &info.mode, P_R, 1 },
|
||||
{ "play.rate", &info.play.sample_rate, UINT, 0 },
|
||||
{ "play.channels", &info.play.channels, UINT, 0 },
|
||||
{ "play.precision", &info.play.precision, UINT, 0 },
|
||||
{ "play.encoding", &info.play.encoding, ENC, 0 },
|
||||
{ "play.gain", &info.play.gain, UINT, 0 },
|
||||
{ "play.port", &info.play.port, UINT, 0 },
|
||||
{ "play.seek", &info.play.seek, ULONG, 1 },
|
||||
{ "play.samples", &info.play.samples, UINT, 1 },
|
||||
{ "play.eof", &info.play.eof, UINT, 1 },
|
||||
{ "play.pause", &info.play.pause, UCHAR, 0 },
|
||||
{ "play.error", &info.play.error, UCHAR, 1 },
|
||||
{ "play.waiting", &info.play.waiting, UCHAR, 1 },
|
||||
{ "play.open", &info.play.open, UCHAR, 1 },
|
||||
{ "play.active", &info.play.active, UCHAR, 1 },
|
||||
{ "record.rate", &info.record.sample_rate,UINT, 0 },
|
||||
{ "record.channels", &info.record.channels, UINT, 0 },
|
||||
{ "record.precision", &info.record.precision, UINT, 0 },
|
||||
{ "record.encoding", &info.record.encoding, ENC, 0 },
|
||||
{ "record.gain", &info.record.gain, UINT, 0 },
|
||||
{ "record.port", &info.record.port, UINT, 0 },
|
||||
{ "record.seek", &info.record.seek, ULONG, 1 },
|
||||
{ "record.samples", &info.record.samples, UINT, 1 },
|
||||
{ "record.eof", &info.record.eof, UINT, 1 },
|
||||
{ "record.pause", &info.record.pause, UCHAR, 0 },
|
||||
{ "record.error", &info.record.error, UCHAR, 1 },
|
||||
{ "record.waiting", &info.record.waiting, UCHAR, 1 },
|
||||
{ "record.open", &info.record.open, UCHAR, 1 },
|
||||
{ "record.active", &info.record.active, UCHAR, 1 },
|
||||
{ "record.errors", &rerror, INT, 1 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
struct {
|
||||
char *ename;
|
||||
int eno;
|
||||
} encs[] = {
|
||||
{ "ulaw", AUDIO_ENCODING_ULAW },
|
||||
{ "alaw", AUDIO_ENCODING_ALAW },
|
||||
{ "linear", AUDIO_ENCODING_LINEAR },
|
||||
{ "ulinear", AUDIO_ENCODING_ULINEAR },
|
||||
{ "adpcm", AUDIO_ENCODING_ADPCM },
|
||||
{ "ADPCM", AUDIO_ENCODING_ADPCM },
|
||||
{ "mulaw", AUDIO_ENCODING_ULAW },
|
||||
{ "linear_le", AUDIO_ENCODING_LINEAR_LE },
|
||||
{ "ulinear_le", AUDIO_ENCODING_ULINEAR_LE },
|
||||
{ "linear_be", AUDIO_ENCODING_LINEAR_BE },
|
||||
{ "ulinear_be", AUDIO_ENCODING_ULINEAR_BE },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
struct field *
|
||||
findfield(char *name)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; fields[i].name; i++)
|
||||
if (strcmp(fields[i].name, name) == 0)
|
||||
return &fields[i];
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
prfield(struct field *p, char *sep)
|
||||
{
|
||||
u_int v;
|
||||
char *cm;
|
||||
int i;
|
||||
|
||||
if (sep)
|
||||
fprintf(out, "%s%s", p->name, sep);
|
||||
switch(p->format) {
|
||||
case STRING:
|
||||
fprintf(out, "%s", (char*)p->valp);
|
||||
break;
|
||||
case INT:
|
||||
fprintf(out, "%d", *(int*)p->valp);
|
||||
break;
|
||||
case UINT:
|
||||
fprintf(out, "%u", *(u_int*)p->valp);
|
||||
break;
|
||||
case UCHAR:
|
||||
fprintf(out, "%u", *(u_char*)p->valp);
|
||||
break;
|
||||
case ULONG:
|
||||
fprintf(out, "%lu", *(u_long*)p->valp);
|
||||
break;
|
||||
case P_R:
|
||||
v = *(u_int*)p->valp;
|
||||
cm = "";
|
||||
if (v & AUMODE_PLAY) {
|
||||
if (v & AUMODE_PLAY_ALL)
|
||||
fprintf(out, "play");
|
||||
else
|
||||
fprintf(out, "playsync");
|
||||
cm = ",";
|
||||
}
|
||||
if (v & AUMODE_RECORD)
|
||||
fprintf(out, "%srecord", cm);
|
||||
break;
|
||||
case ENC:
|
||||
v = *(u_int*)p->valp;
|
||||
for(i = 0; encs[i].ename; i++)
|
||||
if (encs[i].eno == v)
|
||||
break;
|
||||
if (encs[i].ename)
|
||||
fprintf(out, "%s", encs[i].ename);
|
||||
else
|
||||
fprintf(out, "%u", v);
|
||||
break;
|
||||
default:
|
||||
errx(1, "Invalid format.");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rdfield(struct field *p, char *q, char *sep)
|
||||
{
|
||||
u_int v;
|
||||
int i;
|
||||
|
||||
#if 0
|
||||
if (sep)
|
||||
prfield(p, ": ");
|
||||
#else
|
||||
if (sep)
|
||||
fprintf(out, "%s: ", p->name);
|
||||
#endif
|
||||
switch(p->format) {
|
||||
case UINT:
|
||||
if (sscanf(q, "%u", p->valp) != 1)
|
||||
warnx("Bad number %s", q);
|
||||
break;
|
||||
case ENC:
|
||||
for(i = 0; encs[i].ename; i++)
|
||||
if (strcmp(encs[i].ename, q) == 0)
|
||||
break;
|
||||
if (encs[i].ename)
|
||||
*(u_int*)p->valp = encs[i].eno;
|
||||
else
|
||||
warnx("Unknown encoding: %s", q);
|
||||
break;
|
||||
default:
|
||||
errx(1, "Invalid format.");
|
||||
}
|
||||
if (sep) {
|
||||
fprintf(out, " -> ");
|
||||
prfield(p, 0);
|
||||
fprintf(out, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int fd, r, i, ch, pos;
|
||||
int aflag = 0, wflag = 0;
|
||||
char *file = "/dev/sound";
|
||||
char *sep = "=";
|
||||
|
||||
prog = *argv;
|
||||
|
||||
while ((ch = getopt(argc, argv, "af:nw")) != -1) {
|
||||
switch(ch) {
|
||||
case 'a':
|
||||
aflag++;
|
||||
break;
|
||||
case 'w':
|
||||
wflag++;
|
||||
break;
|
||||
case 'n':
|
||||
sep = 0;;
|
||||
break;
|
||||
case 'f':
|
||||
file = optarg;
|
||||
/* XXX this test should be more clever */
|
||||
if (strcmp(file, "/dev/stdout") == 0)
|
||||
out = stderr;
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
usage:
|
||||
fprintf(out, "%s [-f file] [-n] name ...\n", prog);
|
||||
fprintf(out, "%s [-f file] [-n] -w name=value ...\n", prog);
|
||||
fprintf(out, "%s [-f file] [-n] -a\n", prog);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
fd = open(file, O_RDWR);
|
||||
if (fd < 0)
|
||||
fd = open(file, O_WRONLY);
|
||||
if (fd < 0)
|
||||
fd = open(file, O_RDONLY);
|
||||
if (fd < 0)
|
||||
err(1, "%s", file);
|
||||
|
||||
if (!wflag) {
|
||||
if (ioctl(fd, AUDIO_GETDEV, &adev) < 0)
|
||||
err(1, NULL);
|
||||
for(pos = 0, i = 0;; i++) {
|
||||
audio_encoding_t enc;
|
||||
enc.index = i;
|
||||
if (ioctl(fd, AUDIO_GETENC, &enc) < 0)
|
||||
break;
|
||||
if (pos)
|
||||
encbuf[pos++] = ',';
|
||||
sprintf(encbuf+pos, "%s:%d%s", enc.name,
|
||||
enc.precision,
|
||||
enc.flags & AUDIO_ENCODINGFLAG_EMULATED ? "*" : "");
|
||||
pos += strlen(encbuf+pos);
|
||||
}
|
||||
if (ioctl(fd, AUDIO_GETFD, &fullduplex) < 0)
|
||||
err(1, NULL);
|
||||
if (ioctl(fd, AUDIO_RERROR, &rerror) < 0)
|
||||
err(1, NULL);
|
||||
if (ioctl(fd, AUDIO_GETINFO, &info) < 0)
|
||||
err(1, NULL);
|
||||
}
|
||||
|
||||
if (argc == 0 && aflag && !wflag) {
|
||||
for(i = 0; fields[i].name; i++) {
|
||||
prfield(&fields[i], sep);
|
||||
fprintf(out, "\n");
|
||||
}
|
||||
} else if (argc > 0 && !aflag) {
|
||||
struct field *p;
|
||||
if (wflag) {
|
||||
AUDIO_INITINFO(&info);
|
||||
while(argc--) {
|
||||
char *q;
|
||||
|
||||
q = strchr(*argv, '=');
|
||||
if (q) {
|
||||
*q++ = 0;
|
||||
p = findfield(*argv);
|
||||
if (p == 0)
|
||||
warnx("field %s does not exist", *argv);
|
||||
else {
|
||||
if (p->readonly)
|
||||
warnx("%s is read only", *argv);
|
||||
else {
|
||||
rdfield(p, q, sep);
|
||||
if (p->valp == &fullduplex)
|
||||
if (ioctl(fd, AUDIO_SETFD, &fullduplex) < 0)
|
||||
err(1, "set failed");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
warnx("No `=' in %s", *argv);
|
||||
}
|
||||
argv++;
|
||||
}
|
||||
if (ioctl(fd, AUDIO_SETINFO, &info) < 0)
|
||||
err(1, "set failed");
|
||||
} else {
|
||||
while(argc--) {
|
||||
p = findfield(*argv);
|
||||
if (p == 0)
|
||||
warnx("field %s does not exist", *argv);
|
||||
else
|
||||
prfield(p, sep), fprintf(out, "\n");
|
||||
argv++;
|
||||
}
|
||||
}
|
||||
} else
|
||||
goto usage;
|
||||
exit(0);
|
||||
}
|
||||
|
6
usr.bin/audioctl/Makefile
Normal file
6
usr.bin/audioctl/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
# $NetBSD: Makefile,v 1.1 1997/05/13 17:35:52 augustss Exp $
|
||||
# @(#)Makefile 8.1 (Berkeley) 6/6/93
|
||||
|
||||
PROG= audioctl
|
||||
|
||||
.include <bsd.prog.mk>
|
100
usr.bin/audioctl/audioctl.1
Normal file
100
usr.bin/audioctl/audioctl.1
Normal file
@ -0,0 +1,100 @@
|
||||
.\" $NetBSD: audioctl.1,v 1.1 1997/05/13 17:35:52 augustss Exp $
|
||||
.\" Copyright (c) 1997 The NetBSD Foundation, Inc.
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Author: Lennart Augustsson
|
||||
.\"
|
||||
.\" 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.
|
||||
.\" 3. All advertising materials mentioning features or use of this software
|
||||
.\" must display the following acknowledgement:
|
||||
.\" This product includes software developed by the NetBSD
|
||||
.\" Foundation, Inc. and its contributors.
|
||||
.\" 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
.\" contributors may be used to endorse or promote products derived
|
||||
.\" from this software without specific prior written permission.
|
||||
.\"
|
||||
.\" 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 REGENTS 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.
|
||||
.\"
|
||||
.Dd May 4, 1997
|
||||
.Dt AUDIOCTL 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm audioctl
|
||||
.Nd control audio device
|
||||
.Sh SYNOPSIS
|
||||
.Nm audioctl
|
||||
.Op Fl f Ar file
|
||||
.Op Fl n
|
||||
.Fl a
|
||||
.Nm audioctl
|
||||
.Op Fl f Ar file
|
||||
.Op Fl n
|
||||
.Ar name ...
|
||||
.Nm audioctl
|
||||
.Op Fl f Ar file
|
||||
.Op Fl n
|
||||
.Fl w
|
||||
.Ar name=value ...
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm audioctl
|
||||
command displays or sets various audio system driver variables.
|
||||
If a list of variables is present on the command line, then
|
||||
.Nm audioctl
|
||||
prints the current value of those variables for the specified device.
|
||||
If the
|
||||
.Fl a
|
||||
flag is specified, all variables for the device are printed.
|
||||
If the
|
||||
.Fl w
|
||||
flag is specified
|
||||
.Nm audioctl
|
||||
attempts to set the specified variables to the given values.
|
||||
.Pp
|
||||
The
|
||||
.Fl f
|
||||
flag can be used to give an alternative sound device, the default is
|
||||
.Pa /dev/sound.
|
||||
.Pp
|
||||
The
|
||||
.Fl n
|
||||
flag suppresses printing of the variable name.
|
||||
.Sh EXAMPLES
|
||||
To set the playing sampling rate to 11025 you can enter
|
||||
.Dl audioctl -w play.sample_rate=11025
|
||||
Note that many of the variables that can be inspected and changed
|
||||
with
|
||||
.Nm audioctl
|
||||
are reset when the device is opened. This can be circumvented
|
||||
like this
|
||||
.Dl (cat file.au; audioctl -f /dev/stdout -a) > /dev/audio
|
||||
or
|
||||
.Dl (audioctl -f /dev/stdout -w blocksize=1024; cat file.au) > /dev/audio
|
||||
.Sh FILES
|
||||
.Bl -tag -width /dev/sound
|
||||
.It Pa /dev/sound
|
||||
audio device
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr mixerctl 1 ,
|
||||
.Xr audio 4 ,
|
||||
.Xr sysctl 8
|
||||
.Sh AUTHOR
|
||||
Lennart Augustsson, augustss@cs.chalmers.se
|
351
usr.bin/audioctl/audioctl.c
Normal file
351
usr.bin/audioctl/audioctl.c
Normal file
@ -0,0 +1,351 @@
|
||||
/* $NetBSD: audioctl.c,v 1.1 1997/05/13 17:35:53 augustss Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Lennart Augustsson
|
||||
*
|
||||
* 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.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* 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 REGENTS 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 <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <err.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/audioio.h>
|
||||
|
||||
FILE *out = stdout;
|
||||
|
||||
char *prog;
|
||||
|
||||
audio_device_t adev;
|
||||
|
||||
audio_info_t info;
|
||||
|
||||
char encbuf[1000];
|
||||
|
||||
int fullduplex, rerror;
|
||||
|
||||
struct field {
|
||||
char *name;
|
||||
void *valp;
|
||||
int format;
|
||||
#define STRING 1
|
||||
#define INT 2
|
||||
#define UINT 3
|
||||
#define P_R 4
|
||||
#define ULONG 5
|
||||
#define UCHAR 6
|
||||
#define ENC 7
|
||||
char readonly;
|
||||
} fields[] = {
|
||||
{ "name", &adev.name, STRING, 1 },
|
||||
{ "version", &adev.version, STRING, 1 },
|
||||
{ "config", &adev.config, STRING, 1 },
|
||||
{ "encodings", encbuf, STRING, 1 },
|
||||
{ "full_duplex", &fullduplex, INT, 0 },
|
||||
{ "blocksize", &info.blocksize, UINT, 0 },
|
||||
{ "hiwat", &info.hiwat, UINT, 0 },
|
||||
{ "lowat", &info.lowat, UINT, 0 },
|
||||
{ "backlog", &info.backlog, UINT, 0 },
|
||||
{ "mode", &info.mode, P_R, 1 },
|
||||
{ "play.rate", &info.play.sample_rate, UINT, 0 },
|
||||
{ "play.channels", &info.play.channels, UINT, 0 },
|
||||
{ "play.precision", &info.play.precision, UINT, 0 },
|
||||
{ "play.encoding", &info.play.encoding, ENC, 0 },
|
||||
{ "play.gain", &info.play.gain, UINT, 0 },
|
||||
{ "play.port", &info.play.port, UINT, 0 },
|
||||
{ "play.seek", &info.play.seek, ULONG, 1 },
|
||||
{ "play.samples", &info.play.samples, UINT, 1 },
|
||||
{ "play.eof", &info.play.eof, UINT, 1 },
|
||||
{ "play.pause", &info.play.pause, UCHAR, 0 },
|
||||
{ "play.error", &info.play.error, UCHAR, 1 },
|
||||
{ "play.waiting", &info.play.waiting, UCHAR, 1 },
|
||||
{ "play.open", &info.play.open, UCHAR, 1 },
|
||||
{ "play.active", &info.play.active, UCHAR, 1 },
|
||||
{ "record.rate", &info.record.sample_rate,UINT, 0 },
|
||||
{ "record.channels", &info.record.channels, UINT, 0 },
|
||||
{ "record.precision", &info.record.precision, UINT, 0 },
|
||||
{ "record.encoding", &info.record.encoding, ENC, 0 },
|
||||
{ "record.gain", &info.record.gain, UINT, 0 },
|
||||
{ "record.port", &info.record.port, UINT, 0 },
|
||||
{ "record.seek", &info.record.seek, ULONG, 1 },
|
||||
{ "record.samples", &info.record.samples, UINT, 1 },
|
||||
{ "record.eof", &info.record.eof, UINT, 1 },
|
||||
{ "record.pause", &info.record.pause, UCHAR, 0 },
|
||||
{ "record.error", &info.record.error, UCHAR, 1 },
|
||||
{ "record.waiting", &info.record.waiting, UCHAR, 1 },
|
||||
{ "record.open", &info.record.open, UCHAR, 1 },
|
||||
{ "record.active", &info.record.active, UCHAR, 1 },
|
||||
{ "record.errors", &rerror, INT, 1 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
struct {
|
||||
char *ename;
|
||||
int eno;
|
||||
} encs[] = {
|
||||
{ "ulaw", AUDIO_ENCODING_ULAW },
|
||||
{ "alaw", AUDIO_ENCODING_ALAW },
|
||||
{ "linear", AUDIO_ENCODING_LINEAR },
|
||||
{ "ulinear", AUDIO_ENCODING_ULINEAR },
|
||||
{ "adpcm", AUDIO_ENCODING_ADPCM },
|
||||
{ "ADPCM", AUDIO_ENCODING_ADPCM },
|
||||
{ "mulaw", AUDIO_ENCODING_ULAW },
|
||||
{ "linear_le", AUDIO_ENCODING_LINEAR_LE },
|
||||
{ "ulinear_le", AUDIO_ENCODING_ULINEAR_LE },
|
||||
{ "linear_be", AUDIO_ENCODING_LINEAR_BE },
|
||||
{ "ulinear_be", AUDIO_ENCODING_ULINEAR_BE },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
struct field *
|
||||
findfield(char *name)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; fields[i].name; i++)
|
||||
if (strcmp(fields[i].name, name) == 0)
|
||||
return &fields[i];
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
prfield(struct field *p, char *sep)
|
||||
{
|
||||
u_int v;
|
||||
char *cm;
|
||||
int i;
|
||||
|
||||
if (sep)
|
||||
fprintf(out, "%s%s", p->name, sep);
|
||||
switch(p->format) {
|
||||
case STRING:
|
||||
fprintf(out, "%s", (char*)p->valp);
|
||||
break;
|
||||
case INT:
|
||||
fprintf(out, "%d", *(int*)p->valp);
|
||||
break;
|
||||
case UINT:
|
||||
fprintf(out, "%u", *(u_int*)p->valp);
|
||||
break;
|
||||
case UCHAR:
|
||||
fprintf(out, "%u", *(u_char*)p->valp);
|
||||
break;
|
||||
case ULONG:
|
||||
fprintf(out, "%lu", *(u_long*)p->valp);
|
||||
break;
|
||||
case P_R:
|
||||
v = *(u_int*)p->valp;
|
||||
cm = "";
|
||||
if (v & AUMODE_PLAY) {
|
||||
if (v & AUMODE_PLAY_ALL)
|
||||
fprintf(out, "play");
|
||||
else
|
||||
fprintf(out, "playsync");
|
||||
cm = ",";
|
||||
}
|
||||
if (v & AUMODE_RECORD)
|
||||
fprintf(out, "%srecord", cm);
|
||||
break;
|
||||
case ENC:
|
||||
v = *(u_int*)p->valp;
|
||||
for(i = 0; encs[i].ename; i++)
|
||||
if (encs[i].eno == v)
|
||||
break;
|
||||
if (encs[i].ename)
|
||||
fprintf(out, "%s", encs[i].ename);
|
||||
else
|
||||
fprintf(out, "%u", v);
|
||||
break;
|
||||
default:
|
||||
errx(1, "Invalid format.");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rdfield(struct field *p, char *q, char *sep)
|
||||
{
|
||||
u_int v;
|
||||
int i;
|
||||
|
||||
#if 0
|
||||
if (sep)
|
||||
prfield(p, ": ");
|
||||
#else
|
||||
if (sep)
|
||||
fprintf(out, "%s: ", p->name);
|
||||
#endif
|
||||
switch(p->format) {
|
||||
case UINT:
|
||||
if (sscanf(q, "%u", p->valp) != 1)
|
||||
warnx("Bad number %s", q);
|
||||
break;
|
||||
case ENC:
|
||||
for(i = 0; encs[i].ename; i++)
|
||||
if (strcmp(encs[i].ename, q) == 0)
|
||||
break;
|
||||
if (encs[i].ename)
|
||||
*(u_int*)p->valp = encs[i].eno;
|
||||
else
|
||||
warnx("Unknown encoding: %s", q);
|
||||
break;
|
||||
default:
|
||||
errx(1, "Invalid format.");
|
||||
}
|
||||
if (sep) {
|
||||
fprintf(out, " -> ");
|
||||
prfield(p, 0);
|
||||
fprintf(out, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int fd, r, i, ch, pos;
|
||||
int aflag = 0, wflag = 0;
|
||||
char *file = "/dev/sound";
|
||||
char *sep = "=";
|
||||
|
||||
prog = *argv;
|
||||
|
||||
while ((ch = getopt(argc, argv, "af:nw")) != -1) {
|
||||
switch(ch) {
|
||||
case 'a':
|
||||
aflag++;
|
||||
break;
|
||||
case 'w':
|
||||
wflag++;
|
||||
break;
|
||||
case 'n':
|
||||
sep = 0;;
|
||||
break;
|
||||
case 'f':
|
||||
file = optarg;
|
||||
/* XXX this test should be more clever */
|
||||
if (strcmp(file, "/dev/stdout") == 0)
|
||||
out = stderr;
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
usage:
|
||||
fprintf(out, "%s [-f file] [-n] name ...\n", prog);
|
||||
fprintf(out, "%s [-f file] [-n] -w name=value ...\n", prog);
|
||||
fprintf(out, "%s [-f file] [-n] -a\n", prog);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
fd = open(file, O_RDWR);
|
||||
if (fd < 0)
|
||||
fd = open(file, O_WRONLY);
|
||||
if (fd < 0)
|
||||
fd = open(file, O_RDONLY);
|
||||
if (fd < 0)
|
||||
err(1, "%s", file);
|
||||
|
||||
if (!wflag) {
|
||||
if (ioctl(fd, AUDIO_GETDEV, &adev) < 0)
|
||||
err(1, NULL);
|
||||
for(pos = 0, i = 0;; i++) {
|
||||
audio_encoding_t enc;
|
||||
enc.index = i;
|
||||
if (ioctl(fd, AUDIO_GETENC, &enc) < 0)
|
||||
break;
|
||||
if (pos)
|
||||
encbuf[pos++] = ',';
|
||||
sprintf(encbuf+pos, "%s:%d%s", enc.name,
|
||||
enc.precision,
|
||||
enc.flags & AUDIO_ENCODINGFLAG_EMULATED ? "*" : "");
|
||||
pos += strlen(encbuf+pos);
|
||||
}
|
||||
if (ioctl(fd, AUDIO_GETFD, &fullduplex) < 0)
|
||||
err(1, NULL);
|
||||
if (ioctl(fd, AUDIO_RERROR, &rerror) < 0)
|
||||
err(1, NULL);
|
||||
if (ioctl(fd, AUDIO_GETINFO, &info) < 0)
|
||||
err(1, NULL);
|
||||
}
|
||||
|
||||
if (argc == 0 && aflag && !wflag) {
|
||||
for(i = 0; fields[i].name; i++) {
|
||||
prfield(&fields[i], sep);
|
||||
fprintf(out, "\n");
|
||||
}
|
||||
} else if (argc > 0 && !aflag) {
|
||||
struct field *p;
|
||||
if (wflag) {
|
||||
AUDIO_INITINFO(&info);
|
||||
while(argc--) {
|
||||
char *q;
|
||||
|
||||
q = strchr(*argv, '=');
|
||||
if (q) {
|
||||
*q++ = 0;
|
||||
p = findfield(*argv);
|
||||
if (p == 0)
|
||||
warnx("field %s does not exist", *argv);
|
||||
else {
|
||||
if (p->readonly)
|
||||
warnx("%s is read only", *argv);
|
||||
else {
|
||||
rdfield(p, q, sep);
|
||||
if (p->valp == &fullduplex)
|
||||
if (ioctl(fd, AUDIO_SETFD, &fullduplex) < 0)
|
||||
err(1, "set failed");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
warnx("No `=' in %s", *argv);
|
||||
}
|
||||
argv++;
|
||||
}
|
||||
if (ioctl(fd, AUDIO_SETINFO, &info) < 0)
|
||||
err(1, "set failed");
|
||||
} else {
|
||||
while(argc--) {
|
||||
p = findfield(*argv);
|
||||
if (p == 0)
|
||||
warnx("field %s does not exist", *argv);
|
||||
else
|
||||
prfield(p, sep), fprintf(out, "\n");
|
||||
argv++;
|
||||
}
|
||||
}
|
||||
} else
|
||||
goto usage;
|
||||
exit(0);
|
||||
}
|
||||
|
6
usr.bin/mixerctl/Makefile
Normal file
6
usr.bin/mixerctl/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
# $NetBSD: Makefile,v 1.1 1997/05/13 17:35:54 augustss Exp $
|
||||
# @(#)Makefile 8.1 (Berkeley) 6/6/93
|
||||
|
||||
PROG= mixerctl
|
||||
|
||||
.include <bsd.prog.mk>
|
97
usr.bin/mixerctl/mixerctl.1
Normal file
97
usr.bin/mixerctl/mixerctl.1
Normal file
@ -0,0 +1,97 @@
|
||||
.\" $NetBSD: mixerctl.1,v 1.1 1997/05/13 17:35:55 augustss Exp $
|
||||
.\" Copyright (c) 1997 The NetBSD Foundation, Inc.
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Author: Lennart Augustsson
|
||||
.\"
|
||||
.\" 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.
|
||||
.\" 3. All advertising materials mentioning features or use of this software
|
||||
.\" must display the following acknowledgement:
|
||||
.\" This product includes software developed by the NetBSD
|
||||
.\" Foundation, Inc. and its contributors.
|
||||
.\" 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
.\" contributors may be used to endorse or promote products derived
|
||||
.\" from this software without specific prior written permission.
|
||||
.\"
|
||||
.\" 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 REGENTS 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.
|
||||
.\"
|
||||
.Dd May 4, 1997
|
||||
.Dt MIXERCTL 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm mixerctl
|
||||
.Nd control audio mixing
|
||||
.Sh SYNOPSIS
|
||||
.Nm mixerctl
|
||||
.Op Fl f Ar file
|
||||
.Op Fl n
|
||||
.Op Fl v
|
||||
.Fl a
|
||||
.Nm mixerctl
|
||||
.Op Fl f Ar file
|
||||
.Op Fl n
|
||||
.Op Fl v
|
||||
.Ar name ...
|
||||
.Nm mixerctl
|
||||
.Op Fl f Ar file
|
||||
.Op Fl n
|
||||
.Fl w
|
||||
.Ar name=value ...
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm mixerctl
|
||||
command displays or sets various audio system mixing variables.
|
||||
If a list of variables is present on the command line, then
|
||||
.Nm mixerctl
|
||||
prints the current value of those variables for the specified device.
|
||||
If the
|
||||
.Fl a
|
||||
flag is specified, all variables for the device are printed.
|
||||
If the
|
||||
.Fl w
|
||||
flag is specified
|
||||
.Nm mixerctl
|
||||
attempts to set the specified variables to the given values.
|
||||
.Pp
|
||||
The
|
||||
.Fl f
|
||||
flag can be used to give an alternative mixer device, the default is
|
||||
.Pa /dev/mixer.
|
||||
.Pp
|
||||
The
|
||||
.Fl n
|
||||
flag suppresses printing of the variable name.
|
||||
.Pp
|
||||
The
|
||||
.Fl v
|
||||
flag shows the possible values of enumeration and set valued
|
||||
variables. Enumerated values are shown in [] and set values
|
||||
are shown in {}.
|
||||
.Sh FILES
|
||||
.Bl -tag -width /dev/mixer
|
||||
.It Pa /dev/mixer
|
||||
mixer audio device
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr audioctl 1 ,
|
||||
.Xr audio 4 ,
|
||||
.Xr sysctl 8
|
||||
.Sh AUTHOR
|
||||
Lennart Augustsson, augustss@cs.chalmers.se
|
326
usr.bin/mixerctl/mixerctl.c
Normal file
326
usr.bin/mixerctl/mixerctl.c
Normal file
@ -0,0 +1,326 @@
|
||||
/* $NetBSD: mixerctl.c,v 1.1 1997/05/13 17:35:55 augustss Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Lennart Augustsson, with some code and ideas from Chuck Cranor.
|
||||
*
|
||||
* 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.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* 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 REGENTS 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <err.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/audioio.h>
|
||||
|
||||
FILE *out = stdout;
|
||||
|
||||
char *prog;
|
||||
|
||||
struct field {
|
||||
char *name;
|
||||
mixer_ctrl_t *valp;
|
||||
mixer_devinfo_t *infp;
|
||||
} *fields, *rfields;
|
||||
|
||||
mixer_ctrl_t *values;
|
||||
mixer_devinfo_t *infos;
|
||||
|
||||
char *
|
||||
catstr(char *p, char *q)
|
||||
{
|
||||
char *r = malloc(strlen(p) + strlen(q) + 2);
|
||||
strcpy(r, p);
|
||||
strcat(r, ".");
|
||||
strcat(r, q);
|
||||
return r;
|
||||
}
|
||||
|
||||
struct field *
|
||||
findfield(char *name)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; fields[i].name; i++)
|
||||
if (strcmp(fields[i].name, name) == 0)
|
||||
return &fields[i];
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
prfield(struct field *p, char *sep, int prvalset)
|
||||
{
|
||||
mixer_ctrl_t *m;
|
||||
int i, v;
|
||||
|
||||
if (sep)
|
||||
fprintf(out, "%s%s", p->name, sep);
|
||||
m = p->valp;
|
||||
switch(m->type) {
|
||||
case AUDIO_MIXER_ENUM:
|
||||
fprintf(out, "%s", p->infp->un.e.member[m->un.ord].label.name);
|
||||
if (prvalset) {
|
||||
fprintf(out, " [ ");
|
||||
for(i = 0; i < p->infp->un.e.num_mem; i++)
|
||||
fprintf(out, "%s ", p->infp->un.e.member[i].label.name);
|
||||
fprintf(out, "]");
|
||||
}
|
||||
break;
|
||||
case AUDIO_MIXER_SET:
|
||||
for(i = 0, v = m->un.mask; v; i++, v >>= 1)
|
||||
if (v & 1)
|
||||
fprintf(out, "%s%s", p->infp->un.s.member[i].label.name,
|
||||
v >> 1 ? "," : "");
|
||||
if (prvalset) {
|
||||
fprintf(out, " { ");
|
||||
for(i = 0; i < p->infp->un.s.num_mem; i++)
|
||||
fprintf(out, "%s ", p->infp->un.s.member[i].label.name);
|
||||
fprintf(out, "}");
|
||||
}
|
||||
break;
|
||||
case AUDIO_MIXER_VALUE:
|
||||
if (m->un.value.num_channels == 1)
|
||||
fprintf(out, "%d", m->un.value.level[0]);
|
||||
else
|
||||
fprintf(out, "%d,%d", m->un.value.level[0],
|
||||
m->un.value.level[1]);
|
||||
break;
|
||||
default:
|
||||
errx(1, "Invalid format.");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rdfield(struct field *p, char *q, char *sep)
|
||||
{
|
||||
mixer_ctrl_t *m;
|
||||
int v, v0, v1;
|
||||
int i;
|
||||
char *s;
|
||||
|
||||
if (sep)
|
||||
prfield(p, ": ", 0);
|
||||
|
||||
m = p->valp;
|
||||
switch(m->type) {
|
||||
case AUDIO_MIXER_ENUM:
|
||||
for(i = 0; i < p->infp->un.e.num_mem; i++)
|
||||
if (strcmp(p->infp->un.e.member[i].label.name, q) == 0)
|
||||
break;
|
||||
if (i < p->infp->un.e.num_mem)
|
||||
m->un.ord = i;
|
||||
else
|
||||
warnx("Bad enum value %s", q);
|
||||
break;
|
||||
case AUDIO_MIXER_SET:
|
||||
for(v = 0; q && *q; q = s) {
|
||||
s = strchr(q, ',');
|
||||
if (s)
|
||||
*s++ = 0;
|
||||
for(i = 0; i < p->infp->un.s.num_mem; i++)
|
||||
if (strcmp(p->infp->un.s.member[i].label.name, q) == 0)
|
||||
break;
|
||||
if (i < p->infp->un.s.num_mem)
|
||||
m->un.mask = 1 << i;
|
||||
else
|
||||
warnx("Bad enum value %s", q);
|
||||
}
|
||||
break;
|
||||
case AUDIO_MIXER_VALUE:
|
||||
if (m->un.value.num_channels == 1) {
|
||||
if (sscanf(q, "%d", &v) == 1) {
|
||||
m->un.value.level[0] = v;
|
||||
} else {
|
||||
warnx("Bad number %s", q);
|
||||
}
|
||||
} else {
|
||||
if (sscanf(q, "%d,%d", &v0, &v1) == 2) {
|
||||
m->un.value.level[0] = v0;
|
||||
m->un.value.level[1] = v1;
|
||||
} else if (sscanf(q, "%d", &v) == 1) {
|
||||
m->un.value.level[0] = m->un.value.level[1] = v;
|
||||
} else {
|
||||
warnx("Bad numbers %s", q);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
errx(1, "Invalid format.");
|
||||
}
|
||||
|
||||
if (sep) {
|
||||
fprintf(out, " -> ");
|
||||
prfield(p, 0, 0);
|
||||
fprintf(out, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int fd, r, i, j, ch, pos;
|
||||
int aflag = 0, wflag = 0, vflag = 0;
|
||||
char *file = "/dev/mixer";
|
||||
char *sep = "=";
|
||||
mixer_devinfo_t dinfo;
|
||||
int ndev;
|
||||
|
||||
prog = *argv;
|
||||
|
||||
while ((ch = getopt(argc, argv, "af:nvw")) != -1) {
|
||||
switch(ch) {
|
||||
case 'a':
|
||||
aflag++;
|
||||
break;
|
||||
case 'w':
|
||||
wflag++;
|
||||
break;
|
||||
case 'v':
|
||||
vflag++;
|
||||
break;
|
||||
case 'n':
|
||||
sep = 0;
|
||||
break;
|
||||
case 'f':
|
||||
file = optarg;
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
usage:
|
||||
fprintf(out, "%s [-f file] [-v] [-n] name ...\n", prog);
|
||||
fprintf(out, "%s [-f file] [-v] [-n] -w name=value ...\n", prog);
|
||||
fprintf(out, "%s [-f file] [-v] [-n] -a\n", prog);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
fd = open(file, O_RDWR);
|
||||
if (fd < 0)
|
||||
err(1, "%s", file);
|
||||
|
||||
for(ndev = 0; ; ndev++) {
|
||||
dinfo.index = ndev;
|
||||
if (ioctl(fd, AUDIO_MIXER_DEVINFO, &dinfo) < 0)
|
||||
break;
|
||||
}
|
||||
rfields = calloc(ndev, sizeof *rfields);
|
||||
fields = calloc(ndev, sizeof *fields);
|
||||
infos = calloc(ndev, sizeof *infos);
|
||||
values = calloc(ndev, sizeof *values);
|
||||
|
||||
for(i = 0; i < ndev; i++) {
|
||||
infos[i].index = i;
|
||||
ioctl(fd, AUDIO_MIXER_DEVINFO, &infos[i]);
|
||||
}
|
||||
|
||||
for(i = 0; i < ndev; i++) {
|
||||
if (infos[i].mixer_class >= 0 && infos[i].mixer_class < ndev)
|
||||
rfields[i].name = catstr(infos[infos[i].mixer_class].label.name,
|
||||
infos[i].label.name);
|
||||
else
|
||||
rfields[i].name = infos[i].label.name;
|
||||
rfields[i].valp = &values[i];
|
||||
rfields[i].infp = &infos[i];
|
||||
}
|
||||
|
||||
for(i = 0; i < ndev; i++) {
|
||||
values[i].dev = i;
|
||||
values[i].type = infos[i].type;
|
||||
if (infos[i].type != AUDIO_MIXER_CLASS) {
|
||||
values[i].un.value.num_channels = 2;
|
||||
if (ioctl(fd, AUDIO_MIXER_READ, &values[i]) < 0) {
|
||||
values[i].un.value.num_channels = 1;
|
||||
if (ioctl(fd, AUDIO_MIXER_READ, &values[i]) < 0)
|
||||
err(1, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(j = i = 0; i < ndev; i++) {
|
||||
if (infos[i].type != AUDIO_MIXER_CLASS &&
|
||||
infos[i].type != -1) {
|
||||
fields[j++] = rfields[i];
|
||||
for(pos = infos[i].next; pos != AUDIO_MIXER_LAST;
|
||||
pos = infos[pos].next) {
|
||||
fields[j] = rfields[pos];
|
||||
fields[j].name = catstr(rfields[i].name,
|
||||
infos[pos].label.name);
|
||||
infos[pos].type = -1;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (argc == 0 && aflag && !wflag) {
|
||||
for(i = 0; fields[i].name; i++) {
|
||||
prfield(&fields[i], sep, vflag);
|
||||
fprintf(out, "\n");
|
||||
}
|
||||
} else if (argc > 0 && !aflag) {
|
||||
struct field *p;
|
||||
if (wflag) {
|
||||
while(argc--) {
|
||||
char *q;
|
||||
|
||||
q = strchr(*argv, '=');
|
||||
if (q) {
|
||||
*q++ = 0;
|
||||
p = findfield(*argv);
|
||||
if (p == 0)
|
||||
warnx("field %s does not exist", *argv);
|
||||
else {
|
||||
rdfield(p, q, sep);
|
||||
if (ioctl(fd, AUDIO_MIXER_WRITE, p->valp) < 0)
|
||||
warn(NULL);
|
||||
}
|
||||
} else {
|
||||
warnx("No `=' in %s", *argv);
|
||||
}
|
||||
argv++;
|
||||
}
|
||||
} else {
|
||||
while(argc--) {
|
||||
p = findfield(*argv);
|
||||
if (p == 0)
|
||||
warnx("field %s does not exist", *argv);
|
||||
else
|
||||
prfield(p, sep, vflag), fprintf(out, "\n");
|
||||
argv++;
|
||||
}
|
||||
}
|
||||
} else
|
||||
goto usage;
|
||||
exit(0);
|
||||
}
|
Loading…
Reference in New Issue
Block a user