mixer.c revision 29612
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 <stdio.h> 15#include <fcntl.h> 16#include <string.h> 17#include <stdlib.h> 18#include <unistd.h> 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 27void usage(int devmask, int recmask); 28int res_name(const char *name, int mask); 29void print_recsrc(int recsrc); 30 31void 32usage(int devmask, int recmask) 33{ 34 int i, n; 35 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++) 39 if ((1 << i) & devmask) { 40 if (n) 41 printf(", "); 42 printf(names[i]); 43 n = 1; 44 } 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"); 54 exit(1); 55} 56 57int 58res_name(const char *name, int mask) 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{ 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; 92 93 char *name; 94 95 name = strdup("/dev/mixer"); 96 97 if (!strcmp(argv[0], "mixer2")) 98 name = strdup("/dev/mixer1"); 99 else if (!strcmp(argv[0], "mixer3")) 100 name = strdup("/dev/mixer2"); 101 102 if (argc > 1 && !strcmp(argv[1], "-f")) { 103 name = strdup(argv[2]); 104 argc -= 2; argv += 2; 105 } 106 107 if ((baz = open(name, O_RDWR)) < 0) { 108 perror(name); 109 exit(1); 110 } 111 free(name); 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; 125 126 if (argc == 1) { 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 139 argc--; argv++; 140 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; 152 } 153 if ((dev = res_name(argv[1], recmask)) == -1) { 154 dusage = 1; 155 argc -= 1; argv += 1; 156 continue; 157 } 158 switch(**argv) { 159 case '+': 160 recsrc |= (1 << dev); 161 break; 162 case '-': 163 recsrc &= ~(1 << dev); 164 break; 165 case '=': 166 recsrc = (1 << dev); 167 break; 168 case '^': 169 recsrc ^= (1 << dev); 170 break; 171 } 172 drecsrc = 1; 173 argc -= 2; argv += 2; 174 continue; 175 } 176 177 if ((dev = res_name(*argv, devmask)) == -1) { 178 dusage = 1; 179 argc--; argv++; 180 continue; 181 } 182 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); 192 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; 206 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) 212 perror("WRITE_MIXER"); 213 214 argc -= 2; argv += 2; 215 break; 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 233 close(baz); 234 235 if (dusage) 236 usage(devmask, recmask); 237 238 exit(0); 239} 240