xref: /freebsd/usr.sbin/mixer/mixer.c (revision ef5d438ed4bc17ad7ece3e40fe4d1f9baf3aadf7)
1 /*
2  *	This is an example of a mixer program for Linux
3  *
4  *	updated 1/1/93 to add stereo, level query, broken
5  *      	devmask kludge - cmetz@thor.tjhsst.edu
6  *
7  * (C) Craig Metz and Hannu Savolainen 1993.
8  *
9  * You may do anything you wish with this program.
10  */
11 
12 #include <stdio.h>
13 #include <fcntl.h>
14 #include <string.h>
15 #ifdef __FreeBSD__
16 #include <machine/soundcard.h>
17 #else
18 #include <sys/soundcard.h>
19 #endif
20 
21 char *names[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_NAMES;
22 
23 int devmask = 0, recmask = 0, recsrc = 0;
24 
25 void usage(void)
26 {
27 	int i, n = 0;
28 	printf("Usage: mixer { ");
29 
30 	for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
31 		if ((1 << i) & devmask)  {
32 			if (n)
33 				putchar('|');
34 			printf(names[i]);
35 			n = 1;
36 		}
37 	printf(" } <value>\n  or   mixer { +rec|-rec } <devicename>\n");
38 	exit(1);
39 }
40 
41 void print_recsrc(void)
42 {
43 	int i, n = 0;
44 	fprintf(stderr, "Recording source: ");
45 
46 	for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
47 		if ((1 << i) & recsrc) {
48 			if (n)
49 				fprintf(stderr, ", ");
50 			fprintf(stderr, names[i]);
51 			n = 1;
52 		}
53 	fprintf(stderr, "\n");
54 }
55 
56 int
57 main(int argc, char *argv[])
58 {
59 	int foo, bar, baz, dev;
60 
61 	char name[30] = "/dev/mixer";
62 
63 	if (!strcmp(argv[0], "mixer2"))
64 	   strcpy(name, "/dev/mixer1");
65 	else
66 	  if (!strcmp(argv[0], "mixer3"))
67 	     strcpy(name, "/dev/mixer2");
68 
69 	if ((baz = open(name, O_RDWR)) < 0) {
70 		perror(name);
71 		exit(1);
72 	}
73 	if (ioctl(baz, SOUND_MIXER_READ_DEVMASK, &devmask) == -1) {
74 		perror("SOUND_MIXER_READ_DEVMASK");
75 		exit(-1);
76 	}
77 	if (ioctl(baz, SOUND_MIXER_READ_RECMASK, &recmask) == -1) {
78 		perror("SOUND_MIXER_READ_RECMASK");
79 		exit(-1);
80 	}
81 	if (ioctl(baz, SOUND_MIXER_READ_RECSRC, &recsrc) == -1) {
82 		perror("SOUND_MIXER_READ_RECSRC");
83 		exit(-1);
84 	}
85 
86 	switch (argc) {
87 		case 3:
88 			bar = 1;
89 			break;
90 		case 2:
91 			bar = 0;
92 			break;
93 		case 1:
94 			bar = -1;
95 			break;
96 		default:
97 			usage();
98 	}
99 
100 	if (bar < 0) {
101 		for (foo = 0; foo < SOUND_MIXER_NRDEVICES; foo++) {
102 			if (!((1 << foo) & devmask))
103 				continue;
104 			if (ioctl(baz, MIXER_READ(foo),&bar)== -1) {
105 			   	perror("MIXER_READ");
106 				continue;
107 			}
108 			printf("Mixer %-8s is currently set to %3d:%d\n", names[foo], bar & 0x7f, (bar >> 8) & 0x7f);
109 		}
110 		return(0);
111 	}
112 
113 	for (foo = 0; foo < SOUND_MIXER_NRDEVICES && strcmp(names[foo], argv[1]); foo++);
114 
115 	if (foo >= SOUND_MIXER_NRDEVICES) {
116 
117 		if (!strcmp("+rec", argv[1]) || !strcmp("-rec", argv[1])) {
118 			if (argc != 3) {
119 				usage();
120 				/* NOTREACHED */
121 			}
122 			for (dev = 0; dev < SOUND_MIXER_NRDEVICES && strcmp(names[dev], argv[2]); dev++);
123 			if (dev >= SOUND_MIXER_NRDEVICES)
124 				usage();
125 
126 			if (!((1 << dev) & recmask)) {
127 				fprintf(stderr, "Invalid recording source %s\n", argv[2]);
128 				exit(-1);
129 			}
130 			if (argv[1][0] == '+')
131 				recsrc |= (1 << dev);
132 			else
133 				recsrc &= ~(1 << dev);
134 
135 			if (ioctl(baz, SOUND_MIXER_WRITE_RECSRC, &recsrc) == -1) {
136 				perror("SOUND_MIXER_WRITE_RECSRC");
137 				exit(-1);
138 			}
139 			print_recsrc();
140 
141 		} else
142 			usage();
143 	} else {
144 		if (bar) {
145 			if (strchr(argv[2], ':') == NULL) {
146 				sscanf(argv[2], "%d", &bar);
147 				dev = bar;
148 			} else
149 				sscanf(argv[2], "%d:%d", &bar, &dev);
150 
151 			if (bar < 0)
152 				bar = 0;
153 			if (dev < 0)
154 				dev = 0;
155 			if (bar > 100)
156 				bar = 100;
157 			if (dev > 100)
158 				dev = 100;
159 
160 			printf("Setting the mixer %s to %d:%d.\n", names[foo], bar, dev);
161 
162                         bar |= dev << 8;
163 			if (ioctl(baz, MIXER_WRITE(foo), &bar) == -1)
164 				perror("WRITE_MIXER");
165 	return (0);
166 		} else {
167 			if (ioctl(baz, MIXER_READ(foo),&bar)== -1)
168 			   perror("MIXER_READ");
169 			printf("The mixer %s is currently set to %d:%d.\n", names[foo], bar & 0x7f, (bar >> 8) & 0x7f);
170 		}
171 	}
172 
173 	close(baz);
174 }
175