Deleted Added
full compact
mixer.c (177195) mixer.c (177197)
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 * ditto for my modifications (John-Mark Gurney, 1997)
12 */
13
14#include <sys/cdefs.h>
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 * ditto for my modifications (John-Mark Gurney, 1997)
12 */
13
14#include <sys/cdefs.h>
15__FBSDID("$FreeBSD: head/usr.sbin/mixer/mixer.c 177195 2008-03-15 01:09:47Z jkim $");
15__FBSDID("$FreeBSD: head/usr.sbin/mixer/mixer.c 177197 2008-03-15 01:20:05Z jkim $");
16
17#include <err.h>
18#include <fcntl.h>
19#include <libgen.h>
20#include <limits.h>
21#include <stdio.h>
22#include <string.h>
23#include <stdlib.h>
24#include <unistd.h>
25#include <sys/soundcard.h>
26
16
17#include <err.h>
18#include <fcntl.h>
19#include <libgen.h>
20#include <limits.h>
21#include <stdio.h>
22#include <string.h>
23#include <stdlib.h>
24#include <unistd.h>
25#include <sys/soundcard.h>
26
27const char *names[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_NAMES;
27const char *names[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_NAMES;
28
28
29void usage(int devmask, int recmask);
30int res_name(const char *name, int mask);
31void print_recsrc(int recsrc, int recmask, int shortflag);
29static void usage(int devmask, int recmask);
30static int res_name(const char *name, int mask);
31static void print_recsrc(int recsrc, int recmask, int sflag);
32
32
33void
33static void
34usage(int devmask, int recmask)
35{
34usage(int devmask, int recmask)
35{
36 int i, n;
36 int i, n;
37
38 printf("usage: mixer [-f device] [-s | -S] [dev [+|-][voll[:[+|-]volr]] ...\n"
37
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");
39 " mixer [-f device] [-s | -S] recsrc ...\n"
40 " mixer [-f device] [-s | -S] {^|+|-|=}rec rdev ...\n");
41 if (devmask != 0) {
42 printf(" devices: ");
43 for (i = 0, n = 0; i < SOUND_MIXER_NRDEVICES; i++)
44 if ((1 << i) & devmask) {
45 if (n)
46 printf(", ");
47 printf("%s", names[i]);
41 if (devmask != 0) {
42 printf(" devices: ");
43 for (i = 0, n = 0; i < SOUND_MIXER_NRDEVICES; i++)
44 if ((1 << i) & devmask) {
45 if (n)
46 printf(", ");
47 printf("%s", names[i]);
48 n = 1;
48 n++;
49 }
50 }
51 if (recmask != 0) {
52 printf("\n rec devices: ");
53 for (i = 0, n = 0; i < SOUND_MIXER_NRDEVICES; i++)
54 if ((1 << i) & recmask) {
55 if (n)
56 printf(", ");
57 printf("%s", names[i]);
49 }
50 }
51 if (recmask != 0) {
52 printf("\n rec devices: ");
53 for (i = 0, n = 0; i < SOUND_MIXER_NRDEVICES; i++)
54 if ((1 << i) & recmask) {
55 if (n)
56 printf(", ");
57 printf("%s", names[i]);
58 n = 1;
58 n++;
59 }
60 }
61 printf("\n");
62 exit(1);
63}
64
59 }
60 }
61 printf("\n");
62 exit(1);
63}
64
65int
65static int
66res_name(const char *name, int mask)
67{
66res_name(const char *name, int mask)
67{
68 int foo;
68 int foo;
69
70 for (foo = 0; foo < SOUND_MIXER_NRDEVICES; foo++)
69
70 for (foo = 0; foo < SOUND_MIXER_NRDEVICES; foo++)
71 if ((1 << foo) & mask && !strcmp(names[foo], name))
71 if ((1 << foo) & mask && strcmp(names[foo], name) == 0)
72 break;
73
72 break;
73
74 return foo == SOUND_MIXER_NRDEVICES ? -1 : foo;
74 return (foo == SOUND_MIXER_NRDEVICES ? -1 : foo);
75}
76
75}
76
77void
78print_recsrc(int recsrc, int recmask, int shortflag)
77static void
78print_recsrc(int recsrc, int recmask, int sflag)
79{
79{
80 int i, n = 0;
80 int i, n;
81
82 if (recmask == 0)
83 return;
84
81
82 if (recmask == 0)
83 return;
84
85 if (!shortflag)
85 if (!sflag)
86 printf("Recording source: ");
87
86 printf("Recording source: ");
87
88 for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
88 for (i = 0, n = 0; i < SOUND_MIXER_NRDEVICES; i++)
89 if ((1 << i) & recsrc) {
89 if ((1 << i) & recsrc) {
90 if (shortflag) {
91 if (n)
92 printf(" +rec ");
93 else
94 printf("=rec ");
95 } else if (n)
90 if (sflag)
91 printf("%srec ", n ? " +" : "=");
92 else if (n)
96 printf(", ");
97 printf("%s", names[i]);
93 printf(", ");
94 printf("%s", names[i]);
98 n = 1;
95 n++;
99 }
96 }
100 if (!shortflag)
97 if (!sflag)
101 printf("\n");
102}
103
104int
105main(int argc, char *argv[])
106{
98 printf("\n");
99}
100
101int
102main(int argc, char *argv[])
103{
107 char mixer[PATH_MAX] = "/dev/mixer";
108 char *name, *eptr;
109 int foo, bar, baz, dev;
110 int devmask = 0, recmask = 0, recsrc = 0, orecsrc;
111 int dusage = 0, drecsrc = 0, shortflag = 0, Shortflag = 0;
112 int l = 0, r = 0, t = 0;
113 char lstr[5], rstr[5];
114 int n, lrel = 0, rrel = 0;
115 char ch;
104 char mixer[PATH_MAX] = "/dev/mixer";
105 char lstr[5], rstr[5];
106 char *name, *eptr;
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;
116
117 if ((name = strdup(basename(argv[0]))) == NULL)
118 err(1, "strdup()");
119 if (strncmp(name, "mixer", 5) == 0 && name[5] != '\0') {
120 n = strtol(name + 5, &eptr, 10) - 1;
121 if (n > 0 && *eptr == '\0')
122 snprintf(mixer, PATH_MAX - 1, "/dev/mixer%d", n);
123 }

--- 9 unchanged lines hidden (view full) ---

133 dusage = 1;
134 break;
135 }
136 ch = *(argv[n] + 1);
137 if (ch == 'f' && n < argc - 1) {
138 name = argv[n + 1];
139 n += 2;
140 } else if (ch == 's') {
111
112 if ((name = strdup(basename(argv[0]))) == NULL)
113 err(1, "strdup()");
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);
118 }

--- 9 unchanged lines hidden (view full) ---

128 dusage = 1;
129 break;
130 }
131 ch = *(argv[n] + 1);
132 if (ch == 'f' && n < argc - 1) {
133 name = argv[n + 1];
134 n += 2;
135 } else if (ch == 's') {
141 shortflag = 1;
136 sflag = 1;
142 n++;
143 } else if (ch == 'S') {
137 n++;
138 } else if (ch == 'S') {
144 Shortflag = 1;
139 Sflag = 1;
145 n++;
146 } else {
147 dusage = 1;
148 break;
149 }
150 }
140 n++;
141 } else {
142 dusage = 1;
143 break;
144 }
145 }
151 if (shortflag && Shortflag)
146 if (sflag && Sflag)
152 dusage = 1;
153
154 argc -= n - 1;
155 argv += n - 1;
156
157 if ((baz = open(name, O_RDWR)) < 0)
158 err(1, "%s", name);
159 if (ioctl(baz, SOUND_MIXER_READ_DEVMASK, &devmask) == -1)
160 err(1, "SOUND_MIXER_READ_DEVMASK");
161 if (ioctl(baz, SOUND_MIXER_READ_RECMASK, &recmask) == -1)
162 err(1, "SOUND_MIXER_READ_RECMASK");
163 if (ioctl(baz, SOUND_MIXER_READ_RECSRC, &recsrc) == -1)
164 err(1, "SOUND_MIXER_READ_RECSRC");
165 orecsrc = recsrc;
166
147 dusage = 1;
148
149 argc -= n - 1;
150 argv += n - 1;
151
152 if ((baz = open(name, O_RDWR)) < 0)
153 err(1, "%s", name);
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");
160 orecsrc = recsrc;
161
167 if ((argc == 1) && (dusage == 0)) {
168 for (foo = 0; foo < SOUND_MIXER_NRDEVICES; foo++) {
169 if (!((1 << foo) & devmask))
162 if (argc == 1 && dusage == 0) {
163 for (foo = 0, n = 0; foo < SOUND_MIXER_NRDEVICES; foo++) {
164 if (!((1 << foo) & devmask))
170 continue;
165 continue;
171 if (ioctl(baz, MIXER_READ(foo),&bar)== -1) {
166 if (ioctl(baz, MIXER_READ(foo),&bar) == -1) {
172 warn("MIXER_READ");
173 continue;
174 }
167 warn("MIXER_READ");
168 continue;
169 }
175 if (Shortflag)
176 printf("%s:%d:%d ", names[foo], bar & 0x7f,
177 (bar >> 8) & 0x7f);
178 else if (shortflag)
179 printf("%s %d:%d ", names[foo], bar & 0x7f,
180 (bar >> 8) & 0x7f);
181 else
182 printf("Mixer %-8s is currently set to %3d:%d\n",
183 names[foo], bar & 0x7f, (bar >> 8) & 0x7f);
170 if (Sflag || sflag) {
171 printf("%s%s%c%d:%d", n ? " " : "",
172 names[foo], Sflag ? ':' : ' ',
173 bar & 0x7f, (bar >> 8) & 0x7f);
174 n++;
175 } else
176 printf("Mixer %-8s is currently set to "
177 "%3d:%d\n", names[foo], bar & 0x7f,
178 (bar >> 8) & 0x7f);
184 }
179 }
185 if (ioctl(baz, SOUND_MIXER_READ_RECSRC, &recsrc) == -1)
186 err(1, "SOUND_MIXER_READ_RECSRC");
187 print_recsrc(recsrc, recmask, shortflag || Shortflag);
188 return(0);
180 if (n && recmask)
181 printf(" ");
182 print_recsrc(recsrc, recmask, Sflag | sflag);
183 return (0);
189 }
190
184 }
185
191 argc--; argv++;
186 argc--;
187 argv++;
192
188
193 while ((argc > 0) && (dusage == 0)) {
194 if (!strcmp("recsrc", *argv)) {
189 n = 0;
190 while (argc > 0 && dusage == 0) {
191 if (strcmp("recsrc", *argv) == 0) {
195 drecsrc = 1;
192 drecsrc = 1;
196 argc--; argv++;
193 argc--;
194 argv++;
197 continue;
195 continue;
198 } else if (argc > 1 && !strcmp("rec", *argv + 1)) {
196 } else if (argc > 1 && strcmp("rec", *argv + 1) == 0) {
199 if (**argv != '+' && **argv != '-' &&
200 **argv != '=' && **argv != '^') {
201 warnx("unknown modifier: %c", **argv);
202 dusage = 1;
203 break;
204 }
205 if ((dev = res_name(argv[1], recmask)) == -1) {
206 warnx("unknown recording device: %s", argv[1]);
207 dusage = 1;
208 break;
209 }
197 if (**argv != '+' && **argv != '-' &&
198 **argv != '=' && **argv != '^') {
199 warnx("unknown modifier: %c", **argv);
200 dusage = 1;
201 break;
202 }
203 if ((dev = res_name(argv[1], recmask)) == -1) {
204 warnx("unknown recording device: %s", argv[1]);
205 dusage = 1;
206 break;
207 }
210 switch(**argv) {
208 switch (**argv) {
211 case '+':
212 recsrc |= (1 << dev);
213 break;
214 case '-':
215 recsrc &= ~(1 << dev);
216 break;
217 case '=':
218 recsrc = (1 << dev);
219 break;
220 case '^':
221 recsrc ^= (1 << dev);
222 break;
223 }
224 drecsrc = 1;
209 case '+':
210 recsrc |= (1 << dev);
211 break;
212 case '-':
213 recsrc &= ~(1 << dev);
214 break;
215 case '=':
216 recsrc = (1 << dev);
217 break;
218 case '^':
219 recsrc ^= (1 << dev);
220 break;
221 }
222 drecsrc = 1;
225 argc -= 2; argv += 2;
223 argc -= 2;
224 argv += 2;
226 continue;
227 }
228
225 continue;
226 }
227
229 if ((t = sscanf(*argv, "%d:%d", &l, &r)) > 0) {
228 if ((t = sscanf(*argv, "%d:%d", &l, &r)) > 0)
230 dev = 0;
229 dev = 0;
231 }
232 else if((dev = res_name(*argv, devmask)) == -1) {
230 else if ((dev = res_name(*argv, devmask)) == -1) {
233 warnx("unknown device: %s", *argv);
234 dusage = 1;
235 break;
236 }
237
231 warnx("unknown device: %s", *argv);
232 dusage = 1;
233 break;
234 }
235
238#define issign(c) (((c) == '+') || ((c) == '-'))
239
236 lrel = rrel = 0;
240 if (argc > 1) {
237 if (argc > 1) {
241 n = sscanf(argv[1], "%7[^:]:%7s", lstr, rstr);
242 if (n > 0) {
243 if (issign(lstr[0]))
238 m = sscanf(argv[1], "%7[^:]:%7s", lstr, rstr);
239 if (m > 0) {
240 if (*lstr == '+' || *lstr == '-')
244 lrel = rrel = 1;
241 lrel = rrel = 1;
245 l = atoi(lstr);
242 l = strtol(lstr, NULL, 10);
246 }
243 }
247 if (n > 1) {
248 rrel = 0;
249 if (issign(rstr[0]))
244 if (m > 1) {
245 if (*rstr == '+' || *rstr == '-')
250 rrel = 1;
246 rrel = 1;
251 r = atoi(rstr);
247 r = strtol(rstr, NULL, 10);
252 }
253 }
254
248 }
249 }
250
255 switch(argc > 1 ? n : t) {
251 switch (argc > 1 ? m : t) {
256 case 0:
252 case 0:
257 if (ioctl(baz, MIXER_READ(dev),&bar)== -1) {
253 if (ioctl(baz, MIXER_READ(dev), &bar) == -1) {
258 warn("MIXER_READ");
254 warn("MIXER_READ");
259 argc--; argv++;
255 argc--;
256 argv++;
260 continue;
261 }
257 continue;
258 }
262 if (Shortflag)
263 printf("%s:%d:%d ", names[dev], bar & 0x7f,
264 (bar >> 8) & 0x7f);
265 else if (shortflag)
266 printf("%s %d:%d ", names[dev], bar & 0x7f,
267 (bar >> 8) & 0x7f);
268 else
269 printf("Mixer %-8s is currently set to %3d:%d\n",
270 names[dev], bar & 0x7f, (bar >> 8) & 0x7f);
259 if (Sflag || sflag) {
260 printf("%s%s%c%d:%d", n ? " " : "",
261 names[dev], Sflag ? ':' : ' ',
262 bar & 0x7f, (bar >> 8) & 0x7f);
263 n++;
264 } else
265 printf("Mixer %-8s is currently set to "
266 "%3d:%d\n", names[dev], bar & 0x7f,
267 (bar >> 8) & 0x7f);
271
268
272 argc--; argv++;
269 argc--;
270 argv++;
273 break;
274 case 1:
275 r = l;
271 break;
272 case 1:
273 r = l;
274 /* FALLTHROUGH */
276 case 2:
275 case 2:
277 if (ioctl(baz, MIXER_READ(dev),&bar)== -1) {
276 if (ioctl(baz, MIXER_READ(dev), &bar) == -1) {
278 warn("MIXER_READ");
277 warn("MIXER_READ");
279 argc--; argv++;
278 argc--;
279 argv++;
280 continue;
281 }
282
283 if (lrel)
284 l = (bar & 0x7f) + l;
285 if (rrel)
286 r = ((bar >> 8) & 0x7f) + r;
287
288 if (l < 0)
289 l = 0;
290 else if (l > 100)
291 l = 100;
292 if (r < 0)
293 r = 0;
294 else if (r > 100)
295 r = 100;
296
280 continue;
281 }
282
283 if (lrel)
284 l = (bar & 0x7f) + l;
285 if (rrel)
286 r = ((bar >> 8) & 0x7f) + r;
287
288 if (l < 0)
289 l = 0;
290 else if (l > 100)
291 l = 100;
292 if (r < 0)
293 r = 0;
294 else if (r > 100)
295 r = 100;
296
297 if (!Shortflag)
298 printf("Setting the mixer %s from %d:%d to %d:%d.\n",
299 names[dev], bar & 0x7f, (bar >> 8) & 0x7f, l, r);
297 if (!Sflag)
298 printf("Setting the mixer %s from %d:%d to "
299 "%d:%d.\n", names[dev], bar & 0x7f,
300 (bar >> 8) & 0x7f, l, r);
300
301 l |= r << 8;
302 if (ioctl(baz, MIXER_WRITE(dev), &l) == -1)
303 warn("WRITE_MIXER");
304
301
302 l |= r << 8;
303 if (ioctl(baz, MIXER_WRITE(dev), &l) == -1)
304 warn("WRITE_MIXER");
305
305 argc -= 2; argv += 2;
306 argc -= 2;
307 argv += 2;
306 break;
307 }
308 }
309
310 if (dusage) {
311 close(baz);
312 usage(devmask, recmask);
308 break;
309 }
310 }
311
312 if (dusage) {
313 close(baz);
314 usage(devmask, recmask);
313 /* Not reached */
315 /* NOTREACHED */
314 }
315
316 if (orecsrc != recsrc) {
317 if (ioctl(baz, SOUND_MIXER_WRITE_RECSRC, &recsrc) == -1)
318 err(1, "SOUND_MIXER_WRITE_RECSRC");
319 if (ioctl(baz, SOUND_MIXER_READ_RECSRC, &recsrc) == -1)
320 err(1, "SOUND_MIXER_READ_RECSRC");
321 }
316 }
317
318 if (orecsrc != recsrc) {
319 if (ioctl(baz, SOUND_MIXER_WRITE_RECSRC, &recsrc) == -1)
320 err(1, "SOUND_MIXER_WRITE_RECSRC");
321 if (ioctl(baz, SOUND_MIXER_READ_RECSRC, &recsrc) == -1)
322 err(1, "SOUND_MIXER_READ_RECSRC");
323 }
322
324
323 if (drecsrc)
325 if (drecsrc)
324 print_recsrc(recsrc, recmask, shortflag || Shortflag);
326 print_recsrc(recsrc, recmask, Sflag || sflag);
325
326 close(baz);
327
327
328 close(baz);
329
328 exit(0);
330 return (0);
329}
331}