blob: 7740f206dbdbdb7e58abc7177913dd5fed1e1bcc [file] [log] [blame]
Wu-Cheng Li9e5ae902017-10-26 22:55:48 +08001/*
2 * Copyright 2017 The Chromium OS Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
5 */
6
7#include <alsa/asoundlib.h>
8#include <getopt.h>
9#include <stdio.h>
10#include <stdlib.h>
11
12static void print_supported_capture_channels(const char *dev)
13{
14 int err;
15 unsigned int channels_min = 0, channels_max = 0;
16 snd_pcm_hw_params_t *params;
17 snd_pcm_t *handle;
18
19 if ((err = snd_pcm_open(&handle, dev, SND_PCM_STREAM_CAPTURE, 0)) < 0) {
20 fprintf(stderr, "Cannot open audio device for capture: %s (%s)\n",
21 dev, snd_strerror(err));
22 exit(EXIT_FAILURE);
23 }
24
25 if ((err = snd_pcm_hw_params_malloc(&params)) < 0) {
26 fprintf(stderr, "Cannot allocate hw params structure (%s)\n",
27 snd_strerror(err));
28 exit(EXIT_FAILURE);
29 }
30
31 if ((err = snd_pcm_hw_params_any(handle, params)) < 0) {
32 fprintf(stderr, "Cannot initialize hw params structure (%s)\n",
33 snd_strerror(err));
34 exit(EXIT_FAILURE);
35 }
36
37 if ((err = snd_pcm_hw_params_get_channels_min(params, &channels_min)) < 0) {
38 fprintf(stderr, "Cannot get channels min (%s)\n",
39 snd_strerror(err));
40 exit(EXIT_FAILURE);
41 }
42 fprintf(stderr, "channels min=%u\n", channels_min);
43
44 if ((err = snd_pcm_hw_params_get_channels_max(params, &channels_max)) < 0) {
45 fprintf(stderr, "Cannot get channels max (%s)\n",
46 snd_strerror(err));
47 exit(EXIT_FAILURE);
48 }
49 fprintf(stderr, "channels max=%u\n", channels_max);
50
51 for (unsigned int i = channels_min; i <= channels_max; i++) {
52 if ((err = snd_pcm_hw_params_test_channels(handle, params, i)) < 0) {
53 fprintf(stderr, "Test channels %u failed (%s)\n",
54 i, snd_strerror(err));
55 } else {
56 printf("%u\n", i);
57 fprintf(stderr, "Channels %u is supported\n", i);
58 }
59 }
60
61 snd_pcm_hw_params_free(params);
62 snd_pcm_close(handle);
63}
64
Louis Collard07d63992018-01-10 18:16:59 +080065static void print_card_names() {
66 int card = -1;
67 snd_ctl_t *handle;
68 snd_ctl_card_info_t *info;
69 snd_ctl_card_info_alloca(&info);
70
71 if (snd_card_next(&card) < 0 || card < 0) {
72 fprintf(stderr, "Failed to get devices.\n");
73 exit(EXIT_FAILURE);
74 }
75
76 while (card >= 0) {
77 char name[16];
78 sprintf(name, "hw:%d", card);
79
80 if (snd_ctl_open(&handle, name, 0) < 0) {
81 fprintf(stderr, "Failed to open device: %s\n", name);
82 exit(EXIT_FAILURE);
83 }
84
85 if (snd_ctl_card_info(handle, info) < 0) {
86 fprintf(stderr, "Failed to get info for device: %s\n", name);
87 exit(EXIT_FAILURE);
88 }
89
90 printf("%d,%s\n", card, snd_ctl_card_info_get_name(info));
91
92 snd_ctl_close(handle);
93
94 if (snd_card_next(&card) < 0) {
95 fprintf(stderr, "Failed to get next card\n");
96 exit(EXIT_FAILURE);
97 }
98 }
99}
Wu-Cheng Li9e5ae902017-10-26 22:55:48 +0800100
101/* This program has helper functions that are used by autotests. The returned
102 values are printed in stdout. Debug and error logs are printed in stderr.
103 If the program fails to get the requested value, it returns 1. */
104int main(int argc, char *argv[])
105{
Louis Collard07d63992018-01-10 18:16:59 +0800106 int c, get_capture_channels = 0, list_card_names = 0;
107 const char *short_opt = "hd:cl";
Wu-Cheng Li9e5ae902017-10-26 22:55:48 +0800108 char *dev = "hw:0,0";
109
110 struct option long_opt[] =
111 {
112 {"help", no_argument, NULL, 'h'},
113 {"device", required_argument, NULL, 'd'},
114 {"get_capture_channels", no_argument, NULL, 'c'},
Louis Collard07d63992018-01-10 18:16:59 +0800115 {"list_card_names", no_argument, NULL, 'l'},
Wu-Cheng Li9e5ae902017-10-26 22:55:48 +0800116 {NULL, 0, NULL, 0 }
117 };
118
119 while(1) {
120 c = getopt_long(argc, argv, short_opt, long_opt, NULL);
121 if (c == -1)
122 break;
123 switch(c) {
124 case 'd':
125 dev = optarg;
126 fprintf(stderr, "Assign device to %s\n", dev);
127 break;
128
129 case 'c':
130 get_capture_channels = 1;
131 break;
132
Louis Collard07d63992018-01-10 18:16:59 +0800133 case 'l':
134 list_card_names = 1;
135 break;
136
Wu-Cheng Li9e5ae902017-10-26 22:55:48 +0800137 case 'h':
138 printf("Usage: %s [OPTIONS]\n", argv[0]);
Louis Collard07d63992018-01-10 18:16:59 +0800139 printf(" -d, --device <Device> Device, default to hw:0,0\n");
140 printf(" -h, --help Print this help and exit\n");
141 printf(" -c, --get_capture_channels Get supported channels of the "
142 "capture device\n");
143 printf(" -l, --list_card_names List all cards including "
144 "names\n");
Wu-Cheng Li9e5ae902017-10-26 22:55:48 +0800145 return(EXIT_SUCCESS);
Wu-Cheng Li9e5ae902017-10-26 22:55:48 +0800146
147 default:
148 fprintf(stderr, "Try `%s --help' for more information.\n", argv[0]);
149 exit(EXIT_FAILURE);
150 }
151 }
152
153 if (get_capture_channels) {
154 print_supported_capture_channels(dev);
155 exit(EXIT_SUCCESS);
156 }
157
Louis Collard07d63992018-01-10 18:16:59 +0800158 if (list_card_names) {
159 print_card_names();
160 exit(EXIT_SUCCESS);
161 }
162
Wu-Cheng Li9e5ae902017-10-26 22:55:48 +0800163 fprintf(stderr, "Try `%s --help' for more information.\n", argv[0]);
164 exit(EXIT_FAILURE);
165}