File: setmixer.c

package info (click to toggle)
setmixer 27DEC94-9
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 68 kB
  • ctags: 8
  • sloc: ansic: 122; makefile: 58; sh: 54
file content (158 lines) | stat: -rw-r--r-- 3,937 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/*
 * setmixer  - 
 *    simple program to set various sound mixer parameters from a command
 *    line; can be put into rc.local to have an automatic startup
 *    initialization
 *
 * usage: ./setmixer [-V] cntrl val [cntrl val ....]
 *	where val is in 0-100 range and 'cntrl' is one of the following:
 *      vol bass treble synth pcm speaker line mic cd mix pcm2 rec
 * When controlling   
 * Option -V will display current/set values.
 *
 * Compile with the following command:
 * 	gcc -s -O6 -fomit-frame-pointer -Wall -pipe -m486 \
 *	-Xlinker -qmagic -o setmixer setmixer.c
 *
 * Michal Jaegermann, 27 Dec 1994
 * This program is released under terms of GNU General Program Licence.
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/soundcard.h>

#define MIXER "/dev/mixer"

const char * dname[] = SOUND_DEVICE_NAMES;
    
int
main(int argc, const char **argv) {

    int devmask, stereod, i, d;
    int mixer_fd;
    int lcval,rcval,oldlcval,oldrcval,val;
    int verbose = 0;
    size_t len;
    char *endptr;
    const char *cntrl;
    const char *prog = *argv++;

    argc -= 1;
    if (argc > 0) {
	if (0 == strcmp(*argv, "-V")) {
	    verbose = 1;
	    argv++;
	    argc -= 1;
	}
    }
    
    if ((!verbose && ((argc <= 0) || (argc & 1))) || (verbose && argc % 2)) {
	fprintf(stderr, "usage: %s [-V] cntrl val [cntrl val ....]\n"
       "where val is in [+-]0-100 range and 'cntrl' is one of the following:\n\t",
		prog);
	for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
	    fprintf(stderr, "%s ", dname[i]);
	fprintf(stderr, "\n"
		"('lchannel,rchannel' pairs can be given as 'val' for "
		"stereo controls)\n");
	exit(1);
    }

    if ((mixer_fd = open(MIXER, O_RDWR)) < 0) {
	fprintf(stderr, "Error opening /dev/mixer.");
	exit(1);
    }
    if (ioctl(mixer_fd, SOUND_MIXER_READ_DEVMASK, &devmask) == -1) {
	perror("SOUND_MIXER_READ_DEVMASK");
	exit(-1);
    }
    if (ioctl(mixer_fd, SOUND_MIXER_READ_STEREODEVS, &stereod) == -1) {
	perror("SOUND_MIXER_READ_STEREODEVS");
	exit(-1);
    }

    if (!devmask) {
	fprintf(stderr, "No device found.");
	exit(-1);
    }
    
    while (argc) {
	cntrl = *argv++;
	oldlcval = (('+' == **argv) || ('-' == **argv));
	lcval = strtol(*argv++, &endptr, 0);
	if (',' == *endptr) {
	    endptr += 1;
	    oldrcval = (('+' == *endptr) || ('-' == *endptr));
	    rcval = strtol((const char *)endptr, 0, 0);
	}
	else {
	    rcval = lcval;
	    oldrcval = oldlcval;
	}
	argc -= 2;
	len = strlen(cntrl);
	if (oldlcval || oldrcval) {
	    for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
	    	if (0 == strncmp(dname[i], cntrl, len)) {
		    d = (1 << i);
		    if (0 != (devmask & d)) {
			if (-1 == ioctl(mixer_fd, MIXER_READ(i), &val)) {
			    perror("MIXER_READ");
			}
			else {
			    lcval += oldlcval ? (val & 0x7f) : 0;
			    rcval += oldrcval ? ((val >> 8) & 0x7f) : 0;
			}
		    }
		    break;
		}
	    }
	}
	for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
	    if (0 == strncmp(dname[i], cntrl, len)) {
		d = (1 << i);
		if (0 != (devmask & d)) {
		    lcval = (lcval < 0 ? 0 : (lcval > 100 ? 100 : lcval));
		    if (d & stereod) {
			rcval = (rcval < 0 ? 0 : (rcval > 100 ? 100 : rcval));
			lcval |= (rcval << 8);
		    }
		    if (-1 == ioctl(mixer_fd, MIXER_WRITE(i), &lcval)) {
			perror("MIXER_WRITE");
		    }
		}
		break;
	    }
	}
    }

    if (verbose) {
	for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
	    d = (1 << i);
	    if (0 != (devmask & d)) {
		if (-1 == ioctl(mixer_fd, MIXER_READ(i), &lcval)) {
		    perror("MIXER_READ");
		}
		else {
		    printf("%7s - ", dname[i]);
		    printf("%d", lcval & 0x7f);
		    if (d & stereod)
			printf(",%d", (lcval >> 8) & 0x7f);
		    printf("\n");
		}
	    }
	}
    }
    return 0;
}
/*
 * Local variables:
 * compile-command: "gcc -s -O6 -fomit-frame-pointer -Wall -pipe -m486 -Xlinker -N -o setmixer setmixer.c"
 * End:
 */