xref: /aosp_15_r20/external/tinyalsa/tinypcminfo.c (revision d0c94b832dfb3062bf15d9baaf64123fc670b06c)
1*d0c94b83SXin Li /* tinypcminfo.c
2*d0c94b83SXin Li **
3*d0c94b83SXin Li ** Copyright 2012, The Android Open Source Project
4*d0c94b83SXin Li **
5*d0c94b83SXin Li ** Redistribution and use in source and binary forms, with or without
6*d0c94b83SXin Li ** modification, are permitted provided that the following conditions are met:
7*d0c94b83SXin Li **     * Redistributions of source code must retain the above copyright
8*d0c94b83SXin Li **       notice, this list of conditions and the following disclaimer.
9*d0c94b83SXin Li **     * Redistributions in binary form must reproduce the above copyright
10*d0c94b83SXin Li **       notice, this list of conditions and the following disclaimer in the
11*d0c94b83SXin Li **       documentation and/or other materials provided with the distribution.
12*d0c94b83SXin Li **     * Neither the name of The Android Open Source Project nor the names of
13*d0c94b83SXin Li **       its contributors may be used to endorse or promote products derived
14*d0c94b83SXin Li **       from this software without specific prior written permission.
15*d0c94b83SXin Li **
16*d0c94b83SXin Li ** THIS SOFTWARE IS PROVIDED BY The Android Open Source Project ``AS IS'' AND
17*d0c94b83SXin Li ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*d0c94b83SXin Li ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*d0c94b83SXin Li ** ARE DISCLAIMED. IN NO EVENT SHALL The Android Open Source Project BE LIABLE
20*d0c94b83SXin Li ** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21*d0c94b83SXin Li ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22*d0c94b83SXin Li ** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23*d0c94b83SXin Li ** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24*d0c94b83SXin Li ** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25*d0c94b83SXin Li ** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
26*d0c94b83SXin Li ** DAMAGE.
27*d0c94b83SXin Li */
28*d0c94b83SXin Li 
29*d0c94b83SXin Li #include <tinyalsa/asoundlib.h>
30*d0c94b83SXin Li #include <stdio.h>
31*d0c94b83SXin Li #include <stdlib.h>
32*d0c94b83SXin Li #include <string.h>
33*d0c94b83SXin Li 
34*d0c94b83SXin Li #ifndef ARRAY_SIZE
35*d0c94b83SXin Li #define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
36*d0c94b83SXin Li #endif
37*d0c94b83SXin Li 
38*d0c94b83SXin Li /* The format_lookup is in order of SNDRV_PCM_FORMAT_##index and
39*d0c94b83SXin Li  * matches the grouping in sound/asound.h.  Note this is not
40*d0c94b83SXin Li  * continuous and has an empty gap from (25 - 30).
41*d0c94b83SXin Li  */
42*d0c94b83SXin Li static const char *format_lookup[] = {
43*d0c94b83SXin Li         /*[0] =*/ "S8",
44*d0c94b83SXin Li         "U8",
45*d0c94b83SXin Li         "S16_LE",
46*d0c94b83SXin Li         "S16_BE",
47*d0c94b83SXin Li         "U16_LE",
48*d0c94b83SXin Li         "U16_BE",
49*d0c94b83SXin Li         "S24_LE",
50*d0c94b83SXin Li         "S24_BE",
51*d0c94b83SXin Li         "U24_LE",
52*d0c94b83SXin Li         "U24_BE",
53*d0c94b83SXin Li         "S32_LE",
54*d0c94b83SXin Li         "S32_BE",
55*d0c94b83SXin Li         "U32_LE",
56*d0c94b83SXin Li         "U32_BE",
57*d0c94b83SXin Li         "FLOAT_LE",
58*d0c94b83SXin Li         "FLOAT_BE",
59*d0c94b83SXin Li         "FLOAT64_LE",
60*d0c94b83SXin Li         "FLOAT64_BE",
61*d0c94b83SXin Li         "IEC958_SUBFRAME_LE",
62*d0c94b83SXin Li         "IEC958_SUBFRAME_BE",
63*d0c94b83SXin Li         "MU_LAW",
64*d0c94b83SXin Li         "A_LAW",
65*d0c94b83SXin Li         "IMA_ADPCM",
66*d0c94b83SXin Li         "MPEG",
67*d0c94b83SXin Li         /*[24] =*/ "GSM",
68*d0c94b83SXin Li         [31] = "SPECIAL",
69*d0c94b83SXin Li         "S24_3LE",
70*d0c94b83SXin Li         "S24_3BE",
71*d0c94b83SXin Li         "U24_3LE",
72*d0c94b83SXin Li         "U24_3BE",
73*d0c94b83SXin Li         "S20_3LE",
74*d0c94b83SXin Li         "S20_3BE",
75*d0c94b83SXin Li         "U20_3LE",
76*d0c94b83SXin Li         "U20_3BE",
77*d0c94b83SXin Li         "S18_3LE",
78*d0c94b83SXin Li         "S18_3BE",
79*d0c94b83SXin Li         "U18_3LE",
80*d0c94b83SXin Li         /*[43] =*/ "U18_3BE",
81*d0c94b83SXin Li #if 0
82*d0c94b83SXin Li         /* recent additions, may not be present on local asound.h */
83*d0c94b83SXin Li         "G723_24",
84*d0c94b83SXin Li         "G723_24_1B",
85*d0c94b83SXin Li         "G723_40",
86*d0c94b83SXin Li         "G723_40_1B",
87*d0c94b83SXin Li         "DSD_U8",
88*d0c94b83SXin Li         "DSD_U16_LE",
89*d0c94b83SXin Li #endif
90*d0c94b83SXin Li };
91*d0c94b83SXin Li 
92*d0c94b83SXin Li /* Returns a human readable name for the format associated with bit_index,
93*d0c94b83SXin Li  * NULL if bit_index is not known.
94*d0c94b83SXin Li  */
pcm_get_format_name(unsigned bit_index)95*d0c94b83SXin Li static inline const char *pcm_get_format_name(unsigned bit_index)
96*d0c94b83SXin Li {
97*d0c94b83SXin Li     return bit_index < ARRAY_SIZE(format_lookup) ? format_lookup[bit_index] : NULL;
98*d0c94b83SXin Li }
99*d0c94b83SXin Li 
main(int argc,char ** argv)100*d0c94b83SXin Li int main(int argc, char **argv)
101*d0c94b83SXin Li {
102*d0c94b83SXin Li     unsigned int device = 0;
103*d0c94b83SXin Li     unsigned int card = 0;
104*d0c94b83SXin Li     int i;
105*d0c94b83SXin Li 
106*d0c94b83SXin Li     if (argc < 3) {
107*d0c94b83SXin Li         fprintf(stderr, "Usage: %s -D card -d device\n", argv[0]);
108*d0c94b83SXin Li         return 1;
109*d0c94b83SXin Li     }
110*d0c94b83SXin Li 
111*d0c94b83SXin Li     /* parse command line arguments */
112*d0c94b83SXin Li     argv += 1;
113*d0c94b83SXin Li     while (*argv) {
114*d0c94b83SXin Li         if (strcmp(*argv, "-D") == 0) {
115*d0c94b83SXin Li             argv++;
116*d0c94b83SXin Li             if (*argv)
117*d0c94b83SXin Li                 card = atoi(*argv);
118*d0c94b83SXin Li         }
119*d0c94b83SXin Li         if (strcmp(*argv, "-d") == 0) {
120*d0c94b83SXin Li             argv++;
121*d0c94b83SXin Li             if (*argv)
122*d0c94b83SXin Li                 device = atoi(*argv);
123*d0c94b83SXin Li         }
124*d0c94b83SXin Li         if (*argv)
125*d0c94b83SXin Li             argv++;
126*d0c94b83SXin Li     }
127*d0c94b83SXin Li 
128*d0c94b83SXin Li     printf("Info for card %u, device %u:\n", card, device);
129*d0c94b83SXin Li 
130*d0c94b83SXin Li     for (i = 0; i < 2; i++) {
131*d0c94b83SXin Li         struct pcm_params *params;
132*d0c94b83SXin Li         struct pcm_mask *m;
133*d0c94b83SXin Li         unsigned int min;
134*d0c94b83SXin Li         unsigned int max;
135*d0c94b83SXin Li 
136*d0c94b83SXin Li         printf("\nPCM %s:\n", i == 0 ? "out" : "in");
137*d0c94b83SXin Li 
138*d0c94b83SXin Li         params = pcm_params_get(card, device, i == 0 ? PCM_OUT : PCM_IN);
139*d0c94b83SXin Li         if (params == NULL) {
140*d0c94b83SXin Li             printf("Device does not exist.\n");
141*d0c94b83SXin Li             continue;
142*d0c94b83SXin Li         }
143*d0c94b83SXin Li 
144*d0c94b83SXin Li         m = pcm_params_get_mask(params, PCM_PARAM_ACCESS);
145*d0c94b83SXin Li         if (m) { /* bitmask, refer to SNDRV_PCM_ACCESS_*, generally interleaved */
146*d0c94b83SXin Li             printf("      Access:\t%#08x\n", m->bits[0]);
147*d0c94b83SXin Li         }
148*d0c94b83SXin Li         m = pcm_params_get_mask(params, PCM_PARAM_FORMAT);
149*d0c94b83SXin Li         if (m) { /* bitmask, refer to: SNDRV_PCM_FORMAT_* */
150*d0c94b83SXin Li             unsigned j, k, count = 0;
151*d0c94b83SXin Li             const unsigned bitcount = sizeof(m->bits[0]) * 8;
152*d0c94b83SXin Li 
153*d0c94b83SXin Li             /* we only check first two format masks (out of 8) - others are zero. */
154*d0c94b83SXin Li             printf("   Format[0]:\t%#08x\n", m->bits[0]);
155*d0c94b83SXin Li             printf("   Format[1]:\t%#08x\n", m->bits[1]);
156*d0c94b83SXin Li 
157*d0c94b83SXin Li             /* print friendly format names, if they exist */
158*d0c94b83SXin Li             for (k = 0; k < 2; ++k) {
159*d0c94b83SXin Li                 for (j = 0; j < bitcount; ++j) {
160*d0c94b83SXin Li                     const char *name;
161*d0c94b83SXin Li 
162*d0c94b83SXin Li                     if (m->bits[k] & (1 << j)) {
163*d0c94b83SXin Li                         name = pcm_get_format_name(j + k*bitcount);
164*d0c94b83SXin Li                         if (name) {
165*d0c94b83SXin Li                             if (count++ == 0) {
166*d0c94b83SXin Li                                 printf(" Format Name:\t");
167*d0c94b83SXin Li                             } else {
168*d0c94b83SXin Li                                 printf (", ");
169*d0c94b83SXin Li                             }
170*d0c94b83SXin Li                             printf("%s", name);
171*d0c94b83SXin Li                         }
172*d0c94b83SXin Li                     }
173*d0c94b83SXin Li                 }
174*d0c94b83SXin Li             }
175*d0c94b83SXin Li             if (count) {
176*d0c94b83SXin Li                 printf("\n");
177*d0c94b83SXin Li             }
178*d0c94b83SXin Li         }
179*d0c94b83SXin Li         m = pcm_params_get_mask(params, PCM_PARAM_SUBFORMAT);
180*d0c94b83SXin Li         if (m) { /* bitmask, should be 1: SNDRV_PCM_SUBFORMAT_STD */
181*d0c94b83SXin Li             printf("   Subformat:\t%#08x\n", m->bits[0]);
182*d0c94b83SXin Li         }
183*d0c94b83SXin Li         min = pcm_params_get_min(params, PCM_PARAM_RATE);
184*d0c94b83SXin Li         max = pcm_params_get_max(params, PCM_PARAM_RATE);
185*d0c94b83SXin Li         printf("        Rate:\tmin=%uHz\tmax=%uHz\n", min, max);
186*d0c94b83SXin Li         min = pcm_params_get_min(params, PCM_PARAM_CHANNELS);
187*d0c94b83SXin Li         max = pcm_params_get_max(params, PCM_PARAM_CHANNELS);
188*d0c94b83SXin Li         printf("    Channels:\tmin=%u\t\tmax=%u\n", min, max);
189*d0c94b83SXin Li         min = pcm_params_get_min(params, PCM_PARAM_SAMPLE_BITS);
190*d0c94b83SXin Li         max = pcm_params_get_max(params, PCM_PARAM_SAMPLE_BITS);
191*d0c94b83SXin Li         printf(" Sample bits:\tmin=%u\t\tmax=%u\n", min, max);
192*d0c94b83SXin Li         min = pcm_params_get_min(params, PCM_PARAM_PERIOD_SIZE);
193*d0c94b83SXin Li         max = pcm_params_get_max(params, PCM_PARAM_PERIOD_SIZE);
194*d0c94b83SXin Li         printf(" Period size:\tmin=%u\t\tmax=%u\n", min, max);
195*d0c94b83SXin Li         min = pcm_params_get_min(params, PCM_PARAM_PERIODS);
196*d0c94b83SXin Li         max = pcm_params_get_max(params, PCM_PARAM_PERIODS);
197*d0c94b83SXin Li         printf("Period count:\tmin=%u\t\tmax=%u\n", min, max);
198*d0c94b83SXin Li 
199*d0c94b83SXin Li         pcm_params_free(params);
200*d0c94b83SXin Li     }
201*d0c94b83SXin Li 
202*d0c94b83SXin Li     return 0;
203*d0c94b83SXin Li }
204