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