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_buffer.h"
19 #include "test_case_common.h"
20 #include <vector>
21
22 namespace {
23 constexpr uint32_t DEFAULT_CHANNEL_COUNT = 2;
24 constexpr uint32_t DEFAULT_FRAME_LEN = 480;
25 constexpr uint32_t DEFAULT_SAMPLE_RATE = 48000;
26 constexpr uint32_t DEFAULT_FRAME_NUM = 2;
27 constexpr uint32_t DEFAULT_FRAME_SIZE = DEFAULT_CHANNEL_COUNT * DEFAULT_FRAME_LEN;
28 constexpr uint32_t NUM_TWO = 2;
29 constexpr uint32_t NUM_THREE = 3;
30
31 using namespace OHOS;
32 using namespace AudioStandard;
33 using namespace HPAE;
34 using namespace testing::ext;
35 using namespace testing;
36
37 class HpaePcmBufferTest : public testing::Test {
38 public:
39 void SetUp();
40 void TearDown();
41
CreateBufferInfo(uint32_t frames,bool multiFrames=false)42 PcmBufferInfo CreateBufferInfo(uint32_t frames, bool multiFrames = false)
43 {
44 PcmBufferInfo info;
45 info.ch = DEFAULT_CHANNEL_COUNT;
46 info.frameLen = DEFAULT_FRAME_LEN;
47 info.rate = DEFAULT_SAMPLE_RATE;
48 info.frames = frames;
49 info.isMultiFrames = multiFrames;
50 return info;
51 }
52
CreateTestVector(float value=1.0f)53 std::vector<float> CreateTestVector(float value = 1.0f)
54 {
55 return std::vector<float>(DEFAULT_FRAME_SIZE, value);
56 }
57
CreateTestMatrix(float value=1.0f,size_t frames=1)58 std::vector<std::vector<float>> CreateTestMatrix(float value = 1.0f, size_t frames = 1)
59 {
60 std::vector<std::vector<float>> matrix;
61 for (size_t i = 0; i < frames; i++) {
62 matrix.push_back(CreateTestVector(value));
63 }
64 return matrix;
65 }
66 };
67
SetUp()68 void HpaePcmBufferTest::SetUp()
69 {}
70
TearDown()71 void HpaePcmBufferTest::TearDown()
72 {}
73
74 HWTEST_F(HpaePcmBufferTest, constructHpaePcmBufferTest, TestSize.Level0)
75 {
76 PcmBufferInfo pcmBufferInfo;
77 pcmBufferInfo.ch = DEFAULT_CHANNEL_COUNT;
78 pcmBufferInfo.frameLen = DEFAULT_FRAME_LEN;
79 pcmBufferInfo.rate = DEFAULT_SAMPLE_RATE;
80 pcmBufferInfo.frames = DEFAULT_FRAME_NUM;
81 HpaePcmBuffer hpaePcmBuffer(pcmBufferInfo);
82 EXPECT_EQ(hpaePcmBuffer.GetChannelCount(), pcmBufferInfo.ch);
83 EXPECT_EQ(hpaePcmBuffer.GetFrameLen(), pcmBufferInfo.frameLen);
84 EXPECT_EQ(hpaePcmBuffer.GetSampleRate(), pcmBufferInfo.rate);
85 EXPECT_EQ(hpaePcmBuffer.GetFrames(), pcmBufferInfo.frames);
86 EXPECT_EQ(hpaePcmBuffer.GetReadPos(), 0);
87 EXPECT_EQ(hpaePcmBuffer.GetWritePos(), 0);
88 EXPECT_EQ(hpaePcmBuffer.GetCurFrames(), 0);
89 EXPECT_EQ(hpaePcmBuffer.IsMultiFrames(), false);
90 size_t addBytes = MEMORY_ALIGN_BYTE_NUM -
91 (pcmBufferInfo.frameLen * sizeof(float) * pcmBufferInfo.ch) % MEMORY_ALIGN_BYTE_NUM;
92 size_t frameByteSize = pcmBufferInfo.frameLen * sizeof(float) * pcmBufferInfo.ch + addBytes;
93 size_t bufferSize = frameByteSize * pcmBufferInfo.frames;
94 EXPECT_EQ(hpaePcmBuffer.Size(), bufferSize);
95 }
96
97 HWTEST_F(HpaePcmBufferTest, assignHpaePcmBufferTest, TestSize.Level0)
98 {
99 PcmBufferInfo pcmBufferInfo;
100 pcmBufferInfo.ch = DEFAULT_CHANNEL_COUNT;
101 pcmBufferInfo.frameLen = DEFAULT_FRAME_LEN;
102 pcmBufferInfo.rate = DEFAULT_SAMPLE_RATE;
103 pcmBufferInfo.frames = DEFAULT_FRAME_NUM;
104 HpaePcmBuffer hpaePcmBuffer(pcmBufferInfo);
105 size_t tempFrameLen = pcmBufferInfo.frameLen * pcmBufferInfo.ch;
106 std::vector<std::vector<float>> testVec;
107 for (size_t i = 0; i < pcmBufferInfo.frames; i++) {
108 testVec.push_back(std::vector<float>(tempFrameLen, 3.14f));
109 }
110 hpaePcmBuffer = testVec;
111 for (size_t i = 0; i < pcmBufferInfo.frames; i++) {
112 for (size_t j = 0; j < tempFrameLen; j++) {
113 EXPECT_EQ(fabs(hpaePcmBuffer[i][j] - 3.14f) < TEST_VALUE_PRESION, true);
114 }
115 }
116 }
117
118 HWTEST_F(HpaePcmBufferTest, calHpaePcmBufferTest, TestSize.Level0)
119 {
120 PcmBufferInfo pcmBufferInfo;
121 pcmBufferInfo.ch = DEFAULT_CHANNEL_COUNT;
122 pcmBufferInfo.frameLen = DEFAULT_FRAME_LEN;
123 pcmBufferInfo.rate = DEFAULT_SAMPLE_RATE;
124 pcmBufferInfo.frames = DEFAULT_FRAME_NUM;
125 HpaePcmBuffer hpaePcmBuffer(pcmBufferInfo);
126 size_t tempFrameLen = pcmBufferInfo.frameLen * pcmBufferInfo.ch;
127 for (size_t i = 0; i < pcmBufferInfo.frames; i++) {
128 for (size_t j = 0; j < tempFrameLen; j++) {
129 hpaePcmBuffer[i][j] = 3.14f;
130 }
131 }
132 std::vector<std::vector<float>> testVec;
133 for (size_t i = 0; i < pcmBufferInfo.frames; i++) {
134 testVec.push_back(std::vector<float>(tempFrameLen, 3.14f));
135 }
136 HpaePcmBuffer hpaePcmBuffer2(pcmBufferInfo);
137 hpaePcmBuffer2 = testVec;
138 hpaePcmBuffer += hpaePcmBuffer2;
139 for (size_t i = 0; i < pcmBufferInfo.frames; i++) {
140 for (size_t j = 0; j < tempFrameLen; j++) {
141 EXPECT_EQ(fabs(hpaePcmBuffer[i][j] - 6.28f) < TEST_VALUE_PRESION, true);
142 }
143 }
144 hpaePcmBuffer -= hpaePcmBuffer2;
145 for (size_t i = 0; i < pcmBufferInfo.frames; i++) {
146 for (size_t j = 0; j < tempFrameLen; j++) {
147 EXPECT_EQ(fabs(hpaePcmBuffer[i][j] - 3.14f) < TEST_VALUE_PRESION, true);
148 }
149 }
150 hpaePcmBuffer.Reset();
151 for (size_t i = 0; i < pcmBufferInfo.frames; i++) {
152 for (size_t j = 0; j < tempFrameLen; j++) {
153 EXPECT_EQ(fabs(hpaePcmBuffer[i][j] - 0.0f) < TEST_VALUE_PRESION, true);
154 }
155 }
156 }
157
158 HWTEST_F(HpaePcmBufferTest, calHpaePcmBufferMultiFrameTest, TestSize.Level0)
159 {
160 PcmBufferInfo pcmBufferInfo;
161 size_t inputFrames = 4; // 4: input frame numbers
162 pcmBufferInfo.ch = DEFAULT_CHANNEL_COUNT;
163 pcmBufferInfo.frameLen = DEFAULT_FRAME_LEN;
164 pcmBufferInfo.rate = DEFAULT_SAMPLE_RATE;
165 pcmBufferInfo.frames = inputFrames;
166 pcmBufferInfo.isMultiFrames = true;
167 HpaePcmBuffer hpaePcmBuffer(pcmBufferInfo);
168 EXPECT_EQ(hpaePcmBuffer.IsMultiFrames(), true);
169
170 size_t tempFrameLen = pcmBufferInfo.frameLen * pcmBufferInfo.ch;
171 EXPECT_EQ(hpaePcmBuffer.GetFrameSample(), tempFrameLen);
172 for (size_t i = 0; i < inputFrames; i++) {
173 std::vector<float> testVec(tempFrameLen, 3.14f);
174 hpaePcmBuffer = testVec;
175 }
176 std::cout << "tempFrameLen is: " << tempFrameLen << std::endl;
177
178 EXPECT_EQ(hpaePcmBuffer.GetCurFrames(), inputFrames);
179 EXPECT_EQ(hpaePcmBuffer.GetWritePos(), 0);
180
181 std::vector<float> testVec2(tempFrameLen, 0.0f);
182 EXPECT_EQ(hpaePcmBuffer.GetFrameSample(), tempFrameLen);
183 EXPECT_EQ(hpaePcmBuffer.PushFrameData(testVec2), false);
184 pcmBufferInfo.frames = 1;
185 pcmBufferInfo.isMultiFrames = false;
186 HpaePcmBuffer testHpaePcmBuffer(pcmBufferInfo);
187 EXPECT_EQ(hpaePcmBuffer.PushFrameData(testHpaePcmBuffer), false);
188 size_t curFrames = inputFrames;
189 std::cout << "inputFrames is: " << inputFrames << std::endl;
190 for (size_t i = 0; i < inputFrames; i++) {
191 EXPECT_EQ(hpaePcmBuffer.GetFrameData(testHpaePcmBuffer), true);
192 curFrames--;
193 EXPECT_EQ(hpaePcmBuffer.GetCurFrames(), curFrames);
194 for (size_t j = 0; j < tempFrameLen; j++) {
195 EXPECT_EQ(testHpaePcmBuffer[0][j], 3.14f);
196 }
197 }
198 EXPECT_EQ(hpaePcmBuffer.GetCurFrames(), 0);
199 EXPECT_EQ(hpaePcmBuffer.GetReadPos(), 0);
200 EXPECT_EQ(hpaePcmBuffer.GetFrameData(testHpaePcmBuffer), false);
201 EXPECT_EQ(hpaePcmBuffer.GetFrameData(testVec2), false);
202 }
203
204 HWTEST_F(HpaePcmBufferTest, ConstructorInitialization, TestSize.Level0)
205 {
206 PcmBufferInfo info = CreateBufferInfo(NUM_TWO, true);
207 HpaePcmBuffer buffer(info);
208
209 EXPECT_EQ(buffer.GetChannelCount(), DEFAULT_CHANNEL_COUNT);
210 EXPECT_EQ(buffer.GetFrameLen(), DEFAULT_FRAME_LEN);
211 EXPECT_EQ(buffer.GetFrames(), NUM_TWO);
212 EXPECT_EQ(buffer.GetCurFrames(), 0);
213 EXPECT_EQ(buffer.GetReadPos(), 0);
214 EXPECT_EQ(buffer.GetWritePos(), 0);
215 EXPECT_TRUE(buffer.IsMultiFrames());
216 }
217
218 HWTEST_F(HpaePcmBufferTest, arithmeticOperations, TestSize.Level0)
219 {
220 PcmBufferInfo info = CreateBufferInfo(1);
221 HpaePcmBuffer bufferA(info);
222 HpaePcmBuffer bufferB(info);
223 bufferA = CreateTestVector(2.0f);
224 bufferB = CreateTestVector(3.0f);
225 bufferA += bufferB;
226 for (size_t i = 0; i < info.frameLen; ++i) {
227 EXPECT_FLOAT_EQ(bufferA[0][i], 2.0f + 3.0f);
228 }
229 bufferA -= bufferB;
230 for (size_t i = 0; i < info.frameLen; ++i) {
231 EXPECT_FLOAT_EQ(bufferA[0][i], 2.0f);
232 }
233 bufferA *= bufferB;
234 for (size_t i = 0; i < info.frameLen; ++i) {
235 EXPECT_FLOAT_EQ(bufferA[0][i], 2.0f * 3.0f);
236 }
237 }
238
239 HWTEST_F(HpaePcmBufferTest, bufferManagement, TestSize.Level0)
240 {
241 PcmBufferInfo info = CreateBufferInfo(NUM_THREE, true);
242 HpaePcmBuffer buffer(info);
243
244 buffer = CreateTestMatrix(1.0f, NUM_TWO);
245 ASSERT_EQ(buffer.GetCurFrames(), NUM_TWO);
246
247 size_t rewound = buffer.RewindBuffer(NUM_TWO);
248 EXPECT_EQ(rewound, 1);
249 EXPECT_EQ(buffer.GetCurFrames(), NUM_THREE);
250 EXPECT_EQ(buffer.GetReadPos(), NUM_TWO); // (0 - 1 + 3) % 3 = 2
251
252 buffer.UpdateReadPos(1);
253 buffer.UpdateWritePos(1);
254 EXPECT_EQ(buffer.GetReadPos(), 1);
255 EXPECT_EQ(buffer.GetWritePos(), 1);
256
257 buffer.Reset();
258 for (size_t i = 0; i < buffer.GetFrames(); i++) {
259 for (size_t j = 0; j < DEFAULT_FRAME_SIZE; j++) {
260 EXPECT_FLOAT_EQ(buffer[i][j], 0.0f);
261 }
262 }
263 }
264
265 HWTEST_F(HpaePcmBufferTest, edgeCases, TestSize.Level0)
266 {
267 PcmBufferInfo multiInfo = CreateBufferInfo(NUM_TWO, true);
268 HpaePcmBuffer multiBuffer(multiInfo);
269 multiBuffer = std::vector<std::vector<float>>();
270 EXPECT_EQ(multiBuffer.GetCurFrames(), 0);
271
272 std::vector<float> outputVector(DEFAULT_FRAME_SIZE, 1.0f);
273 EXPECT_FALSE(multiBuffer.GetFrameData(outputVector));
274 for (float sample : outputVector) {
275 EXPECT_FLOAT_EQ(sample, 1.0f);
276 }
277
278 std::vector<float> testFrame = CreateTestVector();
279 for (int i = 0; i < NUM_TWO; i++) {
280 EXPECT_TRUE(multiBuffer.PushFrameData(testFrame));
281 }
282 EXPECT_FALSE(multiBuffer.PushFrameData(testFrame));
283
284 size_t rewound = multiBuffer.RewindBuffer(NUM_THREE);
285 EXPECT_EQ(rewound, 0);
286 }
287
288 HWTEST_F(HpaePcmBufferTest, invalidArguments, TestSize.Level0)
289 {
290 PcmBufferInfo multiInfo = CreateBufferInfo(NUM_TWO, true);
291 HpaePcmBuffer multiBuffer(multiInfo);
292
293 PcmBufferInfo singleInfo = CreateBufferInfo(1);
294 HpaePcmBuffer singleBuffer(singleInfo);
295
296 EXPECT_FALSE(multiBuffer.GetFrameData(multiBuffer));
297 EXPECT_FALSE(singleBuffer.GetFrameData(multiBuffer));
298
299 std::vector<float> testFrame = CreateTestVector();
300 EXPECT_FALSE(singleBuffer.PushFrameData(testFrame));
301
302 EXPECT_FALSE(multiBuffer.StoreFrameData(multiBuffer));
303 EXPECT_FALSE(singleBuffer.StoreFrameData(multiBuffer));
304
305 EXPECT_EQ(singleBuffer.RewindBuffer(1), 0);
306 }
307
308 HWTEST_F(HpaePcmBufferTest, positionWrapping, TestSize.Level0)
309 {
310 PcmBufferInfo info = CreateBufferInfo(NUM_TWO, true);
311 HpaePcmBuffer buffer(info);
312
313 buffer.UpdateWritePos(1);
314 buffer.UpdateReadPos(1);
315
316 std::vector<float> testFrame = CreateTestVector();
317 EXPECT_TRUE(buffer.PushFrameData(testFrame));
318
319 EXPECT_EQ(buffer.GetWritePos(), 0);
320 EXPECT_EQ(buffer.GetReadPos(), 1);
321 EXPECT_EQ(buffer.GetCurFrames(), 1);
322
323 PcmBufferInfo outputInfo = CreateBufferInfo(1);
324 HpaePcmBuffer outputBuffer(outputInfo);
325 EXPECT_TRUE(buffer.StoreFrameData(outputBuffer));
326
327 EXPECT_EQ(buffer.GetWritePos(), 1);
328 EXPECT_EQ(buffer.GetReadPos(), 0); // (1 + 1) % 2 = 0
329 }
330 }