]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.sbin/mixer/mixer.c
This commit was generated by cvs2svn to compensate for changes in r175261,
[FreeBSD/FreeBSD.git] / usr.sbin / mixer / mixer.c
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$");
16
17 #include <err.h>
18 #include <fcntl.h>
19 #include <stdio.h>
20 #include <string.h>
21 #include <stdlib.h>
22 #include <unistd.h>
23 #include <sys/soundcard.h>
24
25 const char *names[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_NAMES;
26
27 void usage(int devmask, int recmask);
28 int res_name(const char *name, int mask);
29 void print_recsrc(int recsrc, int shortflag);
30
31 void
32 usage(int devmask, int recmask)
33 {
34         int i, n;
35
36         printf("usage: mixer [-f device] [-s | -S] [dev [+|-][voll[:[+|-]volr]] ...\n"
37                "       mixer [-f device] [-s | -S] recsrc ...\n"
38                "       mixer [-f device] [-s | -S] {^|+|-|=}rec rdev ... \n");
39         printf(" devices: ");
40         for (i = 0, n = 0; i < SOUND_MIXER_NRDEVICES; i++)
41                 if ((1 << i) & devmask)  {
42                         if (n)
43                                 printf(", ");
44                         printf("%s", names[i]);
45                         n = 1;
46                 }
47         printf("\n rec devices: ");
48         for (i = 0, n = 0; i < SOUND_MIXER_NRDEVICES; i++)
49                 if ((1 << i) & recmask)  {
50                         if (n)
51                                 printf(", ");
52                         printf("%s", names[i]);
53                         n = 1;
54                 }
55         printf("\n");
56         exit(1);
57 }
58
59 int
60 res_name(const char *name, int mask)
61 {
62         int foo;
63
64         for (foo = 0; foo < SOUND_MIXER_NRDEVICES; foo++)
65                 if ((1 << foo) & mask && !strcmp(names[foo], name))
66                         break;
67
68         return foo == SOUND_MIXER_NRDEVICES ? -1 : foo;
69 }
70
71 void
72 print_recsrc(int recsrc, int shortflag)
73 {
74         int i, n = 0;
75
76         if (!shortflag)
77                 printf("Recording source: ");
78
79         for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
80                 if ((1 << i) & recsrc) {
81                         if (shortflag) {
82                                 if (n)
83                                         printf(" +rec ");
84                                 else
85                                         printf("=rec ");
86                         } else if (n)
87                                 printf(", ");
88                         printf("%s", names[i]);
89                         n = 1;
90                 }
91         if (!shortflag)
92                 printf("\n");
93 }
94
95 int
96 main(int argc, char *argv[])
97 {
98         int foo, bar, baz, dev;
99         int devmask = 0, recmask = 0, recsrc = 0, orecsrc;
100         int dusage = 0, drecsrc = 0, shortflag = 0, Shortflag = 0;
101         int l = 0, r = 0, t = 0;
102         char lstr[5], rstr[5];
103         int n = 0, lrel = 0, rrel = 0;
104         int ch;
105
106         char *name;
107
108         name = "/dev/mixer";
109
110         if (!strcmp(argv[0], "mixer2"))
111                 name = "/dev/mixer1";
112         else if (!strcmp(argv[0], "mixer3"))
113                 name = "/dev/mixer2";
114
115         while ((ch = getopt(argc, argv, "f:sS")) != -1)
116                 switch (ch) {
117                         case 'f':
118                                 name = optarg;
119                                 break;
120                         case 's':
121                                 shortflag = 1;
122                                 break;
123                         case 'S':
124                                 Shortflag = 1;
125                                 break;
126                         default:
127                                 dusage = 1;
128                 }
129         argc -= (optind - 1);
130         argv += (optind - 1);
131
132         if ((baz = open(name, O_RDWR)) < 0)
133                 err(1, "%s", name);
134         if (ioctl(baz, SOUND_MIXER_READ_DEVMASK, &devmask) == -1)
135                 err(1, "SOUND_MIXER_READ_DEVMASK");
136         if (ioctl(baz, SOUND_MIXER_READ_RECMASK, &recmask) == -1)
137                 err(1, "SOUND_MIXER_READ_RECMASK");
138         if (ioctl(baz, SOUND_MIXER_READ_RECSRC, &recsrc) == -1)
139                 err(1, "SOUND_MIXER_READ_RECSRC");
140         orecsrc = recsrc;
141
142         if ((argc == 1) && (dusage == 0)) {
143                 for (foo = 0; foo < SOUND_MIXER_NRDEVICES; foo++) {
144                         if (!((1 << foo) & devmask)) 
145                                 continue;
146                         if (ioctl(baz, MIXER_READ(foo),&bar)== -1) {
147                                 warn("MIXER_READ");
148                                 continue;
149                         }
150                         if (Shortflag)
151                                 printf("%s:%d:%d ", names[foo], bar & 0x7f,
152                                        (bar >> 8) & 0x7f);
153                         else if (shortflag)
154                                 printf("%s %d:%d ", names[foo], bar & 0x7f,
155                                        (bar >> 8) & 0x7f);
156                         else
157                                 printf("Mixer %-8s is currently set to %3d:%d\n",
158                                        names[foo], bar & 0x7f, (bar >> 8) & 0x7f);
159                 }
160                 if (ioctl(baz, SOUND_MIXER_READ_RECSRC, &recsrc) == -1)
161                         err(1, "SOUND_MIXER_READ_RECSRC");
162                 print_recsrc(recsrc, shortflag || Shortflag);
163                 return(0);
164         }
165
166         argc--; argv++;
167
168         while ((argc > 0) && (dusage == 0)) {
169                 if (!strcmp("recsrc", *argv)) {
170                         drecsrc = 1;
171                         argc--; argv++;
172                         continue;
173                 } else if (argc > 1 && !strcmp("rec", *argv + 1)) {
174                         if (**argv != '+' && **argv != '-' &&
175                             **argv != '=' && **argv != '^') {
176                                 warnx("unknown modifier: %c", **argv);
177                                 dusage = 1;
178                                 break;
179                         }
180                         if ((dev = res_name(argv[1], recmask)) == -1) {
181                                 warnx("unknown recording device: %s", argv[1]);
182                                 dusage = 1;
183                                 break;
184                         }
185                         switch(**argv) {
186                         case '+':
187                                 recsrc |= (1 << dev);
188                                 break;
189                         case '-':
190                                 recsrc &= ~(1 << dev);
191                                 break;
192                         case '=':
193                                 recsrc = (1 << dev);
194                                 break;
195                         case '^':
196                                 recsrc ^= (1 << dev);
197                                 break;
198                         }
199                         drecsrc = 1;
200                         argc -= 2; argv += 2;
201                         continue;
202                 }
203
204                 if ((t = sscanf(*argv, "%d:%d", &l, &r)) > 0) {
205                         dev = 0;
206                 }
207                 else if((dev = res_name(*argv, devmask)) == -1) {
208                         warnx("unknown device: %s", *argv);
209                         dusage = 1;
210                         break;
211                 }
212
213 #define issign(c)       (((c) == '+') || ((c) == '-'))
214
215                 if (argc > 1) {
216                         n = sscanf(argv[1], "%7[^:]:%7s", lstr, rstr);
217                         if (n > 0) {
218                                 if (issign(lstr[0]))
219                                         lrel = rrel = 1;
220                                 l = atoi(lstr);
221                         }
222                         if (n > 1) {
223                                 rrel = 0;
224                                 if (issign(rstr[0]))
225                                         rrel = 1;
226                                 r = atoi(rstr);
227                         }
228                 }
229
230                 switch(argc > 1 ? n : t) {
231                 case 0:
232                         if (ioctl(baz, MIXER_READ(dev),&bar)== -1) {
233                                 warn("MIXER_READ");
234                                 argc--; argv++;
235                                 continue;
236                         }
237                         if (Shortflag)
238                                 printf("%s:%d:%d ", names[dev], bar & 0x7f,
239                                        (bar >> 8) & 0x7f);
240                         else if (shortflag)
241                                 printf("%s %d:%d ", names[dev], bar & 0x7f,
242                                        (bar >> 8) & 0x7f);
243                         else
244                                 printf("Mixer %-8s is currently set to %3d:%d\n",
245                                   names[dev], bar & 0x7f, (bar >> 8) & 0x7f);
246
247                         argc--; argv++;
248                         break;
249                 case 1:
250                         r = l;
251                 case 2:
252                         if (ioctl(baz, MIXER_READ(dev),&bar)== -1) {
253                                 warn("MIXER_READ");
254                                 argc--; argv++;
255                                 continue;
256                         }
257
258                         if (lrel)
259                                 l = (bar & 0x7f) + l;
260                         if (rrel)
261                                 r = ((bar >> 8) & 0x7f) + r;
262
263                         if (l < 0)
264                                 l = 0;
265                         else if (l > 100)
266                                 l = 100;
267                         if (r < 0)
268                                 r = 0;
269                         else if (r > 100)
270                                 r = 100;
271
272                         if (!Shortflag)
273                                 printf("Setting the mixer %s from %d:%d to %d:%d.\n",
274                                        names[dev], bar & 0x7f, (bar >> 8) & 0x7f, l, r);
275
276                         l |= r << 8;
277                         if (ioctl(baz, MIXER_WRITE(dev), &l) == -1)
278                                 warn("WRITE_MIXER");
279
280                         argc -= 2; argv += 2;
281                         break;
282                 }
283         }
284
285         if (dusage) {
286                 close(baz);
287                 usage(devmask, recmask);
288                 /* Not reached */
289         }
290
291         if (orecsrc != recsrc)
292                 if (ioctl(baz, SOUND_MIXER_WRITE_RECSRC, &recsrc) == -1)
293                         err(1, "SOUND_MIXER_WRITE_RECSRC");
294  
295         if (drecsrc) {
296                 if (ioctl(baz, SOUND_MIXER_READ_RECSRC, &recsrc) == -1)
297                         err(1, "SOUND_MIXER_READ_RECSRC");
298                 print_recsrc(recsrc, shortflag || Shortflag);
299         }
300
301         close(baz);
302
303         exit(0);
304 }