Update to latest tinyalsa
[android-sdk/platform-external-tinyalsa.git] / tinymix.c
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 */
29 #include <tinyalsa/asoundlib.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <ctype.h>
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);
41 int main(int argc, char **argv)
42 {
43     struct mixer *mixer;
44     int card = 0;
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     }
57     mixer = mixer_open(card);
58     if (!mixer) {
59         fprintf(stderr, "Failed to open mixer\n");
60         return EXIT_FAILURE;
61     }
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");
72     mixer_close(mixer);
74     return 0;
75 }
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;
84     num_ctls = mixer_get_num_ctls(mixer);
86     printf("Number of controls: %d\n", num_ctls);
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);
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 }
100 static void tinymix_print_enum(struct mixer_ctl *ctl, int print_all)
102     unsigned int num_enums;
103     unsigned int i;
104     const char *string;
106     num_enums = mixer_ctl_get_num_enums(ctl);
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     }
118 static void tinymix_detail_control(struct mixer *mixer, unsigned int id,
119                                    int print_all)
121     struct mixer_ctl *ctl;
122     enum mixer_ctl_type type;
123     unsigned int num_values;
124     unsigned int i;
125     int min, max;
127     if (id >= mixer_get_num_ctls(mixer)) {
128         fprintf(stderr, "Invalid mixer control\n");
129         return;
130     }
132     ctl = mixer_get_ctl(mixer, id);
134     type = mixer_ctl_get_type(ctl);
135     num_values = mixer_ctl_get_num_values(ctl);
137     if (print_all)
138         printf("%s:", mixer_ctl_get_name(ctl));
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     }
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");
171 static void tinymix_set_value(struct mixer *mixer, unsigned int id,
172                               char *string)
174     struct mixer_ctl *ctl;
175     enum mixer_ctl_type type;
176     unsigned int num_values;
177     unsigned int i;
179     ctl = mixer_get_ctl(mixer, id);
180     type = mixer_ctl_get_type(ctl);
181     num_values = mixer_ctl_get_num_values(ctl);
183     if (isdigit(string[0])) {
184         int value = atoi(string);
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     }