• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 #undef LOG_TAG
17 #define LOG_TAG "AudioEnhanceChain"
18 
19 #include "audio_enhance_chain.h"
20 
21 #include <chrono>
22 
23 #include "securec.h"
24 #include "audio_effect_log.h"
25 #include "audio_errors.h"
26 #include "audio_utils.h"
27 #include "volume_tools.h"
28 
29 namespace OHOS {
30 namespace AudioStandard {
31 
32 const uint32_t BITLENGTH = 8;
33 const uint32_t MILLISECOND = 1000;
34 const uint32_t DEFAULT_FRAMELENGTH = 20;
35 const uint32_t DEFAULT_SAMPLE_RATE = 48000;
36 const uint32_t DEFAULT_FORMAT = 2;
37 const uint32_t DEFAULT_MICNUM = 2;
38 const uint32_t DEFAULT_ECNUM = 0;
39 const uint32_t DEFAULT_MICREFNUM = 0;
40 const uint32_t BYTE_SIZE_SAMPLE_U8 = 1;
41 const uint32_t BYTE_SIZE_SAMPLE_S16 = 2;
42 const uint32_t BYTE_SIZE_SAMPLE_S24 = 3;
43 const uint32_t BYTE_SIZE_SAMPLE_S32 = 4;
44 
45 const std::vector<std::string> NEED_EC_SCENE = {
46     "SCENE_VOIP_UP",
47     "SCENE_PRE_ENHANCE",
48 };
49 
50 const std::vector<std::string> NEED_MICREF_SCENE = {
51     "SCENE_VOIP_UP",
52     "SCENE_RECORD",
53 };
54 
55 const std::map<uint32_t, AudioSampleFormat> FORMAT_CONVERT_MAP = {
56     {BYTE_SIZE_SAMPLE_U8, SAMPLE_U8},
57     {BYTE_SIZE_SAMPLE_S16, SAMPLE_S16LE},
58     {BYTE_SIZE_SAMPLE_S24, SAMPLE_S24LE},
59     {BYTE_SIZE_SAMPLE_S32, SAMPLE_S32LE},
60 };
61 
AudioEnhanceChain(const std::string & scene,const AudioEnhanceParamAdapter & algoParam,const AudioEnhanceDeviceAttr & deviceAttr,const bool defaultFlag)62 AudioEnhanceChain::AudioEnhanceChain(const std::string &scene, const AudioEnhanceParamAdapter &algoParam,
63     const AudioEnhanceDeviceAttr &deviceAttr, const bool defaultFlag)
64 {
65     sceneType_ = scene;
66     algoParam_ = algoParam;
67     defaultFlag_ = defaultFlag;
68     deviceAttr_ = deviceAttr;
69     if (deviceAttr_.micChannels == 1) {
70         deviceAttr_.micChannels = DEFAULT_MICNUM;
71     }
72 
73     InitAudioEnhanceChain();
74     InitDump();
75 }
76 
InitAudioEnhanceChain()77 void AudioEnhanceChain::InitAudioEnhanceChain()
78 {
79     setConfigFlag_ = false;
80     needEcFlag_ = false;
81     needMicRefFlag_ = false;
82     enhanceLibHandles_.clear();
83     standByEnhanceHandles_.clear();
84 
85     algoSupportedConfig_ = {DEFAULT_FRAMELENGTH, DEFAULT_SAMPLE_RATE, DEFAULT_FORMAT * BITLENGTH,
86         deviceAttr_.micChannels, DEFAULT_ECNUM, DEFAULT_MICREFNUM, deviceAttr_.micChannels};
87 
88     uint32_t byteLenPerFrame = DEFAULT_FRAMELENGTH * (DEFAULT_SAMPLE_RATE / MILLISECOND) * DEFAULT_FORMAT;
89     algoAttr_ = {DEFAULT_FORMAT, deviceAttr_.micChannels, byteLenPerFrame};
90 
91     if (count(NEED_EC_SCENE.begin(), NEED_EC_SCENE.end(), sceneType_)) {
92         needEcFlag_ = true;
93         algoSupportedConfig_.ecNum = deviceAttr_.ecChannels;
94         algoAttr_.batchLen = deviceAttr_.micChannels + deviceAttr_.ecChannels;
95     }
96 
97     if (count(NEED_MICREF_SCENE.begin(), NEED_MICREF_SCENE.end(), sceneType_)) {
98         needMicRefFlag_ = true;
99         algoSupportedConfig_.micRefNum = deviceAttr_.micRefChannels;
100         algoAttr_.batchLen += deviceAttr_.micRefChannels;
101     }
102 
103     algoCache_.input.resize(algoAttr_.byteLenPerFrame * algoAttr_.batchLen);
104     algoCache_.output.resize(algoAttr_.byteLenPerFrame * deviceAttr_.micChannels);
105     AUDIO_INFO_LOG("micNum: %{public}u ecNum: %{public}u micRefNum: %{public}u outNum: %{public}u \
106         byteLenPerFrame: %{public}u inputsize:%{public}zu outputsize:%{public}zu",
107         algoSupportedConfig_.micNum, algoSupportedConfig_.ecNum, algoSupportedConfig_.micRefNum,
108         algoSupportedConfig_.outNum, byteLenPerFrame, algoCache_.input.size(), algoCache_.output.size());
109 }
110 
InitDump()111 void AudioEnhanceChain::InitDump()
112 {
113     std::string dumpFileName = "Enhance_";
114     std::string dumpFileInName = dumpFileName + sceneType_ + "_" + GetTime() + "_In";
115     if (needEcFlag_) {
116         dumpFileInName += "_EC_" + std::to_string(algoSupportedConfig_.ecNum);
117     }
118     dumpFileInName += "_Mic_" + std::to_string(algoSupportedConfig_.micNum);
119     if (needMicRefFlag_) {
120         dumpFileInName += "_MicRef_" + std::to_string(algoSupportedConfig_.micRefNum);
121     }
122     dumpFileInName += ".pcm";
123     std::string dumpFileOutName = dumpFileName + sceneType_ + "_" + GetTime() + "_Out.pcm";
124     std::string dumpFileDeInterleaverName = dumpFileName + sceneType_ + "_" + GetTime() + "_DeInterLeaver.pcm";
125     DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_SERVER_PARA, dumpFileInName, &dumpFileIn_);
126     DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_SERVER_PARA, dumpFileOutName, &dumpFileOut_);
127     DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_SERVER_PARA, dumpFileDeInterleaverName, &dumpFileDeinterLeaver_);
128 }
129 
~AudioEnhanceChain()130 AudioEnhanceChain::~AudioEnhanceChain()
131 {
132     ReleaseEnhanceChain();
133     DumpFileUtil::CloseDumpFile(&dumpFileIn_);
134     DumpFileUtil::CloseDumpFile(&dumpFileOut_);
135     DumpFileUtil::CloseDumpFile(&dumpFileDeinterLeaver_);
136 }
137 
ReleaseEnhanceChain()138 void AudioEnhanceChain::ReleaseEnhanceChain()
139 {
140     for (uint32_t i = 0; i < standByEnhanceHandles_.size() && i < enhanceLibHandles_.size(); i++) {
141         if (!enhanceLibHandles_[i]) {
142             continue;
143         }
144         if (!standByEnhanceHandles_[i]) {
145             continue;
146         }
147         if (!enhanceLibHandles_[i]->releaseEffect) {
148             continue;
149         }
150         enhanceLibHandles_[i]->releaseEffect(standByEnhanceHandles_[i]);
151     }
152     standByEnhanceHandles_.clear();
153     enhanceLibHandles_.clear();
154 }
155 
SetInputDevice(const std::string & inputDevice,const std::string & deviceName)156 int32_t AudioEnhanceChain::SetInputDevice(const std::string &inputDevice, const std::string &deviceName)
157 {
158     if (inputDevice.size() == 0) {
159         return SUCCESS;
160     }
161     algoParam_.preDevice = inputDevice;
162     algoParam_.preDeviceName = deviceName;
163     AUDIO_INFO_LOG("update input device %{public}s name %{public}s", inputDevice.c_str(), deviceName.c_str());
164     std::lock_guard<std::mutex> lock(chainMutex_);
165     uint32_t size = standByEnhanceHandles_.size();
166     AudioEffectTransInfo cmdInfo = {};
167     AudioEffectTransInfo replyInfo = {};
168     for (uint32_t index = 0; index < size; index++) {
169         auto &handle = standByEnhanceHandles_[index];
170         CHECK_AND_RETURN_RET_LOG(SetEnhanceParamToHandle(handle) == SUCCESS, ERROR,
171             "[%{public}s] effect EFFECT_CMD_SET_PARAM fail", sceneType_.c_str());
172         CHECK_AND_RETURN_RET_LOG((*handle)->command(handle, EFFECT_CMD_INIT, &cmdInfo, &replyInfo) == 0, ERROR,
173             "[%{public}s] effect EFFECT_CMD_INIT fail", sceneType_.c_str());
174     }
175     return SUCCESS;
176 }
177 
SetFoldState(uint32_t foldState)178 int32_t AudioEnhanceChain::SetFoldState(uint32_t foldState)
179 {
180     if (algoParam_.foldState == foldState) {
181         AUDIO_INFO_LOG("no need update fold state %{public}u", foldState);
182         return SUCCESS;
183     }
184     algoParam_.foldState = foldState;
185     AUDIO_INFO_LOG("update fold state %{public}u", foldState);
186     std::lock_guard<std::mutex> lock(chainMutex_);
187     AudioEffectTransInfo cmdInfo = {};
188     AudioEffectTransInfo replyInfo = {};
189     for (const auto &handle : standByEnhanceHandles_) {
190         CHECK_AND_RETURN_RET_LOG(SetEnhanceParamToHandle(handle) == SUCCESS, ERROR,
191             "[%{public}s] effect EFFECT_CMD_SET_PARAM fail", sceneType_.c_str());
192         CHECK_AND_RETURN_RET_LOG((*handle)->command(handle, EFFECT_CMD_INIT, &cmdInfo, &replyInfo) == 0, ERROR,
193             "[%{public}s] effect EFFECT_CMD_INIT fail", sceneType_.c_str());
194     }
195     return SUCCESS;
196 }
197 
SetEnhanceParam(bool mute,uint32_t systemVol)198 int32_t AudioEnhanceChain::SetEnhanceParam(bool mute, uint32_t systemVol)
199 {
200     algoParam_.muteInfo = mute;
201     algoParam_.volumeInfo = systemVol;
202 
203     std::lock_guard<std::mutex> lock(chainMutex_);
204     uint32_t size = standByEnhanceHandles_.size();
205     AudioEffectTransInfo cmdInfo{};
206     AudioEffectTransInfo replyInfo{};
207     for (uint32_t index = 0; index < size; index++) {
208         auto &handle = standByEnhanceHandles_[index];
209         CHECK_AND_RETURN_RET_LOG(SetEnhanceParamToHandle(handle) == SUCCESS, ERROR,
210             "[%{public}s] effect EFFECT_CMD_SET_PARAM fail", sceneType_.c_str());
211         CHECK_AND_RETURN_RET_LOG(
212             (*handle)->command(handle, EFFECT_CMD_INIT, &cmdInfo, &replyInfo) == SUCCESS, ERROR,
213             "[%{public}s] effect EFFECT_CMD_INIT fail", sceneType_.c_str());
214     }
215     return SUCCESS;
216 }
217 
SetEnhanceParamToHandle(AudioEffectHandle handle)218 int32_t AudioEnhanceChain::SetEnhanceParamToHandle(AudioEffectHandle handle)
219 {
220     AudioEffectTransInfo cmdInfo = {};
221     AudioEffectTransInfo replyInfo = {};
222     AudioEnhanceParam setParam = {algoParam_.muteInfo, algoParam_.volumeInfo, algoParam_.foldState,
223         algoParam_.preDevice.c_str(), algoParam_.postDevice.c_str(), algoParam_.sceneType.c_str(),
224         algoParam_.preDeviceName.c_str()};
225     cmdInfo.data = static_cast<void *>(&setParam);
226     cmdInfo.size = sizeof(setParam);
227     return (*handle)->command(handle, EFFECT_CMD_SET_PARAM, &cmdInfo, &replyInfo);
228 }
229 
AddEnhanceHandle(AudioEffectHandle handle,AudioEffectLibrary * libHandle,const std::string & enhance,const std::string & property)230 int32_t AudioEnhanceChain::AddEnhanceHandle(AudioEffectHandle handle, AudioEffectLibrary *libHandle,
231     const std::string &enhance, const std::string &property)
232 {
233     std::lock_guard<std::mutex> lock(chainMutex_);
234     int32_t ret = 0;
235     AudioEffectTransInfo cmdInfo = {};
236     AudioEffectTransInfo replyInfo = {};
237 
238     uint32_t maxSampleRate = DEFAULT_SAMPLE_RATE;
239     replyInfo.data = &maxSampleRate;
240     replyInfo.size = sizeof(maxSampleRate);
241     ret = (*handle)->command(handle, EFFECT_CMD_GET_CONFIG, &cmdInfo, &replyInfo);
242     if (ret != SUCCESS) {
243         AUDIO_ERR_LOG("get algo maxSampleRate failed!");
244     }
245     if (algoSupportedConfig_.sampleRate != maxSampleRate) {
246         algoSupportedConfig_.sampleRate = maxSampleRate;
247         uint32_t byteLenPerFrame = DEFAULT_FRAMELENGTH * (maxSampleRate / MILLISECOND) *
248             DEFAULT_FORMAT;
249         algoAttr_.byteLenPerFrame = byteLenPerFrame;
250 
251         algoCache_.input.resize(algoAttr_.byteLenPerFrame * algoAttr_.batchLen);
252         algoCache_.output.resize(algoAttr_.byteLenPerFrame * deviceAttr_.micChannels);
253         AUDIO_INFO_LOG("algo rate: %{public}u byteLenPerFrame: %{public}u inputsize:%{public}zu outputsize:%{public}zu",
254             maxSampleRate, byteLenPerFrame, algoCache_.input.size(), algoCache_.output.size());
255     }
256 
257     cmdInfo.data = static_cast<void *>(&algoSupportedConfig_);
258     cmdInfo.size = sizeof(algoSupportedConfig_);
259 
260     ret = (*handle)->command(handle, EFFECT_CMD_SET_CONFIG, &cmdInfo, &replyInfo);
261     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "[%{public}s], either one of libs EFFECT_CMD_SET_CONFIG fail",
262         sceneType_.c_str());
263 
264     CHECK_AND_RETURN_RET_LOG(SetEnhanceParamToHandle(handle) == SUCCESS, ERROR,
265         "[%{public}s] %{public}s lib EFFECT_CMD_SET_PARAM fail", sceneType_.c_str(), libHandle->name);
266 
267     CHECK_AND_RETURN_RET_LOG(SetPropertyToHandle(handle, property) == SUCCESS, ERROR,
268         "[%{public}s] %{public}s effect EFFECT_CMD_SET_PROPERTY fail", sceneType_.c_str(), enhance.c_str());
269 
270     ret = (*handle)->command(handle, EFFECT_CMD_INIT, &cmdInfo, &replyInfo);
271     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "[%{public}s], either one of libs EFFECT_CMD_INIT fail",
272         sceneType_.c_str());
273 
274     setConfigFlag_ = true;
275     enhanceNames_.emplace_back(enhance);
276     standByEnhanceHandles_.emplace_back(handle);
277     enhanceLibHandles_.emplace_back(libHandle);
278     return SUCCESS;
279 }
280 
IsEmptyEnhanceHandles()281 bool AudioEnhanceChain::IsEmptyEnhanceHandles()
282 {
283     std::lock_guard<std::mutex> lock(chainMutex_);
284     return standByEnhanceHandles_.size() == 0;
285 }
286 
GetAlgoConfig(AudioBufferConfig & micConfig,AudioBufferConfig & ecConfig,AudioBufferConfig & micRefConfig)287 void AudioEnhanceChain::GetAlgoConfig(AudioBufferConfig &micConfig, AudioBufferConfig &ecConfig,
288     AudioBufferConfig &micRefConfig)
289 {
290     uint8_t configDataformat = static_cast<uint8_t>(algoSupportedConfig_.dataFormat);
291     micConfig.samplingRate = algoSupportedConfig_.sampleRate;
292     micConfig.channels = algoSupportedConfig_.micNum;
293     micConfig.format = configDataformat;
294 
295     if (needEcFlag_) {
296         ecConfig.samplingRate = algoSupportedConfig_.sampleRate;
297         ecConfig.channels = algoSupportedConfig_.ecNum;
298         ecConfig.format = configDataformat;
299     }
300 
301     if (needMicRefFlag_) {
302         micRefConfig.samplingRate = algoSupportedConfig_.sampleRate;
303         micRefConfig.channels = algoSupportedConfig_.micRefNum;
304         micRefConfig.format = configDataformat;
305     }
306     return;
307 }
308 
GetAlgoBufferSize()309 uint32_t AudioEnhanceChain::GetAlgoBufferSize()
310 {
311     uint32_t byteLenPerFrame = DEFAULT_FRAMELENGTH * (algoSupportedConfig_.sampleRate / MILLISECOND) *
312         DEFAULT_FORMAT;
313     return byteLenPerFrame * deviceAttr_.micChannels;
314 }
315 
GetAlgoBufferSizeEc()316 uint32_t AudioEnhanceChain::GetAlgoBufferSizeEc()
317 {
318     uint32_t byteLenPerFrame = DEFAULT_FRAMELENGTH * (algoSupportedConfig_.sampleRate / MILLISECOND) *
319         DEFAULT_FORMAT;
320     return byteLenPerFrame * deviceAttr_.ecChannels;
321 }
322 
GetAlgoBufferSizeMicRef()323 uint32_t AudioEnhanceChain::GetAlgoBufferSizeMicRef()
324 {
325     uint32_t byteLenPerFrame = DEFAULT_FRAMELENGTH * (algoSupportedConfig_.sampleRate / MILLISECOND) *
326         DEFAULT_FORMAT;
327     return byteLenPerFrame * deviceAttr_.micRefChannels;
328 }
329 
DeinterleaverData(uint8_t * src,uint32_t channel,uint8_t * dst,uint32_t offset)330 int32_t AudioEnhanceChain::DeinterleaverData(uint8_t *src, uint32_t channel, uint8_t *dst, uint32_t offset)
331 {
332     CHECK_AND_RETURN_RET_LOG(src != nullptr, ERROR, "src is nullptr");
333     CHECK_AND_RETURN_RET_LOG(dst != nullptr, ERROR, "dst is nullptr");
334     int32_t ret = 0;
335     uint32_t idx = 0;
336     for (uint32_t i = 0; i < algoAttr_.byteLenPerFrame / algoAttr_.bitDepth; ++i) {
337         for (uint32_t j = 0; j < channel; ++j) {
338             ret = memcpy_s(dst + j * algoAttr_.byteLenPerFrame + i * algoAttr_.bitDepth,
339                 algoCache_.input.size() - (j * algoAttr_.byteLenPerFrame + i * algoAttr_.bitDepth + offset),
340                 src + idx, algoAttr_.bitDepth);
341             CHECK_AND_RETURN_RET_LOG(ret == 0, ERROR, "memcpy in deinterleaver error");
342             idx += algoAttr_.bitDepth;
343         }
344     }
345     return SUCCESS;
346 }
347 
GetOneFrameInputData(std::unique_ptr<EnhanceBuffer> & enhanceBuffer)348 int32_t AudioEnhanceChain::GetOneFrameInputData(std::unique_ptr<EnhanceBuffer> &enhanceBuffer)
349 {
350     CHECK_AND_RETURN_RET_LOG(enhanceBuffer != nullptr, ERROR, "enhance buffer is null");
351 
352     uint32_t offset = 0;
353     int32_t ret = 0;
354     if ((enhanceBuffer->ecBuffer.size() != 0) && needEcFlag_) {
355         ret = DeinterleaverData(enhanceBuffer->ecBuffer.data(), deviceAttr_.ecChannels,
356             &algoCache_.input[offset], offset);
357         CHECK_AND_RETURN_RET_LOG(ret == 0, ERROR, "memcpy error in ec channel memcpy");
358         offset += algoAttr_.byteLenPerFrame * deviceAttr_.ecChannels;
359     }
360 
361     if (enhanceBuffer->micBufferIn.size() != 0) {
362         ret = DeinterleaverData(enhanceBuffer->micBufferIn.data(), deviceAttr_.micChannels,
363             &algoCache_.input[offset], offset);
364         CHECK_AND_RETURN_RET_LOG(ret == 0, ERROR, "memcpy error in mic channel memcpy");
365         offset += algoAttr_.byteLenPerFrame * deviceAttr_.micChannels;
366     }
367 
368     if ((enhanceBuffer->micRefBuffer.size() != 0) && needMicRefFlag_) {
369         ret = DeinterleaverData(enhanceBuffer->micRefBuffer.data(), deviceAttr_.micRefChannels,
370             &algoCache_.input[offset], offset);
371         CHECK_AND_RETURN_RET_LOG(ret == 0, ERROR, "memcpy error in mic ref channel memcpy");
372     }
373     return SUCCESS;
374 }
375 
WriteDumpFile(std::unique_ptr<EnhanceBuffer> & enhanceBuffer,uint32_t length)376 void AudioEnhanceChain::WriteDumpFile(std::unique_ptr<EnhanceBuffer> &enhanceBuffer, uint32_t length)
377 {
378     if (dumpFileIn_ == nullptr) {
379         return;
380     }
381     std::vector<uint8_t> buffer;
382     size_t ecLen = algoAttr_.bitDepth * algoSupportedConfig_.ecNum;
383     size_t micLen = algoAttr_.bitDepth * algoSupportedConfig_.micNum;
384     size_t micRefLen = algoAttr_.bitDepth * algoSupportedConfig_.micRefNum;
385     size_t offset = 0;
386     buffer.reserve(length);
387     for (size_t i = 0; i < algoAttr_.byteLenPerFrame / algoAttr_.bitDepth; i++) {
388         if (needEcFlag_) {
389         offset = i * ecLen;
390         buffer.insert(buffer.end(), enhanceBuffer->ecBuffer.begin() + offset,
391             enhanceBuffer->ecBuffer.begin() + offset + ecLen);
392         }
393         offset= i * micLen;
394         buffer.insert(buffer.end(), enhanceBuffer->micBufferIn.begin() + offset,
395             enhanceBuffer->micBufferIn.begin() + offset + micLen);
396         if (needMicRefFlag_) {
397             offset = i * micRefLen;
398             buffer.insert(buffer.end(), enhanceBuffer->micRefBuffer.begin() + offset,
399                 enhanceBuffer->micRefBuffer.begin() + offset + micRefLen);
400         }
401     }
402     DumpFileUtil::WriteDumpFile(dumpFileIn_, buffer.data(), buffer.size());
403 }
404 
ApplyEnhanceChain(std::unique_ptr<EnhanceBuffer> & enhanceBuffer,uint32_t length)405 int32_t AudioEnhanceChain::ApplyEnhanceChain(std::unique_ptr<EnhanceBuffer> &enhanceBuffer, uint32_t length)
406 {
407     std::lock_guard<std::mutex> lock(chainMutex_);
408     CHECK_AND_RETURN_RET_LOG(enhanceBuffer != nullptr, ERROR, "enhance buffer is null");
409 
410     uint32_t inputLen = algoAttr_.byteLenPerFrame * algoAttr_.batchLen;
411     uint32_t outputLen = algoAttr_.byteLenPerFrame * algoSupportedConfig_.outNum;
412 
413     BufferDesc bufferIn = {enhanceBuffer->micBufferIn.data(), length, length};
414     AudioStreamInfo streamInfo(static_cast<AudioSamplingRate>(deviceAttr_.micRate),
415         AudioEncodingType::ENCODING_PCM, ConvertFormat(deviceAttr_.micFormat),
416         static_cast<AudioChannel>(deviceAttr_.micChannels));
417 
418     CHECK_AND_RETURN_RET_LOG(algoCache_.input.size() == inputLen, ERROR,
419         "algo cache input size:%{public}zu != inputLen:%{public}u", algoCache_.input.size(), inputLen);
420     CHECK_AND_RETURN_RET_LOG(algoCache_.output.size() == outputLen, ERROR,
421         "algo cache output size:%{public}zu != outputLen:%{public}u", algoCache_.output.size(), outputLen);
422     VolumeTools::DfxOperation(bufferIn, streamInfo, sceneType_, volumeDataCount_);
423     WriteDumpFile(enhanceBuffer, inputLen);
424     if (standByEnhanceHandles_.size() == 0) {
425         AUDIO_DEBUG_LOG("audioEnhanceChain->standByEnhanceHandles is empty");
426         CHECK_AND_RETURN_RET_LOG(memcpy_s(enhanceBuffer->micBufferOut.data(), enhanceBuffer->micBufferOut.size(),
427             enhanceBuffer->micBufferIn.data(), length) == 0, ERROR, "memcpy error in IsEmptyEnhanceHandles");
428         return ERROR;
429     }
430     if (GetOneFrameInputData(enhanceBuffer) != SUCCESS) {
431         AUDIO_ERR_LOG("GetOneFrameInputData failed");
432         CHECK_AND_RETURN_RET_LOG(memcpy_s(enhanceBuffer->micBufferOut.data(), enhanceBuffer->micBufferOut.size(),
433             enhanceBuffer->micBufferIn.data(), length) == 0, ERROR, "memcpy error in GetOneFrameInputData");
434         return ERROR;
435     }
436     DumpFileUtil::WriteDumpFile(dumpFileDeinterLeaver_, algoCache_.input.data(), algoCache_.input.size());
437     AudioBuffer audioBufIn_ = {};
438     AudioBuffer audioBufOut_ = {};
439     audioBufIn_.frameLength = algoCache_.input.size();
440     audioBufOut_.frameLength = algoCache_.output.size();
441     audioBufIn_.raw = static_cast<void *>(algoCache_.input.data());
442     audioBufOut_.raw = static_cast<void *>(algoCache_.output.data());
443 
444     for (AudioEffectHandle handle : standByEnhanceHandles_) {
445         int32_t ret = (*handle)->process(handle, &audioBufIn_, &audioBufOut_);
446         CHECK_AND_CONTINUE_LOG(ret == 0, "[%{public}s] either one of libs process fail", sceneType_.c_str());
447     }
448     CHECK_AND_RETURN_RET_LOG(memcpy_s(enhanceBuffer->micBufferOut.data(), enhanceBuffer->micBufferOut.size(),
449         audioBufOut_.raw, audioBufOut_.frameLength) == 0,
450         ERROR, "memcpy error in audioBufOut_ to enhanceBuffer->output");
451     DumpFileUtil::WriteDumpFile(dumpFileOut_, enhanceBuffer->micBufferOut.data(), static_cast<uint64_t>(length));
452     return SUCCESS;
453 }
454 
SetEnhanceProperty(const std::string & enhance,const std::string & property)455 int32_t AudioEnhanceChain::SetEnhanceProperty(const std::string &enhance, const std::string &property)
456 {
457     if (property.empty()) { return SUCCESS; }
458     std::lock_guard<std::mutex> lock(chainMutex_);
459     uint32_t size = standByEnhanceHandles_.size();
460     AudioEffectTransInfo cmdInfo{};
461     AudioEffectTransInfo replyInfo{};
462     for (uint32_t index = 0; index < size; index++) {
463         auto &handle = standByEnhanceHandles_[index];
464         auto const &enhanceName = enhanceNames_[index];
465         if (enhance == enhanceName) {
466             CHECK_AND_RETURN_RET_LOG(SetPropertyToHandle(handle, property) == SUCCESS, ERROR,
467                 "[%{public}s] %{public}s effect EFFECT_CMD_SET_PROPERTY fail",
468                 sceneType_.c_str(), enhance.c_str());
469             CHECK_AND_RETURN_RET_LOG(
470                 (*handle)->command(handle, EFFECT_CMD_INIT, &cmdInfo, &replyInfo) == SUCCESS, ERROR,
471                 "[%{public}s] %{public}s effect EFFECT_CMD_INIT fail",
472                 sceneType_.c_str(), enhance.c_str());
473         }
474     }
475     return SUCCESS;
476 }
477 
SetPropertyToHandle(AudioEffectHandle handle,const std::string & property)478 int32_t AudioEnhanceChain::SetPropertyToHandle(AudioEffectHandle handle, const std::string &property)
479 {
480     if (property.empty()) { return SUCCESS; }
481     int32_t replyData = 0;
482     const char *propCstr = property.c_str();
483     AudioEffectTransInfo cmdInfo = {sizeof(const char *), reinterpret_cast<void*>(&propCstr)};
484     AudioEffectTransInfo replyInfo = {sizeof(int32_t), &replyData};
485     return (*handle)->command(handle, EFFECT_CMD_SET_PROPERTY, &cmdInfo, &replyInfo);
486 }
487 
IsDefaultChain()488 bool AudioEnhanceChain::IsDefaultChain()
489 {
490     return defaultFlag_;
491 }
492 
InitCommand()493 int32_t AudioEnhanceChain::InitCommand()
494 {
495     std::lock_guard<std::mutex> lock(chainMutex_);
496     uint32_t size = standByEnhanceHandles_.size();
497     AudioEffectTransInfo cmdInfo{};
498     AudioEffectTransInfo replyInfo{};
499     for (uint32_t index = 0; index < size; index++) {
500         auto &handle = standByEnhanceHandles_[index];
501         CHECK_AND_RETURN_RET_LOG(
502             (*handle)->command(handle, EFFECT_CMD_INIT, &cmdInfo, &replyInfo) == SUCCESS, ERROR,
503             "[%{public}s] effect EFFECT_CMD_INIT fail", sceneType_.c_str());
504     }
505     return SUCCESS;
506 }
507 
ConvertFormat(uint32_t format)508 AudioSampleFormat AudioEnhanceChain::ConvertFormat(uint32_t format)
509 {
510     auto item = FORMAT_CONVERT_MAP.find(format);
511     if (item != FORMAT_CONVERT_MAP.end()) {
512         return item->second;
513     }
514     return INVALID_WIDTH;
515 }
516 } // namespace AudioStandard
517 } // namespace OHOS