OSDN Git Service

am 9fe52666: Merge "Remove bench_locks, which is a subset of bench_pthread."
[android-x86/system-extras.git] / tests / audio / alsa / pcmtest.cpp
1 /*
2  * Copyright (C) 2013 The Android Open Source Project
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 #include <assert.h>
19 #include <dirent.h>
20 #include <errno.h>
21 #include <fcntl.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <gtest/gtest.h>
25 #include <linux/ioctl.h>
26 #define __force
27 #define __bitwise
28 #define __user
29 #include <sound/asound.h>
30 #include <sys/types.h>
31 #include <tinyalsa/asoundlib.h>
32
33 #define LOG_TAG "pcmtest"
34 #include <utils/Log.h>
35 #include <testUtil.h>
36
37 #define PCM_PREFIX      "pcm"
38 #define MIXER_PREFIX    "control"
39 #define TIMER_PREFIX    "timer"
40
41 const char kSoundDir[] = "/dev/snd";
42
43 typedef struct PCM_NODE {
44     unsigned int card;
45     unsigned int device;
46     unsigned int flags;
47 } pcm_node_t;
48
49 static pcm_node_t *pcmnodes;
50
51 static unsigned int pcms;
52 static unsigned int cards;
53 static unsigned int mixers;
54 static unsigned int timers;
55
56 int getPcmNodes(void)
57 {
58     DIR *d;
59     struct dirent *de;
60     unsigned int pcount = 0;
61
62     d = opendir(kSoundDir);
63     if (d == 0)
64         return 0;
65     while ((de = readdir(d)) != NULL) {
66         if (de->d_name[0] == '.')
67             continue;
68         if (strstr(de->d_name, PCM_PREFIX))
69             pcount++;
70     }
71     closedir(d);
72     return pcount;
73 }
74
75 int getSndDev(unsigned int pcmdevs)
76 {
77     DIR *d;
78     struct dirent *de;
79     unsigned int prevcard = -1;
80
81     d = opendir(kSoundDir);
82     if (d == 0)
83         return -ENXIO;
84     pcmnodes = (pcm_node_t *)malloc(pcmdevs * sizeof(pcm_node_t));
85     if (!pcmnodes)
86         return -ENOMEM;
87     pcms = 0;
88     while ((de = readdir(d)) != NULL) {
89         if (de->d_name[0] == '.')
90             continue;
91         /* printf("%s\n", de->d_name); */
92         if (strstr(de->d_name, PCM_PREFIX)) {
93             char flags;
94
95             EXPECT_LE(pcms, pcmdevs) << "Too many PCMs";
96             if (pcms >= pcmdevs)
97                 continue;
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];
101             if (flags == 'c') {
102                 pcmnodes[pcms].flags = PCM_IN;
103             } else if(flags == 'p') {
104                 pcmnodes[pcms].flags = PCM_OUT;
105             } else {
106                 pcmnodes[pcms].flags = -1;
107                 testPrintI("Unknown PCM type = %c", flags);
108             }
109             if (prevcard != pcmnodes[pcms].card)
110                 cards++;
111             prevcard = pcmnodes[pcms].card;
112             pcms++;
113             continue;
114         }
115         if (strstr(de->d_name, MIXER_PREFIX)) {
116             unsigned int mixer = -1;
117             sscanf(de->d_name, MIXER_PREFIX "C%u", &mixer);
118             mixers++;
119             continue;
120         }
121         if (strstr(de->d_name, TIMER_PREFIX)) {
122             timers++;
123             continue;
124         }
125     }
126     closedir(d);
127     return 0;
128 }
129
130 int getPcmParams(unsigned int i)
131 {
132     struct pcm_params *params;
133     unsigned int min;
134     unsigned int max;
135
136     params = pcm_params_get(pcmnodes[i].card, pcmnodes[i].device,
137                             pcmnodes[i].flags);
138     if (params == NULL)
139         return -ENODEV;
140
141     min = pcm_params_get_min(params, PCM_PARAM_RATE);
142     max = pcm_params_get_max(params, PCM_PARAM_RATE);
143     EXPECT_LE(min, max);
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);
147     EXPECT_LE(min, max);
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);
151     EXPECT_LE(min, max);
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);
155     EXPECT_LE(min, max);
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);
159     EXPECT_LE(min, max);
160     /* printf("Period count:\tmin=%u\t\tmax=%u\n", min, max); */
161
162     pcm_params_free(params);
163     return 0;
164 }
165
166 TEST(pcmtest, CheckAudioDir) {
167     pcms = getPcmNodes();
168     ASSERT_GT(pcms, 0);
169 }
170
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);
175     ASSERT_EQ(0, err);
176 }
177
178 TEST(pcmtest, CheckPcmSanity0) {
179     ASSERT_NE(0, pcms);
180 }
181
182 TEST(pcmtest, CheckPcmSanity1) {
183     EXPECT_NE(1, pcms % 2);
184 }
185
186 TEST(pcmtests, CheckMixerSanity) {
187     ASSERT_NE(0, mixers);
188     ASSERT_EQ(mixers, cards);
189 }
190
191 TEST(pcmtest, CheckTimesSanity0) {
192     ASSERT_NE(0, timers);
193 }
194
195 TEST(pcmtest, CheckTimesSanity1) {
196     EXPECT_EQ(1, timers);
197 }
198
199 TEST(pcmtest, CheckPcmDevices) {
200     for (unsigned int i = 0; i < pcms; i++) {
201         EXPECT_EQ(0, getPcmParams(i));
202     }
203     free(pcmnodes);
204 }
205
206 TEST(pcmtest, CheckMixerDevices) {
207     struct mixer *mixer;
208     for (unsigned int i = 0; i < mixers; i++) {
209          mixer = mixer_open(i);
210          EXPECT_TRUE(mixer != NULL);
211          if (mixer)
212              mixer_close(mixer);
213     }
214 }
215
216 TEST(pcmtest, CheckTimer) {
217     int ver = 0;
218     int fd = open("/dev/snd/timer", O_RDWR | O_NONBLOCK);
219     ASSERT_GE(fd, 0);
220     int ret = ioctl(fd, SNDRV_TIMER_IOCTL_PVERSION, &ver);
221     EXPECT_EQ(0, ret);
222     testPrintI(" Timer Version = 0x%x", ver);
223     close(fd);
224 }