• 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 namespace {
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_ECOFF_CH = 0;
39 const uint32_t DEFAULT_MICREFOFF_CH = 0;
40 const uint32_t DEFAULT_ECON_CH = 2;
41 const uint32_t DEFAULT_MICREFON_CH = 4;
42 const uint32_t BYTE_SIZE_SAMPLE_U8 = 1;
43 const uint32_t BYTE_SIZE_SAMPLE_S16 = 2;
44 const uint32_t BYTE_SIZE_SAMPLE_S24 = 3;
45 const uint32_t BYTE_SIZE_SAMPLE_S32 = 4;
46 const uint32_t DEFAULT_DEVICE_TYPE_CH = 4;
47 const std::string DEFAULT_DEVICE_TYPE = "DEVICE_TYPE_MIC";
48 
49 const std::vector<std::string> NEED_EC_SCENE = {
50     "SCENE_VOIP_UP",
51     "SCENE_PRE_ENHANCE",
52     "SCENE_RECOGNITION",
53 };
54 
55 const std::vector<std::string> NEED_MICREF_SCENE = {
56     "SCENE_VOIP_UP",
57     "SCENE_RECORD",
58 };
59 
60 const std::map<uint32_t, AudioSampleFormat> FORMAT_CONVERT_MAP = {
61     {BYTE_SIZE_SAMPLE_U8, SAMPLE_U8},
62     {BYTE_SIZE_SAMPLE_S16, SAMPLE_S16LE},
63     {BYTE_SIZE_SAMPLE_S24, SAMPLE_S24LE},
64     {BYTE_SIZE_SAMPLE_S32, SAMPLE_S32LE},
65 };
66 
ConvertFormat(uint32_t format)67 AudioSampleFormat ConvertFormat(uint32_t format)
68 {
69     auto item = FORMAT_CONVERT_MAP.find(format);
70     if (item != FORMAT_CONVERT_MAP.end()) {
71         return item->second;
72     }
73     return INVALID_WIDTH;
74 }
75 } // namespace
76 
AudioEnhanceChain(uint64_t chainId,const std::string & scene,ScenePriority scenePriority,const AudioEnhanceParamAdapter & algoParam,const AudioEnhanceDeviceAttr & deviceAttr)77 AudioEnhanceChain::AudioEnhanceChain(uint64_t chainId, const std::string &scene, ScenePriority scenePriority,
78     const AudioEnhanceParamAdapter &algoParam, const AudioEnhanceDeviceAttr &deviceAttr)
79     : chainId_(chainId), sceneType_(scene), scenePriority_(scenePriority), algoParam_(algoParam)
80 {
81     deviceAttr_ = deviceAttr;
82     if (deviceAttr_.micChannels == 1) {
83         deviceAttr_.micChannels = DEFAULT_MICNUM;
84     }
85 
86     InitAudioEnhanceChain();
87 }
88 
InitAudioEnhanceChain()89 void AudioEnhanceChain::InitAudioEnhanceChain()
90 {
91     if ((algoParam_.preDevice == DEFAULT_DEVICE_TYPE) && (deviceAttr_.micChannels != DEFAULT_DEVICE_TYPE_CH)) {
92         AUDIO_WARNING_LOG("mic channel[%{public}d] is set to 4", deviceAttr_.micChannels);
93         deviceAttr_.micChannels = DEFAULT_DEVICE_TYPE_CH;
94     }
95 
96     algoSupportedConfig_ = {DEFAULT_FRAMELENGTH, DEFAULT_SAMPLE_RATE, DEFAULT_FORMAT * BITLENGTH,
97         deviceAttr_.micChannels, DEFAULT_ECOFF_CH, DEFAULT_MICREFOFF_CH, deviceAttr_.micChannels};
98 
99     uint32_t byteLenPerFrame = DEFAULT_FRAMELENGTH * (DEFAULT_SAMPLE_RATE / MILLISECOND) * DEFAULT_FORMAT;
100     algoAttr_ = {DEFAULT_FORMAT, deviceAttr_.micChannels, byteLenPerFrame};
101 
102     if (count(NEED_EC_SCENE.begin(), NEED_EC_SCENE.end(), sceneType_)) {
103         needEcFlag_ = true;
104         algoSupportedConfig_.ecNum = DEFAULT_ECON_CH;
105         algoAttr_.batchLen = deviceAttr_.micChannels + algoSupportedConfig_.ecNum;
106         enhanceBuf_.ecBuffer.resize(deviceAttr_.ecChannels * byteLenPerFrame);
107     }
108 
109     if (count(NEED_MICREF_SCENE.begin(), NEED_MICREF_SCENE.end(), sceneType_)) {
110         needMicRefFlag_ = true;
111         algoSupportedConfig_.micRefNum = DEFAULT_MICREFON_CH;
112         algoAttr_.batchLen += algoSupportedConfig_.micRefNum;
113         enhanceBuf_.micRefBuffer.resize(deviceAttr_.micRefChannels * byteLenPerFrame);
114     }
115 
116     enhanceBuf_.micBuffer.resize(deviceAttr_.micChannels * byteLenPerFrame);
117     outputCache_.resize(deviceAttr_.micChannels * byteLenPerFrame);
118     algoCache_.input.resize(algoAttr_.byteLenPerFrame * algoAttr_.batchLen);
119     algoCache_.output.resize(algoAttr_.byteLenPerFrame * deviceAttr_.micChannels);
120     AUDIO_INFO_LOG("micNum: %{public}u ecNum: %{public}u micRefNum: %{public}u outNum: %{public}u"
121         " byteLenPerFrame: %{public}u inputsize:%{public}zu outputsize:%{public}zu",
122         algoSupportedConfig_.micNum, algoSupportedConfig_.ecNum, algoSupportedConfig_.micRefNum,
123         algoSupportedConfig_.outNum, byteLenPerFrame, algoCache_.input.size(), algoCache_.output.size());
124 
125     traceTagIn_ = sceneType_ + "_IN";
126     traceTagOut_ = sceneType_ + "_OUT";
127     dfxStreamInfo_ = { static_cast<AudioSamplingRate>(DEFAULT_SAMPLE_RATE), AudioEncodingType::ENCODING_PCM,
128         ConvertFormat(DEFAULT_FORMAT), static_cast<AudioChannel>(deviceAttr_.micChannels) };
129     std::string dumpFileInName = "Enhance_" + sceneType_ + "_" + GetTime() + "_In_" +
130         std::to_string(algoSupportedConfig_.ecNum) + "Ec_" + std::to_string(algoSupportedConfig_.micNum) + "Mic_" +
131         std::to_string(algoSupportedConfig_.micRefNum) + "MicRef.pcm";
132     std::string dumpFileOutName = "Enhance_" + sceneType_ + "_" + GetTime() + "_Out.pcm";
133     DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_SERVER_PARA, dumpFileInName, &dumpFileIn_);
134     DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_SERVER_PARA, dumpFileOutName, &dumpFileOut_);
135 }
136 
~AudioEnhanceChain()137 AudioEnhanceChain::~AudioEnhanceChain()
138 {
139     threadHandler_ = nullptr;
140     ReleaseAllEnhanceModule();
141     DumpFileUtil::CloseDumpFile(&dumpFileIn_);
142     DumpFileUtil::CloseDumpFile(&dumpFileOut_);
143 }
144 
ReleaseAllEnhanceModule()145 void AudioEnhanceChain::ReleaseAllEnhanceModule()
146 {
147     for (auto &module : enhanceModules_) {
148         if (module.libHandle != nullptr) {
149             module.libHandle->releaseEffect(module.enhanceHandle);
150         }
151     }
152     enhanceModules_.clear();
153 }
154 
SetThreadHandler(const std::shared_ptr<ThreadHandler> & threadHandler)155 int32_t AudioEnhanceChain::SetThreadHandler(const std::shared_ptr<ThreadHandler> &threadHandler)
156 {
157     if (threadHandler == nullptr) {
158         AUDIO_ERR_LOG("threadHandler is null");
159         return ERROR;
160     }
161 
162     threadHandler_ = threadHandler;
163     return SUCCESS;
164 }
165 
ScheduleAudioTask(const ThreadHandler::Task & task)166 void AudioEnhanceChain::ScheduleAudioTask(const ThreadHandler::Task &task)
167 {
168     if (threadHandler_ != nullptr) {
169         threadHandler_->PostTask(task);
170     } else {
171         task();
172     }
173 }
174 
ProcessSetInputDevice(const std::string & inputDevice,const std::string & deviceName)175 int32_t AudioEnhanceChain::ProcessSetInputDevice(const std::string &inputDevice, const std::string &deviceName)
176 {
177     if (inputDevice == algoParam_.preDevice) {
178         AUDIO_INFO_LOG("the current device does not need to be updated");
179         return SUCCESS;
180     }
181     algoParam_.preDevice = inputDevice;
182     algoParam_.preDeviceName = deviceName;
183     AUDIO_INFO_LOG("update input device %{public}s name %{public}s", inputDevice.c_str(), deviceName.c_str());
184     AudioEffectTransInfo cmdInfo = {};
185     AudioEffectTransInfo replyInfo = {};
186     for (const auto &module : enhanceModules_) {
187         auto setParaCmdRet = SetEnhanceParamToHandle(module.enhanceHandle);
188         CHECK_AND_RETURN_RET_LOG(setParaCmdRet == SUCCESS, ERROR,
189             "[%{public}s] effect EFFECT_CMD_SET_PARAM fail", sceneType_.c_str());
190         auto initCmdRet = (*module.enhanceHandle)->command(module.enhanceHandle, EFFECT_CMD_INIT, &cmdInfo, &replyInfo);
191         CHECK_AND_RETURN_RET_LOG(initCmdRet == 0, ERROR,
192             "[%{public}s] effect EFFECT_CMD_INIT fail", sceneType_.c_str());
193     }
194 
195     return SUCCESS;
196 }
197 
SetInputDevice(const std::string & inputDevice,const std::string & deviceName)198 int32_t AudioEnhanceChain::SetInputDevice(const std::string &inputDevice, const std::string &deviceName)
199 {
200     if (inputDevice.size() == 0) {
201         return SUCCESS;
202     }
203 
204     auto task = [self = weak_from_this(), inputDevice, deviceName]() {
205         if (auto chain = self.lock(); chain != nullptr) {
206             chain->ProcessSetInputDevice(inputDevice, deviceName);
207         }
208     };
209 
210     ScheduleAudioTask(task);
211 
212     return SUCCESS;
213 }
214 
ProcessSetFoldState(uint32_t foldState)215 int32_t AudioEnhanceChain::ProcessSetFoldState(uint32_t foldState)
216 {
217     if (foldState == algoParam_.foldState) {
218         AUDIO_INFO_LOG("no need update fold state %{public}u", foldState);
219         return SUCCESS;
220     }
221     algoParam_.foldState = foldState;
222     AUDIO_INFO_LOG("update fold state %{public}u", foldState);
223 
224     AudioEffectTransInfo cmdInfo = {};
225     AudioEffectTransInfo replyInfo = {};
226     for (const auto &module : enhanceModules_) {
227         auto setParaCmdRet = SetEnhanceParamToHandle(module.enhanceHandle);
228         CHECK_AND_RETURN_RET_LOG(setParaCmdRet == SUCCESS, ERROR,
229             "[%{public}s] effect EFFECT_CMD_SET_PARAM fail", sceneType_.c_str());
230         auto initCmdRet = (*module.enhanceHandle)->command(module.enhanceHandle, EFFECT_CMD_INIT, &cmdInfo, &replyInfo);
231         CHECK_AND_RETURN_RET_LOG(initCmdRet == 0, ERROR,
232             "[%{public}s] effect EFFECT_CMD_INIT fail", sceneType_.c_str());
233     }
234 
235     return SUCCESS;
236 }
237 
SetFoldState(uint32_t foldState)238 int32_t AudioEnhanceChain::SetFoldState(uint32_t foldState)
239 {
240     auto task = [self = weak_from_this(), foldState]() {
241         if (auto chain = self.lock(); chain != nullptr) {
242             chain->ProcessSetFoldState(foldState);
243         }
244     };
245 
246     ScheduleAudioTask(task);
247 
248     return SUCCESS;
249 }
250 
ProcessSetEnhanceParam(bool mute,uint32_t systemVol)251 int32_t AudioEnhanceChain::ProcessSetEnhanceParam(bool mute, uint32_t systemVol)
252 {
253     algoParam_.muteInfo = mute;
254     algoParam_.volumeInfo = systemVol;
255 
256     AudioEffectTransInfo cmdInfo = {};
257     AudioEffectTransInfo replyInfo = {};
258     for (const auto &module : enhanceModules_) {
259         auto setParaCmdRet = SetEnhanceParamToHandle(module.enhanceHandle);
260         CHECK_AND_RETURN_RET_LOG(setParaCmdRet == SUCCESS, ERROR,
261             "[%{public}s] effect EFFECT_CMD_SET_PARAM fail", sceneType_.c_str());
262         auto initCmdRet = (*module.enhanceHandle)->command(module.enhanceHandle, EFFECT_CMD_INIT, &cmdInfo, &replyInfo);
263         CHECK_AND_RETURN_RET_LOG(initCmdRet == SUCCESS, ERROR,
264             "[%{public}s] effect EFFECT_CMD_INIT fail", sceneType_.c_str());
265     }
266 
267     return SUCCESS;
268 }
269 
SetEnhanceParam(bool mute,uint32_t systemVol)270 int32_t AudioEnhanceChain::SetEnhanceParam(bool mute, uint32_t systemVol)
271 {
272     auto task = [self = weak_from_this(), mute, systemVol]() {
273         if (auto chain = self.lock(); chain != nullptr) {
274             chain->ProcessSetEnhanceParam(mute, systemVol);
275         }
276     };
277 
278     ScheduleAudioTask(task);
279 
280     return SUCCESS;
281 }
282 
SetEnhanceParamToHandle(AudioEffectHandle handle)283 int32_t AudioEnhanceChain::SetEnhanceParamToHandle(AudioEffectHandle handle)
284 {
285     AudioEffectTransInfo cmdInfo = {};
286     AudioEffectTransInfo replyInfo = {};
287     AudioEnhanceParam setParam = {algoParam_.muteInfo, algoParam_.volumeInfo, algoParam_.foldState,
288         algoParam_.preDevice.c_str(), algoParam_.postDevice.c_str(), algoParam_.sceneType.c_str(),
289         algoParam_.preDeviceName.c_str()};
290     cmdInfo.data = static_cast<void *>(&setParam);
291     cmdInfo.size = sizeof(setParam);
292     return (*handle)->command(handle, EFFECT_CMD_SET_PARAM, &cmdInfo, &replyInfo);
293 }
294 
InitSingleEnhanceModule(AudioEffectHandle enhanceHandle,const std::string & enhanceProp)295 int32_t AudioEnhanceChain::InitSingleEnhanceModule(AudioEffectHandle enhanceHandle, const std::string &enhanceProp)
296 {
297     int32_t ret = ERROR;
298     AudioEffectTransInfo cmdInfo = {};
299     AudioEffectTransInfo replyInfo = {};
300 
301     uint32_t maxSampleRate = DEFAULT_SAMPLE_RATE;
302     replyInfo.data = &maxSampleRate;
303     replyInfo.size = sizeof(maxSampleRate);
304     ret = (*enhanceHandle)->command(enhanceHandle, EFFECT_CMD_GET_CONFIG, &cmdInfo, &replyInfo);
305     if (ret != SUCCESS) {
306         AUDIO_ERR_LOG("get algo maxSampleRate failed!");
307     }
308     if (algoSupportedConfig_.sampleRate != maxSampleRate) {
309         algoSupportedConfig_.sampleRate = maxSampleRate;
310         uint32_t byteLenPerFrame = DEFAULT_FRAMELENGTH * (maxSampleRate / MILLISECOND) *
311             DEFAULT_FORMAT;
312         algoAttr_.byteLenPerFrame = byteLenPerFrame;
313 
314         algoCache_.input.resize(algoAttr_.byteLenPerFrame * algoAttr_.batchLen);
315         algoCache_.output.resize(algoAttr_.byteLenPerFrame * deviceAttr_.micChannels);
316         AUDIO_INFO_LOG("algorate: %{public}u byteLenPerFrame: %{public}u inputsize:%{public}zu outputsize:%{public}zu",
317             maxSampleRate, byteLenPerFrame, algoCache_.input.size(), algoCache_.output.size());
318     }
319 
320     cmdInfo.data = static_cast<void *>(&algoSupportedConfig_);
321     cmdInfo.size = sizeof(algoSupportedConfig_);
322 
323     ret = (*enhanceHandle)->command(enhanceHandle, EFFECT_CMD_SET_CONFIG, &cmdInfo, &replyInfo);
324     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "[%{public}s], either one of libs EFFECT_CMD_SET_CONFIG fail",
325         sceneType_.c_str());
326 
327     CHECK_AND_RETURN_RET_LOG(SetEnhanceParamToHandle(enhanceHandle) == SUCCESS, ERROR,
328         "[%{public}s] EFFECT_CMD_SET_PARAM fail", sceneType_.c_str());
329 
330     CHECK_AND_RETURN_RET_LOG(SetPropertyToHandle(enhanceHandle, enhanceProp) == SUCCESS, ERROR,
331         "[%{public}s] EFFECT_CMD_SET_PROPERTY fail", sceneType_.c_str());
332 
333     ret = (*enhanceHandle)->command(enhanceHandle, EFFECT_CMD_INIT, &cmdInfo, &replyInfo);
334     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "[%{public}s], either one of libs EFFECT_CMD_INIT fail",
335         sceneType_.c_str());
336 
337     return SUCCESS;
338 }
339 
ProcessCreateAllEnhanceModule(const std::vector<EnhanceModulePara> & moduleParas)340 int32_t AudioEnhanceChain::ProcessCreateAllEnhanceModule(const std::vector<EnhanceModulePara> &moduleParas)
341 {
342     for (const auto &para : moduleParas) {
343         AudioEffectDescriptor descriptor = { para.libName, para.enhanceName };
344         AUDIO_INFO_LOG("libName: %{public}s enhanceName:%{public}s", para.libName.c_str(), para.enhanceName.c_str());
345         AudioEffectHandle enhanceHandle = nullptr;
346         int32_t ret = para.libHandle->createEffect(descriptor, &enhanceHandle);
347         CHECK_AND_RETURN_RET_LOG(ret == 0, ERROR, "create effect: %{public}s fail", para.enhanceName.c_str());
348         CHECK_AND_RETURN_RET_LOG(enhanceHandle != nullptr, ERROR, "enhanceHandle is null");
349 
350         int32_t initSingleModuleRet = InitSingleEnhanceModule(enhanceHandle, para.enhanceProp);
351         if (initSingleModuleRet != SUCCESS) {
352             AUDIO_ERR_LOG("init enhance: %{public}s fail", para.enhanceName.c_str());
353             para.libHandle->releaseEffect(enhanceHandle);
354             return ERROR;
355         }
356 
357         EnhanceModule module = { para.enhanceName, enhanceHandle, para.libHandle };
358         enhanceModules_.emplace_back(module);
359     }
360 
361     {
362         std::lock_guard<std::mutex> lock(chainMutex_);
363         chainIsReady_ = true;
364     }
365 
366     return SUCCESS;
367 }
368 
CreateAllEnhanceModule(const std::vector<EnhanceModulePara> & moduleParas)369 int32_t AudioEnhanceChain::CreateAllEnhanceModule(const std::vector<EnhanceModulePara> &moduleParas)
370 {
371     for (const auto &para : moduleParas) {
372         if (para.libHandle == nullptr || para.libHandle->createEffect == nullptr ||
373             para.libHandle->releaseEffect == nullptr) {
374             AUDIO_ERR_LOG("enhance: %{public}s interface is null", para.enhanceName.c_str());
375             return ERROR;
376         }
377     }
378 
379     auto task = [self = weak_from_this(), moduleParas]() {
380         if (auto chain = self.lock(); chain != nullptr) {
381             chain->ProcessCreateAllEnhanceModule(moduleParas);
382         }
383     };
384 
385     ScheduleAudioTask(task);
386 
387     return SUCCESS;
388 }
389 
IsEmptyEnhanceHandles()390 bool AudioEnhanceChain::IsEmptyEnhanceHandles()
391 {
392     return enhanceModules_.empty();
393 }
394 
GetAlgoConfig(AudioBufferConfig & micConfig,AudioBufferConfig & ecConfig,AudioBufferConfig & micRefConfig)395 void AudioEnhanceChain::GetAlgoConfig(AudioBufferConfig &micConfig, AudioBufferConfig &ecConfig,
396     AudioBufferConfig &micRefConfig)
397 {
398     uint8_t configDataformat = static_cast<uint8_t>(algoSupportedConfig_.dataFormat);
399     micConfig.samplingRate = algoSupportedConfig_.sampleRate;
400     micConfig.channels = algoSupportedConfig_.micNum;
401     micConfig.format = configDataformat;
402 
403     if (needEcFlag_) {
404         ecConfig.samplingRate = algoSupportedConfig_.sampleRate;
405         ecConfig.channels = algoSupportedConfig_.ecNum;
406         ecConfig.format = configDataformat;
407     }
408     if (needMicRefFlag_) {
409         micRefConfig.samplingRate = algoSupportedConfig_.sampleRate;
410         micRefConfig.channels = algoSupportedConfig_.micRefNum;
411         micRefConfig.format = configDataformat;
412     }
413     return;
414 }
415 
GetChainId(void) const416 uint64_t AudioEnhanceChain::GetChainId(void) const
417 {
418     return chainId_;
419 }
420 
GetScenePriority(void) const421 ScenePriority AudioEnhanceChain::GetScenePriority(void) const
422 {
423     return scenePriority_;
424 }
425 
DeinterleaverData(uint8_t * src,uint32_t channel,uint8_t * dst,uint32_t dstLen)426 int32_t AudioEnhanceChain::DeinterleaverData(uint8_t *src, uint32_t channel, uint8_t *dst, uint32_t dstLen)
427 {
428     uint32_t srcIdx = 0;
429     uint32_t frameCount = algoAttr_.byteLenPerFrame / algoAttr_.bitDepth;
430     for (uint32_t i = 0; i < frameCount; ++i) {
431         for (uint32_t j = 0; j < channel; ++j) {
432             uint32_t dstIdx = j * algoAttr_.byteLenPerFrame + i * algoAttr_.bitDepth;
433             auto memcpyRet = memcpy_s(dst + dstIdx, dstLen - srcIdx, &src[srcIdx], algoAttr_.bitDepth);
434             CHECK_AND_RETURN_RET_LOG(memcpyRet == EOK, ERROR, "memcpy in deinterleaver error");
435             srcIdx += algoAttr_.bitDepth;
436         }
437     }
438     return SUCCESS;
439 }
440 
ProcessSetEnhanceProperty(const std::string & enhance,const std::string & property)441 int32_t AudioEnhanceChain::ProcessSetEnhanceProperty(const std::string &enhance, const std::string &property)
442 {
443     AudioEffectTransInfo cmdInfo = {};
444     AudioEffectTransInfo replyInfo = {};
445     for (const auto &module : enhanceModules_) {
446         if (module.enhanceName != enhance) {
447             continue;
448         }
449         auto setPropCmdRet = SetPropertyToHandle(module.enhanceHandle, property);
450         CHECK_AND_RETURN_RET_LOG(setPropCmdRet == SUCCESS, ERROR,
451             "[%{public}s] %{public}s effect EFFECT_CMD_SET_PROPERTY fail", sceneType_.c_str(), enhance.c_str());
452         auto initCmdRet = (*module.enhanceHandle)->command(module.enhanceHandle, EFFECT_CMD_INIT, &cmdInfo, &replyInfo);
453         CHECK_AND_RETURN_RET_LOG(initCmdRet == SUCCESS, ERROR,
454             "[%{public}s] %{public}s effect EFFECT_CMD_INIT fail", sceneType_.c_str(), enhance.c_str());
455     }
456 
457     return SUCCESS;
458 }
459 
SetEnhanceProperty(const std::string & enhance,const std::string & property)460 int32_t AudioEnhanceChain::SetEnhanceProperty(const std::string &enhance, const std::string &property)
461 {
462     auto task = [self = weak_from_this(), enhance, property]() {
463         if (auto chain = self.lock(); chain != nullptr) {
464             chain->ProcessSetEnhanceProperty(enhance, property);
465         }
466     };
467 
468     ScheduleAudioTask(task);
469 
470     return SUCCESS;
471 }
472 
SetPropertyToHandle(AudioEffectHandle handle,const std::string & property)473 int32_t AudioEnhanceChain::SetPropertyToHandle(AudioEffectHandle handle, const std::string &property)
474 {
475     int32_t replyData = 0;
476     const char *propCstr = property.c_str();
477     AudioEffectTransInfo cmdInfo = {sizeof(const char *), reinterpret_cast<void*>(&propCstr)};
478     AudioEffectTransInfo replyInfo = {sizeof(int32_t), &replyData};
479     return (*handle)->command(handle, EFFECT_CMD_SET_PROPERTY, &cmdInfo, &replyInfo);
480 }
481 
CacheChainInputData(const EnhanceTransBuffer & transBuf)482 int32_t AudioEnhanceChain::CacheChainInputData(const EnhanceTransBuffer &transBuf)
483 {
484     if (transBuf.ecData != nullptr && transBuf.ecDataLen == enhanceBuf_.ecBuffer.size()) {
485         auto memcpyEcRet = memcpy_s(enhanceBuf_.ecBuffer.data(), enhanceBuf_.ecBuffer.size(),
486             transBuf.ecData, transBuf.ecDataLen);
487         CHECK_AND_RETURN_RET_LOG(memcpyEcRet == EOK, ERROR, "cache ec data fail");
488     }
489 
490     if (transBuf.micData != nullptr && transBuf.micDataLen == enhanceBuf_.micBuffer.size()) {
491         auto memcpyMicRet = memcpy_s(enhanceBuf_.micBuffer.data(), enhanceBuf_.micBuffer.size(),
492             transBuf.micData, transBuf.micDataLen);
493         CHECK_AND_RETURN_RET_LOG(memcpyMicRet == EOK, ERROR, "cache mic data fail");
494     }
495 
496     if (transBuf.micRefData != nullptr && transBuf.micRefDataLen == enhanceBuf_.micRefBuffer.size()) {
497         auto memcpyMIcRefRet = memcpy_s(enhanceBuf_.micRefBuffer.data(), enhanceBuf_.micRefBuffer.size(),
498             transBuf.micRefData, transBuf.micRefDataLen);
499         CHECK_AND_RETURN_RET_LOG(memcpyMIcRefRet == EOK, ERROR, "cache micRef data fail");
500     }
501 
502     hasTask_ = true;
503 
504     return SUCCESS;
505 }
506 
GetOutputDataFromChain(void * buf,size_t bufSize)507 int32_t AudioEnhanceChain::GetOutputDataFromChain(void *buf, size_t bufSize)
508 {
509     CHECK_AND_RETURN_RET_LOG(buf != nullptr, ERROR, "buf is null");
510     CHECK_AND_RETURN_RET_LOG(bufSize != 0, ERROR, "bufSize is 0");
511 
512     std::lock_guard<std::mutex> lock(chainMutex_);
513     auto memcpyRet = memcpy_s(buf, bufSize, outputCache_.data(), outputCache_.size());
514     CHECK_AND_RETURN_RET_LOG(memcpyRet == EOK, ERROR, "memcpy chain out data fail");
515 
516     return SUCCESS;
517 }
518 
WriteChainOutputData(void * buf,size_t bufSize)519 int32_t AudioEnhanceChain::WriteChainOutputData(void *buf, size_t bufSize)
520 {
521     CHECK_AND_RETURN_RET_LOG(buf != nullptr, ERROR, "buf is null");
522     CHECK_AND_RETURN_RET_LOG(bufSize != 0, ERROR, "bufSize is 0");
523 
524     auto memcpyRet = memcpy_s(outputCache_.data(), outputCache_.size(), buf, bufSize);
525     CHECK_AND_RETURN_RET_LOG(memcpyRet == EOK, ERROR, "write chain out data fail");
526 
527     return SUCCESS;
528 }
529 
PrepareChainInputData(void)530 int32_t AudioEnhanceChain::PrepareChainInputData(void)
531 {
532     int32_t ret = 0;
533     uint32_t ecIdx = 0;
534     uint32_t micIdx = algoAttr_.byteLenPerFrame * algoSupportedConfig_.ecNum;
535     uint32_t micRefIdx = micIdx + algoAttr_.byteLenPerFrame * algoSupportedConfig_.micNum;
536     auto enhanceBufLen = enhanceBuf_.ecBuffer.size() + enhanceBuf_.micBuffer.size() + enhanceBuf_.micRefBuffer.size();
537     CHECK_AND_RETURN_RET_LOG(enhanceBufLen <= algoCache_.input.size(), ERROR, "input cache insufficient");
538 
539     if (enhanceBuf_.ecBuffer.size() != 0) {
540         ret = DeinterleaverData(enhanceBuf_.ecBuffer.data(), deviceAttr_.ecChannels,
541             &algoCache_.input[ecIdx], enhanceBuf_.ecBuffer.size());
542         CHECK_AND_RETURN_RET_LOG(ret == 0, ERROR, "deinterleaver ec data fail");
543     }
544 
545     if (enhanceBuf_.micBuffer.size() != 0) {
546         BufferDesc bufferIn = { enhanceBuf_.micBuffer.data(), enhanceBuf_.micBuffer.size(),
547             enhanceBuf_.micBuffer.size() };
548         VolumeTools::DfxOperation(bufferIn, dfxStreamInfo_, traceTagIn_, volumeDataCountIn_);
549         ret = DeinterleaverData(enhanceBuf_.micBuffer.data(), deviceAttr_.micChannels,
550             &algoCache_.input[micIdx], enhanceBuf_.micBuffer.size());
551         CHECK_AND_RETURN_RET_LOG(ret == 0, ERROR, "deinterleaver mic data fail");
552     }
553 
554     if (enhanceBuf_.micRefBuffer.size() != 0) {
555         ret = DeinterleaverData(enhanceBuf_.micRefBuffer.data(), deviceAttr_.micRefChannels,
556             &algoCache_.input[micRefIdx], enhanceBuf_.micRefBuffer.size());
557         CHECK_AND_RETURN_RET_LOG(ret == 0, ERROR, "deinterleaver micRef data fail");
558     }
559 
560     return SUCCESS;
561 }
562 
ProcessApplyEnhanceChain(void)563 int32_t AudioEnhanceChain::ProcessApplyEnhanceChain(void)
564 {
565     Trace trace("ProcessCapData");
566 
567     {
568         std::lock_guard<std::mutex> lock(chainMutex_);
569         CHECK_AND_RETURN_RET(hasTask_ == true, ERROR);
570         if (PrepareChainInputData() != SUCCESS || enhanceModules_.empty()) {
571             WriteChainOutputData(enhanceBuf_.micBuffer.data(), enhanceBuf_.micBuffer.size());
572             return SUCCESS;
573         }
574         hasTask_ = false;
575     }
576 
577     AudioBuffer audioBufIn = { .frameLength = algoCache_.input.size(), .raw = algoCache_.input.data() };
578     AudioBuffer audioBufOut = { .frameLength = algoCache_.output.size(), .raw = algoCache_.output.data() };
579     DumpFileUtil::WriteDumpFile(dumpFileIn_, algoCache_.input.data(), algoCache_.input.size());
580 
581     for (const auto &module : enhanceModules_) {
582         int32_t ret = (*module.enhanceHandle)->process(module.enhanceHandle, &audioBufIn, &audioBufOut);
583         CHECK_AND_CONTINUE_LOG(ret == 0, "module: [%{public}s] process fail", module.enhanceName.c_str());
584     }
585 
586     DumpFileUtil::WriteDumpFile(dumpFileOut_, algoCache_.output.data(), algoCache_.output.size());
587     BufferDesc bufferOut = { algoCache_.output.data(), algoCache_.output.size(), algoCache_.output.size() };
588     VolumeTools::DfxOperation(bufferOut, dfxStreamInfo_, traceTagOut_, volumeDataCountOut_);
589 
590     {
591         std::lock_guard<std::mutex> lock(chainMutex_);
592         WriteChainOutputData(audioBufOut.raw, audioBufOut.frameLength);
593     }
594 
595     return SUCCESS;
596 }
597 
ApplyEnhanceChain(const EnhanceTransBuffer & transBuf)598 int32_t AudioEnhanceChain::ApplyEnhanceChain(const EnhanceTransBuffer &transBuf)
599 {
600     {
601         std::lock_guard<std::mutex> lock(chainMutex_);
602         if (chainIsReady_) {
603             auto cacheChainInputDataRet = CacheChainInputData(transBuf);
604             CHECK_AND_RETURN_RET_LOG(cacheChainInputDataRet == SUCCESS, ERROR, "cache chain input data fail");
605         } else {
606             AUDIO_INFO_LOG("chain is not ready, passthrough data");
607             WriteChainOutputData(transBuf.micData, transBuf.micDataLen);
608             return SUCCESS;
609         }
610     }
611 
612     auto task = [self = weak_from_this()]() {
613         if (auto chain = self.lock(); chain != nullptr) {
614             chain->ProcessApplyEnhanceChain();
615         }
616     };
617 
618     ScheduleAudioTask(task);
619 
620     return SUCCESS;
621 }
622 
ProcessInitCommand(void)623 int32_t AudioEnhanceChain::ProcessInitCommand(void)
624 {
625     AudioEffectTransInfo cmdInfo = {};
626     AudioEffectTransInfo replyInfo = {};
627     for (const auto &module : enhanceModules_) {
628         auto initCmdRet = (*module.enhanceHandle)->command(module.enhanceHandle, EFFECT_CMD_INIT, &cmdInfo, &replyInfo);
629         CHECK_AND_RETURN_RET_LOG(initCmdRet == SUCCESS, ERROR,
630             "[%{public}s] effect EFFECT_CMD_INIT fail", sceneType_.c_str());
631     }
632 
633     return SUCCESS;
634 }
635 
InitCommand()636 int32_t AudioEnhanceChain::InitCommand()
637 {
638     auto task = [self = weak_from_this()]() {
639         if (auto chain = self.lock(); chain != nullptr) {
640             chain->ProcessInitCommand();
641         }
642     };
643 
644     ScheduleAudioTask(task);
645 
646     return SUCCESS;
647 }
648 } // namespace AudioStandard
649 } // namespace OHOS