1 /*
2 * Copyright 2017 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 required 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 #define LOG_NDEBUG 0
18 #define LOG_TAG "AAudioTest"
19
20 #include <aaudio/AAudio.h>
21 #include <android/log.h>
22 #include <gtest/gtest.h>
23
24 // Creates a builder, the caller takes ownership
create_stream_builder(AAudioStreamBuilder ** aaudioBuilder)25 static void create_stream_builder(AAudioStreamBuilder** aaudioBuilder) {
26 aaudio_result_t result = AAudio_createStreamBuilder(aaudioBuilder);
27 ASSERT_EQ(AAUDIO_OK, result);
28 ASSERT_NE(nullptr, *aaudioBuilder);
29 }
30
31 enum class Expect { FAIL, SUCCEED, NOT_CRASH };
32
33 // Tries to open an audio stream using a primed Builder.
34 // Takes ownership of the Builder.
try_opening_audio_stream(AAudioStreamBuilder * aaudioBuilder,Expect expect)35 static void try_opening_audio_stream(AAudioStreamBuilder *aaudioBuilder, Expect expect) {
36 // Create an AAudioStream using the Builder.
37 AAudioStream *aaudioStream = nullptr;
38 aaudio_result_t result = AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream);
39 if (expect == Expect::FAIL) {
40 ASSERT_NE(AAUDIO_OK, result);
41 ASSERT_EQ(nullptr, aaudioStream);
42 } else if (expect == Expect::SUCCEED) {
43 ASSERT_EQ(AAUDIO_OK, result);
44 ASSERT_NE(nullptr, aaudioStream);
45 } else { // NOT_CRASH
46 ASSERT_TRUE(((result < 0) && (aaudioStream == nullptr))
47 || ((result == AAUDIO_OK) && (aaudioStream != nullptr)));
48 }
49
50 // Cleanup
51 ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_delete(aaudioBuilder));
52 if (aaudioStream != nullptr) {
53 ASSERT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream));
54 }
55 }
56
57 // Test creating a default stream with specific devices
runtest_aaudio_devices(int32_t deviceId,Expect expect)58 static void runtest_aaudio_devices(int32_t deviceId, Expect expect) {
59 AAudioStreamBuilder *aaudioBuilder = nullptr;
60 create_stream_builder(&aaudioBuilder);
61 AAudioStreamBuilder_setDeviceId(aaudioBuilder, deviceId);
62 try_opening_audio_stream(aaudioBuilder, expect);
63 }
64
TEST(test_aaudio,aaudio_stream_device_unspecified)65 TEST(test_aaudio, aaudio_stream_device_unspecified) {
66 runtest_aaudio_devices(AAUDIO_UNSPECIFIED, Expect::NOT_CRASH);
67 }
68
69 /* FIXME - why can we open this device? What is an illegal deviceId?
70 TEST(test_aaudio, aaudio_stream_device_absurd) {
71 runtest_aaudio_devices(19736459, true);
72 }
73 */
74 /* FIXME review
75 TEST(test_aaudio, aaudio_stream_device_reasonable) {
76 runtest_aaudio_devices(1, false);
77 }
78 */
79
80 /* FIXME - why can we open this device? What is an illegal deviceId?
81 TEST(test_aaudio, aaudio_stream_device_negative) {
82 runtest_aaudio_devices(-765, true);
83 }
84 */
85
86 // Test creating a default stream with everything unspecified.
TEST(test_aaudio,aaudio_stream_unspecified)87 TEST(test_aaudio, aaudio_stream_unspecified) {
88 AAudioStreamBuilder *aaudioBuilder = nullptr;
89 create_stream_builder(&aaudioBuilder);
90
91 // Create an AAudioStream using the Builder.
92 AAudioStream *aaudioStream = nullptr;
93 ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream));
94 ASSERT_NE(nullptr, aaudioStream);
95
96 // Cleanup
97 EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_delete(aaudioBuilder));
98 EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream));
99 }
100
101 class AAudioStreamBuilderSamplingRateTest : public ::testing::TestWithParam<int32_t> {
102 public:
getTestName(const::testing::TestParamInfo<int32_t> & info)103 static std::string getTestName(const ::testing::TestParamInfo<int32_t>& info) {
104 return info.param >= 0 ? std::to_string(info.param) : "_" + std::to_string(-info.param);
105 }
106 protected:
isValidSamplingRate(int32_t sr)107 static bool isValidSamplingRate(int32_t sr) {
108 return sr == AAUDIO_UNSPECIFIED || (sr >= 8000 && sr <= 1000000);
109 }
110 };
111
TEST_P(AAudioStreamBuilderSamplingRateTest,openStream)112 TEST_P(AAudioStreamBuilderSamplingRateTest, openStream) {
113 AAudioStreamBuilder *aaudioBuilder = nullptr;
114 create_stream_builder(&aaudioBuilder);
115 AAudioStreamBuilder_setSampleRate(aaudioBuilder, GetParam());
116 try_opening_audio_stream(
117 aaudioBuilder, isValidSamplingRate(GetParam()) ? Expect::SUCCEED : Expect::FAIL);
118 }
119
120 INSTANTIATE_TEST_CASE_P(SR, AAudioStreamBuilderSamplingRateTest,
121 ::testing::Values(
122 // Commonly used values
123 AAUDIO_UNSPECIFIED, 8000, 11025, 16000, 22050, 44100, 48000, 88200, 96000,
124 176400, 192000, 384000,
125 // Odd values
126 AAUDIO_UNSPECIFIED - 1, AAUDIO_UNSPECIFIED + 1, 1234, 10000000),
127 &AAudioStreamBuilderSamplingRateTest::getTestName);
128
129 class AAudioStreamBuilderChannelCountTest : public ::testing::TestWithParam<int32_t> {
130 public:
getTestName(const::testing::TestParamInfo<int32_t> & info)131 static std::string getTestName(const ::testing::TestParamInfo<int32_t>& info) {
132 return info.param >= 0 ? std::to_string(info.param) : "_" + std::to_string(-info.param);
133 }
134 protected:
isValidChannelCount(int32_t cc)135 static bool isValidChannelCount(int32_t cc) {
136 return cc == AAUDIO_UNSPECIFIED || (cc >= 1 && cc <= 8);
137 }
138 };
139
TEST_P(AAudioStreamBuilderChannelCountTest,openStream)140 TEST_P(AAudioStreamBuilderChannelCountTest, openStream) {
141 AAudioStreamBuilder *aaudioBuilder = nullptr;
142 create_stream_builder(&aaudioBuilder);
143 AAudioStreamBuilder_setChannelCount(aaudioBuilder, GetParam());
144 try_opening_audio_stream(
145 aaudioBuilder, isValidChannelCount(GetParam()) ? Expect::SUCCEED : Expect::FAIL);
146 }
147
148 INSTANTIATE_TEST_CASE_P(CC, AAudioStreamBuilderChannelCountTest,
149 ::testing::Values(
150 // Reasonable values
151 AAUDIO_UNSPECIFIED, 1, 2, 3, 4, 5, 6, 7, 8,
152 // Odd values
153 AAUDIO_UNSPECIFIED - 1, 9, 100, 1000000, 10000000),
154 &AAudioStreamBuilderChannelCountTest::getTestName);
155
156 class AAudioStreamBuilderFormatTest : public ::testing::TestWithParam<aaudio_format_t> {
157 public:
getTestName(const::testing::TestParamInfo<aaudio_format_t> & info)158 static std::string getTestName(const ::testing::TestParamInfo<aaudio_format_t>& info) {
159 return info.param >= 0 ? std::to_string(info.param) : "_" + std::to_string(-info.param);
160 }
161 protected:
isValidFormat(aaudio_format_t f)162 static bool isValidFormat(aaudio_format_t f) {
163 switch (f) {
164 case AAUDIO_FORMAT_UNSPECIFIED:
165 case AAUDIO_FORMAT_PCM_I16:
166 case AAUDIO_FORMAT_PCM_FLOAT:
167 return true;
168 }
169 return false;
170 }
171 };
172
TEST_P(AAudioStreamBuilderFormatTest,openStream)173 TEST_P(AAudioStreamBuilderFormatTest, openStream) {
174 AAudioStreamBuilder *aaudioBuilder = nullptr;
175 create_stream_builder(&aaudioBuilder);
176 AAudioStreamBuilder_setFormat(aaudioBuilder, GetParam());
177 try_opening_audio_stream(
178 aaudioBuilder, isValidFormat(GetParam()) ? Expect::SUCCEED : Expect::FAIL);
179 }
180
181 INSTANTIATE_TEST_CASE_P(F, AAudioStreamBuilderFormatTest,
182 ::testing::Values(
183 // Reasonable values
184 AAUDIO_FORMAT_UNSPECIFIED, AAUDIO_FORMAT_PCM_I16, AAUDIO_FORMAT_PCM_FLOAT,
185 // Odd values
186 AAUDIO_FORMAT_INVALID, AAUDIO_FORMAT_INVALID - 1, 100, 1000000, 10000000),
187 &AAudioStreamBuilderFormatTest::getTestName);
188
189 class AAudioStreamBuilderSharingModeTest : public ::testing::TestWithParam<aaudio_sharing_mode_t> {
190 public:
getTestName(const::testing::TestParamInfo<aaudio_sharing_mode_t> & info)191 static std::string getTestName(const ::testing::TestParamInfo<aaudio_sharing_mode_t>& info) {
192 return info.param >= 0 ? std::to_string(info.param) : "_" + std::to_string(-info.param);
193 }
194 protected:
isValidSharingMode(aaudio_sharing_mode_t f)195 static bool isValidSharingMode(aaudio_sharing_mode_t f) {
196 return f == AAUDIO_SHARING_MODE_SHARED || f == AAUDIO_SHARING_MODE_EXCLUSIVE;
197 }
198 };
199
TEST_P(AAudioStreamBuilderSharingModeTest,openStream)200 TEST_P(AAudioStreamBuilderSharingModeTest, openStream) {
201 AAudioStreamBuilder *aaudioBuilder = nullptr;
202 create_stream_builder(&aaudioBuilder);
203 AAudioStreamBuilder_setFormat(aaudioBuilder, GetParam());
204 try_opening_audio_stream(
205 aaudioBuilder, isValidSharingMode(GetParam()) ? Expect::SUCCEED : Expect::FAIL);
206 }
207
208 INSTANTIATE_TEST_CASE_P(SM, AAudioStreamBuilderSharingModeTest,
209 ::testing::Values(
210 // Reasonable values
211 AAUDIO_SHARING_MODE_SHARED, AAUDIO_SHARING_MODE_EXCLUSIVE,
212 // Odd values
213 -1, 100, 1000000, 10000000),
214 &AAudioStreamBuilderSharingModeTest::getTestName);
215
216 class AAudioStreamBuilderDirectionTest : public ::testing::TestWithParam<aaudio_direction_t> {
217 public:
getTestName(const::testing::TestParamInfo<aaudio_direction_t> & info)218 static std::string getTestName(const ::testing::TestParamInfo<aaudio_direction_t>& info) {
219 return info.param >= 0 ? std::to_string(info.param) : "_" + std::to_string(-info.param);
220 }
221 protected:
isValidSharingMode(aaudio_direction_t f)222 static bool isValidSharingMode(aaudio_direction_t f) {
223 return f == AAUDIO_DIRECTION_OUTPUT || f == AAUDIO_DIRECTION_INPUT;
224 }
225 };
226
TEST_P(AAudioStreamBuilderDirectionTest,openStream)227 TEST_P(AAudioStreamBuilderDirectionTest, openStream) {
228 AAudioStreamBuilder *aaudioBuilder = nullptr;
229 create_stream_builder(&aaudioBuilder);
230 AAudioStreamBuilder_setFormat(aaudioBuilder, GetParam());
231 try_opening_audio_stream(
232 aaudioBuilder, isValidSharingMode(GetParam()) ? Expect::SUCCEED : Expect::FAIL);
233 }
234
235 INSTANTIATE_TEST_CASE_P(SD, AAudioStreamBuilderDirectionTest,
236 ::testing::Values(
237 // Reasonable values
238 AAUDIO_DIRECTION_OUTPUT, AAUDIO_DIRECTION_INPUT,
239 // Odd values
240 -1, 100, 1000000, 10000000),
241 &AAudioStreamBuilderDirectionTest::getTestName);
242
243 class AAudioStreamBuilderBufferCapacityTest : public ::testing::TestWithParam<int32_t> {
244 public:
getTestName(const::testing::TestParamInfo<int32_t> & info)245 static std::string getTestName(const ::testing::TestParamInfo<int32_t>& info) {
246 return info.param >= 0 ? std::to_string(info.param) : "_" + std::to_string(-info.param);
247 }
248 protected:
249 // There is no hard defined limit, the actual maximum capacity depends
250 // on the implementation.
isValidCapacity(int32_t bc)251 static bool isValidCapacity(int32_t bc) {
252 return bc == AAUDIO_UNSPECIFIED || bc >= 0;
253 }
254 };
255
TEST_P(AAudioStreamBuilderBufferCapacityTest,openStream)256 TEST_P(AAudioStreamBuilderBufferCapacityTest, openStream) {
257 AAudioStreamBuilder *aaudioBuilder = nullptr;
258 create_stream_builder(&aaudioBuilder);
259 AAudioStreamBuilder_setBufferCapacityInFrames(aaudioBuilder, GetParam());
260 try_opening_audio_stream(
261 aaudioBuilder, isValidCapacity(GetParam()) ? Expect::SUCCEED : Expect::FAIL);
262 }
263
264 INSTANTIATE_TEST_CASE_P(BC, AAudioStreamBuilderBufferCapacityTest,
265 ::testing::Values(
266 // Reasonable values that should not fail
267 AAUDIO_UNSPECIFIED, 8 * 192, 2 * 1024,
268 // Odd values
269 AAUDIO_UNSPECIFIED - 1),
270 &AAudioStreamBuilderBufferCapacityTest::getTestName);
271
272 class AAudioStreamBuilderPerfModeTest : public ::testing::TestWithParam<aaudio_performance_mode_t> {
273 public:
getTestName(const::testing::TestParamInfo<aaudio_performance_mode_t> & info)274 static std::string getTestName(const ::testing::TestParamInfo<aaudio_performance_mode_t>& info) {
275 return info.param >= 0 ? std::to_string(info.param) : "_" + std::to_string(-info.param);
276 }
277 protected:
isValidPerfMode(aaudio_performance_mode_t pm)278 static bool isValidPerfMode(aaudio_performance_mode_t pm) {
279 switch (pm) {
280 case AAUDIO_PERFORMANCE_MODE_NONE:
281 case AAUDIO_PERFORMANCE_MODE_POWER_SAVING:
282 case AAUDIO_PERFORMANCE_MODE_LOW_LATENCY:
283 return true;
284 }
285 return false;
286 }
287 };
288
TEST_P(AAudioStreamBuilderPerfModeTest,openStream)289 TEST_P(AAudioStreamBuilderPerfModeTest, openStream) {
290 AAudioStreamBuilder *aaudioBuilder = nullptr;
291 create_stream_builder(&aaudioBuilder);
292 AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, GetParam());
293 try_opening_audio_stream(
294 aaudioBuilder, isValidPerfMode(GetParam()) ? Expect::SUCCEED : Expect::FAIL);
295 }
296
297 INSTANTIATE_TEST_CASE_P(PM, AAudioStreamBuilderPerfModeTest,
298 ::testing::Values(
299 // Reasonable values
300 AAUDIO_PERFORMANCE_MODE_NONE,
301 AAUDIO_PERFORMANCE_MODE_POWER_SAVING,
302 AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
303 // Odd values
304 AAUDIO_UNSPECIFIED - 1, AAUDIO_UNSPECIFIED, 100, 1000000, 10000000),
305 &AAudioStreamBuilderPerfModeTest::getTestName);
306