1 /* tinymix.c
2 **
3 ** Copyright 2011, The Android Open Source Project
4 **
5 ** Redistribution and use in source and binary forms, with or without
6 ** modification, are permitted provided that the following conditions are met:
7 ** * Redistributions of source code must retain the above copyright
8 ** notice, this list of conditions and the following disclaimer.
9 ** * Redistributions in binary form must reproduce the above copyright
10 ** notice, this list of conditions and the following disclaimer in the
11 ** documentation and/or other materials provided with the distribution.
12 ** * Neither the name of The Android Open Source Project nor the names of
13 ** its contributors may be used to endorse or promote products derived
14 ** from this software without specific prior written permission.
15 **
16 ** THIS SOFTWARE IS PROVIDED BY The Android Open Source Project ``AS IS'' AND
17 ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 ** ARE DISCLAIMED. IN NO EVENT SHALL The Android Open Source Project BE LIABLE
20 ** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 ** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 ** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 ** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 ** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
26 ** DAMAGE.
27 */
28
29 #include <tinyalsa/asoundlib.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <ctype.h>
33
34 static void tinymix_list_controls(struct mixer *mixer);
35 static void tinymix_detail_control(struct mixer *mixer, unsigned int id,
36 int print_all);
37 static void tinymix_set_value(struct mixer *mixer, unsigned int id,
38 char *value);
39 static void tinymix_print_enum(struct mixer_ctl *ctl, int print_all);
40
main(int argc,char ** argv)41 int main(int argc, char **argv)
42 {
43 struct mixer *mixer;
44 int card = 0;
45
46 if ((argc > 2) && (strcmp(argv[1], "-D") == 0)) {
47 argv++;
48 if (argv[1]) {
49 card = atoi(argv[1]);
50 argv++;
51 argc -= 2;
52 } else {
53 argc -= 1;
54 }
55 }
56
57 mixer = mixer_open(card);
58 if (!mixer) {
59 fprintf(stderr, "Failed to open mixer\n");
60 return EXIT_FAILURE;
61 }
62
63 if (argc == 1)
64 tinymix_list_controls(mixer);
65 else if (argc == 2)
66 tinymix_detail_control(mixer, atoi(argv[1]), 1);
67 else if (argc == 3)
68 tinymix_set_value(mixer, atoi(argv[1]), argv[2]);
69 else
70 printf("Usage: tinymix [-D card] [control id] [value to set]\n");
71
72 mixer_close(mixer);
73
74 return 0;
75 }
76
tinymix_list_controls(struct mixer * mixer)77 static void tinymix_list_controls(struct mixer *mixer)
78 {
79 struct mixer_ctl *ctl;
80 const char *name, *type;
81 unsigned int num_ctls, num_values;
82 unsigned int i;
83
84 num_ctls = mixer_get_num_ctls(mixer);
85
86 printf("Number of controls: %d\n", num_ctls);
87
88 printf("ctl\ttype\tnum\t%-40s value\n", "name");
89 for (i = 0; i < num_ctls; i++) {
90 ctl = mixer_get_ctl(mixer, i);
91
92 name = mixer_ctl_get_name(ctl);
93 type = mixer_ctl_get_type_string(ctl);
94 num_values = mixer_ctl_get_num_values(ctl);
95 printf("%d\t%s\t%d\t%-40s", i, type, num_values, name);
96 tinymix_detail_control(mixer, i, 0);
97 }
98 }
99
tinymix_print_enum(struct mixer_ctl * ctl,int print_all)100 static void tinymix_print_enum(struct mixer_ctl *ctl, int print_all)
101 {
102 unsigned int num_enums;
103 unsigned int i;
104 const char *string;
105
106 num_enums = mixer_ctl_get_num_enums(ctl);
107
108 for (i = 0; i < num_enums; i++) {
109 string = mixer_ctl_get_enum_string(ctl, i);
110 if (print_all)
111 printf("\t%s%s", mixer_ctl_get_value(ctl, 0) == (int)i ? ">" : "",
112 string);
113 else if (mixer_ctl_get_value(ctl, 0) == (int)i)
114 printf(" %-s", string);
115 }
116 }
117
tinymix_detail_control(struct mixer * mixer,unsigned int id,int print_all)118 static void tinymix_detail_control(struct mixer *mixer, unsigned int id,
119 int print_all)
120 {
121 struct mixer_ctl *ctl;
122 enum mixer_ctl_type type;
123 unsigned int num_values;
124 unsigned int i;
125 int min, max;
126
127 if (id >= mixer_get_num_ctls(mixer)) {
128 fprintf(stderr, "Invalid mixer control\n");
129 return;
130 }
131
132 ctl = mixer_get_ctl(mixer, id);
133
134 type = mixer_ctl_get_type(ctl);
135 num_values = mixer_ctl_get_num_values(ctl);
136
137 if (print_all)
138 printf("%s:", mixer_ctl_get_name(ctl));
139
140 for (i = 0; i < num_values; i++) {
141 switch (type)
142 {
143 case MIXER_CTL_TYPE_INT:
144 printf(" %d", mixer_ctl_get_value(ctl, i));
145 break;
146 case MIXER_CTL_TYPE_BOOL:
147 printf(" %s", mixer_ctl_get_value(ctl, i) ? "On" : "Off");
148 break;
149 case MIXER_CTL_TYPE_ENUM:
150 tinymix_print_enum(ctl, print_all);
151 break;
152 case MIXER_CTL_TYPE_BYTE:
153 printf(" 0x%02x", mixer_ctl_get_value(ctl, i));
154 break;
155 default:
156 printf(" unknown");
157 break;
158 };
159 }
160
161 if (print_all) {
162 if (type == MIXER_CTL_TYPE_INT) {
163 min = mixer_ctl_get_range_min(ctl);
164 max = mixer_ctl_get_range_max(ctl);
165 printf(" (range %d->%d)", min, max);
166 }
167 }
168 printf("\n");
169 }
170
tinymix_set_value(struct mixer * mixer,unsigned int id,char * string)171 static void tinymix_set_value(struct mixer *mixer, unsigned int id,
172 char *string)
173 {
174 struct mixer_ctl *ctl;
175 enum mixer_ctl_type type;
176 unsigned int num_values;
177 unsigned int i;
178
179 ctl = mixer_get_ctl(mixer, id);
180 type = mixer_ctl_get_type(ctl);
181 num_values = mixer_ctl_get_num_values(ctl);
182
183 if (isdigit(string[0])) {
184 int value = atoi(string);
185
186 for (i = 0; i < num_values; i++) {
187 if (mixer_ctl_set_value(ctl, i, value)) {
188 fprintf(stderr, "Error: invalid value\n");
189 return;
190 }
191 }
192 } else {
193 if (type == MIXER_CTL_TYPE_ENUM) {
194 if (mixer_ctl_set_enum_by_string(ctl, string))
195 fprintf(stderr, "Error: invalid enum value\n");
196 } else {
197 fprintf(stderr, "Error: only enum types can be set with strings\n");
198 }
199 }
200 }
201
202