Add the DragonFly cvs id and perform general cleanups on cvs/rcs/sccs ids. Most
[dragonfly.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  * $FreeBSD: src/usr.sbin/mixer/mixer.c,v 1.11.2.6 2001/07/30 10:22:58 dd Exp $
14  * $DragonFly: src/usr.sbin/mixer/mixer.c,v 1.2 2003/06/17 04:29:57 dillon Exp $
15  */
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);
30
31 void
32 usage(int devmask, int recmask)
33 {
34         int i, n;
35
36         printf("usage: mixer [-f device] [-s] [[dev [voll[:volr]] | recsrc | {^|+|-|=}rec recdev] ... ]\n");
37         printf(" devices: ");
38         for (i = 0, n = 0; i < SOUND_MIXER_NRDEVICES; i++)
39                 if ((1 << i) & devmask)  {
40                         if (n)
41                                 printf(", ");
42                         printf("%s", names[i]);
43                         n = 1;
44                 }
45         printf("\n rec devices: ");
46         for (i = 0, n = 0; i < SOUND_MIXER_NRDEVICES; i++)
47                 if ((1 << i) & recmask)  {
48                         if (n)
49                                 printf(", ");
50                         printf("%s", names[i]);
51                         n = 1;
52                 }
53         printf("\n");
54         exit(1);
55 }
56
57 int
58 res_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
69 void
70 print_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, "%s", names[i]);
80                         n = 1;
81                 }
82         fprintf(stderr, "\n");
83 }
84
85 int
86 main(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, shortflag = 0;
91         int l = 0, r = 0, t = 0;
92         char ch;
93
94         char *name;
95
96         name = strdup("/dev/mixer");
97
98         if (!strcmp(argv[0], "mixer2"))
99                 name = strdup("/dev/mixer1");
100         else if (!strcmp(argv[0], "mixer3"))
101                 name = strdup("/dev/mixer2");
102
103         while ((ch = getopt(argc, argv, "f:s")) != -1)
104                 switch (ch) {
105                         case 'f':
106                                 name = strdup(optarg);
107                                 break;
108                         case 's':
109                                 shortflag = 1;
110                                 break;
111                         default:
112                                 dusage = 1;
113                 }
114         argc -= (optind - 1);
115         argv += (optind - 1);
116
117         if ((baz = open(name, O_RDWR)) < 0)
118                 err(1, "%s", name);
119         free(name);
120         if (ioctl(baz, SOUND_MIXER_READ_DEVMASK, &devmask) == -1)
121                 err(1, "SOUND_MIXER_READ_DEVMASK");
122         if (ioctl(baz, SOUND_MIXER_READ_RECMASK, &recmask) == -1)
123                 err(1, "SOUND_MIXER_READ_RECMASK");
124         if (ioctl(baz, SOUND_MIXER_READ_RECSRC, &recsrc) == -1)
125                 err(1, "SOUND_MIXER_READ_RECSRC");
126         orecsrc = recsrc;
127
128         if ((argc == 1) && (dusage == 0)) {
129                 for (foo = 0; foo < SOUND_MIXER_NRDEVICES; foo++) {
130                         if (!((1 << foo) & devmask)) 
131                                 continue;
132                         if (ioctl(baz, MIXER_READ(foo),&bar)== -1) {
133                                 warn("MIXER_READ");
134                                 continue;
135                         }
136                         if (shortflag)
137                                 printf("%s %d:%d ", names[foo], bar & 0x7f, (bar >> 8) & 0x7f);
138                         else
139                                 printf("Mixer %-8s is currently set to %3d:%d\n", names[foo], bar & 0x7f, (bar >> 8) & 0x7f);
140                 }
141                 return(0);
142         }
143
144         argc--; argv++;
145
146         while ((argc > 0) && (dusage == 0)) {
147                 if (!strcmp("recsrc", *argv)) {
148                         drecsrc = 1;
149                         argc--; argv++;
150                         continue;
151                 } else if (argc > 1 && !strcmp("rec", *argv + 1)) {
152                         if (**argv != '+' && **argv != '-' &&
153                             **argv != '=' && **argv != '^') {
154                                 warnx("unknown modifier: %c", **argv);
155                                 dusage = 1;
156                                 break;
157                         }
158                         if ((dev = res_name(argv[1], recmask)) == -1) {
159                                 warnx("unknown recording device: %s", argv[1]);
160                                 dusage = 1;
161                                 break;
162                         }
163                         switch(**argv) {
164                         case '+':
165                                 recsrc |= (1 << dev);
166                                 break;
167                         case '-':
168                                 recsrc &= ~(1 << dev);
169                                 break;
170                         case '=':
171                                 recsrc = (1 << dev);
172                                 break;
173                         case '^':
174                                 recsrc ^= (1 << dev);
175                                 break;
176                         }
177                         drecsrc = 1;
178                         argc -= 2; argv += 2;
179                         continue;
180                 }
181
182                 if ((t = sscanf(*argv, "%d:%d", &l, &r)) > 0) {
183                         dev = 0;
184                 }
185                 else if((dev = res_name(*argv, devmask)) == -1) {
186                         warnx("unknown device: %s", *argv);
187                         dusage = 1;
188                         break;
189                 }
190
191                 switch(argc > 1 ? sscanf(argv[1], "%d:%d", &l, &r) : t) {
192                 case 0:
193                         if (ioctl(baz, MIXER_READ(dev),&bar)== -1) {
194                                 warn("MIXER_READ");
195                                 argc--; argv++;
196                                 continue;
197                         }
198                         if (shortflag)
199                                 printf("%s %d:%d ", names[dev], bar & 0x7f, (bar >> 8) & 0x7f);
200                         else
201                                 printf("Mixer %-8s is currently set to %3d:%d\n",
202                                   names[dev], bar & 0x7f, (bar >> 8) & 0x7f);
203
204                         argc--; argv++;
205                         break;
206                 case 1:
207                         r = l;
208                 case 2:
209                         if (l < 0)
210                                 l = 0;
211                         else if (l > 100)
212                                 l = 100;
213                         if (r < 0)
214                                 r = 0;
215                         else if (r > 100)
216                                 r = 100;
217
218                         printf("Setting the mixer %s to %d:%d.\n", names[dev],
219                             l, r);
220
221                         l |= r << 8;
222                         if (ioctl(baz, MIXER_WRITE(dev), &l) == -1)
223                                 warn("WRITE_MIXER");
224
225                         argc -= 2; argv += 2;
226                         break;
227                 }
228         }
229
230         if (dusage) {
231                 close(baz);
232                 usage(devmask, recmask);
233                 /* Not reached */
234         }
235
236         if (orecsrc != recsrc)
237                 if (ioctl(baz, SOUND_MIXER_WRITE_RECSRC, &recsrc) == -1)
238                         err(1, "SOUND_MIXER_WRITE_RECSRC");
239  
240         if (drecsrc) {
241                 if (ioctl(baz, SOUND_MIXER_READ_RECSRC, &recsrc) == -1)
242                         err(1, "SOUND_MIXER_READ_RECSRC");
243                 print_recsrc(recsrc);
244         }
245
246         close(baz);
247
248         exit(0);
249 }