• 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_output_cluster.h"
24 using namespace testing::ext;
25 using namespace testing;
26 namespace OHOS {
27 namespace AudioStandard {
28 namespace HPAE {
29 constexpr uint32_t NODE_ID = 1243;
30 constexpr uint32_t SESSION_ID_1 = 12345;
31 constexpr uint32_t SESSION_ID_2 = 12346;
32 constexpr uint32_t FRAME_LEN = 960;
33 constexpr uint32_t FRAME_LEN_2 = 820;
34 constexpr uint32_t NUM_TWO = 2;
35 constexpr int32_t TEST_VALUE_1 = 300;
36 constexpr int32_t TEST_VALUE_2 = 400;
37 
38 static std::string g_deviceClass = "file_io";
39 static std::string g_deviceNetId = "LocalDevice";
40 
41 
TestRendererRenderFrame(const char * data,uint64_t len)42 static int32_t TestRendererRenderFrame(const char *data, uint64_t len)
43 {
44     float curGain = 0.0f;
45     float targetGain = 1.0f;
46     uint64_t frameLen = len / (SAMPLE_F32LE * STEREO);
47     float stepGain = (targetGain - curGain) / frameLen;
48 
49     const float *tempData = reinterpret_cast<const float *>(data);
50     for (int32_t i = 0; i < frameLen; i++) {
51         const float left = tempData[NUM_TWO * i];
52         const float right = tempData[NUM_TWO * i + 1];
53         const float expectedValue = TEST_VALUE_1 * (curGain + i * stepGain) + TEST_VALUE_2 * (curGain + i * stepGain);
54         EXPECT_EQ(left, expectedValue);
55         EXPECT_EQ(right, expectedValue);
56     }
57     return 0;
58 }
59 
InitHpaeWriteDataOutSessionTest(HpaeNodeInfo & nodeInfo,HpaeSinkInfo & dummySinkInfo)60 static void InitHpaeWriteDataOutSessionTest(HpaeNodeInfo &nodeInfo, HpaeSinkInfo &dummySinkInfo)
61 {
62     nodeInfo.nodeId = NODE_ID;
63     nodeInfo.frameLen = FRAME_LEN;
64     nodeInfo.samplingRate = SAMPLE_RATE_48000;
65     nodeInfo.channels = STEREO;
66     nodeInfo.format = SAMPLE_F32LE;
67 
68     dummySinkInfo.frameLen = FRAME_LEN;
69     dummySinkInfo.samplingRate = SAMPLE_RATE_48000;
70     dummySinkInfo.channels = STEREO;
71     dummySinkInfo.format = SAMPLE_F32LE;
72     dummySinkInfo.deviceClass = g_deviceClass;
73     dummySinkInfo.deviceNetId = g_deviceNetId;
74 }
75 
76 class HpaeOutputClusterTest : public testing::Test {
77 public:
78     void SetUp();
79     void TearDown();
80 };
81 
SetUp()82 void HpaeOutputClusterTest::SetUp()
83 {}
84 
TearDown()85 void HpaeOutputClusterTest::TearDown()
86 {}
87 
88 HWTEST_F(HpaeOutputClusterTest, constructHpaeOutputClusterNode, TestSize.Level0)
89 {
90     HpaeNodeInfo nodeInfo;
91     nodeInfo.nodeId = NODE_ID;
92     nodeInfo.frameLen = FRAME_LEN;
93     nodeInfo.sessionId = SESSION_ID_1;
94     nodeInfo.samplingRate = SAMPLE_RATE_48000;
95     nodeInfo.channels = STEREO;
96     nodeInfo.format = SAMPLE_F32LE;
97     int32_t syncId = 123;
98 
99     std::shared_ptr<HpaeOutputCluster> hpaeoutputCluster = std::make_shared<HpaeOutputCluster>(nodeInfo);
100     EXPECT_EQ(hpaeoutputCluster->GetSampleRate(), nodeInfo.samplingRate);
101     EXPECT_EQ(hpaeoutputCluster->GetFrameLen(), nodeInfo.frameLen);
102     EXPECT_EQ(hpaeoutputCluster->GetChannelCount(), nodeInfo.channels);
103     EXPECT_EQ(hpaeoutputCluster->GetBitWidth(), nodeInfo.format);
104 
105     std::shared_ptr<HpaeSinkInputNode> hpaeSinkInputNode = std::make_shared<HpaeSinkInputNode>(nodeInfo);
106     hpaeoutputCluster->Connect(hpaeSinkInputNode);
107     EXPECT_EQ(hpaeSinkInputNode.use_count(), NUM_TWO);
108     EXPECT_EQ(hpaeoutputCluster->GetConverterNodeCount(), 1);
109     nodeInfo.frameLen = FRAME_LEN_2;
110     nodeInfo.sessionId = SESSION_ID_2;
111     nodeInfo.samplingRate = SAMPLE_RATE_44100;
112     std::shared_ptr<HpaeSinkInputNode> hpaeSinkInputNode1 = std::make_shared<HpaeSinkInputNode>(nodeInfo);
113     hpaeoutputCluster->Connect(hpaeSinkInputNode1);
114     EXPECT_EQ(hpaeSinkInputNode1.use_count(), NUM_TWO);
115     EXPECT_EQ(hpaeoutputCluster->GetConverterNodeCount(), 1);
116     EXPECT_EQ(hpaeoutputCluster->SetSyncId(syncId), SUCCESS);
117 }
118 
119 HWTEST_F(HpaeOutputClusterTest, testHpaeWriteDataOutSessionTest, TestSize.Level0)
120 {
121     HpaeNodeInfo nodeInfo;
122     HpaeSinkInfo dummySinkInfo;
123     InitHpaeWriteDataOutSessionTest(nodeInfo, dummySinkInfo);
124     std::shared_ptr<HpaeOutputCluster> hpaeOutputCluster = std::make_shared<HpaeOutputCluster>(nodeInfo);
125     nodeInfo.sessionId = SESSION_ID_1;
126     nodeInfo.streamType = STREAM_MUSIC;
127     if (hpaeOutputCluster->mixerNode_) {
128         hpaeOutputCluster->mixerNode_->limiter_ = nullptr;
129     }
130     std::shared_ptr<HpaeSinkInputNode> musicSinkInputNode = std::make_shared<HpaeSinkInputNode>(nodeInfo);
131     nodeInfo.sessionId = SESSION_ID_2;
132     nodeInfo.streamType = STREAM_RING;
133     std::shared_ptr<HpaeSinkInputNode> ringSinkInputNode = std::make_shared<HpaeSinkInputNode>(nodeInfo);
134     nodeInfo.sceneType = HPAE_SCENE_MUSIC;
135     std::shared_ptr<HpaeProcessCluster> muiscProcessCluster =
136         std::make_shared<HpaeProcessCluster>(nodeInfo, dummySinkInfo);
137     nodeInfo.sceneType = HPAE_SCENE_RING;
138     std::shared_ptr<HpaeProcessCluster> ringProcessCluster =
139         std::make_shared<HpaeProcessCluster>(nodeInfo, dummySinkInfo);
140     muiscProcessCluster->Connect(musicSinkInputNode);
141     ringProcessCluster->Connect(ringSinkInputNode);
142     hpaeOutputCluster->Connect(muiscProcessCluster);
143     hpaeOutputCluster->Connect(ringProcessCluster);
144 
145     EXPECT_EQ(ringProcessCluster->GetGainNodeCount(), 1);
146     EXPECT_EQ(muiscProcessCluster->GetGainNodeCount(), 1);
147     EXPECT_EQ(muiscProcessCluster->GetConverterNodeCount(), 1);
148     EXPECT_EQ(ringProcessCluster->GetConverterNodeCount(), 1);
149     EXPECT_EQ(hpaeOutputCluster->GetConverterNodeCount(), NUM_TWO);
150     EXPECT_EQ(hpaeOutputCluster->GetPreOutNum(), NUM_TWO);
151 
152     EXPECT_EQ(hpaeOutputCluster->GetInstance(g_deviceClass, g_deviceNetId), 0);
153     EXPECT_EQ(musicSinkInputNode.use_count(), NUM_TWO);
154     EXPECT_EQ(ringSinkInputNode.use_count(), NUM_TWO);
155     EXPECT_EQ(muiscProcessCluster.use_count(), 1);
156     std::shared_ptr<WriteFixedValueCb> writeFixedValueCb0 =
157         std::make_shared<WriteFixedValueCb>(SAMPLE_F32LE, TEST_VALUE_1);
158     musicSinkInputNode->RegisterWriteCallback(writeFixedValueCb0);
159     std::shared_ptr<WriteFixedValueCb> writeFixedValueCb1 =
160         std::make_shared<WriteFixedValueCb>(SAMPLE_F32LE, TEST_VALUE_2);
161     ringSinkInputNode->RegisterWriteCallback(writeFixedValueCb1);
162     hpaeOutputCluster->DoProcess();
163     TestRendererRenderFrame(hpaeOutputCluster->GetFrameData(),
164         nodeInfo.frameLen * nodeInfo.channels * GetSizeFromFormat(nodeInfo.format));
165     muiscProcessCluster->DisConnect(musicSinkInputNode);
166     EXPECT_EQ(musicSinkInputNode.use_count(), 1);
167     EXPECT_EQ(muiscProcessCluster->GetGainNodeCount(), 0);
168     ringProcessCluster->DisConnect(ringSinkInputNode);
169     EXPECT_EQ(ringSinkInputNode.use_count(), 1);
170     hpaeOutputCluster->DisConnect(muiscProcessCluster);
171     EXPECT_EQ(hpaeOutputCluster->GetPreOutNum(), 1);
172     hpaeOutputCluster->DisConnect(ringProcessCluster);
173     EXPECT_EQ(hpaeOutputCluster->GetPreOutNum(), 0);
174 }
175 }  // namespace HPAE
176 }  // namespace AudioStandard
177 }  // namespace OHOS