2 * Copyright (C) 2013 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless requied by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
24 #include <gtest/gtest.h>
25 #include <linux/ioctl.h>
29 #include <sound/asound.h>
30 #include <sys/types.h>
31 #include <tinyalsa/asoundlib.h>
33 #define LOG_TAG "pcmtest"
34 #include <utils/Log.h>
37 #define PCM_PREFIX "pcm"
38 #define MIXER_PREFIX "control"
39 #define TIMER_PREFIX "timer"
41 const char kSoundDir[] = "/dev/snd";
43 typedef struct PCM_NODE {
49 static pcm_node_t *pcmnodes;
51 static unsigned int pcms;
52 static unsigned int cards;
53 static unsigned int mixers;
54 static unsigned int timers;
60 unsigned int pcount = 0;
62 d = opendir(kSoundDir);
65 while ((de = readdir(d)) != NULL) {
66 if (de->d_name[0] == '.')
68 if (strstr(de->d_name, PCM_PREFIX))
75 int getSndDev(unsigned int pcmdevs)
79 unsigned int prevcard = -1;
81 d = opendir(kSoundDir);
84 pcmnodes = (pcm_node_t *)malloc(pcmdevs * sizeof(pcm_node_t));
88 while ((de = readdir(d)) != NULL) {
89 if (de->d_name[0] == '.')
91 /* printf("%s\n", de->d_name); */
92 if (strstr(de->d_name, PCM_PREFIX)) {
95 EXPECT_LE(pcms, pcmdevs) << "Too many PCMs";
98 sscanf(de->d_name, PCM_PREFIX "C%uD%u", &(pcmnodes[pcms].card),
99 &(pcmnodes[pcms].device));
100 flags = de->d_name[strlen(de->d_name)-1];
102 pcmnodes[pcms].flags = PCM_IN;
103 } else if(flags == 'p') {
104 pcmnodes[pcms].flags = PCM_OUT;
106 pcmnodes[pcms].flags = -1;
107 testPrintI("Unknown PCM type = %c", flags);
109 if (prevcard != pcmnodes[pcms].card)
111 prevcard = pcmnodes[pcms].card;
115 if (strstr(de->d_name, MIXER_PREFIX)) {
116 unsigned int mixer = -1;
117 sscanf(de->d_name, MIXER_PREFIX "C%u", &mixer);
121 if (strstr(de->d_name, TIMER_PREFIX)) {
130 int getPcmParams(unsigned int i)
132 struct pcm_params *params;
136 params = pcm_params_get(pcmnodes[i].card, pcmnodes[i].device,
141 min = pcm_params_get_min(params, PCM_PARAM_RATE);
142 max = pcm_params_get_max(params, PCM_PARAM_RATE);
144 /* printf(" Rate:\tmin=%uHz\tmax=%uHz\n", min, max); */
145 min = pcm_params_get_min(params, PCM_PARAM_CHANNELS);
146 max = pcm_params_get_max(params, PCM_PARAM_CHANNELS);
148 /* printf(" Channels:\tmin=%u\t\tmax=%u\n", min, max); */
149 min = pcm_params_get_min(params, PCM_PARAM_SAMPLE_BITS);
150 max = pcm_params_get_max(params, PCM_PARAM_SAMPLE_BITS);
152 /* printf(" Sample bits:\tmin=%u\t\tmax=%u\n", min, max); */
153 min = pcm_params_get_min(params, PCM_PARAM_PERIOD_SIZE);
154 max = pcm_params_get_max(params, PCM_PARAM_PERIOD_SIZE);
156 /* printf(" Period size:\tmin=%u\t\tmax=%u\n", min, max); */
157 min = pcm_params_get_min(params, PCM_PARAM_PERIODS);
158 max = pcm_params_get_max(params, PCM_PARAM_PERIODS);
160 /* printf("Period count:\tmin=%u\t\tmax=%u\n", min, max); */
162 pcm_params_free(params);
166 TEST(pcmtest, CheckAudioDir) {
167 pcms = getPcmNodes();
171 TEST(pcmtest, GetSoundDevs) {
172 int err = getSndDev(pcms);
173 testPrintI(" DEVICES = PCMS:%u CARDS:%u MIXERS:%u TIMERS:%u",
174 pcms, cards, mixers, timers);
178 TEST(pcmtest, CheckPcmSanity0) {
182 TEST(pcmtest, CheckPcmSanity1) {
183 EXPECT_NE(1, pcms % 2);
186 TEST(pcmtests, CheckMixerSanity) {
187 ASSERT_NE(0, mixers);
188 ASSERT_EQ(mixers, cards);
191 TEST(pcmtest, CheckTimesSanity0) {
192 ASSERT_NE(0, timers);
195 TEST(pcmtest, CheckTimesSanity1) {
196 EXPECT_EQ(1, timers);
199 TEST(pcmtest, CheckPcmDevices) {
200 for (unsigned int i = 0; i < pcms; i++) {
201 EXPECT_EQ(0, getPcmParams(i));
206 TEST(pcmtest, CheckMixerDevices) {
208 for (unsigned int i = 0; i < mixers; i++) {
209 mixer = mixer_open(i);
210 EXPECT_TRUE(mixer != NULL);
216 TEST(pcmtest, CheckTimer) {
218 int fd = open("/dev/snd/timer", O_RDWR | O_NONBLOCK);
220 int ret = ioctl(fd, SNDRV_TIMER_IOCTL_PVERSION, &ver);
222 testPrintI(" Timer Version = 0x%x", ver);