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