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} |