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 <cstring>
21 #include <sstream>
22 #include <utility>
23
24 #include <aaudio/AAudio.h>
25 #include <android/log.h>
26 #include <android-base/properties.h>
27 #include <gtest/gtest.h>
28 #include <system/audio.h> /* FCC_LIMIT */
29
30 #include "utils.h"
31
32 /**
33 * See https://source.android.com/devices/tech/perf/low-ram
34 * for more details.
35 *
36 * @return true if running on low memory device
37 */
isLowRamDevice()38 static bool isLowRamDevice() {
39 return android::base::GetBoolProperty("ro.config.low_ram", false);
40 }
41
42 // Creates a builder, the caller takes ownership
create_stream_builder(AAudioStreamBuilder ** aaudioBuilder)43 static void create_stream_builder(AAudioStreamBuilder** aaudioBuilder) {
44 aaudio_result_t result = AAudio_createStreamBuilder(aaudioBuilder);
45 ASSERT_EQ(AAUDIO_OK, result);
46 ASSERT_NE(nullptr, *aaudioBuilder);
47 }
48
49 enum class Expect { FAIL, SUCCEED, NOT_CRASH };
50
51 // Tries to open an audio stream using a primed Builder.
52 // Takes ownership of the Builder.
try_opening_audio_stream(AAudioStreamBuilder * aaudioBuilder,Expect expect)53 static void try_opening_audio_stream(AAudioStreamBuilder *aaudioBuilder, Expect expect) {
54 // Create an AAudioStream using the Builder.
55 AAudioStream *aaudioStream = nullptr;
56 int64_t beforeTimeNanos = getNanoseconds();
57 aaudio_result_t result = AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream);
58 if (expect == Expect::FAIL) {
59 ASSERT_NE(AAUDIO_OK, result);
60 ASSERT_EQ(nullptr, aaudioStream);
61 } else if (expect == Expect::SUCCEED) {
62 ASSERT_EQ(AAUDIO_OK, result);
63 ASSERT_NE(nullptr, aaudioStream);
64 } else { // NOT_CRASH
65 ASSERT_TRUE(((result < 0) && (aaudioStream == nullptr))
66 || ((result == AAUDIO_OK) && (aaudioStream != nullptr)));
67 }
68
69 // The stream should be open within one second.
70 static const int64_t kNanosPerSecond = 1e9;
71 ASSERT_LT(getNanoseconds() - beforeTimeNanos, kNanosPerSecond)
72 << "It took more than one second to open stream";
73
74 // Cleanup
75 ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_delete(aaudioBuilder));
76 if (aaudioStream != nullptr) {
77 beforeTimeNanos = getNanoseconds();
78 ASSERT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream));
79 // The stream should be closed within one second.
80 ASSERT_LT(getNanoseconds() - beforeTimeNanos, kNanosPerSecond)
81 << "It took more than one second to close stream";
82 }
83 }
84
85 // Test creating a default stream with specific devices
runtest_aaudio_devices(int32_t deviceId,Expect expect)86 static void runtest_aaudio_devices(int32_t deviceId, Expect expect) {
87 AAudioStreamBuilder *aaudioBuilder = nullptr;
88 create_stream_builder(&aaudioBuilder);
89 AAudioStreamBuilder_setDeviceId(aaudioBuilder, deviceId);
90 try_opening_audio_stream(aaudioBuilder, expect);
91 }
92
93 class AAudioTest : public AAudioCtsBase {};
94
TEST_F(AAudioTest,aaudio_stream_device_unspecified)95 TEST_F(AAudioTest, aaudio_stream_device_unspecified) {
96 runtest_aaudio_devices(AAUDIO_UNSPECIFIED, Expect::NOT_CRASH);
97 }
98
99 /* FIXME - why can we open this device? What is an illegal deviceId?
100 TEST_F(AAudioTest, aaudio_stream_device_absurd) {
101 runtest_aaudio_devices(19736459, true);
102 }
103 */
104 /* FIXME review
105 TEST_F(AAudioTest, aaudio_stream_device_reasonable) {
106 runtest_aaudio_devices(1, false);
107 }
108 */
109
110 /* FIXME - why can we open this device? What is an illegal deviceId?
111 TEST_F(AAudioTest, aaudio_stream_device_negative) {
112 runtest_aaudio_devices(-765, true);
113 }
114 */
115
116 // Test creating a default stream with everything unspecified.
TEST_F(AAudioTest,aaudio_stream_unspecified)117 TEST_F(AAudioTest, aaudio_stream_unspecified) {
118 if (!deviceSupportsFeature(FEATURE_PLAYBACK)) return;
119 AAudioStreamBuilder *aaudioBuilder = nullptr;
120 create_stream_builder(&aaudioBuilder);
121
122 // Create an AAudioStream using the Builder.
123 AAudioStream *aaudioStream = nullptr;
124 ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream));
125 ASSERT_NE(nullptr, aaudioStream);
126
127 // Cleanup
128 EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_delete(aaudioBuilder));
129 EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream));
130 }
131
132 class AAudioStreamBuilderSamplingRateTest : public AAudioCtsBase,
133 public ::testing::WithParamInterface<int32_t> {
134 public:
getTestName(const::testing::TestParamInfo<int32_t> & info)135 static std::string getTestName(const ::testing::TestParamInfo<int32_t>& info) {
136 return info.param >= 0 ? std::to_string(info.param) : "_" + std::to_string(-info.param);
137 }
138 protected:
isValidSamplingRate(int32_t sr)139 static bool isValidSamplingRate(int32_t sr) {
140 return sr == AAUDIO_UNSPECIFIED || (sr >= 8000 && sr <= 1000000);
141 }
142 };
143
TEST_P(AAudioStreamBuilderSamplingRateTest,openStream)144 TEST_P(AAudioStreamBuilderSamplingRateTest, openStream) {
145 if (!deviceSupportsFeature(FEATURE_PLAYBACK)) return;
146 const int32_t sampleRate = GetParam();
147 const bool isSampleRateValid = isValidSamplingRate(sampleRate);
148 // Opening a stream with a high sample rates can fail because the required buffer size
149 // is bigger than the heap size. This is a limitation in AudioFlinger. b/112528380
150 if (isSampleRateValid && isLowRamDevice() && (sampleRate > 192000)) {
151 return; // skip this test
152 }
153 AAudioStreamBuilder *aaudioBuilder = nullptr;
154 create_stream_builder(&aaudioBuilder);
155 AAudioStreamBuilder_setSampleRate(aaudioBuilder, sampleRate);
156 try_opening_audio_stream(
157 aaudioBuilder, isSampleRateValid ? Expect::SUCCEED : Expect::FAIL);
158 }
159
160 INSTANTIATE_TEST_CASE_P(SR, AAudioStreamBuilderSamplingRateTest,
161 ::testing::Values(
162 // Commonly used values
163 AAUDIO_UNSPECIFIED, 8000, 11025, 16000, 22050, 44100, 48000, 88200, 96000,
164 176400, 192000, 384000,
165 // Odd values
166 AAUDIO_UNSPECIFIED - 1, AAUDIO_UNSPECIFIED + 1, 1234, 10000000),
167 &AAudioStreamBuilderSamplingRateTest::getTestName);
168
169 class AAudioStreamBuilderChannelCountTest : public AAudioCtsBase,
170 public ::testing::WithParamInterface<int32_t> {
171 public:
getTestName(const::testing::TestParamInfo<int32_t> & info)172 static std::string getTestName(const ::testing::TestParamInfo<int32_t>& info) {
173 return info.param >= 0 ? std::to_string(info.param) : "_" + std::to_string(-info.param);
174 }
175 protected:
isValidChannelCount(int32_t cc)176 static bool isValidChannelCount(int32_t cc) {
177 return cc == AAUDIO_UNSPECIFIED || (cc >= 1 && cc <= FCC_LIMIT);
178 }
179 };
180
TEST_P(AAudioStreamBuilderChannelCountTest,openStream)181 TEST_P(AAudioStreamBuilderChannelCountTest, openStream) {
182 if (!deviceSupportsFeature(FEATURE_PLAYBACK)) return;
183 AAudioStreamBuilder *aaudioBuilder = nullptr;
184 create_stream_builder(&aaudioBuilder);
185 AAudioStreamBuilder_setChannelCount(aaudioBuilder, GetParam());
186 try_opening_audio_stream(
187 aaudioBuilder, isValidChannelCount(GetParam()) ? Expect::SUCCEED : Expect::FAIL);
188 }
189
190 INSTANTIATE_TEST_CASE_P(CC, AAudioStreamBuilderChannelCountTest,
191 ::testing::Values(
192 // Reasonable values that should work OK.
193 AAUDIO_UNSPECIFIED, 1, 2, 3, 4, 5, 6, 7, 8, FCC_LIMIT,
194 // These values should fail.
195 AAUDIO_UNSPECIFIED - 1, (FCC_LIMIT + 1), 1000, 1000000),
196 &AAudioStreamBuilderChannelCountTest::getTestName);
197
198 class AAudioStreamBuilderFormatTest : public AAudioCtsBase,
199 public ::testing::WithParamInterface<aaudio_format_t> {
200 public:
getTestName(const::testing::TestParamInfo<aaudio_format_t> & info)201 static std::string getTestName(const ::testing::TestParamInfo<aaudio_format_t>& info) {
202 return info.param >= 0 ? std::to_string(info.param) : "_" + std::to_string(-info.param);
203 }
204 protected:
isValidFormat(aaudio_format_t f)205 static bool isValidFormat(aaudio_format_t f) {
206 switch (f) {
207 case AAUDIO_FORMAT_UNSPECIFIED:
208 case AAUDIO_FORMAT_PCM_I16:
209 case AAUDIO_FORMAT_PCM_FLOAT:
210 case AAUDIO_FORMAT_IEC61937:
211 case AAUDIO_FORMAT_PCM_I24_PACKED:
212 case AAUDIO_FORMAT_PCM_I32:
213 return true;
214 }
215 return false;
216 }
217 };
218
TEST_P(AAudioStreamBuilderFormatTest,openStream)219 TEST_P(AAudioStreamBuilderFormatTest, openStream) {
220 if (!deviceSupportsFeature(FEATURE_PLAYBACK)) return;
221 AAudioStreamBuilder *aaudioBuilder = nullptr;
222 create_stream_builder(&aaudioBuilder);
223 AAudioStreamBuilder_setFormat(aaudioBuilder, GetParam());
224 const aaudio_format_t format = GetParam();
225 Expect expectedResult = isValidFormat(format) ? Expect::SUCCEED : Expect::FAIL;
226 if (format == AAUDIO_FORMAT_IEC61937) {
227 expectedResult = isIEC61937Supported() ? Expect::SUCCEED : Expect::FAIL;
228 // For IEC61937, sample rate and channel mask should be specified.
229 AAudioStreamBuilder_setSampleRate(aaudioBuilder, 48000);
230 AAudioStreamBuilder_setChannelMask(aaudioBuilder, AAUDIO_CHANNEL_STEREO);
231 }
232 try_opening_audio_stream(aaudioBuilder, expectedResult);
233 }
234
235 INSTANTIATE_TEST_CASE_P(F, AAudioStreamBuilderFormatTest,
236 ::testing::Values(
237 // Reasonable values
238 AAUDIO_FORMAT_UNSPECIFIED, AAUDIO_FORMAT_PCM_I16, AAUDIO_FORMAT_PCM_FLOAT,
239 AAUDIO_FORMAT_PCM_I24_PACKED, AAUDIO_FORMAT_PCM_I32, AAUDIO_FORMAT_IEC61937,
240 // Odd values
241 AAUDIO_FORMAT_INVALID, AAUDIO_FORMAT_INVALID - 1, 100, 1000000, 10000000),
242 &AAudioStreamBuilderFormatTest::getTestName);
243
244 class AAudioStreamBuilderSharingModeTest :
245 public AAudioCtsBase, public ::testing::WithParamInterface<aaudio_sharing_mode_t> {
246 public:
getTestName(const::testing::TestParamInfo<aaudio_sharing_mode_t> & info)247 static std::string getTestName(const ::testing::TestParamInfo<aaudio_sharing_mode_t>& info) {
248 return info.param >= 0 ? std::to_string(info.param) : "_" + std::to_string(-info.param);
249 }
250 protected:
isValidSharingMode(aaudio_sharing_mode_t f)251 static bool isValidSharingMode(aaudio_sharing_mode_t f) {
252 return f == AAUDIO_SHARING_MODE_SHARED || f == AAUDIO_SHARING_MODE_EXCLUSIVE;
253 }
254 };
255
TEST_P(AAudioStreamBuilderSharingModeTest,openStream)256 TEST_P(AAudioStreamBuilderSharingModeTest, openStream) {
257 if (!deviceSupportsFeature(FEATURE_PLAYBACK)) return;
258 AAudioStreamBuilder *aaudioBuilder = nullptr;
259 create_stream_builder(&aaudioBuilder);
260 AAudioStreamBuilder_setSharingMode(aaudioBuilder, GetParam());
261 try_opening_audio_stream(
262 aaudioBuilder, isValidSharingMode(GetParam()) ? Expect::SUCCEED : Expect::FAIL);
263 }
264
265 INSTANTIATE_TEST_CASE_P(SM, AAudioStreamBuilderSharingModeTest,
266 ::testing::Values(
267 // Reasonable values
268 AAUDIO_SHARING_MODE_SHARED, AAUDIO_SHARING_MODE_EXCLUSIVE,
269 // Odd values
270 -1, 100, 1000000, 10000000),
271 &AAudioStreamBuilderSharingModeTest::getTestName);
272
273 class AAudioStreamBuilderDirectionTest : public AAudioCtsBase,
274 public ::testing::WithParamInterface<aaudio_direction_t> {
275 public:
getTestName(const::testing::TestParamInfo<aaudio_direction_t> & info)276 static std::string getTestName(const ::testing::TestParamInfo<aaudio_direction_t>& info) {
277 return info.param >= 0 ? std::to_string(info.param) : "_" + std::to_string(-info.param);
278 }
279 protected:
isValidDirection(aaudio_direction_t f)280 static bool isValidDirection(aaudio_direction_t f) {
281 return f == AAUDIO_DIRECTION_OUTPUT || f == AAUDIO_DIRECTION_INPUT;
282 }
283 };
284
TEST_P(AAudioStreamBuilderDirectionTest,openStream)285 TEST_P(AAudioStreamBuilderDirectionTest, openStream) {
286 if (GetParam() == AAUDIO_DIRECTION_OUTPUT
287 && !deviceSupportsFeature(FEATURE_PLAYBACK)) return;
288 if (GetParam() == AAUDIO_DIRECTION_INPUT
289 && !deviceSupportsFeature(FEATURE_RECORDING)) return;
290 AAudioStreamBuilder *aaudioBuilder = nullptr;
291 create_stream_builder(&aaudioBuilder);
292 AAudioStreamBuilder_setDirection(aaudioBuilder, GetParam());
293 try_opening_audio_stream(
294 aaudioBuilder, isValidDirection(GetParam()) ? Expect::SUCCEED : Expect::FAIL);
295 }
296
297 INSTANTIATE_TEST_CASE_P(SD, AAudioStreamBuilderDirectionTest,
298 ::testing::Values(
299 // Reasonable values
300 AAUDIO_DIRECTION_OUTPUT, AAUDIO_DIRECTION_INPUT,
301 // Odd values
302 -1, 100, 1000000, 10000000),
303 &AAudioStreamBuilderDirectionTest::getTestName);
304
305 class AAudioStreamBuilderBufferCapacityTest : public AAudioCtsBase,
306 public ::testing::WithParamInterface<int32_t> {
307 public:
getTestName(const::testing::TestParamInfo<int32_t> & info)308 static std::string getTestName(const ::testing::TestParamInfo<int32_t>& info) {
309 return info.param >= 0 ? std::to_string(info.param) : "_" + std::to_string(-info.param);
310 }
311 protected:
312 // There is no hard defined limit, the actual maximum capacity depends
313 // on the implementation.
isValidCapacity(int32_t bc)314 static bool isValidCapacity(int32_t bc) {
315 return bc == AAUDIO_UNSPECIFIED || bc >= 0;
316 }
317 };
318
TEST_P(AAudioStreamBuilderBufferCapacityTest,openStream)319 TEST_P(AAudioStreamBuilderBufferCapacityTest, openStream) {
320 if (!deviceSupportsFeature(FEATURE_PLAYBACK)) return;
321 AAudioStreamBuilder *aaudioBuilder = nullptr;
322 create_stream_builder(&aaudioBuilder);
323 AAudioStreamBuilder_setBufferCapacityInFrames(aaudioBuilder, GetParam());
324 try_opening_audio_stream(
325 aaudioBuilder, isValidCapacity(GetParam()) ? Expect::SUCCEED : Expect::FAIL);
326 }
327
328 INSTANTIATE_TEST_CASE_P(BC, AAudioStreamBuilderBufferCapacityTest,
329 ::testing::Values(
330 // Reasonable values that should not fail
331 AAUDIO_UNSPECIFIED, 8 * 192, 2 * 1024,
332 // Some large number, should not fail
333 8192, 512 * 1024,
334 // Odd values
335 AAUDIO_UNSPECIFIED - 1),
336 &AAudioStreamBuilderBufferCapacityTest::getTestName);
337
338 class AAudioStreamBuilderPerfModeTest :
339 public AAudioCtsBase, public ::testing::WithParamInterface<aaudio_performance_mode_t> {
340 public:
getTestName(const::testing::TestParamInfo<aaudio_performance_mode_t> & info)341 static std::string getTestName(const ::testing::TestParamInfo<aaudio_performance_mode_t>& info) {
342 return info.param >= 0 ? std::to_string(info.param) : "_" + std::to_string(-info.param);
343 }
344 protected:
isValidPerfMode(aaudio_performance_mode_t pm)345 static bool isValidPerfMode(aaudio_performance_mode_t pm) {
346 switch (pm) {
347 case AAUDIO_PERFORMANCE_MODE_NONE:
348 case AAUDIO_PERFORMANCE_MODE_POWER_SAVING:
349 case AAUDIO_PERFORMANCE_MODE_LOW_LATENCY:
350 return true;
351 }
352 return false;
353 }
354 };
355
TEST_P(AAudioStreamBuilderPerfModeTest,openStream)356 TEST_P(AAudioStreamBuilderPerfModeTest, openStream) {
357 if (!deviceSupportsFeature(FEATURE_PLAYBACK)) return;
358 AAudioStreamBuilder *aaudioBuilder = nullptr;
359 create_stream_builder(&aaudioBuilder);
360 AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, GetParam());
361 try_opening_audio_stream(
362 aaudioBuilder, isValidPerfMode(GetParam()) ? Expect::SUCCEED : Expect::FAIL);
363 }
364
365 INSTANTIATE_TEST_CASE_P(PM, AAudioStreamBuilderPerfModeTest,
366 ::testing::Values(
367 // Reasonable values
368 AAUDIO_PERFORMANCE_MODE_NONE,
369 AAUDIO_PERFORMANCE_MODE_POWER_SAVING,
370 AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
371 // Odd values
372 AAUDIO_UNSPECIFIED - 1, AAUDIO_UNSPECIFIED, 100, 1000000, 10000000),
373 &AAudioStreamBuilderPerfModeTest::getTestName);
374
375 class AAudioStreamBuilderChannelMaskTest :
376 public AAudioCtsBase, public ::testing::WithParamInterface<aaudio_channel_mask_t> {
377 public:
getTestName(const::testing::TestParamInfo<aaudio_channel_mask_t> & info)378 static std::string getTestName(const ::testing::TestParamInfo<aaudio_channel_mask_t>& info) {
379 std::stringstream ss;
380 ss << "0x" << std::hex << info.param;
381 return ss.str();
382 }
383 protected:
384
isValidChannelMask(aaudio_channel_mask_t channelMask,bool isInput)385 static bool isValidChannelMask(aaudio_channel_mask_t channelMask, bool isInput) {
386 if (channelMask == AAUDIO_UNSPECIFIED) {
387 return true;
388 }
389
390 if (__builtin_popcount(channelMask) > FCC_LIMIT) {
391 return false;
392 }
393
394 if (isInput) {
395 switch (channelMask) {
396 case AAUDIO_CHANNEL_MONO:
397 case AAUDIO_CHANNEL_STEREO:
398 case AAUDIO_CHANNEL_FRONT_BACK:
399 case AAUDIO_CHANNEL_2POINT0POINT2:
400 case AAUDIO_CHANNEL_2POINT1POINT2:
401 case AAUDIO_CHANNEL_3POINT0POINT2:
402 case AAUDIO_CHANNEL_3POINT1POINT2:
403 case AAUDIO_CHANNEL_5POINT1:
404 return true;
405 }
406 return false;
407 } else {
408 switch (channelMask) {
409 case AAUDIO_CHANNEL_MONO:
410 case AAUDIO_CHANNEL_STEREO:
411 case AAUDIO_CHANNEL_2POINT1:
412 case AAUDIO_CHANNEL_TRI:
413 case AAUDIO_CHANNEL_TRI_BACK:
414 case AAUDIO_CHANNEL_3POINT1:
415 case AAUDIO_CHANNEL_2POINT0POINT2:
416 case AAUDIO_CHANNEL_2POINT1POINT2:
417 case AAUDIO_CHANNEL_3POINT0POINT2:
418 case AAUDIO_CHANNEL_3POINT1POINT2:
419 case AAUDIO_CHANNEL_QUAD:
420 case AAUDIO_CHANNEL_QUAD_SIDE:
421 case AAUDIO_CHANNEL_SURROUND:
422 case AAUDIO_CHANNEL_PENTA:
423 case AAUDIO_CHANNEL_5POINT1:
424 case AAUDIO_CHANNEL_5POINT1_SIDE:
425 case AAUDIO_CHANNEL_5POINT1POINT2:
426 case AAUDIO_CHANNEL_5POINT1POINT4:
427 case AAUDIO_CHANNEL_6POINT1:
428 case AAUDIO_CHANNEL_7POINT1:
429 case AAUDIO_CHANNEL_7POINT1POINT2:
430 case AAUDIO_CHANNEL_7POINT1POINT4:
431 case AAUDIO_CHANNEL_9POINT1POINT4:
432 case AAUDIO_CHANNEL_9POINT1POINT6:
433 return true;
434 }
435 return false;
436 }
437 }
438
439 void testChannelMask(aaudio_channel_mask_t channelMask, aaudio_direction_t direction);
440 };
441
testChannelMask(aaudio_channel_mask_t channelMask,aaudio_direction_t direction)442 void AAudioStreamBuilderChannelMaskTest::testChannelMask(aaudio_channel_mask_t channelMask,
443 aaudio_direction_t direction) {
444 AAudioStreamBuilder *aaudioBuilder = nullptr;
445 create_stream_builder(&aaudioBuilder);
446 AAudioStreamBuilder_setDirection(aaudioBuilder, direction);
447 AAudioStreamBuilder_setChannelMask(aaudioBuilder, channelMask);
448 const Expect expect =
449 isValidChannelMask(channelMask, direction) ? Expect::SUCCEED : Expect::FAIL;
450 AAudioStream *aaudioStream = nullptr;
451 aaudio_result_t result = AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream);
452 if (expect == Expect::FAIL) {
453 ASSERT_NE(AAUDIO_OK, result);
454 ASSERT_EQ(nullptr, aaudioStream);
455 } else if (expect == Expect::SUCCEED) {
456 ASSERT_EQ(AAUDIO_OK, result);
457 ASSERT_NE(nullptr, aaudioStream);
458 ASSERT_NE(0, AAudioStream_getChannelCount(aaudioStream));
459 ASSERT_NE(0, AAudioStream_getHardwareChannelCount(aaudioStream));
460 ASSERT_NE(AAUDIO_UNSPECIFIED, AAudioStream_getChannelMask(aaudioStream));
461 ASSERT_NE(AAUDIO_CHANNEL_INVALID, AAudioStream_getChannelMask(aaudioStream));
462 } else { // NOT_CRASH
463 ASSERT_TRUE(((result < 0) && (aaudioStream == nullptr))
464 || ((result == AAUDIO_OK) && (aaudioStream != nullptr)));
465 }
466
467 // Cleanup
468 ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_delete(aaudioBuilder));
469 if (aaudioStream != nullptr) {
470 ASSERT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream));
471 }
472 }
473
TEST_P(AAudioStreamBuilderChannelMaskTest,openInputStream)474 TEST_P(AAudioStreamBuilderChannelMaskTest, openInputStream) {
475 if (!deviceSupportsFeature(FEATURE_RECORDING)) {
476 return;
477 }
478 testChannelMask(GetParam(), AAUDIO_DIRECTION_INPUT);
479 }
480
TEST_P(AAudioStreamBuilderChannelMaskTest,openOutputStream)481 TEST_P(AAudioStreamBuilderChannelMaskTest, openOutputStream) {
482 if (!deviceSupportsFeature(FEATURE_PLAYBACK)) {
483 return;
484 }
485 testChannelMask(GetParam(), AAUDIO_DIRECTION_OUTPUT);
486 }
487
488 INSTANTIATE_TEST_CASE_P(
489 CM, AAudioStreamBuilderChannelMaskTest,
490 ::testing::Values(
491 // UNSPECIFIED is valid channel mask
492 AAUDIO_UNSPECIFIED,
493 AAUDIO_CHANNEL_INVALID,
494 // Channel mask listed in audio.h
495 // AAUDIO_CHANNEL_FRONT_LEFT,
496 AAUDIO_CHANNEL_FRONT_RIGHT,
497 AAUDIO_CHANNEL_FRONT_CENTER,
498 AAUDIO_CHANNEL_LOW_FREQUENCY,
499 AAUDIO_CHANNEL_BACK_LEFT,
500 AAUDIO_CHANNEL_BACK_RIGHT,
501 AAUDIO_CHANNEL_FRONT_LEFT_OF_CENTER,
502 AAUDIO_CHANNEL_FRONT_RIGHT_OF_CENTER,
503 AAUDIO_CHANNEL_BACK_CENTER,
504 AAUDIO_CHANNEL_SIDE_LEFT,
505 AAUDIO_CHANNEL_SIDE_RIGHT,
506 AAUDIO_CHANNEL_TOP_CENTER,
507 AAUDIO_CHANNEL_TOP_FRONT_LEFT,
508 AAUDIO_CHANNEL_TOP_FRONT_CENTER,
509 AAUDIO_CHANNEL_TOP_FRONT_RIGHT,
510 AAUDIO_CHANNEL_TOP_BACK_LEFT,
511 AAUDIO_CHANNEL_TOP_BACK_CENTER,
512 AAUDIO_CHANNEL_TOP_BACK_RIGHT,
513 AAUDIO_CHANNEL_TOP_SIDE_LEFT,
514 AAUDIO_CHANNEL_TOP_SIDE_RIGHT,
515 AAUDIO_CHANNEL_BOTTOM_FRONT_LEFT,
516 AAUDIO_CHANNEL_BOTTOM_FRONT_CENTER,
517 AAUDIO_CHANNEL_BOTTOM_FRONT_RIGHT,
518 AAUDIO_CHANNEL_LOW_FREQUENCY_2,
519 AAUDIO_CHANNEL_FRONT_WIDE_LEFT,
520 AAUDIO_CHANNEL_FRONT_WIDE_RIGHT,
521 AAUDIO_CHANNEL_MONO,
522 AAUDIO_CHANNEL_STEREO,
523 AAUDIO_CHANNEL_2POINT1,
524 AAUDIO_CHANNEL_TRI,
525 AAUDIO_CHANNEL_TRI_BACK,
526 AAUDIO_CHANNEL_3POINT1,
527 AAUDIO_CHANNEL_2POINT0POINT2,
528 AAUDIO_CHANNEL_2POINT1POINT2,
529 AAUDIO_CHANNEL_3POINT0POINT2,
530 AAUDIO_CHANNEL_3POINT1POINT2,
531 AAUDIO_CHANNEL_QUAD,
532 AAUDIO_CHANNEL_QUAD_SIDE,
533 AAUDIO_CHANNEL_SURROUND,
534 AAUDIO_CHANNEL_PENTA,
535 AAUDIO_CHANNEL_5POINT1,
536 AAUDIO_CHANNEL_5POINT1_SIDE,
537 AAUDIO_CHANNEL_6POINT1,
538 AAUDIO_CHANNEL_7POINT1,
539 AAUDIO_CHANNEL_5POINT1POINT2,
540 AAUDIO_CHANNEL_5POINT1POINT4,
541 AAUDIO_CHANNEL_7POINT1POINT2,
542 AAUDIO_CHANNEL_7POINT1POINT4,
543 AAUDIO_CHANNEL_9POINT1POINT4,
544 AAUDIO_CHANNEL_9POINT1POINT6,
545 AAUDIO_CHANNEL_FRONT_BACK,
546 // Odd value
547 0x20000000,
548 0x30000000,
549 0x40000005),
550 &AAudioStreamBuilderChannelMaskTest::getTestName);
551
552 using ChannelMaskAndCountParams = std::pair<aaudio_direction_t, aaudio_channel_mask_t>;
553 class AAudioStreamBuilderChannelMaskAndCountTest :
554 public AAudioCtsBase, public ::testing::WithParamInterface<ChannelMaskAndCountParams> {
555 public:
getTestName(const::testing::TestParamInfo<ChannelMaskAndCountParams> & info)556 static std::string getTestName(
557 const ::testing::TestParamInfo<ChannelMaskAndCountParams>& info) {
558 std::stringstream ss;
559 ss << (info.param.first == AAUDIO_DIRECTION_INPUT ? "INPUT_0x" : "OUTPUT_0x")
560 << std::hex << info.param.second;
561 return ss.str();
562 }
563
564 protected:
565 void testSetChannelMaskAndCount(aaudio_direction_t direction,
566 aaudio_channel_mask_t channelMask,
567 int32_t channelCount,
568 bool channelMaskFirst);
569 };
570
testSetChannelMaskAndCount(aaudio_direction_t direction,aaudio_channel_mask_t channelMask,int32_t channelCount,bool setChannelMaskFirst)571 void AAudioStreamBuilderChannelMaskAndCountTest::testSetChannelMaskAndCount(
572 aaudio_direction_t direction, aaudio_channel_mask_t channelMask,
573 int32_t channelCount, bool setChannelMaskFirst) {
574 AAudioStreamBuilder *aaudioBuilder = nullptr;
575 create_stream_builder(&aaudioBuilder);
576 AAudioStreamBuilder_setDirection(aaudioBuilder, direction);
577 if (setChannelMaskFirst) {
578 AAudioStreamBuilder_setChannelMask(aaudioBuilder, channelMask);
579 AAudioStreamBuilder_setChannelCount(aaudioBuilder, channelCount);
580 } else {
581 AAudioStreamBuilder_setChannelCount(aaudioBuilder, channelCount);
582 AAudioStreamBuilder_setChannelMask(aaudioBuilder, channelMask);
583 }
584 AAudioStream *aaudioStream = nullptr;
585 aaudio_result_t result = AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream);
586 ASSERT_EQ(AAUDIO_OK, result);
587 ASSERT_NE(nullptr, aaudioStream);
588 if (setChannelMaskFirst) {
589 ASSERT_EQ(channelCount, AAudioStream_getChannelCount(aaudioStream));
590 ASSERT_EQ(AAUDIO_UNSPECIFIED, AAudioStream_getChannelMask(aaudioStream));
591 } else {
592 // If channel mask is unspecified, stereo will be returned.
593 ASSERT_EQ(channelMask == AAUDIO_UNSPECIFIED ? AAUDIO_CHANNEL_STEREO : channelMask,
594 AAudioStream_getChannelMask(aaudioStream));
595 ASSERT_EQ(channelMask == AAUDIO_UNSPECIFIED ? 2 : __builtin_popcount(channelMask),
596 AAudioStream_getChannelCount(aaudioStream));
597 }
598 ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_delete(aaudioBuilder));
599 if (aaudioStream != nullptr) {
600 ASSERT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream));
601 }
602 }
603
TEST_P(AAudioStreamBuilderChannelMaskAndCountTest,channelMaskAndCount)604 TEST_P(AAudioStreamBuilderChannelMaskAndCountTest, channelMaskAndCount) {
605 const aaudio_direction_t direction = GetParam().first;
606 if ((direction == AAUDIO_DIRECTION_OUTPUT && !deviceSupportsFeature(FEATURE_PLAYBACK)) ||
607 (direction == AAUDIO_DIRECTION_INPUT && !deviceSupportsFeature(FEATURE_RECORDING))) {
608 return;
609 }
610 const aaudio_channel_mask_t channelMask = GetParam().second;
611
612 testSetChannelMaskAndCount(direction, channelMask,
613 2 /*channelCount*/, true /*setChannelMaskFirst*/);
614 testSetChannelMaskAndCount(direction, channelMask,
615 2 /*channelCount*/, false /*setChannelMaskFirst*/);
616
617 testSetChannelMaskAndCount(direction, AAUDIO_CHANNEL_5POINT1,
618 2 /*channelCount*/, true /*setChannelMaskFirst*/);
619 testSetChannelMaskAndCount(direction, AAUDIO_CHANNEL_5POINT1,
620 2 /*channelCount*/, false /*setChannelMaskFirst*/);
621 }
622
623 INSTANTIATE_TEST_CASE_P(CMC, AAudioStreamBuilderChannelMaskAndCountTest,
624 ::testing::Values(
625 std::make_pair(AAUDIO_DIRECTION_OUTPUT, AAUDIO_CHANNEL_MONO),
626 std::make_pair(AAUDIO_DIRECTION_OUTPUT, AAUDIO_CHANNEL_5POINT1),
627 std::make_pair(AAUDIO_DIRECTION_OUTPUT, AAUDIO_UNSPECIFIED),
628 std::make_pair(AAUDIO_DIRECTION_INPUT, AAUDIO_CHANNEL_MONO),
629 std::make_pair(AAUDIO_DIRECTION_INPUT, AAUDIO_CHANNEL_5POINT1),
630 std::make_pair(AAUDIO_DIRECTION_INPUT, AAUDIO_UNSPECIFIED)),
631 &AAudioStreamBuilderChannelMaskAndCountTest::getTestName);
632
633 using CommonCombinationTestParams = std::tuple<aaudio_direction_t,
634 aaudio_sharing_mode_t,
635 aaudio_performance_mode_t,
636 int32_t /*sample rate*/,
637 aaudio_format_t,
638 aaudio_channel_mask_t>;
639 enum {
640 PARAM_DIRECTION = 0,
641 PARAM_SHARING_MODE,
642 PARAM_PERFORMANCE_MODE,
643 PARAM_SAMPLE_RATE,
644 PARAM_FORMAT,
645 PARAM_CHANNEL_MASK
646 };
647 class AAudioStreamBuilderCommonCombinationTest :
648 public AAudioCtsBase, public ::testing::WithParamInterface<CommonCombinationTestParams> {
649 public:
getTestName(const::testing::TestParamInfo<CommonCombinationTestParams> & info)650 static std::string getTestName(
651 const ::testing::TestParamInfo<CommonCombinationTestParams>& info) {
652 std::stringstream ss;
653 ss << (std::get<PARAM_DIRECTION>(info.param) == AAUDIO_DIRECTION_INPUT ? "INPUT_"
654 : "OUTPUT_")
655 << sharingModeToString(std::get<PARAM_SHARING_MODE>(info.param)) << "_"
656 << performanceModeToString(std::get<PARAM_PERFORMANCE_MODE>(info.param)) << "_"
657 << "sampleRate_" << std::get<PARAM_SAMPLE_RATE>(info.param) << "_"
658 << "format_0x" << std::hex << std::get<PARAM_FORMAT>(info.param) << "_"
659 << "channelMask_0x" << std::get<PARAM_CHANNEL_MASK>(info.param) << "";
660 return ss.str();
661 }
662 };
663
TEST_P(AAudioStreamBuilderCommonCombinationTest,openStream)664 TEST_P(AAudioStreamBuilderCommonCombinationTest, openStream) {
665 if (!deviceSupportsFeature(FEATURE_PLAYBACK)) return;
666 AAudioStreamBuilder *aaudioBuilder = nullptr;
667 create_stream_builder(&aaudioBuilder);
668 const auto param = GetParam();
669 AAudioStreamBuilder_setDirection(aaudioBuilder, std::get<PARAM_DIRECTION>(param));
670 AAudioStreamBuilder_setSharingMode(aaudioBuilder, std::get<PARAM_SHARING_MODE>(param));
671 AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, std::get<PARAM_PERFORMANCE_MODE>(param));
672 AAudioStreamBuilder_setSampleRate(aaudioBuilder, std::get<PARAM_SAMPLE_RATE>(param));
673 AAudioStreamBuilder_setFormat(aaudioBuilder, std::get<PARAM_FORMAT>(param));
674 AAudioStreamBuilder_setChannelMask(aaudioBuilder, std::get<PARAM_CHANNEL_MASK>(param));
675 // All the test parameters all reasonable values with different combination. In that case,
676 // it is expected that the opening will be successful.
677 try_opening_audio_stream(aaudioBuilder, Expect::SUCCEED);
678 }
679
680 INSTANTIATE_TEST_CASE_P(CommonComb, AAudioStreamBuilderCommonCombinationTest,
681 ::testing::Combine(
682 ::testing::Values(AAUDIO_DIRECTION_OUTPUT, AAUDIO_DIRECTION_INPUT),
683 ::testing::Values(AAUDIO_SHARING_MODE_SHARED, AAUDIO_SHARING_MODE_EXCLUSIVE),
684 ::testing::Values(
685 AAUDIO_PERFORMANCE_MODE_NONE,
686 AAUDIO_PERFORMANCE_MODE_POWER_SAVING,
687 AAUDIO_PERFORMANCE_MODE_LOW_LATENCY),
688 ::testing::Values(// Sample rate
689 AAUDIO_UNSPECIFIED, 8000, 16000, 44100, 48000, 96000, 192000),
690 ::testing::Values(
691 AAUDIO_UNSPECIFIED,
692 AAUDIO_FORMAT_PCM_I16,
693 AAUDIO_FORMAT_PCM_FLOAT),
694 ::testing::Values(AAUDIO_CHANNEL_MONO, AAUDIO_CHANNEL_STEREO)),
695 &AAudioStreamBuilderCommonCombinationTest::getTestName);
696