1 /*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <gtest/gtest.h>
17 #include <cmath>
18 #include "hpae_pcm_process.h"
19 #include "test_case_common.h"
20
21 using namespace testing::ext;
22 using namespace testing;
23
24 namespace OHOS {
25 namespace AudioStandard {
26 namespace HPAE {
27
28 constexpr uint32_t NUM_TWO = 2;
29 constexpr int ALIGIN_FLOAT_SIZE = 4;
30
31 class HpaePcmProcessTest : public testing::Test {
32 public:
33 void SetUp();
34 void TearDown();
35 };
36
SetUp()37 void HpaePcmProcessTest::SetUp()
38 {}
39
TearDown()40 void HpaePcmProcessTest::TearDown()
41 {}
42
43 std::aligned_storage<sizeof(float), alignof(float)> aligned_memory;
44
45 HWTEST_F(HpaePcmProcessTest, constructHpaePcmProcess, TestSize.Level0)
46 {
47 std::vector<float> testData(TEST_FREAME_LEN);
48 HpaePcmProcess hpaePcmProcess(testData.data(), TEST_FREAME_LEN);
49 EXPECT_EQ(hpaePcmProcess.Size(), TEST_FREAME_LEN);
50 for (int i = 0; i < TEST_FREAME_LEN; i++) {
51 testData[i] = i;
52 EXPECT_EQ(hpaePcmProcess[i], i);
53 const float testValue = hpaePcmProcess[i];
54 EXPECT_EQ(hpaePcmProcess[i], testValue);
55 }
56 EXPECT_EQ(&testData[0], hpaePcmProcess.Begin());
57 EXPECT_EQ(&testData[TEST_FREAME_LEN - 1], hpaePcmProcess.End() - 1);
58 }
59
60 HWTEST_F(HpaePcmProcessTest, assignHpaeProcessTest, TestSize.Level0)
61 {
62 std::vector<float> testData(TEST_FREAME_LEN);
63 for (int i = 0; i < TEST_FREAME_LEN; i++) {
64 testData[i] = i;
65 }
66 std::vector<float> testData2(TEST_SUB_FREAME_LEN);
67 for (int i = 0; i < TEST_SUB_FREAME_LEN; i++) {
68 testData2[i] = i;
69 }
70 std::vector<float> tmpData(TEST_FREAME_LEN);
71 for (int i = 0; i < TEST_FREAME_LEN; i++) {
72 tmpData[i] = i;
73 }
74 HpaePcmProcess tmpPcmProcess(tmpData.data(), TEST_FREAME_LEN);
75 std::vector<float> pcmData(TEST_SUB_FREAME_LEN);
76 std::vector<float> pcmData2(TEST_FREAME_LEN);
77 HpaePcmProcess hpaePcmProcessTest(pcmData.data(), TEST_SUB_FREAME_LEN);
78 hpaePcmProcessTest = testData;
79 // errcase
80 for (int i = 0; i < TEST_SUB_FREAME_LEN; i++) {
81 EXPECT_EQ(hpaePcmProcessTest[i], 0);
82 }
83 hpaePcmProcessTest = testData2;
84 // normalcase
85 for (int i = 0; i < TEST_SUB_FREAME_LEN; i++) {
86 EXPECT_EQ(hpaePcmProcessTest[i], i);
87 }
88 HpaePcmProcess hpaePcmProcessTest2(pcmData2.data(), TEST_SUB_FREAME_LEN);
89 hpaePcmProcessTest2 = tmpPcmProcess;
90 // errcase
91 for (int i = 0; i < TEST_SUB_FREAME_LEN; i++) {
92 EXPECT_EQ(hpaePcmProcessTest2[i], 0);
93 }
94 hpaePcmProcessTest2 = hpaePcmProcessTest;
95 // normalcase
96 for (int i = 0; i < TEST_SUB_FREAME_LEN; i++) {
97 EXPECT_EQ(hpaePcmProcessTest2[i], i);
98 }
99 }
100
101 HWTEST_F(HpaePcmProcessTest, calHpaeProcessTest, TestSize.Level0)
102 {
103 std::vector<float> testData(TEST_SUB_FREAME_LEN);
104 for (int i = 0; i < TEST_SUB_FREAME_LEN; i++) {
105 testData[i] = i;
106 }
107 HpaePcmProcess hpaePcmProcessTest(testData.data(), TEST_SUB_FREAME_LEN);
108 std::vector<float> testData2(TEST_SUB_FREAME_LEN, NUM_TWO);
109 HpaePcmProcess hpaePcmProcessTest2(testData2.data(), TEST_SUB_FREAME_LEN);
110 hpaePcmProcessTest2 += hpaePcmProcessTest;
111 for (int i = 0; i < TEST_SUB_FREAME_LEN; i++) {
112 EXPECT_EQ(hpaePcmProcessTest2[i], i + NUM_TWO);
113 }
114 hpaePcmProcessTest2 -= hpaePcmProcessTest;
115 for (int i = 0; i < TEST_SUB_FREAME_LEN; i++) {
116 EXPECT_EQ(hpaePcmProcessTest2[i], NUM_TWO);
117 }
118 hpaePcmProcessTest2 *= hpaePcmProcessTest;
119 for (int i = 0; i < TEST_SUB_FREAME_LEN; i++) {
120 EXPECT_EQ(hpaePcmProcessTest2[i], NUM_TWO * i);
121 }
122 hpaePcmProcessTest2.Reset();
123 for (int i = 0; i < TEST_SUB_FREAME_LEN; i++) {
124 EXPECT_EQ(hpaePcmProcessTest2[i], 0);
125 }
126 }
127
128 HWTEST_F(HpaePcmProcessTest, selfAssignHpaeProcessTest, TestSize.Level0)
129 {
130 std::vector<float> testData(TEST_SUB_FREAME_LEN);
131 for (int i = 0; i < TEST_SUB_FREAME_LEN; i++) {
132 testData[i] = i + 1;
133 }
134
135 HpaePcmProcess hpaePcmProcessTest(testData.data(), TEST_SUB_FREAME_LEN);
136
137 std::vector<float> originalData;
138 for (int i = 0; i < TEST_SUB_FREAME_LEN; i++) {
139 originalData.push_back(hpaePcmProcessTest[i]);
140 }
141
142 HpaePcmProcess& hpaePcmProcessTestRef = hpaePcmProcessTest;
143 hpaePcmProcessTest = hpaePcmProcessTestRef;
144
145 for (int i = 0; i < TEST_SUB_FREAME_LEN; i++) {
146 EXPECT_EQ(hpaePcmProcessTest[i], originalData[i]);
147 EXPECT_EQ(hpaePcmProcessTest[i], i + 1);
148 }
149
150 EXPECT_EQ(hpaePcmProcessTest.Begin(), testData.data());
151 EXPECT_EQ(hpaePcmProcessTest.End(), testData.data() + TEST_SUB_FREAME_LEN);
152 }
153
154 HWTEST_F(HpaePcmProcessTest, smallArrayOperations, TestSize.Level0)
155 {
156 // Only test lengths smaller than ALIGIN_FLOAT_SIZE (0,1,2,3)
157 const size_t testLengths[] = {0, 1, 2};
158 for (auto len : testLengths) {
159 // ================== Addition Test ==================
160 {
161 // Initialize objects with fixed size data
162 std::vector<float> leftData(len, 1.5f);
163 std::vector<float> rightData(len, 2.5f);
164 HpaePcmProcess leftObj(leftData.data(), len);
165 HpaePcmProcess rightObj(rightData.data(), len);
166 // Force operation on small arrays
167 leftObj += rightObj;
168 // Verify all elements
169 for (size_t i = 0; i < len; i++) {
170 EXPECT_FLOAT_EQ(leftObj[i], 4.0f);
171 }
172 }
173 // ================== Subtraction Test ==================
174 {
175 std::vector<float> leftData(len, 5.0f);
176 std::vector<float> rightData(len, 3.0f);
177 HpaePcmProcess leftObj(leftData.data(), len);
178 HpaePcmProcess rightObj(rightData.data(), len);
179 leftObj -= rightObj;
180 for (size_t i = 0; i < len; i++) {
181 EXPECT_FLOAT_EQ(leftObj[i], 2.0f);
182 }
183 }
184 // ================== Multiplication Test ==================
185 {
186 std::vector<float> leftData(len, 3.0f);
187 std::vector<float> rightData(len, 1.5f);
188
189 HpaePcmProcess leftObj(leftData.data(), len);
190 HpaePcmProcess rightObj(rightData.data(), len);
191 leftObj *= rightObj;
192 for (size_t i = 0; i < len; i++) {
193 EXPECT_FLOAT_EQ(leftObj[i], 4.5f);
194 }
195 }
196 }
197 }
198
199 HWTEST_F(HpaePcmProcessTest, multiplicationExactAlignment, TestSize.Level0)
200 {
201 // Test lengths that are multiples of ALIGIN_FLOAT_SIZE
202 const size_t testLen = ALIGIN_FLOAT_SIZE * 4; // 16 elements
203 // Prepare data with unique values for each element
204 std::vector<float> leftData(testLen);
205 std::vector<float> rightData(testLen);
206 std::vector<float> expected(testLen);
207 for (size_t i = 0; i < testLen; i++) {
208 leftData[i] = 1.0f + i * 0.1f;
209 rightData[i] = 2.0f + i * 0.1f;
210 expected[i] = leftData[i] * rightData[i];
211 }
212 HpaePcmProcess leftObj(leftData.data(), testLen);
213 HpaePcmProcess rightObj(rightData.data(), testLen);
214 // Execute multiplication operation
215 leftObj *= rightObj;
216 // Verify all elements
217 for (size_t i = 0; i < testLen; i++) {
218 EXPECT_FLOAT_EQ(leftObj[i], expected[i]);
219 }
220 }
221
222 HWTEST_F(HpaePcmProcessTest, zeroRemainderEdgeCases, TestSize.Level0)
223 {
224 // Test multiple exact alignment cases
225 const size_t multipliers[] = {1, 2, 3}; // x4, x8, x12
226 const float testValue = 0.0f;
227
228 for (auto multiplier : multipliers) {
229 const size_t testLen = ALIGIN_FLOAT_SIZE * multiplier;
230
231 std::vector<float> leftVec(testLen, testValue);
232 std::vector<float> rightVec(testLen, testValue);
233
234 HpaePcmProcess leftObj(leftVec.data(), testLen);
235 HpaePcmProcess rightObj(rightVec.data(), testLen);
236
237 // Test all operations
238 leftObj += rightObj;
239 for (size_t i = 0; i < testLen; i++) {
240 EXPECT_FLOAT_EQ(leftObj[i], testValue);
241 }
242
243 leftObj -= rightObj;
244 for (size_t i = 0; i < testLen; i++) {
245 EXPECT_FLOAT_EQ(leftObj[i], testValue);
246 }
247
248 leftObj *= rightObj;
249 for (size_t i = 0; i < testLen; i++) {
250 EXPECT_FLOAT_EQ(leftObj[i], 0.0f);
251 }
252 }
253 }
254
255 HWTEST_F(HpaePcmProcessTest, hpaeProcessTestShortLen, TestSize.Level0)
256 {
257 std::vector<float> testData(TEST_LEN_LT_FOUR);
258 for (int i = 0; i < TEST_LEN_LT_FOUR; i++) {
259 testData[i] = i;
260 }
261 HpaePcmProcess hpaePcmProcessTest(testData.data(), TEST_LEN_LT_FOUR);
262 std::vector<float> testData2(TEST_LEN_LT_FOUR, NUM_TWO);
263 HpaePcmProcess hpaePcmProcessTest2(testData2.data(), TEST_LEN_LT_FOUR);
264 hpaePcmProcessTest2 += hpaePcmProcessTest;
265 for (int i = 0; i < TEST_LEN_LT_FOUR; i++) {
266 EXPECT_EQ(hpaePcmProcessTest2[i], i + NUM_TWO);
267 }
268 hpaePcmProcessTest2 -= hpaePcmProcessTest;
269 for (int i = 0; i < TEST_LEN_LT_FOUR; i++) {
270 EXPECT_EQ(hpaePcmProcessTest2[i], NUM_TWO);
271 }
272 hpaePcmProcessTest2 *= hpaePcmProcessTest;
273 for (int i = 0; i < TEST_LEN_LT_FOUR; i++) {
274 EXPECT_EQ(hpaePcmProcessTest2[i], NUM_TWO * i);
275 }
276 hpaePcmProcessTest2.Reset();
277 for (int i = 0; i < TEST_LEN_LT_FOUR; i++) {
278 EXPECT_EQ(hpaePcmProcessTest2[i], 0);
279 }
280 }
281 } // namespace HPAE
282 } // namespace AudioStandard
283 } // namespace OHOS