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