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