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.
| 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)
|
10 */ 11 12#include <stdio.h> 13#include <fcntl.h> 14#include <string.h>
| 12 */ 13 14#include <stdio.h> 15#include <fcntl.h> 16#include <string.h>
|
| 17#include <stdlib.h> 18#include <unistd.h>
|
15#ifdef __FreeBSD__ 16#include <machine/soundcard.h> 17#else 18#include <sys/soundcard.h> 19#endif 20 21char *names[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_NAMES; 22
| 19#ifdef __FreeBSD__ 20#include <machine/soundcard.h> 21#else 22#include <sys/soundcard.h> 23#endif 24 25char *names[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_NAMES; 26
|
23int devmask = 0, recmask = 0, recsrc = 0;
| 27void usage(int devmask, int recmask); 28int res_name(const char *name, int mask); 29void print_recsrc(int recsrc);
|
24
| 30
|
25void usage(void)
| 31void 32usage(int devmask, int recmask)
|
26{
| 33{
|
27 int i, n = 0; 28 printf("Usage: mixer { ");
| 34 int i, n;
|
29
| 35
|
30 for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
| 36 printf("usage:\tmixer [[dev [voll[:volr]] | recsrc | {^|+|-|=}rec recdev] ... ]\n"); 37 printf(" devices:\t"); 38 for (i = 0, n = 0; i < SOUND_MIXER_NRDEVICES; i++)
|
31 if ((1 << i) & devmask) { 32 if (n)
| 39 if ((1 << i) & devmask) { 40 if (n)
|
33 putchar('|');
| 41 printf(", ");
|
34 printf(names[i]); 35 n = 1; 36 }
| 42 printf(names[i]); 43 n = 1; 44 }
|
37 printf(" } <value>\n or mixer { +rec|-rec } <devicename>\n");
| 45 printf("\n rec devices:\t"); 46 for (i = 0, n = 0; i < SOUND_MIXER_NRDEVICES; i++) 47 if ((1 << i) & recmask) { 48 if (n) 49 printf(", "); 50 printf(names[i]); 51 n = 1; 52 } 53 printf("\n");
|
38 exit(1); 39} 40
| 54 exit(1); 55} 56
|
41void print_recsrc(void)
| 57int 58res_name(const char *name, int mask)
|
42{
| 59{
|
| 60 int foo; 61 62 for (foo = 0; foo < SOUND_MIXER_NRDEVICES; foo++) 63 if ((1 << foo) & mask && !strcmp(names[foo], name)) 64 break; 65 66 return foo == SOUND_MIXER_NRDEVICES ? -1 : foo; 67} 68 69void 70print_recsrc(int recsrc) 71{
|
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 56int 57main(int argc, char *argv[]) 58{ 59 int foo, bar, baz, dev;
| 72 int i, n = 0; 73 fprintf(stderr, "Recording source: "); 74 75 for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) 76 if ((1 << i) & recsrc) { 77 if (n) 78 fprintf(stderr, ", "); 79 fprintf(stderr, names[i]); 80 n = 1; 81 } 82 fprintf(stderr, "\n"); 83} 84 85int 86main(int argc, char *argv[]) 87{ 88 int foo, bar, baz, dev;
|
| 89 int devmask = 0, recmask = 0, recsrc = 0, orecsrc; 90 int dusage = 0, drecsrc = 0; 91 int l, r;
|
60
| 92
|
61 char name[30] = "/dev/mixer";
| 93 char *name;
|
62
| 94
|
| 95 name = strdup("/dev/mixer"); 96
|
63 if (!strcmp(argv[0], "mixer2"))
| 97 if (!strcmp(argv[0], "mixer2"))
|
64 strcpy(name, "/dev/mixer1"); 65 else 66 if (!strcmp(argv[0], "mixer3")) 67 strcpy(name, "/dev/mixer2");
| 98 name = strdup("/dev/mixer1"); 99 else if (!strcmp(argv[0], "mixer3")) 100 name = strdup("/dev/mixer2");
|
68
| 101
|
| 102 if (argc > 1 && !strcmp(argv[1], "-f")) { 103 name = strdup(argv[2]); 104 argc -= 2; argv += 2; 105 } 106
|
69 if ((baz = open(name, O_RDWR)) < 0) { 70 perror(name); 71 exit(1); 72 }
| 107 if ((baz = open(name, O_RDWR)) < 0) { 108 perror(name); 109 exit(1); 110 }
|
| 111 free(name);
|
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 }
| 112 if (ioctl(baz, SOUND_MIXER_READ_DEVMASK, &devmask) == -1) { 113 perror("SOUND_MIXER_READ_DEVMASK"); 114 exit(-1); 115 } 116 if (ioctl(baz, SOUND_MIXER_READ_RECMASK, &recmask) == -1) { 117 perror("SOUND_MIXER_READ_RECMASK"); 118 exit(-1); 119 } 120 if (ioctl(baz, SOUND_MIXER_READ_RECSRC, &recsrc) == -1) { 121 perror("SOUND_MIXER_READ_RECSRC"); 122 exit(-1); 123 }
|
| 124 orecsrc = recsrc;
|
85
| 125
|
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) {
| 126 if (argc == 1) {
|
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
| 127 for (foo = 0; foo < SOUND_MIXER_NRDEVICES; foo++) { 128 if (!((1 << foo) & devmask)) 129 continue; 130 if (ioctl(baz, MIXER_READ(foo),&bar)== -1) { 131 perror("MIXER_READ"); 132 continue; 133 } 134 printf("Mixer %-8s is currently set to %3d:%d\n", names[foo], bar & 0x7f, (bar >> 8) & 0x7f); 135 } 136 return(0); 137 } 138
|
113 for (foo = 0; foo < SOUND_MIXER_NRDEVICES && strcmp(names[foo], argv[1]); foo++);
| 139 argc--; argv++;
|
114
| 140
|
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 */
| 141 while (argc) { 142 if (!strcmp("recsrc", *argv)) { 143 drecsrc = 1; 144 argc--; argv++; 145 continue; 146 } else if (argc > 1 && !strcmp("rec", *argv + 1)) { 147 if (**argv != '+' && **argv != '-' && 148 **argv != '=' && **argv != '^') { 149 dusage = 1; 150 argc -= 1; argv += 1; 151 continue;
|
121 }
| 152 }
|
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);
| 153 if ((dev = res_name(argv[1], recmask)) == -1) { 154 dusage = 1; 155 argc -= 1; argv += 1; 156 continue;
|
129 }
| 157 }
|
130 if (argv[1][0] == '+')
| 158 switch(**argv) { 159 case '+':
|
131 recsrc |= (1 << dev);
| 160 recsrc |= (1 << dev);
|
132 else
| 161 break; 162 case '-':
|
133 recsrc &= ~(1 << dev);
| 163 recsrc &= ~(1 << dev);
|
134 135 if (ioctl(baz, SOUND_MIXER_WRITE_RECSRC, &recsrc) == -1) { 136 perror("SOUND_MIXER_WRITE_RECSRC"); 137 exit(-1);
| 164 break; 165 case '=': 166 recsrc = (1 << dev); 167 break; 168 case '^': 169 recsrc ^= (1 << dev); 170 break;
|
138 }
| 171 }
|
139 print_recsrc();
| 172 drecsrc = 1; 173 argc -= 2; argv += 2; 174 continue; 175 }
|
140
| 176
|
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);
| 177 if ((dev = res_name(*argv, devmask)) == -1) { 178 dusage = 1; 179 argc--; argv++; 180 continue; 181 }
|
150
| 182
|
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;
| 183 switch(argc > 1 ? sscanf(argv[1], "%d:%d", &l, &r) : 0) { 184 case 0: 185 if (ioctl(baz, MIXER_READ(dev),&bar)== -1) { 186 perror("MIXER_READ"); 187 argc--; argv++; 188 continue; 189 } 190 printf("Mixer %-8s is currently set to %3d:%d\n", 191 names[dev], bar & 0x7f, (bar >> 8) & 0x7f);
|
159
| 192
|
160 printf("Setting the mixer %s to %d:%d.\n", names[foo], bar, dev);
| 193 argc--; argv++; 194 break; 195 case 1: 196 r = l; 197 case 2: 198 if (l < 0) 199 l = 0; 200 else if (l > 100) 201 l = 100; 202 if (r < 0) 203 r = 0; 204 else if (r > 100) 205 r = 100;
|
161
| 206
|
162 bar |= dev << 8; 163 if (ioctl(baz, MIXER_WRITE(foo), &bar) == -1)
| 207 printf("Setting the mixer %s to %d:%d.\n", names[dev], 208 l, r); 209 210 l |= r << 8; 211 if (ioctl(baz, MIXER_WRITE(dev), &l) == -1)
|
164 perror("WRITE_MIXER");
| 212 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);
| 213 214 argc -= 2; argv += 2; 215 break;
|
170 } 171 } 172
| 216 } 217 } 218
|
| 219 if (orecsrc != recsrc) 220 if (ioctl(baz, SOUND_MIXER_WRITE_RECSRC, &recsrc) == -1) { 221 perror("SOUND_MIXER_WRITE_RECSRC"); 222 exit(-1); 223 } 224 225 if (drecsrc) { 226 if (ioctl(baz, SOUND_MIXER_READ_RECSRC, &recsrc) == -1) { 227 perror("SOUND_MIXER_READ_RECSRC"); 228 exit(-1); 229 } 230 print_recsrc(recsrc); 231 } 232
|
173 close(baz);
| 233 close(baz);
|
| 234 235 if (dusage) 236 usage(devmask, recmask); 237 238 exit(0);
|
174}
| 239}
|