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
45 mixer = mixer_open(0);
46 if (!mixer) {
47 fprintf(stderr, "Failed to open mixer\n");
48 return EXIT_FAILURE;
49 }
50
51 if (argc == 1)
52 tinymix_list_controls(mixer);
53 else if (argc == 2)
54 tinymix_detail_control(mixer, atoi(argv[1]), 1);
55 else if (argc == 3)
56 tinymix_set_value(mixer, atoi(argv[1]), argv[2]);
57 else
58 printf("Usage: tinymix [control id] [value to set]\n");
59
60 mixer_close(mixer);
61
62 return 0;
63 }
64
tinymix_list_controls(struct mixer * mixer)65 static void tinymix_list_controls(struct mixer *mixer)
66 {
67 struct mixer_ctl *ctl;
68 const char *type;
69 unsigned int num_ctls, num_values;
70 char buffer[256];
71 unsigned int i;
72
73 num_ctls = mixer_get_num_ctls(mixer);
74
75 printf("Number of controls: %d\n", num_ctls);
76
77 printf("ctl\ttype\tnum\t%-40s value\n", "name");
78 for (i = 0; i < num_ctls; i++) {
79 ctl = mixer_get_ctl(mixer, i);
80
81 mixer_ctl_get_name(ctl, buffer, sizeof(buffer));
82 type = mixer_ctl_get_type_string(ctl);
83 num_values = mixer_ctl_get_num_values(ctl);
84 printf("%d\t%s\t%d\t%-40s", i, type, num_values, buffer);
85 tinymix_detail_control(mixer, i, 0);
86 }
87 }
88
tinymix_print_enum(struct mixer_ctl * ctl,int print_all)89 static void tinymix_print_enum(struct mixer_ctl *ctl, int print_all)
90 {
91 unsigned int num_enums;
92 char buffer[256];
93 unsigned int i;
94
95 num_enums = mixer_ctl_get_num_enums(ctl);
96
97 for (i = 0; i < num_enums; i++) {
98 mixer_ctl_get_enum_string(ctl, i, buffer, sizeof(buffer));
99 if (print_all)
100 printf("\t%s%s", mixer_ctl_get_value(ctl, 0) == (int)i ? ">" : "",
101 buffer);
102 else if (mixer_ctl_get_value(ctl, 0) == (int)i)
103 printf(" %-s", buffer);
104 }
105 }
106
tinymix_detail_control(struct mixer * mixer,unsigned int id,int print_all)107 static void tinymix_detail_control(struct mixer *mixer, unsigned int id,
108 int print_all)
109 {
110 struct mixer_ctl *ctl;
111 enum mixer_ctl_type type;
112 unsigned int num_values;
113 char buffer[256];
114 unsigned int i;
115 int min, max;
116
117 if (id >= mixer_get_num_ctls(mixer)) {
118 fprintf(stderr, "Invalid mixer control\n");
119 return;
120 }
121
122 ctl = mixer_get_ctl(mixer, id);
123
124 mixer_ctl_get_name(ctl, buffer, sizeof(buffer));
125 type = mixer_ctl_get_type(ctl);
126 num_values = mixer_ctl_get_num_values(ctl);
127
128 if (print_all)
129 printf("%s:", buffer);
130
131 for (i = 0; i < num_values; i++) {
132 switch (type)
133 {
134 case MIXER_CTL_TYPE_INT:
135 printf(" %d", mixer_ctl_get_value(ctl, i));
136 break;
137 case MIXER_CTL_TYPE_BOOL:
138 printf(" %s", mixer_ctl_get_value(ctl, i) ? "On" : "Off");
139 break;
140 case MIXER_CTL_TYPE_ENUM:
141 tinymix_print_enum(ctl, print_all);
142 break;
143 default:
144 printf(" unknown");
145 break;
146 };
147 }
148
149 if (print_all) {
150 if (type == MIXER_CTL_TYPE_INT) {
151 min = mixer_ctl_get_range_min(ctl);
152 max = mixer_ctl_get_range_max(ctl);
153 printf(" (range %d->%d)", min, max);
154 }
155 }
156 printf("\n");
157 }
158
tinymix_set_value(struct mixer * mixer,unsigned int id,char * string)159 static void tinymix_set_value(struct mixer *mixer, unsigned int id,
160 char *string)
161 {
162 struct mixer_ctl *ctl;
163 enum mixer_ctl_type type;
164 unsigned int num_values;
165 unsigned int i;
166
167 ctl = mixer_get_ctl(mixer, id);
168 type = mixer_ctl_get_type(ctl);
169 num_values = mixer_ctl_get_num_values(ctl);
170
171 if (isdigit(string[0])) {
172 int value = atoi(string);
173
174 for (i = 0; i < num_values; i++) {
175 if (mixer_ctl_set_value(ctl, i, value)) {
176 fprintf(stderr, "Error: invalid value\n");
177 return;
178 }
179 }
180 } else {
181 if (type == MIXER_CTL_TYPE_ENUM) {
182 if (mixer_ctl_set_enum_by_string(ctl, string))
183 fprintf(stderr, "Error: invalid enum value\n");
184 } else {
185 fprintf(stderr, "Error: only enum types can be set with strings\n");
186 }
187 }
188 }
189
190