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 "HpaeCaptureEffectNode"
18 #endif
19
20 #include "hpae_capture_effect_node.h"
21 #include <iostream>
22 #include "hpae_pcm_buffer.h"
23 #include "audio_errors.h"
24 #include "hpae_format_convert.h"
25 #include "audio_enhance_chain_manager.h"
26 #include "audio_effect_map.h"
27 #include "audio_utils.h"
28 #include "audio_effect_log.h"
29
30 namespace OHOS {
31 namespace AudioStandard {
32 namespace HPAE {
HpaeCaptureEffectNode(HpaeNodeInfo & nodeInfo)33 HpaeCaptureEffectNode::HpaeCaptureEffectNode(HpaeNodeInfo &nodeInfo)
34 : HpaeNode(nodeInfo), HpaePluginNode(nodeInfo)
35 {
36 const std::unordered_map<AudioEnhanceScene, std::string> &audioEnhanceSupportedSceneTypes =
37 GetEnhanceSupportedSceneType();
38 auto item = audioEnhanceSupportedSceneTypes.find(nodeInfo.effectInfo.enhanceScene);
39 if (item != audioEnhanceSupportedSceneTypes.end()) {
40 sceneType_ = item->second;
41 AUDIO_INFO_LOG("HpaeCaptureEffectNode created scenetype: [%{public}s]", sceneType_.c_str());
42 } else {
43 AUDIO_ERR_LOG("scenetype: %{public}u not supported", nodeInfo.effectInfo.enhanceScene);
44 }
45 #ifdef ENABLE_HIDUMP_DFX
46 SetNodeName("hpaeCaptureEffectNode");
47 #endif
48 }
49
~HpaeCaptureEffectNode()50 HpaeCaptureEffectNode::~HpaeCaptureEffectNode()
51 {
52 #ifdef ENABLE_HIDUMP_DFX
53 AUDIO_INFO_LOG("NodeId: %{public}u NodeName: %{public}s destructed.",
54 GetNodeId(), GetNodeName().c_str());
55 #endif
56 }
57
Reset()58 bool HpaeCaptureEffectNode::Reset()
59 {
60 return HpaePluginNode::Reset();
61 }
62
SignalProcess(const std::vector<HpaePcmBuffer * > & inputs)63 HpaePcmBuffer *HpaeCaptureEffectNode::SignalProcess(const std::vector<HpaePcmBuffer *> &inputs)
64 {
65 Trace trace("[" + sceneType_ + "]HpaeRenderEffectNode::SignalProcess inputs num[" +
66 std::to_string(inputs.size()) + "]");
67 if (inputs.empty()) {
68 AUDIO_WARNING_LOG("HpaeCaptureEffectNode inputs size is empty, SessionId:%{public}d", GetSessionId());
69 return nullptr;
70 }
71
72 AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance();
73 EnhanceTransBuffer transBuf = {};
74 uint32_t processLength = 0;
75 for (uint32_t i = 0; i < inputs.size(); i++) {
76 if (inputs[i]->GetSourceBufferType() == HPAE_SOURCE_BUFFER_TYPE_MIC) {
77 ConvertFromFloat(SAMPLE_S16LE, micBufferLength_ / GetSizeFromFormat(SAMPLE_S16LE),
78 inputs[i]->GetPcmDataBuffer(), static_cast<void *>(micCache_.data()));
79 transBuf.micData = static_cast<void *>(micCache_.data());
80 transBuf.micDataLen = micCache_.size();
81 processLength = micBufferLength_;
82 AUDIO_DEBUG_LOG("CopyToEnhanceBuffer size:%{public}u", processLength);
83 } else if (inputs[i]->GetSourceBufferType() == HPAE_SOURCE_BUFFER_TYPE_EC) {
84 ConvertFromFloat(SAMPLE_S16LE, ecBufferLength_ / GetSizeFromFormat(SAMPLE_S16LE),
85 inputs[i]->GetPcmDataBuffer(), static_cast<void *>(ecCache_.data()));
86 transBuf.ecData = static_cast<void *>(ecCache_.data());
87 transBuf.ecDataLen = ecCache_.size();
88 AUDIO_DEBUG_LOG("CopyEcToEnhanceBuffer size:%{public}u", ecBufferLength_);
89 } else if (inputs[i]->GetSourceBufferType() == HPAE_SOURCE_BUFFER_TYPE_MICREF) {
90 ConvertFromFloat(SAMPLE_S16LE, micrefBufferLength_ / GetSizeFromFormat(SAMPLE_S16LE),
91 inputs[i]->GetPcmDataBuffer(), static_cast<void *>(micRefCache_.data()));
92 transBuf.micRefData = static_cast<void *>(micRefCache_.data());
93 transBuf.micRefDataLen = micRefCache_.size();
94 AUDIO_DEBUG_LOG("CopyMicRefToEnhanceBuffer size:%{public}u", micrefBufferLength_);
95 }
96 }
97
98 outPcmBuffer_->SetBufferValid(processLength != 0);
99 CHECK_AND_RETURN_RET(processLength != 0, outPcmBuffer_.get(), "error, main mic data is null");
100
101 int32_t ret = audioEnhanceChainManager->ApplyEnhanceChainById(sceneKeyCode_, transBuf);
102 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, outPcmBuffer_.get(), "effect apply failed, ret:%{public}d", ret);
103 audioEnhanceChainManager->GetChainOutputDataById(sceneKeyCode_, static_cast<void *>(cacheDataOut_.data()),
104 static_cast<size_t>(processLength));
105 ConvertToFloat(SAMPLE_S16LE, micBufferLength_ / GetSizeFromFormat(SAMPLE_S16LE),
106 static_cast<void *>(cacheDataOut_.data()), outPcmBuffer_->GetPcmDataBuffer());
107 return outPcmBuffer_.get();
108 }
109
ConnectWithInfo(const std::shared_ptr<OutputNode<HpaePcmBuffer * >> & preNode,HpaeNodeInfo & nodeInfo)110 void HpaeCaptureEffectNode::ConnectWithInfo(const std::shared_ptr<OutputNode<HpaePcmBuffer*>> &preNode,
111 HpaeNodeInfo &nodeInfo)
112 {
113 std::shared_ptr<HpaeNode> realPreNode = preNode->GetSharedInstance(nodeInfo);
114 CHECK_AND_RETURN_LOG(realPreNode != nullptr, "realPreNode is nullptr");
115 inputStream_.Connect(realPreNode, preNode->GetOutputPort(nodeInfo));
116 #ifdef ENABLE_HIDUMP_DFX
117 if (auto callback = GetNodeStatusCallback().lock()) {
118 callback->OnNotifyDfxNodeInfo(true, realPreNode->GetNodeId(), GetNodeInfo());
119 }
120 #endif
121 }
122
DisConnectWithInfo(const std::shared_ptr<OutputNode<HpaePcmBuffer * >> & preNode,HpaeNodeInfo & nodeInfo)123 void HpaeCaptureEffectNode::DisConnectWithInfo(const std::shared_ptr<OutputNode<HpaePcmBuffer*>>& preNode,
124 HpaeNodeInfo &nodeInfo)
125 {
126 CHECK_AND_RETURN_LOG(!inputStream_.CheckIfDisConnected(preNode->GetOutputPort(nodeInfo)),
127 "HpaeCaptureEffectNode[%{public}u] has disconnected with preNode", GetNodeId());
128 inputStream_.DisConnect(preNode->GetOutputPort(nodeInfo, true));
129 #ifdef ENABLE_HIDUMP_DFX
130 if (auto callback = GetNodeStatusCallback().lock()) {
131 callback->OnNotifyDfxNodeInfo(false, GetNodeId(), GetNodeInfo());
132 }
133 #endif
134 }
135
GetCapturerEffectConfig(HpaeNodeInfo & nodeInfo,HpaeSourceBufferType type)136 bool HpaeCaptureEffectNode::GetCapturerEffectConfig(HpaeNodeInfo& nodeInfo, HpaeSourceBufferType type)
137 {
138 CHECK_AND_RETURN_RET_LOG(capturerEffectConfigMap_.find(type) != capturerEffectConfigMap_.end(),
139 false, "not need resample node, type:%{public}u", type);
140 nodeInfo = capturerEffectConfigMap_[type];
141 return true;
142 }
143
SetCapturerEffectConfig(AudioBufferConfig micConfig,AudioBufferConfig ecConfig,AudioBufferConfig micrefConfig)144 void HpaeCaptureEffectNode::SetCapturerEffectConfig(AudioBufferConfig micConfig, AudioBufferConfig ecConfig,
145 AudioBufferConfig micrefConfig)
146 {
147 HpaeNodeInfo micInfo = {};
148 HpaeNodeInfo ecInfo = {};
149 HpaeNodeInfo micrefInfo = {};
150 micInfo.sourceBufferType = HPAE_SOURCE_BUFFER_TYPE_MIC;
151 micInfo.frameLen = FRAME_LEN * (micConfig.samplingRate / MILLISECOND_PER_SECOND);
152 micInfo.samplingRate = static_cast<AudioSamplingRate>(micConfig.samplingRate);
153 micInfo.channels = static_cast<AudioChannel>(micConfig.channels);
154 micInfo.format = static_cast<AudioSampleFormat>(micConfig.format / BITLENGTH - 1);
155 ecInfo.sourceBufferType = HPAE_SOURCE_BUFFER_TYPE_EC;
156 ecInfo.frameLen = FRAME_LEN * (ecConfig.samplingRate / MILLISECOND_PER_SECOND);
157 ecInfo.samplingRate = static_cast<AudioSamplingRate>(ecConfig.samplingRate);
158 ecInfo.channels = static_cast<AudioChannel>(ecConfig.channels);
159 ecInfo.format = static_cast<AudioSampleFormat>(ecConfig.format / BITLENGTH - 1);
160 micrefInfo.sourceBufferType = HPAE_SOURCE_BUFFER_TYPE_MICREF;
161 micrefInfo.frameLen = FRAME_LEN * (micrefConfig.samplingRate / MILLISECOND_PER_SECOND);
162 micrefInfo.samplingRate = static_cast<AudioSamplingRate>(micrefConfig.samplingRate);
163 micrefInfo.channels = static_cast<AudioChannel>(micrefConfig.channels);
164 micrefInfo.format = static_cast<AudioSampleFormat>(micrefConfig.format / BITLENGTH - 1);
165 capturerEffectConfigMap_.emplace(HPAE_SOURCE_BUFFER_TYPE_MIC, micInfo);
166 capturerEffectConfigMap_.emplace(HPAE_SOURCE_BUFFER_TYPE_EC, ecInfo);
167 capturerEffectConfigMap_.emplace(HPAE_SOURCE_BUFFER_TYPE_MICREF, micrefInfo);
168 }
169
CaptureEffectCreate(uint64_t sceneKeyCode,CaptureEffectAttr attr)170 int32_t HpaeCaptureEffectNode::CaptureEffectCreate(uint64_t sceneKeyCode, CaptureEffectAttr attr)
171 {
172 sceneKeyCode_ = sceneKeyCode;
173 AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance();
174 CHECK_AND_RETURN_RET_LOG(audioEnhanceChainManager, ERR_ILLEGAL_STATE, "audioEnhanceChainManager is nullptr");
175 AudioEnhanceDeviceAttr enhanceAttr = {};
176 enhanceAttr.micChannels = attr.micChannels;
177 enhanceAttr.ecChannels = attr.ecChannels;
178 enhanceAttr.micRefChannels = attr.micRefChannels;
179 int32_t ret = audioEnhanceChainManager->CreateAudioEnhanceChainDynamic(sceneKeyCode, enhanceAttr);
180 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "CreateAudioEnhanceChainDynamic failed, ret:%{public}d", ret);
181
182 AudioBufferConfig micConfig = {};
183 AudioBufferConfig ecConfig = {};
184 AudioBufferConfig micrefConfig = {};
185 ret = audioEnhanceChainManager->AudioEnhanceChainGetAlgoConfig(sceneKeyCode, micConfig, ecConfig, micrefConfig);
186 CHECK_AND_RETURN_RET_LOG(ret == 0 && micConfig.samplingRate != 0, ERROR,
187 "get algo config failed, ret:%{public}d", ret);
188 SetCapturerEffectConfig(micConfig, ecConfig, micrefConfig);
189 micBufferLength_ = FRAME_LEN * micConfig.channels * (micConfig.samplingRate / MILLISECOND_PER_SECOND) *
190 (micConfig.format / BITLENGTH);
191 ecBufferLength_ = FRAME_LEN * ecConfig.channels * (ecConfig.samplingRate / MILLISECOND_PER_SECOND) *
192 (ecConfig.format / BITLENGTH);
193 micrefBufferLength_ = FRAME_LEN * micrefConfig.channels * (micrefConfig.samplingRate / MILLISECOND_PER_SECOND) *
194 (micrefConfig.format / BITLENGTH);
195 uint32_t maxLength = (micBufferLength_ > ecBufferLength_) ?
196 (micBufferLength_ > micrefBufferLength_ ? micBufferLength_ : micrefBufferLength_) :
197 (ecBufferLength_ > micrefBufferLength_ ? ecBufferLength_ : micrefBufferLength_);
198 AUDIO_INFO_LOG("micLength: %{public}u, ecLength: %{public}u, micrefLength: %{public}u, maxLength:%{public}u",
199 micBufferLength_, ecBufferLength_, micrefBufferLength_, maxLength);
200 ecCache_.resize(ecBufferLength_);
201 micCache_.resize(micBufferLength_);
202 micRefCache_.resize(micrefBufferLength_);
203 cacheDataOut_.resize(maxLength);
204 PcmBufferInfo pcmBufferInfo(micConfig.channels, FRAME_LEN * (micConfig.samplingRate / MILLISECOND_PER_SECOND),
205 micConfig.samplingRate);
206 outPcmBuffer_ = std::make_unique<HpaePcmBuffer>(pcmBufferInfo);
207 if (outPcmBuffer_ == nullptr) {
208 AUDIO_ERR_LOG("create effect out pcm buffer fail");
209 return ERROR;
210 }
211
212 return ret;
213 }
214
CaptureEffectRelease(uint64_t sceneKeyCode)215 int32_t HpaeCaptureEffectNode::CaptureEffectRelease(uint64_t sceneKeyCode)
216 {
217 AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance();
218 CHECK_AND_RETURN_RET_LOG(audioEnhanceChainManager, ERR_ILLEGAL_STATE, "audioEnhanceChainManager is nullptr");
219 return audioEnhanceChainManager->ReleaseAudioEnhanceChainDynamic(sceneKeyCode);
220 }
221
222 } // namespace HPAE
223 } // namespace AudioStandard
224 } // namespace OHOS
225