• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <memory>
19 #include "hpae_process_cluster.h"
20 #include "test_case_common.h"
21 #include "audio_errors.h"
22 #include "hpae_sink_input_node.h"
23 #include "hpae_sink_output_node.h"
24 #include "audio_effect.h"
25 
26 using namespace OHOS;
27 using namespace AudioStandard;
28 using namespace HPAE;
29 using namespace testing::ext;
30 using namespace testing;
31 
32 namespace OHOS {
33 namespace AudioStandard {
34 
35 const int32_t DEFAULT_VALUE_TWO = 2;
36 const uint32_t DEFAULT_SESSIONID_NUM_FIRST = 12345;
37 const uint32_t DEFAULT_SESSIONID_NUM_SECOND = 12346;
38 const uint32_t DEFAULT_NODEID_NUM_FIRST = 1243;
39 const size_t DEFAULT_FRAMELEN_FIRST = 820;
40 const size_t DEFAULT_FRAMELEN_SECOND = 960;
41 const int32_t DEFAULT_TEST_VALUE_FIRST = 100;
42 const int32_t DEFAULT_TEST_VALUE_SECOND = 200;
43 const float LOUDNESS_GAIN = 1.0f;
44 
45 
46 class HpaeProcessClusterTest : public testing::Test {
47 public:
48     void SetUp();
49     void TearDown();
50 };
51 
SetUp()52 void HpaeProcessClusterTest::SetUp()
53 {}
54 
TearDown()55 void HpaeProcessClusterTest::TearDown()
56 {}
57 
58 HWTEST_F(HpaeProcessClusterTest, constructHpaeProcessClusterNode, TestSize.Level0)
59 {
60     HpaeNodeInfo nodeInfo;
61     nodeInfo.nodeId = DEFAULT_NODEID_NUM_FIRST;
62     nodeInfo.frameLen = DEFAULT_FRAMELEN_SECOND;
63     nodeInfo.sessionId = DEFAULT_SESSIONID_NUM_FIRST;
64     nodeInfo.samplingRate = SAMPLE_RATE_48000;
65     nodeInfo.channels = STEREO;
66     nodeInfo.format = SAMPLE_F32LE;
67 
68     HpaeSinkInfo dummySinkInfo;
69 
70     std::shared_ptr<HpaeProcessCluster> hpaeProcessCluster =
71         std::make_shared<HpaeProcessCluster>(nodeInfo, dummySinkInfo);
72     EXPECT_EQ(hpaeProcessCluster->GetSampleRate(), nodeInfo.samplingRate);
73     EXPECT_EQ(hpaeProcessCluster->GetFrameLen(), nodeInfo.frameLen);
74     EXPECT_EQ(hpaeProcessCluster->GetChannelCount(), nodeInfo.channels);
75     EXPECT_EQ(hpaeProcessCluster->GetBitWidth(), nodeInfo.format);
76     HpaeNodeInfo &retNi = hpaeProcessCluster->GetNodeInfo();
77     EXPECT_EQ(retNi.samplingRate, nodeInfo.samplingRate);
78     EXPECT_EQ(retNi.frameLen, nodeInfo.frameLen);
79     EXPECT_EQ(retNi.channels, nodeInfo.channels);
80     EXPECT_EQ(retNi.format, nodeInfo.format);
81 
82     std::shared_ptr<HpaeSinkInputNode> hpaeSinkInputNode = std::make_shared<HpaeSinkInputNode>(nodeInfo);
83     hpaeProcessCluster->Connect(hpaeSinkInputNode);
84     EXPECT_EQ(hpaeSinkInputNode.use_count(), static_cast<long>(DEFAULT_VALUE_TWO));
85     EXPECT_EQ(hpaeProcessCluster->GetGainNodeCount(), 1);
86     EXPECT_EQ(hpaeProcessCluster->GetConverterNodeCount(), 1);
87     nodeInfo.frameLen = DEFAULT_FRAMELEN_FIRST;
88     nodeInfo.sessionId = DEFAULT_SESSIONID_NUM_SECOND;
89     nodeInfo.samplingRate = SAMPLE_RATE_44100;
90     std::shared_ptr<HpaeSinkInputNode> hpaeSinkInputNode1 = std::make_shared<HpaeSinkInputNode>(nodeInfo);
91     hpaeProcessCluster->Connect(hpaeSinkInputNode1);
92     EXPECT_EQ(hpaeSinkInputNode1.use_count(), static_cast<long>(DEFAULT_VALUE_TWO));
93     EXPECT_EQ(hpaeProcessCluster->GetGainNodeCount(), (DEFAULT_VALUE_TWO));
94     EXPECT_EQ(hpaeProcessCluster->GetConverterNodeCount(), 1 + 1);
95 }
96 static int32_t g_testValue1 = 0;
97 static int32_t g_testValue2 = 0;
TestRendererRenderFrame(const char * data,uint64_t len)98 static int32_t TestRendererRenderFrame(const char *data, uint64_t len)
99 {
100     float curGain = 0.0f;
101     float targetGain = 1.0f;
102     uint64_t frameLen = len / (SAMPLE_F32LE * STEREO);
103     float stepGain = (targetGain - curGain) / frameLen;
104     for (int32_t i = 0; i < frameLen; i++) {
105         EXPECT_EQ(*((float *)data + i * STEREO + 1), (g_testValue1 * (curGain + i * stepGain) +
106             g_testValue2 * (curGain + i * stepGain)));
107         EXPECT_EQ(*((float *)data + i * STEREO), (g_testValue1 * (curGain + i * stepGain) +
108             g_testValue2 * (curGain + i * stepGain)));
109     }
110     return 0;
111 }
CreateHpaeInfo(HpaeNodeInfo & nodeInfo,HpaeSinkInfo & dummySinkInfo)112 static void CreateHpaeInfo(HpaeNodeInfo &nodeInfo, HpaeSinkInfo &dummySinkInfo)
113 {
114     nodeInfo.nodeId = DEFAULT_NODEID_NUM_FIRST;
115     nodeInfo.frameLen = DEFAULT_FRAMELEN_SECOND;
116     nodeInfo.samplingRate = SAMPLE_RATE_48000;
117     nodeInfo.channels = STEREO;
118     nodeInfo.format = SAMPLE_F32LE;
119     dummySinkInfo.channels = STEREO;
120     dummySinkInfo.frameLen = DEFAULT_FRAMELEN_SECOND;
121     dummySinkInfo.format = SAMPLE_F32LE;
122     dummySinkInfo.samplingRate = SAMPLE_RATE_48000;
123 }
124 
125 HWTEST_F(HpaeProcessClusterTest, testHpaeWriteDataProcessSessionTest, TestSize.Level0)
126 {
127     HpaeNodeInfo nodeInfo;
128     HpaeSinkInfo dummySinkInfo;
129     CreateHpaeInfo(nodeInfo, dummySinkInfo);
130     std::shared_ptr<HpaeSinkOutputNode> hpaeSinkOutputNode = std::make_shared<HpaeSinkOutputNode>(nodeInfo);
131     nodeInfo.sessionId = DEFAULT_SESSIONID_NUM_FIRST;
132     std::shared_ptr<HpaeSinkInputNode> hpaeSinkInputNode0 = std::make_shared<HpaeSinkInputNode>(nodeInfo);
133     nodeInfo.sessionId = DEFAULT_SESSIONID_NUM_SECOND;
134     std::shared_ptr<HpaeSinkInputNode> hpaeSinkInputNode1 = std::make_shared<HpaeSinkInputNode>(nodeInfo);
135     std::shared_ptr<HpaeProcessCluster> hpaeProcessCluster =
136         std::make_shared<HpaeProcessCluster>(nodeInfo, dummySinkInfo);
137     hpaeProcessCluster->Connect(hpaeSinkInputNode0);
138     hpaeProcessCluster->Connect(hpaeSinkInputNode1);
139     EXPECT_EQ(hpaeSinkOutputNode->GetPreOutNum(), 0);
140     EXPECT_EQ(hpaeProcessCluster->GetGainNodeCount(), DEFAULT_VALUE_TWO);
141     EXPECT_EQ(hpaeProcessCluster->GetConverterNodeCount(), DEFAULT_VALUE_TWO);
142     EXPECT_EQ(hpaeSinkOutputNode->GetPreOutNum(), 0);
143     hpaeSinkOutputNode->Connect(hpaeProcessCluster);
144     std::string deviceClass = "file_io";
145     std::string deviceNetId = "LocalDevice";
146     EXPECT_EQ(hpaeSinkOutputNode->GetPreOutNum(), 1);
147     EXPECT_EQ(hpaeSinkOutputNode->GetRenderSinkInstance(deviceClass, deviceNetId), 0);
148     EXPECT_EQ(hpaeSinkInputNode0.use_count(), static_cast<long>(DEFAULT_VALUE_TWO));
149     EXPECT_EQ(hpaeSinkInputNode1.use_count(), static_cast<long>(DEFAULT_VALUE_TWO));
150     EXPECT_EQ(hpaeProcessCluster.use_count(), 1);
151     g_testValue1 = DEFAULT_TEST_VALUE_FIRST;
152     std::shared_ptr<WriteFixedValueCb> writeFixedValueCb0 =
153         std::make_shared<WriteFixedValueCb>(SAMPLE_F32LE, g_testValue1);
154     hpaeSinkInputNode0->RegisterWriteCallback(writeFixedValueCb0);
155     g_testValue2 = DEFAULT_TEST_VALUE_SECOND;
156     std::shared_ptr<WriteFixedValueCb> writeFixedValueCb1 =
157         std::make_shared<WriteFixedValueCb>(SAMPLE_F32LE, g_testValue2);
158     hpaeSinkInputNode1->RegisterWriteCallback(writeFixedValueCb1);
159     hpaeSinkOutputNode->DoProcess();
160     TestRendererRenderFrame(hpaeSinkOutputNode->GetRenderFrameData(),
161         nodeInfo.frameLen * nodeInfo.channels * GetSizeFromFormat(nodeInfo.format));
162     hpaeSinkOutputNode->DisConnect(hpaeProcessCluster);
163     EXPECT_EQ(hpaeSinkOutputNode->GetPreOutNum(), 0);
164     EXPECT_EQ(hpaeProcessCluster.use_count(), 1);
165     hpaeProcessCluster->DisConnect(hpaeSinkInputNode0);
166     EXPECT_EQ(hpaeSinkInputNode0.use_count(), 1);
167     EXPECT_EQ(hpaeProcessCluster->GetGainNodeCount(), 1);
168     hpaeProcessCluster->DisConnect(hpaeSinkInputNode1);
169     EXPECT_EQ(hpaeSinkInputNode1.use_count(), 1);
170     EXPECT_EQ(hpaeProcessCluster->GetGainNodeCount(), 0);
171 }
172 
173 HWTEST_F(HpaeProcessClusterTest, testEffectNode_001, TestSize.Level0)
174 {
175     HpaeNodeInfo nodeInfo;
176     nodeInfo.nodeId = DEFAULT_NODEID_NUM_FIRST;
177     nodeInfo.frameLen = DEFAULT_FRAMELEN_SECOND;
178     nodeInfo.sessionId = DEFAULT_SESSIONID_NUM_FIRST;
179     nodeInfo.samplingRate = SAMPLE_RATE_48000;
180     nodeInfo.channels = STEREO;
181     nodeInfo.format = SAMPLE_F32LE;
182     HpaeSinkInfo dummySinkInfo;
183 
184     std::shared_ptr<HpaeProcessCluster> hpaeProcessCluster =
185         std::make_shared<HpaeProcessCluster>(nodeInfo, dummySinkInfo);
186     hpaeProcessCluster->DoProcess();
187     EXPECT_EQ(hpaeProcessCluster->AudioRendererCreate(nodeInfo), 0);
188     hpaeProcessCluster->DoProcess();
189     EXPECT_EQ(hpaeProcessCluster->AudioRendererStart(nodeInfo), 0);
190     EXPECT_EQ(hpaeProcessCluster->AudioRendererStop(nodeInfo), 0);
191     EXPECT_EQ(hpaeProcessCluster->AudioRendererRelease(nodeInfo), 0);
192 
193     nodeInfo.sceneType = HPAE_SCENE_SPLIT_MEDIA;
194     hpaeProcessCluster =
195         std::make_shared<HpaeProcessCluster>(nodeInfo, dummySinkInfo);
196     EXPECT_EQ(hpaeProcessCluster->AudioRendererCreate(nodeInfo), 0);
197     EXPECT_EQ(hpaeProcessCluster->AudioRendererStart(nodeInfo), 0);
198     EXPECT_EQ(hpaeProcessCluster->AudioRendererStop(nodeInfo), 0);
199     EXPECT_EQ(hpaeProcessCluster->AudioRendererRelease(nodeInfo), 0);
200 }
201 
202 HWTEST_F(HpaeProcessClusterTest, testGetNodeInputFormatInfo, TestSize.Level0)
203 {
204     // test processCluster without effectnode and loundess algorithm handle
205     HpaeNodeInfo nodeInfo;
206     nodeInfo.nodeId = DEFAULT_NODEID_NUM_FIRST;
207     nodeInfo.frameLen = DEFAULT_FRAMELEN_SECOND;
208     nodeInfo.sessionId = DEFAULT_SESSIONID_NUM_FIRST;
209     nodeInfo.samplingRate = SAMPLE_RATE_44100;
210     nodeInfo.channels = CHANNEL_6;
211     nodeInfo.channelLayout = CH_LAYOUT_5POINT1;
212     nodeInfo.format = SAMPLE_F32LE;
213     nodeInfo.sceneType = HPAE_SCENE_EFFECT_NONE;
214 
215     HpaeSinkInfo dummySinkInfo;
216     dummySinkInfo.samplingRate = SAMPLE_RATE_96000;
217     dummySinkInfo.channels = STEREO;
218     dummySinkInfo.channelLayout = CH_LAYOUT_STEREO;
219 
220     auto dummySinkInputNode = std::make_shared<HpaeSinkInputNode>(nodeInfo);
221     std::shared_ptr<HpaeProcessCluster> hpaeProcessCluster =
222         std::make_shared<HpaeProcessCluster>(nodeInfo, dummySinkInfo);
223 
224     hpaeProcessCluster->Connect(dummySinkInputNode);
225 
226     AudioBasicFormat basicFormat;
227     hpaeProcessCluster->SetLoudnessGain(DEFAULT_NODEID_NUM_FIRST, 0.0f);
228     int32_t ret = hpaeProcessCluster->GetNodeInputFormatInfo(nodeInfo.sessionId, basicFormat);
229 
230     EXPECT_EQ(ret, SUCCESS);
231     EXPECT_EQ(basicFormat.audioChannelInfo.channelLayout, CH_LAYOUT_STEREO);
232     EXPECT_EQ(basicFormat.audioChannelInfo.numChannels, static_cast<uint32_t>(STEREO));
233     EXPECT_EQ(basicFormat.rate, SAMPLE_RATE_96000);
234 
235     // test processCluster with effectnode and loundess algorithm handle
236     hpaeProcessCluster = nullptr;
237     nodeInfo.sceneType = HPAE_SCENE_MUSIC;
238     hpaeProcessCluster = std::make_shared<HpaeProcessCluster>(nodeInfo, dummySinkInfo);
239     hpaeProcessCluster->Connect(dummySinkInputNode);
240     EXPECT_EQ(hpaeProcessCluster->AudioRendererCreate(nodeInfo), SUCCESS);
241 
242     hpaeProcessCluster->SetLoudnessGain(DEFAULT_NODEID_NUM_FIRST, LOUDNESS_GAIN);
243     ret = hpaeProcessCluster->GetNodeInputFormatInfo(nodeInfo.sessionId, basicFormat);
244     EXPECT_EQ(basicFormat.audioChannelInfo.channelLayout, CH_LAYOUT_STEREO);
245     EXPECT_EQ(basicFormat.audioChannelInfo.numChannels, static_cast<uint32_t>(STEREO));
246     EXPECT_EQ(basicFormat.rate, SAMPLE_RATE_48000);
247 }
248 } // AudioStandard
249 } // OHOS