2 * This is an example of a mixer program for Linux
4 * updated 1/1/93 to add stereo, level query, broken
5 * devmask kludge - cmetz@thor.tjhsst.edu
7 * (C) Craig Metz and Hannu Savolainen 1993.
9 * You may do anything you wish with this program.
11 * ditto for my modifications (John-Mark Gurney, 1997)
14 #include <sys/cdefs.h>
15 __FBSDID("$FreeBSD$");
25 #include <sys/soundcard.h>
27 const char *names[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_NAMES;
29 static void usage(int devmask, int recmask);
30 static int res_name(const char *name, int mask);
31 static void print_recsrc(int recsrc, int recmask, int sflag);
34 usage(int devmask, int recmask)
38 printf("usage: mixer [-f device] [-s | -S] [dev [+|-][voll[:[+|-]volr]] ...\n"
39 " mixer [-f device] [-s | -S] recsrc ...\n"
40 " mixer [-f device] [-s | -S] {^|+|-|=}rec rdev ...\n");
43 for (i = 0, n = 0; i < SOUND_MIXER_NRDEVICES; i++)
44 if ((1 << i) & devmask) {
47 printf("%s", names[i]);
52 printf("\n rec devices: ");
53 for (i = 0, n = 0; i < SOUND_MIXER_NRDEVICES; i++)
54 if ((1 << i) & recmask) {
57 printf("%s", names[i]);
66 res_name(const char *name, int mask)
70 for (foo = 0; foo < SOUND_MIXER_NRDEVICES; foo++)
71 if ((1 << foo) & mask && strcmp(names[foo], name) == 0)
74 return (foo == SOUND_MIXER_NRDEVICES ? -1 : foo);
78 print_recsrc(int recsrc, int recmask, int sflag)
86 printf("Recording source: ");
88 for (i = 0, n = 0; i < SOUND_MIXER_NRDEVICES; i++)
89 if ((1 << i) & recsrc) {
91 printf("%srec ", n ? " +" : "=");
94 printf("%s", names[i]);
102 main(int argc, char *argv[])
104 char mixer[PATH_MAX] = "/dev/mixer";
105 char lstr[5], rstr[5];
107 int devmask = 0, recmask = 0, recsrc = 0, orecsrc;
108 int dusage = 0, drecsrc = 0, sflag = 0, Sflag = 0;
109 int l, r, lrel, rrel;
110 int ch, foo, bar, baz, dev, m, n, t;
112 if ((name = strdup(basename(argv[0]))) == NULL)
114 if (strncmp(name, "mixer", 5) == 0 && name[5] != '\0') {
115 n = strtol(name + 5, &eptr, 10) - 1;
116 if (n > 0 && *eptr == '\0')
117 snprintf(mixer, PATH_MAX - 1, "/dev/mixer%d", n);
124 if (n >= argc || *argv[n] != '-')
126 if (strlen(argv[n]) != 2) {
127 if (strcmp(argv[n] + 1, "rec") != 0)
132 if (ch == 'f' && n < argc - 1) {
135 } else if (ch == 's') {
138 } else if (ch == 'S') {
152 if ((baz = open(name, O_RDWR)) < 0)
154 if (ioctl(baz, SOUND_MIXER_READ_DEVMASK, &devmask) == -1)
155 err(1, "SOUND_MIXER_READ_DEVMASK");
156 if (ioctl(baz, SOUND_MIXER_READ_RECMASK, &recmask) == -1)
157 err(1, "SOUND_MIXER_READ_RECMASK");
158 if (ioctl(baz, SOUND_MIXER_READ_RECSRC, &recsrc) == -1)
159 err(1, "SOUND_MIXER_READ_RECSRC");
162 if (argc == 1 && dusage == 0) {
163 for (foo = 0, n = 0; foo < SOUND_MIXER_NRDEVICES; foo++) {
164 if (!((1 << foo) & devmask))
166 if (ioctl(baz, MIXER_READ(foo),&bar) == -1) {
170 if (Sflag || sflag) {
171 printf("%s%s%c%d:%d", n ? " " : "",
172 names[foo], Sflag ? ':' : ' ',
173 bar & 0x7f, (bar >> 8) & 0x7f);
176 printf("Mixer %-8s is currently set to "
177 "%3d:%d\n", names[foo], bar & 0x7f,
182 print_recsrc(recsrc, recmask, Sflag || sflag);
190 while (argc > 0 && dusage == 0) {
191 if (strcmp("recsrc", *argv) == 0) {
196 } else if (strcmp("rec", *argv + 1) == 0) {
197 if (**argv != '+' && **argv != '-' &&
198 **argv != '=' && **argv != '^') {
199 warnx("unknown modifier: %c", **argv);
204 warnx("no recording device specified");
208 if ((dev = res_name(argv[1], recmask)) == -1) {
209 warnx("unknown recording device: %s", argv[1]);
215 recsrc |= (1 << dev);
218 recsrc &= ~(1 << dev);
224 recsrc ^= (1 << dev);
233 if ((t = sscanf(*argv, "%d:%d", &l, &r)) > 0)
235 else if ((dev = res_name(*argv, devmask)) == -1) {
236 warnx("unknown device: %s", *argv);
243 m = sscanf(argv[1], "%7[^:]:%7s", lstr, rstr);
245 if (*lstr == '+' || *lstr == '-')
247 l = strtol(lstr, NULL, 10);
250 if (*rstr == '+' || *rstr == '-')
252 r = strtol(rstr, NULL, 10);
256 switch (argc > 1 ? m : t) {
258 if (ioctl(baz, MIXER_READ(dev), &bar) == -1) {
264 if (Sflag || sflag) {
265 printf("%s%s%c%d:%d", n ? " " : "",
266 names[dev], Sflag ? ':' : ' ',
267 bar & 0x7f, (bar >> 8) & 0x7f);
270 printf("Mixer %-8s is currently set to "
271 "%3d:%d\n", names[dev], bar & 0x7f,
281 if (ioctl(baz, MIXER_READ(dev), &bar) == -1) {
289 l = (bar & 0x7f) + l;
291 r = ((bar >> 8) & 0x7f) + r;
303 printf("Setting the mixer %s from %d:%d to "
304 "%d:%d.\n", names[dev], bar & 0x7f,
305 (bar >> 8) & 0x7f, l, r);
308 if (ioctl(baz, MIXER_WRITE(dev), &l) == -1)
319 usage(devmask, recmask);
323 if (orecsrc != recsrc) {
324 if (ioctl(baz, SOUND_MIXER_WRITE_RECSRC, &recsrc) == -1)
325 err(1, "SOUND_MIXER_WRITE_RECSRC");
326 if (ioctl(baz, SOUND_MIXER_READ_RECSRC, &recsrc) == -1)
327 err(1, "SOUND_MIXER_READ_RECSRC");
331 print_recsrc(recsrc, recmask, Sflag || sflag);