1 /*
2 * Copyright (C) 2022 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 #include <cstdint>
18 #include <limits>
19 #include <type_traits>
20 #include <utility>
21 #include <vector>
22
23 #include <Utils.h>
24
25 #include <gtest/gtest.h>
26 #define LOG_TAG "Utils_Test"
27 #include <log/log.h>
28
29 using aidl::android::hardware::audio::common::getChannelCount;
30 using aidl::android::hardware::audio::common::getFrameSizeInBytes;
31 using aidl::android::hardware::audio::common::getPcmSampleSizeInBytes;
32 using aidl::android::media::audio::common::AudioChannelLayout;
33 using aidl::android::media::audio::common::AudioFormatDescription;
34 using aidl::android::media::audio::common::AudioFormatType;
35 using aidl::android::media::audio::common::PcmType;
36
TEST(UtilsTest,ChannelCountOddCases)37 TEST(UtilsTest, ChannelCountOddCases) {
38 using Tag = AudioChannelLayout::Tag;
39 EXPECT_EQ(0UL, getChannelCount(AudioChannelLayout{}));
40 EXPECT_EQ(0UL, getChannelCount(AudioChannelLayout::make<Tag::invalid>(0)));
41 EXPECT_EQ(0UL, getChannelCount(AudioChannelLayout::make<Tag::invalid>(-1)));
42 }
43
TEST(UtilsTest,ChannelCountForIndexMask)44 TEST(UtilsTest, ChannelCountForIndexMask) {
45 using Tag = AudioChannelLayout::Tag;
46 EXPECT_EQ(0UL, getChannelCount(AudioChannelLayout::make<Tag::indexMask>(0)));
47 #define VERIFY_INDEX_MASK(N) \
48 { \
49 const auto l = \
50 AudioChannelLayout::make<Tag::indexMask>(AudioChannelLayout::INDEX_MASK_##N); \
51 EXPECT_EQ(N##UL, getChannelCount(l)) << l.toString(); \
52 }
53 VERIFY_INDEX_MASK(1);
54 VERIFY_INDEX_MASK(2);
55 VERIFY_INDEX_MASK(3);
56 VERIFY_INDEX_MASK(4);
57 VERIFY_INDEX_MASK(5);
58 VERIFY_INDEX_MASK(6);
59 VERIFY_INDEX_MASK(7);
60 VERIFY_INDEX_MASK(8);
61 VERIFY_INDEX_MASK(9);
62 VERIFY_INDEX_MASK(10);
63 VERIFY_INDEX_MASK(11);
64 VERIFY_INDEX_MASK(12);
65 VERIFY_INDEX_MASK(13);
66 VERIFY_INDEX_MASK(14);
67 VERIFY_INDEX_MASK(15);
68 VERIFY_INDEX_MASK(16);
69 VERIFY_INDEX_MASK(17);
70 VERIFY_INDEX_MASK(18);
71 VERIFY_INDEX_MASK(19);
72 VERIFY_INDEX_MASK(20);
73 VERIFY_INDEX_MASK(21);
74 VERIFY_INDEX_MASK(22);
75 VERIFY_INDEX_MASK(23);
76 VERIFY_INDEX_MASK(24);
77 #undef VERIFY_INDEX_MASK
78 }
79
TEST(UtilsTest,ChannelCountForLayoutMask)80 TEST(UtilsTest, ChannelCountForLayoutMask) {
81 using Tag = AudioChannelLayout::Tag;
82 const std::vector<std::pair<size_t, int32_t>> kTestLayouts = {
83 std::make_pair(0UL, 0),
84 std::make_pair(1UL, AudioChannelLayout::LAYOUT_MONO),
85 std::make_pair(2UL, AudioChannelLayout::LAYOUT_STEREO),
86 std::make_pair(6UL, AudioChannelLayout::LAYOUT_5POINT1),
87 std::make_pair(8UL, AudioChannelLayout::LAYOUT_7POINT1),
88 std::make_pair(16UL, AudioChannelLayout::LAYOUT_9POINT1POINT6),
89 std::make_pair(13UL, AudioChannelLayout::LAYOUT_13POINT_360RA),
90 std::make_pair(24UL, AudioChannelLayout::LAYOUT_22POINT2),
91 std::make_pair(3UL, AudioChannelLayout::LAYOUT_STEREO_HAPTIC_A),
92 std::make_pair(4UL, AudioChannelLayout::LAYOUT_STEREO_HAPTIC_AB)};
93 for (const auto& [expected_count, layout] : kTestLayouts) {
94 const auto l = AudioChannelLayout::make<Tag::layoutMask>(layout);
95 EXPECT_EQ(expected_count, getChannelCount(l)) << l.toString();
96 }
97 }
98
TEST(UtilsTest,ChannelCountForVoiceMask)99 TEST(UtilsTest, ChannelCountForVoiceMask) {
100 using Tag = AudioChannelLayout::Tag;
101 // clang-format off
102 const std::vector<std::pair<size_t, int32_t>> kTestLayouts = {
103 std::make_pair(0UL, 0),
104 std::make_pair(1UL, AudioChannelLayout::VOICE_UPLINK_MONO),
105 std::make_pair(1UL, AudioChannelLayout::VOICE_DNLINK_MONO),
106 std::make_pair(2UL, AudioChannelLayout::VOICE_CALL_MONO)};
107 // clang-format on
108 for (const auto& [expected_count, layout] : kTestLayouts) {
109 const auto l = AudioChannelLayout::make<Tag::voiceMask>(layout);
110 EXPECT_EQ(expected_count, getChannelCount(l)) << l.toString();
111 }
112 }
113
114 namespace {
115
make_AudioChannelLayout_Mono()116 AudioChannelLayout make_AudioChannelLayout_Mono() {
117 return AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
118 AudioChannelLayout::LAYOUT_MONO);
119 }
120
make_AudioChannelLayout_Stereo()121 AudioChannelLayout make_AudioChannelLayout_Stereo() {
122 return AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
123 AudioChannelLayout::LAYOUT_STEREO);
124 }
125
make_AudioFormatDescription(AudioFormatType type)126 AudioFormatDescription make_AudioFormatDescription(AudioFormatType type) {
127 AudioFormatDescription result;
128 result.type = type;
129 return result;
130 }
131
make_AudioFormatDescription(PcmType pcm)132 AudioFormatDescription make_AudioFormatDescription(PcmType pcm) {
133 auto result = make_AudioFormatDescription(AudioFormatType::PCM);
134 result.pcm = pcm;
135 return result;
136 }
137
make_AudioFormatDescription(const std::string & encoding)138 AudioFormatDescription make_AudioFormatDescription(const std::string& encoding) {
139 AudioFormatDescription result;
140 result.encoding = encoding;
141 return result;
142 }
143
make_AudioFormatDescription(PcmType transport,const std::string & encoding)144 AudioFormatDescription make_AudioFormatDescription(PcmType transport, const std::string& encoding) {
145 auto result = make_AudioFormatDescription(encoding);
146 result.pcm = transport;
147 return result;
148 }
149
150 } // namespace
151
TEST(UtilsTest,FrameSize)152 TEST(UtilsTest, FrameSize) {
153 EXPECT_EQ(0UL, getFrameSizeInBytes(AudioFormatDescription{}, AudioChannelLayout{}));
154 EXPECT_EQ(sizeof(int16_t), getFrameSizeInBytes(make_AudioFormatDescription(PcmType::INT_16_BIT),
155 make_AudioChannelLayout_Mono()));
156 EXPECT_EQ(2 * sizeof(int16_t),
157 getFrameSizeInBytes(make_AudioFormatDescription(PcmType::INT_16_BIT),
158 make_AudioChannelLayout_Stereo()));
159 EXPECT_EQ(sizeof(int32_t), getFrameSizeInBytes(make_AudioFormatDescription(PcmType::INT_32_BIT),
160 make_AudioChannelLayout_Mono()));
161 EXPECT_EQ(2 * sizeof(int32_t),
162 getFrameSizeInBytes(make_AudioFormatDescription(PcmType::INT_32_BIT),
163 make_AudioChannelLayout_Stereo()));
164 EXPECT_EQ(sizeof(float), getFrameSizeInBytes(make_AudioFormatDescription(PcmType::FLOAT_32_BIT),
165 make_AudioChannelLayout_Mono()));
166 EXPECT_EQ(2 * sizeof(float),
167 getFrameSizeInBytes(make_AudioFormatDescription(PcmType::FLOAT_32_BIT),
168 make_AudioChannelLayout_Stereo()));
169 EXPECT_EQ(sizeof(uint8_t),
170 getFrameSizeInBytes(make_AudioFormatDescription("bitstream"), AudioChannelLayout{}));
171 EXPECT_EQ(sizeof(int16_t),
172 getFrameSizeInBytes(make_AudioFormatDescription(PcmType::INT_16_BIT, "encapsulated"),
173 AudioChannelLayout{}));
174 }
175
TEST(UtilsTest,PcmSampleSize)176 TEST(UtilsTest, PcmSampleSize) {
177 EXPECT_EQ(1UL, getPcmSampleSizeInBytes(PcmType{}));
178 EXPECT_EQ(sizeof(uint8_t), getPcmSampleSizeInBytes(PcmType::UINT_8_BIT));
179 EXPECT_EQ(sizeof(int16_t), getPcmSampleSizeInBytes(PcmType::INT_16_BIT));
180 EXPECT_EQ(sizeof(int32_t), getPcmSampleSizeInBytes(PcmType::INT_32_BIT));
181 EXPECT_EQ(sizeof(int32_t), getPcmSampleSizeInBytes(PcmType::FIXED_Q_8_24));
182 EXPECT_EQ(sizeof(float), getPcmSampleSizeInBytes(PcmType::FLOAT_32_BIT));
183 EXPECT_EQ(3UL, getPcmSampleSizeInBytes(PcmType::INT_24_BIT));
184 EXPECT_EQ(0UL, getPcmSampleSizeInBytes(PcmType(-1)));
185 using PcmTypeUnderlyingType = std::underlying_type_t<PcmType>;
186 EXPECT_EQ(0UL,
187 getPcmSampleSizeInBytes(PcmType(std::numeric_limits<PcmTypeUnderlyingType>::min())));
188 EXPECT_EQ(0UL,
189 getPcmSampleSizeInBytes(PcmType(std::numeric_limits<PcmTypeUnderlyingType>::max())));
190 }
191