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