blob: a8ea627d7eaa8e4f94cf218f3766ad6be3466b97 [file] [log] [blame]
Simon Wilson42fc2d32012-12-03 11:18:57 -08001/* 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
Andy Hunga5b44d92014-03-10 18:08:15 -070034#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 */
42static 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 */
95inline 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
Simon Wilson42fc2d32012-12-03 11:18:57 -0800100int 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
Dong Jinguanga1902c02017-12-20 10:18:09 +0800128 printf("Info for card %u, device %u:\n", card, device);
Simon Wilson42fc2d32012-12-03 11:18:57 -0800129
130 for (i = 0; i < 2; i++) {
131 struct pcm_params *params;
Andy Hunga5b44d92014-03-10 18:08:15 -0700132 struct pcm_mask *m;
Simon Wilson42fc2d32012-12-03 11:18:57 -0800133 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
Andy Hunga5b44d92014-03-10 18:08:15 -0700144 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 }
Simon Wilson42fc2d32012-12-03 11:18:57 -0800183 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}