Home | History | Annotate | Download | only in tinyalsa
      1 /* tinypcminfo.c
      2 **
      3 ** Copyright 2012, 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 <string.h>
     33 
     34 #ifndef ARRAY_SIZE
     35 #define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
     36 #endif
     37 
     38 /* The format_lookup is in order of SNDRV_PCM_FORMAT_##index and
     39  * matches the grouping in sound/asound.h.  Note this is not
     40  * continuous and has an empty gap from (25 - 30).
     41  */
     42 static const char *format_lookup[] = {
     43         /*[0] =*/ "S8",
     44         "U8",
     45         "S16_LE",
     46         "S16_BE",
     47         "U16_LE",
     48         "U16_BE",
     49         "S24_LE",
     50         "S24_BE",
     51         "U24_LE",
     52         "U24_BE",
     53         "S32_LE",
     54         "S32_BE",
     55         "U32_LE",
     56         "U32_BE",
     57         "FLOAT_LE",
     58         "FLOAT_BE",
     59         "FLOAT64_LE",
     60         "FLOAT64_BE",
     61         "IEC958_SUBFRAME_LE",
     62         "IEC958_SUBFRAME_BE",
     63         "MU_LAW",
     64         "A_LAW",
     65         "IMA_ADPCM",
     66         "MPEG",
     67         /*[24] =*/ "GSM",
     68         [31] = "SPECIAL",
     69         "S24_3LE",
     70         "S24_3BE",
     71         "U24_3LE",
     72         "U24_3BE",
     73         "S20_3LE",
     74         "S20_3BE",
     75         "U20_3LE",
     76         "U20_3BE",
     77         "S18_3LE",
     78         "S18_3BE",
     79         "U18_3LE",
     80         /*[43] =*/ "U18_3BE",
     81 #if 0
     82         /* recent additions, may not be present on local asound.h */
     83         "G723_24",
     84         "G723_24_1B",
     85         "G723_40",
     86         "G723_40_1B",
     87         "DSD_U8",
     88         "DSD_U16_LE",
     89 #endif
     90 };
     91 
     92 /* Returns a human readable name for the format associated with bit_index,
     93  * NULL if bit_index is not known.
     94  */
     95 inline const char *pcm_get_format_name(unsigned bit_index)
     96 {
     97     return bit_index < ARRAY_SIZE(format_lookup) ? format_lookup[bit_index] : NULL;
     98 }
     99 
    100 int main(int argc, char **argv)
    101 {
    102     unsigned int device = 0;
    103     unsigned int card = 0;
    104     int i;
    105 
    106     if (argc < 3) {
    107         fprintf(stderr, "Usage: %s -D card -d device\n", argv[0]);
    108         return 1;
    109     }
    110 
    111     /* parse command line arguments */
    112     argv += 1;
    113     while (*argv) {
    114         if (strcmp(*argv, "-D") == 0) {
    115             argv++;
    116             if (*argv)
    117                 card = atoi(*argv);
    118         }
    119         if (strcmp(*argv, "-d") == 0) {
    120             argv++;
    121             if (*argv)
    122                 device = atoi(*argv);
    123         }
    124         if (*argv)
    125             argv++;
    126     }
    127 
    128     printf("Info for card %d, device %d:\n", card, device);
    129 
    130     for (i = 0; i < 2; i++) {
    131         struct pcm_params *params;
    132         struct pcm_mask *m;
    133         unsigned int min;
    134         unsigned int max;
    135 
    136         printf("\nPCM %s:\n", i == 0 ? "out" : "in");
    137 
    138         params = pcm_params_get(card, device, i == 0 ? PCM_OUT : PCM_IN);
    139         if (params == NULL) {
    140             printf("Device does not exist.\n");
    141             continue;
    142         }
    143 
    144         m = pcm_params_get_mask(params, PCM_PARAM_ACCESS);
    145         if (m) { /* bitmask, refer to SNDRV_PCM_ACCESS_*, generally interleaved */
    146             printf("      Access:\t%#08x\n", m->bits[0]);
    147         }
    148         m = pcm_params_get_mask(params, PCM_PARAM_FORMAT);
    149         if (m) { /* bitmask, refer to: SNDRV_PCM_FORMAT_* */
    150             unsigned j, k, count = 0;
    151             const unsigned bitcount = sizeof(m->bits[0]) * 8;
    152 
    153             /* we only check first two format masks (out of 8) - others are zero. */
    154             printf("   Format[0]:\t%#08x\n", m->bits[0]);
    155             printf("   Format[1]:\t%#08x\n", m->bits[1]);
    156 
    157             /* print friendly format names, if they exist */
    158             for (k = 0; k < 2; ++k) {
    159                 for (j = 0; j < bitcount; ++j) {
    160                     const char *name;
    161 
    162                     if (m->bits[k] & (1 << j)) {
    163                         name = pcm_get_format_name(j + k*bitcount);
    164                         if (name) {
    165                             if (count++ == 0) {
    166                                 printf(" Format Name:\t");
    167                             } else {
    168                                 printf (", ");
    169                             }
    170                             printf("%s", name);
    171                         }
    172                     }
    173                 }
    174             }
    175             if (count) {
    176                 printf("\n");
    177             }
    178         }
    179         m = pcm_params_get_mask(params, PCM_PARAM_SUBFORMAT);
    180         if (m) { /* bitmask, should be 1: SNDRV_PCM_SUBFORMAT_STD */
    181             printf("   Subformat:\t%#08x\n", m->bits[0]);
    182         }
    183         min = pcm_params_get_min(params, PCM_PARAM_RATE);
    184         max = pcm_params_get_max(params, PCM_PARAM_RATE);
    185         printf("        Rate:\tmin=%uHz\tmax=%uHz\n", min, max);
    186         min = pcm_params_get_min(params, PCM_PARAM_CHANNELS);
    187         max = pcm_params_get_max(params, PCM_PARAM_CHANNELS);
    188         printf("    Channels:\tmin=%u\t\tmax=%u\n", min, max);
    189         min = pcm_params_get_min(params, PCM_PARAM_SAMPLE_BITS);
    190         max = pcm_params_get_max(params, PCM_PARAM_SAMPLE_BITS);
    191         printf(" Sample bits:\tmin=%u\t\tmax=%u\n", min, max);
    192         min = pcm_params_get_min(params, PCM_PARAM_PERIOD_SIZE);
    193         max = pcm_params_get_max(params, PCM_PARAM_PERIOD_SIZE);
    194         printf(" Period size:\tmin=%u\t\tmax=%u\n", min, max);
    195         min = pcm_params_get_min(params, PCM_PARAM_PERIODS);
    196         max = pcm_params_get_max(params, PCM_PARAM_PERIODS);
    197         printf("Period count:\tmin=%u\t\tmax=%u\n", min, max);
    198 
    199         pcm_params_free(params);
    200     }
    201 
    202     return 0;
    203 }
    204