tinymix.c revision 621047309242d04a6186230e7a337de8642ec754
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
34static void tinymix_list_controls(struct mixer *mixer);
35static void tinymix_detail_control(struct mixer *mixer, unsigned int id,
36                                   int print_all);
37static void tinymix_set_value(struct mixer *mixer, unsigned int id,
38                              char *value);
39static void tinymix_print_enum(struct mixer_ctl *ctl, int print_all);
40
41int 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
65static 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
89static 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
107static 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
159static 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