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