• 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 #ifndef LOG_TAG
17 #define LOG_TAG "HpaeInnerCapSinkNode"
18 #endif
19 
20 #include <ctime>
21 #include "hpae_inner_cap_sink_node.h"
22 #include "hpae_format_convert.h"
23 #include "audio_errors.h"
24 #include "hpae_node_common.h"
25 #include "audio_utils.h"
26 #ifdef ENABLE_HOOK_PCM
27 #include "hpae_pcm_dumper.h"
28 #endif
29 #include "audio_engine_log.h"
30 
31 namespace OHOS {
32 namespace AudioStandard {
33 namespace HPAE {
34 
35 constexpr auto DEFAULT_NANO_SECONDS = std::chrono::nanoseconds(20000000); // 20000000ns = 20ms
36 
HpaeInnerCapSinkNode(HpaeNodeInfo & nodeInfo)37 HpaeInnerCapSinkNode::HpaeInnerCapSinkNode(HpaeNodeInfo &nodeInfo)
38     : HpaeNode(nodeInfo), outputStream_(this),
39       pcmBufferInfo_(nodeInfo.channels, nodeInfo.frameLen, nodeInfo.samplingRate), silenceData_(pcmBufferInfo_)
40 {
41     silenceData_.Reset();
42     historyTime_ = std::chrono::high_resolution_clock::now();
43     sleepTime_ = std::chrono::nanoseconds(0);
44 #ifdef ENABLE_HOOK_PCM
45     outputPcmDumper_ = std::make_unique<HpaePcmDumper>("HpaeInnerCapSinkNode_bit_" +
46                        std::to_string(SAMPLE_F32LE) + "_ch_" + std::to_string(GetChannelCount()) +
47                        "_rate_" + std::to_string(GetSampleRate()) + ".pcm");
48 #endif
49 #ifdef ENABLE_HIDUMP_DFX
50     SetNodeName("hpaeInnerCapSinkNode");
51     if (auto callback = GetNodeStatusCallback().lock()) {
52         callback->OnNotifyDfxNodeInfo(true, 0, GetNodeInfo());
53     }
54 #endif
55 }
56 
~HpaeInnerCapSinkNode()57 HpaeInnerCapSinkNode::~HpaeInnerCapSinkNode()
58 {
59 #ifdef ENABLE_HIDUMP_DFX
60     AUDIO_INFO_LOG("NodeId: %{public}u NodeName: %{public}s destructed.",
61         GetNodeId(), GetNodeName().c_str());
62 #endif
63 }
64 
DoProcess()65 void HpaeInnerCapSinkNode::DoProcess()
66 {
67     Trace trace("[" + std::to_string(GetSessionId()) + "]HpaeInnerCapSinkNode::DoProcess " + GetTraceInfo());
68     std::vector<HpaePcmBuffer *> &outputVec = inputStream_.ReadPreOutputData();
69     if (outputVec.empty() || isMute_ == true) {
70         outputStream_.WriteDataToOutput(&silenceData_);
71 #ifdef ENABLE_HOOK_PCM
72         if (outputPcmDumper_) {
73             outputPcmDumper_->Dump((int8_t *)silenceData_.GetPcmDataBuffer(), GetChannelCount() *
74                 GetFrameLen() * GetSizeFromFormat(SAMPLE_F32LE));
75         }
76 #endif
77     } else {
78         HpaePcmBuffer *outputData = outputVec.front();
79 #ifdef ENABLE_HOOK_PCM
80         if (outputPcmDumper_) {
81             outputPcmDumper_->Dump((int8_t *)outputData->GetPcmDataBuffer(), GetChannelCount() *
82                 GetFrameLen() * GetSizeFromFormat(SAMPLE_F32LE));
83         }
84 #endif
85     // no need convert
86         outputStream_.WriteDataToOutput(outputVec[0]);
87     }
88     // sleep
89     endTime_ = std::chrono::high_resolution_clock::now();
90     std::this_thread::sleep_for(std::chrono::duration_cast<std::chrono::nanoseconds>(DEFAULT_NANO_SECONDS -
91         (endTime_ - historyTime_ - sleepTime_)));
92     AUDIO_DEBUG_LOG("sleeptime : %{public} " PRIi64"", static_cast<int64_t>(std::chrono::duration_cast
93         <std::chrono::nanoseconds>(DEFAULT_NANO_SECONDS - (endTime_ - historyTime_ - sleepTime_)).count()));
94     if (static_cast<int64_t>(std::chrono::duration_cast<std::chrono::nanoseconds>(DEFAULT_NANO_SECONDS -
95         (endTime_ - historyTime_ - sleepTime_)).count()) <= 0) {
96         sleepTime_ = std::chrono::nanoseconds(0);
97     } else {
98         sleepTime_ = DEFAULT_NANO_SECONDS - (endTime_ - historyTime_ - sleepTime_);
99     }
100     historyTime_ = endTime_;
101 }
102 
Reset()103 bool HpaeInnerCapSinkNode::Reset()
104 {
105     const auto preOutputMap = inputStream_.GetPreOutputMap();
106     for (const auto &preOutput : preOutputMap) {
107         OutputPort<HpaePcmBuffer *> *output = preOutput.first;
108         inputStream_.DisConnect(output);
109     }
110     return true;
111 }
112 
ResetAll()113 bool HpaeInnerCapSinkNode::ResetAll()
114 {
115     const auto preOutputMap = inputStream_.GetPreOutputMap();
116     for (const auto &preOutput : preOutputMap) {
117         OutputPort<HpaePcmBuffer *> *output = preOutput.first;
118         std::shared_ptr<HpaeNode> hpaeNode = preOutput.second;
119         if (hpaeNode->ResetAll()) {
120             inputStream_.DisConnect(output);
121         }
122     }
123     return true;
124 }
125 
126 // todo
GetSharedInstance()127 std::shared_ptr<HpaeNode> HpaeInnerCapSinkNode::GetSharedInstance()
128 {
129     return shared_from_this();
130 }
131 
132 // todo
GetOutputPort()133 OutputPort<HpaePcmBuffer *> *HpaeInnerCapSinkNode::GetOutputPort()
134 {
135     return &outputStream_;
136 }
137 
Connect(const std::shared_ptr<OutputNode<HpaePcmBuffer * >> & preNode)138 void HpaeInnerCapSinkNode::Connect(const std::shared_ptr<OutputNode<HpaePcmBuffer*>>& preNode)
139 {
140     AUDIO_INFO_LOG("Connect");
141     inputStream_.Connect(preNode->GetSharedInstance(), preNode->GetOutputPort());
142 #ifdef ENABLE_HIDUMP_DFX
143     if (auto callback = GetNodeStatusCallback().lock()) {
144         callback->OnNotifyDfxNodeInfo(true, GetNodeId(), preNode->GetSharedInstance()->GetNodeInfo());
145     }
146 #endif
147 }
148 
DisConnect(const std::shared_ptr<OutputNode<HpaePcmBuffer * >> & preNode)149 void HpaeInnerCapSinkNode::DisConnect(const std::shared_ptr<OutputNode<HpaePcmBuffer*>>& preNode)
150 {
151     AUDIO_INFO_LOG("DisConnect");
152     inputStream_.DisConnect(preNode->GetOutputPort());
153 #ifdef ENABLE_HIDUMP_DFX
154     if (auto callback = GetNodeStatusCallback().lock()) {
155         auto preNodeReal = preNode->GetSharedInstance();
156         callback->OnNotifyDfxNodeInfo(false, preNodeReal->GetNodeId(), preNodeReal->GetNodeInfo());
157     }
158 #endif
159 }
160 
InnerCapturerSinkInit()161 int32_t HpaeInnerCapSinkNode::InnerCapturerSinkInit()
162 {
163     AUDIO_INFO_LOG("Init");
164     SetSinkState(STREAM_MANAGER_IDLE);
165     return SUCCESS;
166 }
167 
InnerCapturerSinkDeInit()168 int32_t HpaeInnerCapSinkNode::InnerCapturerSinkDeInit()
169 {
170     AUDIO_INFO_LOG("DeInit");
171     SetSinkState(STREAM_MANAGER_RELEASED);
172     return SUCCESS;
173 }
174 
InnerCapturerSinkFlush()175 int32_t HpaeInnerCapSinkNode::InnerCapturerSinkFlush()
176 {
177     AUDIO_INFO_LOG("Flush");
178     return SUCCESS;
179 }
180 
InnerCapturerSinkPause()181 int32_t HpaeInnerCapSinkNode::InnerCapturerSinkPause()
182 {
183     AUDIO_INFO_LOG("Pause");
184     SetSinkState(STREAM_MANAGER_SUSPENDED);
185     return SUCCESS;
186 }
187 
InnerCapturerSinkReset()188 int32_t HpaeInnerCapSinkNode::InnerCapturerSinkReset()
189 {
190     AUDIO_INFO_LOG("Reset");
191     return SUCCESS;
192 }
193 
InnerCapturerSinkResume()194 int32_t HpaeInnerCapSinkNode::InnerCapturerSinkResume()
195 {
196     AUDIO_INFO_LOG("Resume");
197     SetSinkState(STREAM_MANAGER_RUNNING);
198     return SUCCESS;
199 }
200 
InnerCapturerSinkStart()201 int32_t HpaeInnerCapSinkNode::InnerCapturerSinkStart()
202 {
203     AUDIO_INFO_LOG("Start");
204     SetSinkState(STREAM_MANAGER_RUNNING);
205     return SUCCESS;
206 }
207 
InnerCapturerSinkStop()208 int32_t HpaeInnerCapSinkNode::InnerCapturerSinkStop()
209 {
210     AUDIO_INFO_LOG("Stop");
211     SetSinkState(STREAM_MANAGER_SUSPENDED);
212     return SUCCESS;
213 }
214 
GetSinkState(void)215 StreamManagerState HpaeInnerCapSinkNode::GetSinkState(void)
216 {
217     return state_;
218 }
219 
SetSinkState(StreamManagerState sinkState)220 int32_t HpaeInnerCapSinkNode::SetSinkState(StreamManagerState sinkState)
221 {
222     AUDIO_INFO_LOG("Sink[%{public}s] state change:[%{public}s]-->[%{public}s]",
223         GetDeviceClass().c_str(), ConvertStreamManagerState2Str(state_).c_str(),
224         ConvertStreamManagerState2Str(sinkState).c_str());
225     state_ = sinkState;
226     return SUCCESS;
227 }
228 
SetMute(bool isMute)229 void HpaeInnerCapSinkNode::SetMute(bool isMute)
230 {
231     if (isMute_ != isMute) {
232         isMute_ = isMute;
233         AUDIO_INFO_LOG("SetMute: %{public}d", isMute);
234     }
235 }
236 
GetPreOutNum()237 size_t HpaeInnerCapSinkNode::GetPreOutNum()
238 {
239     return inputStream_.GetPreOutputNum();
240 }
241 
GetOutputPortNum()242 size_t HpaeInnerCapSinkNode::GetOutputPortNum()
243 {
244     return outputStream_.GetInputNum();
245 }
246 }  // namespace HPAE
247 }  // namespace AudioStandard
248 }  // namespace OHOS