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 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 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 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 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 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