mixer.c revision 13803
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
21char *names[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_NAMES;
22
23int devmask = 0, recmask = 0, recsrc = 0;
24
25void 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
41void 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
56int
57main(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