Home | History | Annotate | Download | only in tinyalsa
      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 #include <string.h>
     34 
     35 static void tinymix_list_controls(struct mixer *mixer);
     36 static void tinymix_detail_control(struct mixer *mixer, const char *control,
     37                                    int print_all);
     38 static void tinymix_set_value(struct mixer *mixer, const char *control,
     39                               char **values, unsigned int num_values);
     40 static void tinymix_print_enum(struct mixer_ctl *ctl, int print_all);
     41 
     42 int main(int argc, char **argv)
     43 {
     44     struct mixer *mixer;
     45     int card = 0;
     46 
     47     if ((argc > 2) && (strcmp(argv[1], "-D") == 0)) {
     48         argv++;
     49         if (argv[1]) {
     50             card = atoi(argv[1]);
     51             argv++;
     52             argc -= 2;
     53         } else {
     54             argc -= 1;
     55         }
     56     }
     57 
     58     mixer = mixer_open(card);
     59     if (!mixer) {
     60         fprintf(stderr, "Failed to open mixer\n");
     61         return EXIT_FAILURE;
     62     }
     63 
     64     if (argc == 1)
     65         tinymix_list_controls(mixer);
     66     else if (argc == 2)
     67         tinymix_detail_control(mixer, argv[1], 1);
     68     else if (argc >= 3)
     69         tinymix_set_value(mixer, argv[1], &argv[2], argc - 2);
     70     else
     71         printf("Usage: tinymix [-D card] [control id] [value to set]\n");
     72 
     73     mixer_close(mixer);
     74 
     75     return 0;
     76 }
     77 
     78 static void tinymix_list_controls(struct mixer *mixer)
     79 {
     80     struct mixer_ctl *ctl;
     81     const char *name, *type;
     82     unsigned int num_ctls, num_values;
     83     unsigned int i;
     84 
     85     num_ctls = mixer_get_num_ctls(mixer);
     86 
     87     printf("Number of controls: %d\n", num_ctls);
     88 
     89     printf("ctl\ttype\tnum\t%-40s value\n", "name");
     90     for (i = 0; i < num_ctls; i++) {
     91         ctl = mixer_get_ctl(mixer, i);
     92 
     93         name = mixer_ctl_get_name(ctl);
     94         type = mixer_ctl_get_type_string(ctl);
     95         num_values = mixer_ctl_get_num_values(ctl);
     96         printf("%d\t%s\t%d\t%-40s", i, type, num_values, name);
     97         tinymix_detail_control(mixer, name, 0);
     98     }
     99 }
    100 
    101 static void tinymix_print_enum(struct mixer_ctl *ctl, int print_all)
    102 {
    103     unsigned int num_enums;
    104     unsigned int i;
    105     const char *string;
    106 
    107     num_enums = mixer_ctl_get_num_enums(ctl);
    108 
    109     for (i = 0; i < num_enums; i++) {
    110         string = mixer_ctl_get_enum_string(ctl, i);
    111         if (print_all)
    112             printf("\t%s%s", mixer_ctl_get_value(ctl, 0) == (int)i ? ">" : "",
    113                    string);
    114         else if (mixer_ctl_get_value(ctl, 0) == (int)i)
    115             printf(" %-s", string);
    116     }
    117 }
    118 
    119 static void tinymix_detail_control(struct mixer *mixer, const char *control,
    120                                    int print_all)
    121 {
    122     struct mixer_ctl *ctl;
    123     enum mixer_ctl_type type;
    124     unsigned int num_values;
    125     unsigned int i;
    126     int min, max;
    127 
    128     if (isdigit(control[0]))
    129         ctl = mixer_get_ctl(mixer, atoi(control));
    130     else
    131         ctl = mixer_get_ctl_by_name(mixer, control);
    132 
    133     if (!ctl) {
    134         fprintf(stderr, "Invalid mixer control\n");
    135         return;
    136     }
    137 
    138     type = mixer_ctl_get_type(ctl);
    139     num_values = mixer_ctl_get_num_values(ctl);
    140 
    141     if (print_all)
    142         printf("%s:", mixer_ctl_get_name(ctl));
    143 
    144     for (i = 0; i < num_values; i++) {
    145         switch (type)
    146         {
    147         case MIXER_CTL_TYPE_INT:
    148             printf(" %d", mixer_ctl_get_value(ctl, i));
    149             break;
    150         case MIXER_CTL_TYPE_BOOL:
    151             printf(" %s", mixer_ctl_get_value(ctl, i) ? "On" : "Off");
    152             break;
    153         case MIXER_CTL_TYPE_ENUM:
    154             tinymix_print_enum(ctl, print_all);
    155             break;
    156          case MIXER_CTL_TYPE_BYTE:
    157             printf(" 0x%02x", mixer_ctl_get_value(ctl, i));
    158             break;
    159         default:
    160             printf(" unknown");
    161             break;
    162         };
    163     }
    164 
    165     if (print_all) {
    166         if (type == MIXER_CTL_TYPE_INT) {
    167             min = mixer_ctl_get_range_min(ctl);
    168             max = mixer_ctl_get_range_max(ctl);
    169             printf(" (range %d->%d)", min, max);
    170         }
    171     }
    172     printf("\n");
    173 }
    174 
    175 static void tinymix_set_value(struct mixer *mixer, const char *control,
    176                               char **values, unsigned int num_values)
    177 {
    178     struct mixer_ctl *ctl;
    179     enum mixer_ctl_type type;
    180     unsigned int num_ctl_values;
    181     unsigned int i;
    182 
    183     if (isdigit(control[0]))
    184         ctl = mixer_get_ctl(mixer, atoi(control));
    185     else
    186         ctl = mixer_get_ctl_by_name(mixer, control);
    187 
    188     if (!ctl) {
    189         fprintf(stderr, "Invalid mixer control\n");
    190         return;
    191     }
    192 
    193     type = mixer_ctl_get_type(ctl);
    194     num_ctl_values = mixer_ctl_get_num_values(ctl);
    195 
    196     if (isdigit(values[0][0])) {
    197         if (num_values == 1) {
    198             /* Set all values the same */
    199             int value = atoi(values[0]);
    200 
    201             for (i = 0; i < num_ctl_values; i++) {
    202                 if (mixer_ctl_set_value(ctl, i, value)) {
    203                     fprintf(stderr, "Error: invalid value\n");
    204                     return;
    205                 }
    206             }
    207         } else {
    208             /* Set multiple values */
    209             if (num_values > num_ctl_values) {
    210                 fprintf(stderr,
    211                         "Error: %d values given, but control only takes %d\n",
    212                         num_values, num_ctl_values);
    213                 return;
    214             }
    215             for (i = 0; i < num_values; i++) {
    216                 if (mixer_ctl_set_value(ctl, i, atoi(values[i]))) {
    217                     fprintf(stderr, "Error: invalid value for index %d\n", i);
    218                     return;
    219                 }
    220             }
    221         }
    222     } else {
    223         if (type == MIXER_CTL_TYPE_ENUM) {
    224             if (num_values != 1) {
    225                 fprintf(stderr, "Enclose strings in quotes and try again\n");
    226                 return;
    227             }
    228             if (mixer_ctl_set_enum_by_string(ctl, values[0]))
    229                 fprintf(stderr, "Error: invalid enum value\n");
    230         } else {
    231             fprintf(stderr, "Error: only enum types can be set with strings\n");
    232         }
    233     }
    234 }
    235 
    236