major modifications to the mixer. currently it doesn't report errors

that it encounters (such as invalid device), but does print usage upon
this error...

but otherwise allows complex commands such as:
mixer -f /dev/mixer4 synth line 50 -rec mic +rec line =rec cd ^rec mix
This commit is contained in:
John-Mark Gurney 1997-09-19 13:38:51 +00:00
parent cf2900be52
commit eddcf96d7d
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=29612
3 changed files with 206 additions and 106 deletions

View File

@ -1,4 +1,4 @@
# $Id$
# $Id: Makefile,v 1.4 1997/02/22 16:06:33 peter Exp $
PROG = mixer
MAN8= mixer.8

View File

@ -33,55 +33,86 @@
.Nd set/display soundcard mixer values
.Sh SYNOPSIS
.Nm
.Nm mixer
.Ar setting
.Op Ar lvalue:rvalue
.Nm mixer
.Ar +rec | -rec
.Op Ar device
.Op Fl f Ar device
.Oo
.Oo Ns
.Ar dev Op Ar lvol Ns Op Ar :rvol
.Li | recsrc |
.Ar {^|+|-|=}rec rdev
.Oc
.Ar ... \&
.Oc
.Sh DESCRIPTION
The
.Nm
command is used to set and display soundcard mixer settings. It may also be
used to start and stop recording from the soundcard. The list of mixer
settings that may
be modified are:
command is used to set and display soundcard mixer device levels. It may
also be used to start and stop recording from the soundcard. The list
of mixer devices that may be modified are:
.Pp
.Bd -ragged -offset indent
vol, bass, treble, synth, pcm, speaker, mic, cd, mix,
pcm2, rec, igain, ogain, line1, line2, and line3.
.Ed
.Pp
Not all mixer settings are available on all soundcards.
Not all mixer devices are available.
.Pp
When
.Nm
is run without any arguments, all settings that are supported by the
soundcard will be displayed.
is run without any arguments, all supported devices are displayed
along with current values.
If the
.Ar setting
argument is specified, then only the value for
the
.Ar setting
mixer will be displayed.
.Ar dev
argument is specified, the value for the
.Ar dev
device will be displayed.
.Pp
To modify the mixer value
.Ar setting ,
.Ar dev ,
the optional left and right channel settings of
.Ar lvalue:rvalue
.Ar lvol Ns Op Ar :rvol
may be specified. The
.Ar lvalue
.Ar lvol
and
.Ar rvalue
.Ar rvol
arguments may be from 0 - 100.
.Pp
To start recording, use the
.Ar +rec
argument. To stop recording, use the
.Ar -rec
argument. The optional argument
To change the recording device you use one of:
.Bl -tag -width =rec -offset indent
.It ^rec
toggles
.Ar rdev
of possible recording devices
.It +rec
adds
.Ar rdev
to possible recording devices
.It -rec
removes
.Ar rdev
from possible recording devices
.It =rec
sets the recording device to
.Ar rdev
.El
.Pp
The above commands work on an internal mask. After all the options
have been parsed, it will set then read the mask from the sound card.
This will let you see EXACTLY what the soundcard is using for the
recording device(s).
.Pp
The option recsrc will display the current recording devices.
.Pp
The option
.Fl f
.Ar device
may be specified to use a different
mixer device. The default device is
.Pa /dev/mixer .
will open
.Ar device
as the mixer device.
This will ONLY work if the
.Fl f
option is immediately after the
.Nm
command.
.Sh FILES
.Bl -tag -width /dev/mixer -compact
.It Pa /dev/mixer
@ -95,7 +126,11 @@ The
command first appeared in
.Fx 2.0.5 .
.Sh AUTHORS
Craig Metz and Hannu Savolainen.
Original source by Craig Metz
.Aq cmetz@thor.tjhsst.edu
and Hannu Savolainen.
Mostly rewriten by John-Mark Gurney
.Aq jmg@freebsd.org .
This
manual page was written by Mike Pritchard
.Aq mpp@FreeBSD.ORG .

View File

@ -7,11 +7,15 @@
* (C) Craig Metz and Hannu Savolainen 1993.
*
* You may do anything you wish with this program.
*
* ditto for my modifications (John-Mark Gurney, 1997)
*/
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#ifdef __FreeBSD__
#include <machine/soundcard.h>
#else
@ -20,25 +24,50 @@
char *names[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_NAMES;
int devmask = 0, recmask = 0, recsrc = 0;
void usage(int devmask, int recmask);
int res_name(const char *name, int mask);
void print_recsrc(int recsrc);
void usage(void)
void
usage(int devmask, int recmask)
{
int i, n = 0;
printf("Usage: mixer { ");
int i, n;
for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
printf("usage:\tmixer [[dev [voll[:volr]] | recsrc | {^|+|-|=}rec recdev] ... ]\n");
printf(" devices:\t");
for (i = 0, n = 0; i < SOUND_MIXER_NRDEVICES; i++)
if ((1 << i) & devmask) {
if (n)
putchar('|');
printf(", ");
printf(names[i]);
n = 1;
}
printf(" } <value>\n or mixer { +rec|-rec } <devicename>\n");
printf("\n rec devices:\t");
for (i = 0, n = 0; i < SOUND_MIXER_NRDEVICES; i++)
if ((1 << i) & recmask) {
if (n)
printf(", ");
printf(names[i]);
n = 1;
}
printf("\n");
exit(1);
}
void print_recsrc(void)
int
res_name(const char *name, int mask)
{
int foo;
for (foo = 0; foo < SOUND_MIXER_NRDEVICES; foo++)
if ((1 << foo) & mask && !strcmp(names[foo], name))
break;
return foo == SOUND_MIXER_NRDEVICES ? -1 : foo;
}
void
print_recsrc(int recsrc)
{
int i, n = 0;
fprintf(stderr, "Recording source: ");
@ -57,19 +86,29 @@ int
main(int argc, char *argv[])
{
int foo, bar, baz, dev;
int devmask = 0, recmask = 0, recsrc = 0, orecsrc;
int dusage = 0, drecsrc = 0;
int l, r;
char name[30] = "/dev/mixer";
char *name;
name = strdup("/dev/mixer");
if (!strcmp(argv[0], "mixer2"))
strcpy(name, "/dev/mixer1");
else
if (!strcmp(argv[0], "mixer3"))
strcpy(name, "/dev/mixer2");
name = strdup("/dev/mixer1");
else if (!strcmp(argv[0], "mixer3"))
name = strdup("/dev/mixer2");
if (argc > 1 && !strcmp(argv[1], "-f")) {
name = strdup(argv[2]);
argc -= 2; argv += 2;
}
if ((baz = open(name, O_RDWR)) < 0) {
perror(name);
exit(1);
}
free(name);
if (ioctl(baz, SOUND_MIXER_READ_DEVMASK, &devmask) == -1) {
perror("SOUND_MIXER_READ_DEVMASK");
exit(-1);
@ -82,22 +121,9 @@ main(int argc, char *argv[])
perror("SOUND_MIXER_READ_RECSRC");
exit(-1);
}
orecsrc = recsrc;
switch (argc) {
case 3:
bar = 1;
break;
case 2:
bar = 0;
break;
case 1:
bar = -1;
break;
default:
usage();
}
if (bar < 0) {
if (argc == 1) {
for (foo = 0; foo < SOUND_MIXER_NRDEVICES; foo++) {
if (!((1 << foo) & devmask))
continue;
@ -110,65 +136,104 @@ main(int argc, char *argv[])
return(0);
}
for (foo = 0; foo < SOUND_MIXER_NRDEVICES && strcmp(names[foo], argv[1]); foo++);
argc--; argv++;
if (foo >= SOUND_MIXER_NRDEVICES) {
if (!strcmp("+rec", argv[1]) || !strcmp("-rec", argv[1])) {
if (argc != 3) {
usage();
/* NOTREACHED */
while (argc) {
if (!strcmp("recsrc", *argv)) {
drecsrc = 1;
argc--; argv++;
continue;
} else if (argc > 1 && !strcmp("rec", *argv + 1)) {
if (**argv != '+' && **argv != '-' &&
**argv != '=' && **argv != '^') {
dusage = 1;
argc -= 1; argv += 1;
continue;
}
for (dev = 0; dev < SOUND_MIXER_NRDEVICES && strcmp(names[dev], argv[2]); dev++);
if (dev >= SOUND_MIXER_NRDEVICES)
usage();
if (!((1 << dev) & recmask)) {
fprintf(stderr, "Invalid recording source %s\n", argv[2]);
exit(-1);
if ((dev = res_name(argv[1], recmask)) == -1) {
dusage = 1;
argc -= 1; argv += 1;
continue;
}
if (argv[1][0] == '+')
switch(**argv) {
case '+':
recsrc |= (1 << dev);
else
break;
case '-':
recsrc &= ~(1 << dev);
if (ioctl(baz, SOUND_MIXER_WRITE_RECSRC, &recsrc) == -1) {
perror("SOUND_MIXER_WRITE_RECSRC");
exit(-1);
break;
case '=':
recsrc = (1 << dev);
break;
case '^':
recsrc ^= (1 << dev);
break;
}
print_recsrc();
drecsrc = 1;
argc -= 2; argv += 2;
continue;
}
} else
usage();
} else {
if (bar) {
if (strchr(argv[2], ':') == NULL) {
sscanf(argv[2], "%d", &bar);
dev = bar;
} else
sscanf(argv[2], "%d:%d", &bar, &dev);
if ((dev = res_name(*argv, devmask)) == -1) {
dusage = 1;
argc--; argv++;
continue;
}
if (bar < 0)
bar = 0;
if (dev < 0)
dev = 0;
if (bar > 100)
bar = 100;
if (dev > 100)
dev = 100;
switch(argc > 1 ? sscanf(argv[1], "%d:%d", &l, &r) : 0) {
case 0:
if (ioctl(baz, MIXER_READ(dev),&bar)== -1) {
perror("MIXER_READ");
argc--; argv++;
continue;
}
printf("Mixer %-8s is currently set to %3d:%d\n",
names[dev], bar & 0x7f, (bar >> 8) & 0x7f);
printf("Setting the mixer %s to %d:%d.\n", names[foo], bar, dev);
argc--; argv++;
break;
case 1:
r = l;
case 2:
if (l < 0)
l = 0;
else if (l > 100)
l = 100;
if (r < 0)
r = 0;
else if (r > 100)
r = 100;
bar |= dev << 8;
if (ioctl(baz, MIXER_WRITE(foo), &bar) == -1)
printf("Setting the mixer %s to %d:%d.\n", names[dev],
l, r);
l |= r << 8;
if (ioctl(baz, MIXER_WRITE(dev), &l) == -1)
perror("WRITE_MIXER");
return (0);
} else {
if (ioctl(baz, MIXER_READ(foo),&bar)== -1)
perror("MIXER_READ");
printf("The mixer %s is currently set to %d:%d.\n", names[foo], bar & 0x7f, (bar >> 8) & 0x7f);
argc -= 2; argv += 2;
break;
}
}
if (orecsrc != recsrc)
if (ioctl(baz, SOUND_MIXER_WRITE_RECSRC, &recsrc) == -1) {
perror("SOUND_MIXER_WRITE_RECSRC");
exit(-1);
}
if (drecsrc) {
if (ioctl(baz, SOUND_MIXER_READ_RECSRC, &recsrc) == -1) {
perror("SOUND_MIXER_READ_RECSRC");
exit(-1);
}
print_recsrc(recsrc);
}
close(baz);
if (dusage)
usage(devmask, recmask);
exit(0);
}