mixer.c revision 13435
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		default:
94			usage();
95	}
96
97	for (foo = 0; foo < SOUND_MIXER_NRDEVICES && strcmp(names[foo], argv[1]); foo++);
98
99	if (foo >= SOUND_MIXER_NRDEVICES) {
100
101		if (!strcmp("+rec", argv[1]) || !strcmp("-rec", argv[1])) {
102			if (argc != 3) {
103				usage();
104				/* NOTREACHED */
105			}
106			for (dev = 0; dev < SOUND_MIXER_NRDEVICES && strcmp(names[dev], argv[2]); dev++);
107			if (dev >= SOUND_MIXER_NRDEVICES)
108				usage();
109
110			if (!((1 << dev) & recmask)) {
111				fprintf(stderr, "Invalid recording source %s\n", argv[2]);
112				exit(-1);
113			}
114			if (argv[1][0] == '+')
115				recsrc |= (1 << dev);
116			else
117				recsrc &= ~(1 << dev);
118
119			if (ioctl(baz, SOUND_MIXER_WRITE_RECSRC, &recsrc) == -1) {
120				perror("SOUND_MIXER_WRITE_RECSRC");
121				exit(-1);
122			}
123			print_recsrc();
124
125		} else
126			usage();
127	} else {
128		if (bar) {
129			if (strchr(argv[2], ':') == NULL) {
130				sscanf(argv[2], "%d", &bar);
131				dev = bar;
132			} else
133				sscanf(argv[2], "%d:%d", &bar, &dev);
134
135			if (bar < 0)
136				bar = 0;
137			if (dev < 0)
138				dev = 0;
139			if (bar > 100)
140				bar = 100;
141			if (dev > 100)
142				dev = 100;
143
144			printf("Setting the mixer %s to %d:%d.\n", names[foo], bar, dev);
145
146                        bar |= dev << 8;
147			if (ioctl(baz, MIXER_WRITE(foo), &bar) == -1)
148				perror("WRITE_MIXER");
149	return (0);
150		} else {
151			if (ioctl(baz, MIXER_READ(foo),&bar)== -1)
152			   perror("MIXER_READ");
153			printf("The mixer %s is currently set to %d:%d.\n", names[foo], bar & 0x7f, (bar >> 8) & 0x7f);
154		}
155	}
156
157	close(baz);
158}
159