• 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 "HpaeResampleNode"
18 #endif
19 
20 #include <iostream>
21 #include <algorithm>
22 #include <memory>
23 #include "hpae_resample_node.h"
24 #include "hpae_pcm_buffer.h"
25 #include "audio_utils.h"
26 #include "audio_effect_log.h"
27 
28 namespace OHOS {
29 namespace AudioStandard {
30 namespace HPAE {
31 constexpr int REASAMPLE_QUAILTY = 5;
Min(const uint32_t a,const uint32_t b)32 static inline uint32_t Min(const uint32_t a, const uint32_t b) {return a > b ? b : a;}
HpaeResampleNode(HpaeNodeInfo & preNodeInfo,HpaeNodeInfo & nodeInfo,ResamplerType type)33 HpaeResampleNode::HpaeResampleNode(HpaeNodeInfo &preNodeInfo, HpaeNodeInfo &nodeInfo, ResamplerType type)
34     : HpaeNode(nodeInfo), HpaePluginNode(nodeInfo),
35     pcmBufferInfo_(nodeInfo.channels, nodeInfo.frameLen, nodeInfo.samplingRate),
36     resampleOutput_(pcmBufferInfo_), preNodeInfo_(preNodeInfo), tempOutput_(preNodeInfo.channels * nodeInfo.frameLen)
37 {
38     if (type == ResamplerType::PRORESAMPLER) {
39         resampler_ = std::make_unique<ProResampler>(preNodeInfo_.samplingRate, nodeInfo.samplingRate,
40             preNodeInfo_.channels, REASAMPLE_QUAILTY);
41     }
42 #ifdef ENABLE_HOOK_PCM
43     inputPcmDumper_ = std::make_unique<HpaePcmDumper>("HpaeResampleNodeInput1_id_" +
44         std::to_string(GetSessionId()) + "_ch_" + std::to_string(preNodeInfo_.channels) +
45         "_rate_" + std::to_string(preNodeInfo_.samplingRate) + "_scene_" +
46         std::to_string(HpaeNode::GetSceneType()) + "_" + GetTime() + ".pcm");
47     outputPcmDumper_ = std::make_unique<HpaePcmDumper>("HpaeResampleNodeOutput1_id_" +
48         std::to_string(GetSessionId()) + "_ch_" + std::to_string(GetChannelCount()) +
49         "_rate_" + std::to_string(GetSampleRate()) + "_scene_" +
50         std::to_string(HpaeNode::GetSceneType())+ "_" + GetTime() + ".pcm");
51 #endif
52 }
53 
HpaeResampleNode(HpaeNodeInfo & preNodeInfo,HpaeNodeInfo & nodeInfo)54 HpaeResampleNode::HpaeResampleNode(HpaeNodeInfo &preNodeInfo, HpaeNodeInfo &nodeInfo)
55     : HpaeNode(nodeInfo), HpaePluginNode(nodeInfo),
56     pcmBufferInfo_(nodeInfo.channels, nodeInfo.frameLen, nodeInfo.samplingRate),
57     resampleOutput_(pcmBufferInfo_), preNodeInfo_(preNodeInfo), tempOutput_(preNodeInfo.channels * nodeInfo.frameLen)
58 {   // use ProResampler as default
59     resampler_ = std::make_unique<ProResampler>(preNodeInfo_.samplingRate, nodeInfo.samplingRate,
60         preNodeInfo_.channels, REASAMPLE_QUAILTY);
61 
62 #ifdef ENABLE_HOOK_PCM
63     inputPcmDumper_ = std::make_unique<HpaePcmDumper>("HpaeResampleNodeInput1_id_" +
64         std::to_string(HpaeNode::GetSessionId()) + "_ch_" + std::to_string(preNodeInfo_.channels) + "_rate_" +
65         std::to_string(preNodeInfo_.samplingRate) + "_scene_" + std::to_string(HpaeNode::GetSceneType())+".pcm");
66 
67     outputPcmDumper_ = std::make_unique<HpaePcmDumper>("HpaeResampleNodeOutput1_id_" +
68         std::to_string(HpaeNode::GetSessionId()) + "_ch_" + std::to_string(HpaeNode::GetChannelCount()) +
69         "_rate_" + std::to_string(HpaeNode::GetSampleRate()) +
70         "_scene_"+ std::to_string(HpaeNode::GetSceneType())+".pcm");
71 #endif
72     AUDIO_INFO_LOG("input rate %{public}u, output rate %{public}u", preNodeInfo_.samplingRate, nodeInfo.samplingRate);
73     AUDIO_INFO_LOG("input SessionId %{public}u, output streamType %{public}u", HpaeNode::GetSessionId(),
74         nodeInfo.streamType);
75     AUDIO_INFO_LOG("input ch %{public}u, output ch %{public}u", preNodeInfo_.channels,  HpaeNode::GetChannelCount());
76 }
77 
Reset()78 bool HpaeResampleNode::Reset()
79 {
80     if (resampler_ == nullptr) {
81         AUDIO_WARNING_LOG("resampler_ is nullptr, SessionId:%{public}d", GetSessionId());
82         return false;
83     }
84     resampler_->Reset();
85     return true;
86 }
87 
SignalProcess(const std::vector<HpaePcmBuffer * > & inputs)88 HpaePcmBuffer *HpaeResampleNode::SignalProcess(const std::vector<HpaePcmBuffer *> &inputs)
89 {
90     Trace trace("[" + std::to_string(GetSessionId()) + "]HpaeResampleNode::SignalProcess");
91     if (inputs.empty()) {
92         AUDIO_WARNING_LOG("HpaeResampleNode inputs size is empty, SessionId:%{public}d", GetSessionId());
93         return nullptr;
94     }
95     if (inputs.size() != 1) {
96         AUDIO_WARNING_LOG("error inputs size is not eqaul to 1, SessionId:%{public}d", GetSessionId());
97     }
98     if (resampler_ == nullptr) {
99         return &silenceData_;
100     }
101     resampleOutput_.Reset();
102     uint32_t inputFrameLen = preNodeInfo_.frameLen;
103     uint32_t outputFrameLen = GetFrameLen();
104     float *srcData = (*(inputs[0])).GetPcmDataBuffer();
105     float *dstData = tempOutput_.data();
106     if (preNodeInfo_.channels == GetChannelCount()) {
107         dstData = resampleOutput_.GetPcmDataBuffer();
108     }
109 #ifdef ENABLE_HOOK_PCM
110     if (inputPcmDumper_ != nullptr) {
111         inputPcmDumper_->CheckAndReopenHandle();
112         inputPcmDumper_->Dump((int8_t *)(srcData), (inputFrameLen * sizeof(float) * preNodeInfo_.channels));
113     }
114 #endif
115     ResampleProcess(srcData, inputFrameLen, dstData, outputFrameLen);
116     return &resampleOutput_;
117 }
118 
ResampleProcess(float * srcData,uint32_t inputFrameLen,float * dstData,uint32_t outputFrameLen)119 void HpaeResampleNode::ResampleProcess(float *srcData, uint32_t inputFrameLen, float *dstData, uint32_t outputFrameLen)
120 {
121     resampler_->Process(srcData, inputFrameLen, dstData, outputFrameLen);
122 
123     if (preNodeInfo_.channels == GetChannelCount()) {
124 #ifdef ENABLE_HOOK_PCM
125         if (outputPcmDumper_ != nullptr) {
126             outputPcmDumper_->CheckAndReopenHandle();
127             outputPcmDumper_->Dump(
128                 (int8_t *)(resampleOutput_.GetPcmDataBuffer()), GetFrameLen() * sizeof(float) * GetChannelCount());
129         }
130 #endif
131         return;
132     }
133 
134     float *targetData = resampleOutput_.GetPcmDataBuffer();
135     uint32_t targetChannels = GetChannelCount();
136     for (uint32_t i = 0; i < outputFrameLen; ++i) {
137         for (uint32_t ch = 0; ch < targetChannels; ++ch) {
138             uint32_t leftChIndex = Min(ch, (preNodeInfo_.channels - 1));
139             targetData[i * targetChannels + ch] =
140                 dstData[i * preNodeInfo_.channels + leftChIndex];
141         }
142     }
143 
144 #ifdef ENABLE_HOOK_PCM
145     if (outputPcmDumper_ != nullptr) {
146         outputPcmDumper_->CheckAndReopenHandle();
147         outputPcmDumper_->Dump(
148             (int8_t *)(resampleOutput_.GetPcmDataBuffer()), GetFrameLen() * sizeof(float) * GetChannelCount());
149     }
150 #endif
151 }
152 
ConnectWithInfo(const std::shared_ptr<OutputNode<HpaePcmBuffer * >> & preNode,HpaeNodeInfo & nodeInfo)153 void HpaeResampleNode::ConnectWithInfo(const std::shared_ptr<OutputNode<HpaePcmBuffer*>> &preNode,
154     HpaeNodeInfo &nodeInfo)
155 {
156     inputStream_.Connect(preNode->GetSharedInstance(), preNode->GetOutputPort(nodeInfo));
157     resampleOutput_.SetSourceBufferType(preNode->GetOutputPortBufferType(nodeInfo));
158 }
159 
DisConnectWithInfo(const std::shared_ptr<OutputNode<HpaePcmBuffer * >> & preNode,HpaeNodeInfo & nodeInfo)160 void HpaeResampleNode::DisConnectWithInfo(const std::shared_ptr<OutputNode<HpaePcmBuffer*>> &preNode,
161     HpaeNodeInfo &nodeInfo)
162 {
163     inputStream_.DisConnect(preNode->GetOutputPort(nodeInfo, true));
164 }
165 
166 }  // namespace HPAE
167 }  // namespace AudioStandard
168 }  // namespace OHOS