summaryrefslogtreecommitdiffstats
path: root/usr.sbin/mixer/mixer.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/mixer/mixer.c')
-rw-r--r--usr.sbin/mixer/mixer.c221
1 files changed, 143 insertions, 78 deletions
diff --git a/usr.sbin/mixer/mixer.c b/usr.sbin/mixer/mixer.c
index 9415a42..edb9ab7 100644
--- a/usr.sbin/mixer/mixer.c
+++ b/usr.sbin/mixer/mixer.c
@@ -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("\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(" } <value>\n or mixer { +rec|-rec } <devicename>\n");
+ 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;
- char name[30] = "/dev/mixer";
+ 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++);
-
- if (foo >= SOUND_MIXER_NRDEVICES) {
-
- if (!strcmp("+rec", argv[1]) || !strcmp("-rec", argv[1])) {
- if (argc != 3) {
- usage();
- /* NOTREACHED */
+ argc--; argv++;
+
+ 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);
+ break;
+ case '=':
+ recsrc = (1 << dev);
+ break;
+ case '^':
+ recsrc ^= (1 << dev);
+ break;
+ }
+ drecsrc = 1;
+ argc -= 2; argv += 2;
+ continue;
+ }
- if (ioctl(baz, SOUND_MIXER_WRITE_RECSRC, &recsrc) == -1) {
- perror("SOUND_MIXER_WRITE_RECSRC");
- exit(-1);
+ if ((dev = res_name(*argv, devmask)) == -1) {
+ dusage = 1;
+ argc--; argv++;
+ continue;
+ }
+
+ 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;
}
- print_recsrc();
-
- } 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 (bar < 0)
- bar = 0;
- if (dev < 0)
- dev = 0;
- if (bar > 100)
- bar = 100;
- if (dev > 100)
- dev = 100;
-
- printf("Setting the mixer %s to %d:%d.\n", names[foo], bar, dev);
-
- bar |= dev << 8;
- if (ioctl(baz, MIXER_WRITE(foo), &bar) == -1)
+ printf("Mixer %-8s is currently set to %3d:%d\n",
+ names[dev], bar & 0x7f, (bar >> 8) & 0x7f);
+
+ 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;
+
+ 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);
}
OpenPOWER on IntegriCloud