• 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 #undef LOG_TAG
17 #define LOG_TAG "AudioEnhanceChainManagerImpl"
18 
19 #include "audio_enhance_chain_manager_impl.h"
20 
21 #include <algorithm>
22 #include <charconv>
23 #include <system_error>
24 
25 #include "securec.h"
26 #include "system_ability_definition.h"
27 
28 #include "audio_effect_log.h"
29 #include "audio_errors.h"
30 #include "audio_effect.h"
31 #include "audio_enhance_chain.h"
32 #include "audio_setting_provider.h"
33 #include "audio_device_type.h"
34 #include "audio_effect_map.h"
35 #include "audio_utils.h"
36 #include "chain_pool.h"
37 
38 namespace OHOS {
39 namespace AudioStandard {
40 namespace {
41 constexpr uint32_t SCENE_TYPE_OFFSET = 32;
42 constexpr uint32_t CAPTURER_ID_OFFSET = 16;
43 constexpr uint64_t SCENE_TYPE_MASK = 0xFF00000000;
44 constexpr uint64_t CAPTURER_ID_MASK = 0x0000FFFF0000;
45 constexpr uint32_t VOLUME_FACTOR = 100;
46 const std::vector<AudioEnhanceScene> AUDIO_WITH_DEVICE_ENHANCES = { SCENE_VOIP_UP };
47 const std::string MAINKEY_DEVICE_STATUS = "device_status";
48 const std::string SUBKEY_FOLD_STATE = "fold_state";
49 
50 const std::map<AudioEnhanceScene, uint32_t> SCENE_THREAD_ID_MAP = {
51     { SCENE_VOIP_UP, 1 },
52     { SCENE_RECORD, 2 },
53     { SCENE_PRE_ENHANCE, 3 },
54     { SCENE_ASR, 4 },
55     { SCENE_VOICE_MESSAGE, 4 },
56     { SCENE_NONE, 4 },
57 };
58 
GetThreadIdByScene(AudioEnhanceScene scene)59 uint32_t GetThreadIdByScene(AudioEnhanceScene scene)
60 {
61     auto iter = SCENE_THREAD_ID_MAP.find(scene);
62     if (iter != SCENE_THREAD_ID_MAP.end()) {
63         return iter->second;
64     }
65 
66     return SCENE_THREAD_ID_MAP.at(SCENE_NONE);
67 }
68 
FindEnhanceLib(const std::string & enhanceName,const std::vector<std::shared_ptr<AudioEffectLibEntry>> & libList)69 std::shared_ptr<AudioEffectLibEntry> FindEnhanceLib(const std::string &enhanceName,
70     const std::vector<std::shared_ptr<AudioEffectLibEntry>> &libList)
71 {
72     for (const auto &lib : libList) {
73         if (lib == nullptr) {
74             continue;
75         }
76         auto iter = std::find(lib->effectName.begin(), lib->effectName.end(), enhanceName);
77         if (iter != lib->effectName.end()) {
78             return lib;
79         }
80     }
81 
82     return nullptr;
83 }
84 } // namespace
85 
ResetInfo()86 void AudioEnhanceChainManagerImpl::ResetInfo()
87 {
88     enhanceConfigInfoMap_.clear();
89     chainConfigInfoMap_.clear();
90     enhancePropertyMap_.clear();
91     captureIdToDeviceMap_.clear();
92     threadHandlerMap_.clear();
93     maxNormalInstanceNum_ = 0;
94     defaultScene_ = "";
95     priorSceneSet_.clear();
96     enhancePara_ = {};
97 }
98 
SetRelateWithDevicePropForEnhance()99 void AudioEnhanceChainManagerImpl::SetRelateWithDevicePropForEnhance()
100 {
101     const auto &audioEnhanceSupportedSceneTypes = GetEnhanceSupportedSceneType();
102     for (const auto& sceneType : AUDIO_WITH_DEVICE_ENHANCES) {
103         std::string scene = audioEnhanceSupportedSceneTypes.find(sceneType)->second;
104         std::string sceneAndMode = scene + "_&_" + "ENHANCE_DEFAULT";
105         auto iter = chainConfigInfoMap_.find(sceneAndMode);
106         CHECK_AND_CONTINUE_LOG(iter != chainConfigInfoMap_.end(),
107             "no such sceneAndMode %{public}s", sceneAndMode.c_str());
108         for (const auto &enhanceName : iter->second.enhanceNames) {
109             auto propIter = enhancePropertyMap_.find(enhanceName);
110             if (propIter == enhancePropertyMap_.end()) {
111                 continue;
112             }
113             auto enhanceIter = enhanceConfigInfoMap_.find(enhanceName);
114             if (enhanceIter != enhanceConfigInfoMap_.end()) {
115                 enhanceIter->second.relateWithDevice = true;
116             }
117         }
118     }
119 }
120 
UpdateEnhancePropertyMapFromDb(DeviceType deviceType)121 void AudioEnhanceChainManagerImpl::UpdateEnhancePropertyMapFromDb(DeviceType deviceType)
122 {
123     std::string deviceTypeName = "";
124     GetDeviceTypeName(deviceType, deviceTypeName);
125     CHECK_AND_RETURN_LOG(deviceTypeName != "", "get deviceTypeName fail");
126     AudioSettingProvider &settingProvider = AudioSettingProvider::GetInstance(AUDIO_POLICY_SERVICE_ID);
127     CHECK_AND_RETURN_LOG(settingProvider.CheckOsAccountReady(), "os account not ready");
128     for (auto &[enhance, prop] : enhancePropertyMap_) {
129         std::string property = "";
130         std::string key = enhance;
131         auto iter = enhanceConfigInfoMap_.find(enhance);
132         if (iter != enhanceConfigInfoMap_.end() && iter->second.relateWithDevice) {
133             key = enhance + "_&_" + deviceTypeName;
134         }
135         ErrCode ret = settingProvider.GetStringValue(key, property, "system");
136         if (ret == SUCCESS) {
137             prop = property;
138             AUDIO_INFO_LOG("Get Effect_&_DeviceType:%{public}s is Property:%{public}s", key.c_str(), property.c_str());
139         } else {
140             std::string defaultProp = "";
141             if (iter != enhanceConfigInfoMap_.end()) {
142                 defaultProp = iter->second.defaultProp;
143             }
144             ret = settingProvider.PutStringValue(key, defaultProp, "system");
145             if (ret != SUCCESS) {
146                 AUDIO_ERR_LOG("set default Property:%{public}s failed, ErrCode: %{public}d", defaultProp.c_str(), ret);
147                 return;
148             }
149             prop = defaultProp;
150             AUDIO_INFO_LOG("Get prop failed,Effect_&_DeviceType:%{public}s is set to default Property:%{public}s",
151                 key.c_str(), prop.c_str());
152         }
153     }
154 }
155 
InitAudioEnhanceChainManager(const std::vector<EffectChain> & enhanceChains,const EffectChainManagerParam & managerParam,const std::vector<std::shared_ptr<AudioEffectLibEntry>> & libList)156 void AudioEnhanceChainManagerImpl::InitAudioEnhanceChainManager(const std::vector<EffectChain> &enhanceChains,
157     const EffectChainManagerParam &managerParam, const std::vector<std::shared_ptr<AudioEffectLibEntry>> &libList)
158 {
159     std::set<std::string> enhanceNameSet;
160     for (const auto &it : managerParam.sceneTypeToChainNameMap) {
161         EnhanceChainConfigInfo info = {};
162         info.chainName = it.second;
163         for (const auto &chain : enhanceChains) {
164             if (chain.name == info.chainName) {
165                 info.chainLabel = chain.label;
166                 info.enhanceNames = chain.apply;
167                 break;
168             }
169         }
170         chainConfigInfoMap_.emplace(it.first, info);
171         for (const auto &enhanceName : info.enhanceNames) {
172             enhanceNameSet.emplace(enhanceName);
173         }
174     }
175 
176     for (const auto &enhanceName : enhanceNameSet) {
177         EnhanceConfigInfo info = {};
178         info.enhanceLib = FindEnhanceLib(enhanceName, libList);
179         if (info.enhanceLib == nullptr) {
180             continue;
181         }
182         auto iter = managerParam.effectDefaultProperty.find(enhanceName);
183         if (iter != managerParam.effectDefaultProperty.end()) {
184             info.defaultProp = iter->second;
185         }
186         info.relateWithDevice = false;
187         enhanceConfigInfoMap_.emplace(enhanceName, info);
188     }
189 
190     priorSceneSet_.insert(managerParam.priorSceneList.begin(), managerParam.priorSceneList.end());
191     enhancePropertyMap_.insert(managerParam.effectDefaultProperty.begin(), managerParam.effectDefaultProperty.end());
192     defaultScene_ = managerParam.defaultSceneName;
193     maxNormalInstanceNum_ = managerParam.maxExtraNum;
194     SetRelateWithDevicePropForEnhance();
195 }
196 
ParseSceneKeyCode(uint64_t sceneKeyCode,std::string & sceneType,std::string & capturerDeviceStr,std::string & rendererDeviceStr)197 int32_t AudioEnhanceChainManagerImpl::ParseSceneKeyCode(uint64_t sceneKeyCode, std::string &sceneType,
198     std::string &capturerDeviceStr, std::string &rendererDeviceStr)
199 {
200     uint32_t sceneCode = (sceneKeyCode & SCENE_TYPE_MASK) >> SCENE_TYPE_OFFSET;
201     AUDIO_INFO_LOG("sceneKeyCode = %{public}" PRIu64 ", sceneCode = %{public}u", sceneKeyCode, sceneCode);
202     AudioEnhanceScene scene = static_cast<AudioEnhanceScene>(sceneCode);
203     DeviceType capturerDevice = DEVICE_TYPE_INVALID;
204     const std::unordered_map<DeviceType, std::string> &supportDeviceType = GetSupportedDeviceType();
205     const auto &audioEnhanceSupportedSceneTypes = GetEnhanceSupportedSceneType();
206     auto item = audioEnhanceSupportedSceneTypes.find(scene);
207     if (item != audioEnhanceSupportedSceneTypes.end()) {
208         sceneType = item->second;
209     } else {
210         AUDIO_ERR_LOG("scene[%{public}d] not be supported", scene);
211         return ERROR;
212     }
213     uint32_t captureId = (sceneKeyCode & CAPTURER_ID_MASK) >> CAPTURER_ID_OFFSET;
214     auto capItem = captureIdToDeviceMap_.find(captureId);
215     if (capItem != captureIdToDeviceMap_.end()) {
216         capturerDevice = capItem->second;
217     } else {
218         AUDIO_ERR_LOG("can't find captureId[%{public}u] in captureIdToDeviceMap_", captureId);
219         return ERROR;
220     }
221 
222     DeviceType rendererDevice = DEVICE_TYPE_NONE;
223 
224     auto deviceItem = supportDeviceType.find(capturerDevice);
225     if (deviceItem != supportDeviceType.end()) {
226         if ((capturerDevice == DEVICE_TYPE_INVALID) || (capturerDevice == DEVICE_TYPE_NONE)) {
227             capturerDeviceStr = "DEVICE_TYPE_MIC";
228             AUDIO_ERR_LOG("capturerDevice not availd");
229         } else {
230             capturerDeviceStr = deviceItem->second;
231         }
232     } else {
233         AUDIO_ERR_LOG("capturerDevice[%{public}d] not in supportDeviceType", capturerDevice);
234         return ERROR;
235     }
236     deviceItem = supportDeviceType.find(rendererDevice);
237     if (deviceItem != supportDeviceType.end()) {
238         rendererDeviceStr = deviceItem->second;
239     } else {
240         AUDIO_ERR_LOG("rendererDevice[%{public}d] not in supportDeviceType", rendererDevice);
241         return ERROR;
242     }
243     return SUCCESS;
244 }
245 
GetThreadHandlerByScene(AudioEnhanceScene scene)246 std::shared_ptr<ThreadHandler> AudioEnhanceChainManagerImpl::GetThreadHandlerByScene(AudioEnhanceScene scene)
247 {
248     auto threadId = GetThreadIdByScene(scene);
249     auto iter = threadHandlerMap_.find(threadId);
250     if (iter != threadHandlerMap_.end()) {
251         ++iter->second.second;
252         return iter->second.first;
253     }
254 
255     std::string threadName = "OS_ProCap" + std::to_string(scene);
256     Trace trace("CreateThread: " + std::to_string(scene));
257     auto threadHandler = ThreadHandler::NewInstance(threadName);
258     if (threadHandler == nullptr) {
259         AUDIO_ERR_LOG("create thread handler fail");
260         return nullptr;
261     }
262     uint32_t useCount = 0;
263     threadHandlerMap_.emplace(threadId, std::make_pair(threadHandler, ++useCount));
264 
265     return threadHandler;
266 }
267 
ReleaseThreadHandlerByScene(AudioEnhanceScene scene)268 void AudioEnhanceChainManagerImpl::ReleaseThreadHandlerByScene(AudioEnhanceScene scene)
269 {
270     auto threadId = GetThreadIdByScene(scene);
271     auto iter = threadHandlerMap_.find(threadId);
272     if (iter != threadHandlerMap_.end() && --iter->second.second > 0) {
273         AUDIO_INFO_LOG("threadId: %{public}u useCount: %{public}u", threadId, iter->second.second);
274     } else {
275         Trace trace("DeleteThread: " + std::to_string(scene));
276         threadHandlerMap_.erase(threadId);
277     }
278 }
279 
CreateAudioEnhanceChainDynamic(uint64_t sceneKeyCode,const AudioEnhanceDeviceAttr & deviceAttr)280 int32_t AudioEnhanceChainManagerImpl::CreateAudioEnhanceChainDynamic(uint64_t sceneKeyCode,
281     const AudioEnhanceDeviceAttr &deviceAttr)
282 {
283     CHECK_AND_RETURN_RET_LOG(chainConfigInfoMap_.size() != 0, ERROR, "no enhance chain config info");
284 
285     std::lock_guard<std::mutex> lock(chainManagerMutex_);
286     auto chain = ChainPool::GetInstance().GetChainById(sceneKeyCode);
287     if (chain != nullptr) {
288         AUDIO_INFO_LOG("chain: %{public}" PRIu64 " is exist", sceneKeyCode);
289         return SUCCESS;
290     }
291 
292     auto newChain = CreateEnhanceChainInner(sceneKeyCode, deviceAttr);
293     CHECK_AND_RETURN_RET_LOG(newChain != nullptr, ERROR, "CreateEnhanceChainInner fail");
294 
295     bool defaultFlag = (newChain->GetScenePriority() == DEFAULT_SCENE);
296     auto enhanceNames = GetEnhanceNamesBySceneCode(sceneKeyCode, defaultFlag);
297     CHECK_AND_RETURN_RET_LOG(enhanceNames.size() != 0, ERROR, "enhanceNames is empty");
298 
299     auto scene = static_cast<AudioEnhanceScene>((sceneKeyCode & SCENE_TYPE_MASK) >> SCENE_TYPE_OFFSET);
300     auto handler = GetThreadHandlerByScene(scene);
301     CHECK_AND_RETURN_RET_LOG(handler != nullptr, ERROR, "handler is null");
302     newChain->SetThreadHandler(handler);
303 
304     if (AddAudioEnhanceChainHandles(newChain, enhanceNames) != SUCCESS) {
305         AUDIO_ERR_LOG("chain: %{public}" PRIu64 " create failed", sceneKeyCode);
306         ReleaseThreadHandlerByScene(scene);
307         return ERROR;
308     }
309 
310     ChainPool::GetInstance().AddChain(newChain);
311     AUDIO_INFO_LOG("chain: %{public}" PRIu64 " create success", sceneKeyCode);
312 
313     return SUCCESS;
314 }
315 
GetEnhanceNamesBySceneCode(uint64_t sceneKeyCode,bool defaultFlag)316 std::vector<std::string> AudioEnhanceChainManagerImpl::GetEnhanceNamesBySceneCode(uint64_t sceneKeyCode,
317     bool defaultFlag)
318 {
319     std::string sceneType = "";
320     std::string capturerDevice = "";
321     std::string rendererDeivce = "";
322     auto parseSceneKeyCodeRet = ParseSceneKeyCode(sceneKeyCode, sceneType, capturerDevice, rendererDeivce);
323     CHECK_AND_RETURN_RET_LOG(parseSceneKeyCodeRet == SUCCESS, {}, "ParseSceneKeyCode fail");
324 
325     if (defaultFlag) {
326         AUDIO_INFO_LOG("sceneType %{public}s set to defaultScene %{public}s", sceneType.c_str(), defaultScene_.c_str());
327         sceneType = defaultScene_;
328     }
329     // first check specific device, then check no device
330     std::string enhanceChainKey = sceneType + "_&_" + "ENHANCE_DEFAULT" + "_&_" + capturerDevice;
331     auto mapIter = chainConfigInfoMap_.find(enhanceChainKey);
332     if (mapIter == chainConfigInfoMap_.end()) {
333         enhanceChainKey = sceneType + "_&_" + "ENHANCE_DEFAULT";
334         mapIter = chainConfigInfoMap_.find(enhanceChainKey);
335     }
336     if (mapIter == chainConfigInfoMap_.end()) {
337         AUDIO_ERR_LOG("EnhanceChain key [%{public}s] does not exist", enhanceChainKey.c_str());
338         return {};
339     } else {
340         return mapIter->second.enhanceNames;
341     }
342 }
343 
CreateEnhanceChainInner(uint64_t sceneKeyCode,const AudioEnhanceDeviceAttr & deviceAttr)344 std::shared_ptr<AudioEnhanceChain> AudioEnhanceChainManagerImpl::CreateEnhanceChainInner(uint64_t sceneKeyCode,
345     const AudioEnhanceDeviceAttr &deviceAttr)
346 {
347     std::string sceneType = "";
348     std::string capturerDevice = "";
349     std::string rendererDeivce = "";
350     auto parseSceneKeyCodeRet = ParseSceneKeyCode(sceneKeyCode, sceneType, capturerDevice, rendererDeivce);
351     CHECK_AND_RETURN_RET_LOG(parseSceneKeyCodeRet == SUCCESS, nullptr, "ParseSceneKeyCode fail");
352 
353     AudioEnhanceParamAdapter enhancePara = { enhancePara_.muteInfo, enhancePara_.volumeInfo, enhancePara_.foldState,
354         capturerDevice, rendererDeivce, sceneType, "" };
355     if (priorSceneSet_.find(sceneType) != priorSceneSet_.end()) {
356         AUDIO_INFO_LOG("scene: %{public}s create prior enhance chain", sceneType.c_str());
357         return std::make_shared<AudioEnhanceChain>(sceneKeyCode, sceneType, PRIOR_SCENE, enhancePara, deviceAttr);
358     }
359 
360     uint32_t normalSceneNum = 0;
361     auto chainArray = ChainPool::GetInstance().GetAllChain();
362     for (const auto &chain : chainArray) {
363         if (chain != nullptr && chain->GetScenePriority() == NORMAL_SCENE) {
364             ++normalSceneNum;
365         }
366     }
367 
368     std::shared_ptr<AudioEnhanceChain> chain = nullptr;
369     if (normalSceneNum >= maxNormalInstanceNum_) {
370         AUDIO_INFO_LOG("scene: %{public}s create default enhance chain", sceneType.c_str());
371         enhancePara.sceneType = defaultScene_;
372         chain = std::make_shared<AudioEnhanceChain>(sceneKeyCode, defaultScene_, DEFAULT_SCENE,
373             enhancePara, deviceAttr);
374     } else {
375         AUDIO_INFO_LOG("scene: %{public}s create normal enhance chain", sceneType.c_str());
376         chain = std::make_shared<AudioEnhanceChain>(sceneKeyCode, sceneType, NORMAL_SCENE, enhancePara, deviceAttr);
377     }
378 
379     return chain;
380 }
381 
AddAudioEnhanceChainHandles(std::shared_ptr<AudioEnhanceChain> & audioEnhanceChain,const std::vector<std::string> & enhanceNames)382 int32_t AudioEnhanceChainManagerImpl::AddAudioEnhanceChainHandles(std::shared_ptr<AudioEnhanceChain> &audioEnhanceChain,
383     const std::vector<std::string> &enhanceNames)
384 {
385     std::vector<EnhanceModulePara> moduleParas;
386     for (const auto &enhance : enhanceNames) {
387         EnhanceModulePara para = {};
388         para.enhanceName = enhance;
389         auto enhanceIter = enhanceConfigInfoMap_.find(enhance);
390         if (enhanceIter != enhanceConfigInfoMap_.end() && enhanceIter->second.enhanceLib != nullptr) {
391             para.libName = enhanceIter->second.enhanceLib->libraryName;
392             para.libHandle = enhanceIter->second.enhanceLib->audioEffectLibHandle;
393         }
394         if (auto iter = enhancePropertyMap_.find(enhance); iter != enhancePropertyMap_.end()) {
395             para.enhanceProp = iter->second;
396         }
397 
398         moduleParas.emplace_back(para);
399     }
400 
401     int32_t createAllModuleRet = audioEnhanceChain->CreateAllEnhanceModule(moduleParas);
402     CHECK_AND_RETURN_RET_LOG(createAllModuleRet == SUCCESS, ERROR, "CreateAllEnhanceModule fail");
403 
404     return SUCCESS;
405 }
406 
ReleaseAudioEnhanceChainDynamic(uint64_t sceneKeyCode)407 int32_t AudioEnhanceChainManagerImpl::ReleaseAudioEnhanceChainDynamic(uint64_t sceneKeyCode)
408 {
409     std::lock_guard<std::mutex> lock(chainManagerMutex_);
410 
411     AUDIO_INFO_LOG("release chain: %{public}" PRIu64, sceneKeyCode);
412     ChainPool::GetInstance().DeleteChain(sceneKeyCode);
413 
414     auto scene = static_cast<AudioEnhanceScene>((sceneKeyCode & SCENE_TYPE_MASK) >> SCENE_TYPE_OFFSET);
415     ReleaseThreadHandlerByScene(scene);
416 
417     return SUCCESS;
418 }
419 
AudioEnhanceChainGetAlgoConfig(uint64_t sceneKeyCode,AudioBufferConfig & micConfig,AudioBufferConfig & ecConfig,AudioBufferConfig & micRefConfig)420 int32_t AudioEnhanceChainManagerImpl::AudioEnhanceChainGetAlgoConfig(uint64_t sceneKeyCode,
421     AudioBufferConfig &micConfig, AudioBufferConfig &ecConfig, AudioBufferConfig &micRefConfig)
422 {
423     auto chain = ChainPool::GetInstance().GetChainById(sceneKeyCode);
424     if (chain == nullptr) {
425         AUDIO_ERR_LOG("chain: %{public}" PRIu64 " is not found", sceneKeyCode);
426         return ERROR;
427     }
428 
429     chain->GetAlgoConfig(micConfig, ecConfig, micRefConfig);
430 
431     return SUCCESS;
432 }
433 
ApplyEnhanceChainById(uint64_t sceneKeyCode,const EnhanceTransBuffer & transBuf)434 int32_t AudioEnhanceChainManagerImpl::ApplyEnhanceChainById(uint64_t sceneKeyCode, const EnhanceTransBuffer &transBuf)
435 {
436     auto chain = ChainPool::GetInstance().GetChainById(sceneKeyCode);
437     if (chain == nullptr) {
438         AUDIO_ERR_LOG("chain: %{public}" PRIu64 " is not found", sceneKeyCode);
439         return ERROR;
440     }
441 
442     auto applyChainRet = chain->ApplyEnhanceChain(transBuf);
443     if (applyChainRet != SUCCESS) {
444         AUDIO_ERR_LOG("apply chain: %{public}" PRIu64 " fail", sceneKeyCode);
445         return ERROR;
446     }
447 
448     return SUCCESS;
449 }
450 
GetChainOutputDataById(uint64_t sceneKeyCode,void * buf,size_t bufSize)451 int32_t AudioEnhanceChainManagerImpl::GetChainOutputDataById(uint64_t sceneKeyCode, void *buf, size_t bufSize)
452 {
453     auto chain = ChainPool::GetInstance().GetChainById(sceneKeyCode);
454     if (chain == nullptr) {
455         AUDIO_ERR_LOG("chain: %{public}" PRIu64 " is not found", sceneKeyCode);
456         return ERROR;
457     }
458 
459     auto getChainOutputRet = chain->GetOutputDataFromChain(buf, bufSize);
460     if (getChainOutputRet != SUCCESS) {
461         AUDIO_ERR_LOG("get chain %{public}" PRIu64 " output fail", sceneKeyCode);
462         return ERROR;
463     }
464 
465     return SUCCESS;
466 }
467 
UpdatePropertyAndSendToAlgo(DeviceType inputDevice)468 int32_t AudioEnhanceChainManagerImpl::UpdatePropertyAndSendToAlgo(DeviceType inputDevice)
469 {
470     UpdateEnhancePropertyMapFromDb(inputDevice);
471     auto chainArray = ChainPool::GetInstance().GetAllChain();
472     for (const auto &[enhance, prop] : enhancePropertyMap_) {
473         for (const auto &chain : chainArray) {
474             if (chain != nullptr) {
475                 int32_t ret = chain->SetEnhanceProperty(enhance, prop);
476                 CHECK_AND_RETURN_RET_LOG(ret == 0, ERR_OPERATION_FAILED, "set property failed");
477             }
478         }
479     }
480     return SUCCESS;
481 }
482 
SetInputDevice(uint32_t captureId,DeviceType inputDevice,const std::string & deviceName)483 int32_t AudioEnhanceChainManagerImpl::SetInputDevice(uint32_t captureId, DeviceType inputDevice,
484     const std::string &deviceName)
485 {
486     const auto &supportDeviceType = GetSupportedDeviceType();
487     std::lock_guard<std::mutex> lock(chainManagerMutex_);
488     auto item = captureIdToDeviceMap_.find(captureId);
489     if (item == captureIdToDeviceMap_.end()) {
490         captureIdToDeviceMap_[captureId] = inputDevice;
491         AUDIO_INFO_LOG("set new inputdevice, captureId: %{public}u, inputDevice: %{public}d", captureId, inputDevice);
492         return SUCCESS;
493     }
494     if (item->second == inputDevice) {
495         AUDIO_INFO_LOG("set same device, captureId: %{public}u, inputDevice: %{public}d", captureId, inputDevice);
496         return SUCCESS;
497     }
498 
499     captureIdToDeviceMap_[captureId] = inputDevice;
500     std::string inputDeviceStr = "";
501 
502     if (auto iter = supportDeviceType.find(inputDevice); iter != supportDeviceType.end()) {
503         inputDeviceStr = iter->second;
504     } else {
505         return ERROR;
506     }
507 
508     auto chainArray = ChainPool::GetInstance().GetAllChain();
509     for (const auto &chain : chainArray) {
510         if (chain == nullptr) {
511             continue;
512         }
513         uint64_t sceneKeyCode = chain->GetChainId();
514         uint32_t tempCaptureId = (sceneKeyCode & CAPTURER_ID_MASK) >> CAPTURER_ID_OFFSET;
515         if (tempCaptureId == captureId) {
516             if (chain->SetInputDevice(inputDeviceStr, deviceName) != SUCCESS) {
517                 AUDIO_ERR_LOG("chain:%{public}" PRIu64 " set input device failed", sceneKeyCode);
518             }
519         }
520     }
521 
522     if (UpdatePropertyAndSendToAlgo(inputDevice) != SUCCESS) {
523         return ERROR;
524     }
525     AUDIO_INFO_LOG("success, captureId: %{public}u, inputDevice: %{public}d deviceName:%{public}s",
526         captureId, inputDevice, deviceName.c_str());
527     return SUCCESS;
528 }
529 
SetOutputDevice(uint32_t renderId,DeviceType outputDevice)530 int32_t AudioEnhanceChainManagerImpl::SetOutputDevice(uint32_t renderId, DeviceType outputDevice)
531 {
532     static_cast<void>(renderId);
533     static_cast<void>(outputDevice);
534 
535     return SUCCESS;
536 }
537 
SetVolumeInfo(AudioVolumeType volumeType,float systemVol)538 int32_t AudioEnhanceChainManagerImpl::SetVolumeInfo(AudioVolumeType volumeType, float systemVol)
539 {
540     AUDIO_DEBUG_LOG("success, volumeType: %{public}d, systemVol: %{public}f", volumeType, systemVol);
541 
542     std::lock_guard<std::mutex> lock(chainManagerMutex_);
543     enhancePara_.volumeInfo = static_cast<uint32_t>(systemVol * VOLUME_FACTOR);
544     static_cast<void>(volumeType);
545 
546     return SUCCESS;
547 }
548 
SetMicrophoneMuteInfo(bool isMute)549 int32_t AudioEnhanceChainManagerImpl::SetMicrophoneMuteInfo(bool isMute)
550 {
551     {
552         std::lock_guard<std::mutex> lock(chainManagerMutex_);
553         enhancePara_.muteInfo = static_cast<uint32_t>(isMute);
554     }
555     uint32_t volumeInfo = enhancePara_.volumeInfo;
556     auto chainArray = ChainPool::GetInstance().GetAllChain();
557     for (const auto &chain : chainArray) {
558         if (chain != nullptr) {
559             int32_t ret = chain->SetEnhanceParam(isMute, volumeInfo);
560             CHECK_AND_RETURN_RET_LOG(ret == 0, ERROR,
561                 "[%{public}" PRIu64 "] set mute:%{public}d fail", chain->GetChainId(), static_cast<int32_t>(isMute));
562         }
563     }
564     AUDIO_INFO_LOG("success, isMute: %{public}d", static_cast<int32_t>(isMute));
565 
566     return SUCCESS;
567 }
568 
SetStreamVolumeInfo(uint32_t sessionId,float streamVol)569 int32_t AudioEnhanceChainManagerImpl::SetStreamVolumeInfo(uint32_t sessionId, float streamVol)
570 {
571     AUDIO_DEBUG_LOG("success, sessionId: %{public}u, streamVol: %{public}f", sessionId, streamVol);
572 
573     return SUCCESS;
574 }
575 
SetAudioEnhanceProperty(const AudioEffectPropertyArrayV3 & propertyArray,DeviceType deviceType)576 int32_t AudioEnhanceChainManagerImpl::SetAudioEnhanceProperty(const AudioEffectPropertyArrayV3 &propertyArray,
577     DeviceType deviceType)
578 {
579     int32_t ret = ERROR;
580     std::lock_guard<std::mutex> lock(chainManagerMutex_);
581     for (const auto &property : propertyArray.property) {
582         std::string key = "";
583         enhancePropertyMap_.insert_or_assign(property.name, property.category);
584         auto iter = enhanceConfigInfoMap_.find(property.name);
585         if (iter == enhanceConfigInfoMap_.end() || !iter->second.relateWithDevice) {
586             key = property.name;
587         } else {
588             std::string deviceTypeName = "";
589             GetDeviceTypeName(deviceType, deviceTypeName);
590             key = property.name + "_&_" + deviceTypeName;
591         }
592         ret = WriteEnhancePropertyToDb(key, property.category);
593         if (ret != SUCCESS) {
594             AUDIO_ERR_LOG("fail, WriteEnhancePropertyToDb, ErrCode: %{public}d", ret);
595             continue;
596         }
597         SetAudioEnhancePropertyToChains(property);
598     }
599 
600     return SUCCESS;
601 }
602 
SetAudioEnhancePropertyToChains(const AudioEffectPropertyV3 & property)603 int32_t AudioEnhanceChainManagerImpl::SetAudioEnhancePropertyToChains(const AudioEffectPropertyV3 &property)
604 {
605     auto chainArray = ChainPool::GetInstance().GetAllChain();
606     for (const auto &chain : chainArray) {
607         if (chain != nullptr) {
608             AUDIO_DEBUG_LOG("effectClass->name %{public}s effectProp->category %{public}s",
609                 property.name.c_str(), property.category.c_str());
610             int32_t ret = chain->SetEnhanceProperty(property.name, property.category);
611             CHECK_AND_CONTINUE_LOG(ret == SUCCESS, "set property failed[%{public}d]", ret);
612         }
613     }
614 
615     return SUCCESS;
616 }
617 
SetAudioEnhanceProperty(const AudioEnhancePropertyArray & propertyArray,DeviceType deviceType)618 int32_t AudioEnhanceChainManagerImpl::SetAudioEnhanceProperty(const AudioEnhancePropertyArray &propertyArray,
619     DeviceType deviceType)
620 {
621     AudioEffectPropertyArrayV3 localPropertyArray = {};
622     for (const auto &prop : propertyArray.property) {
623         AudioEffectPropertyV3 propertyV3 = { prop.enhanceClass, prop.enhanceProp, CAPTURE_EFFECT_FLAG };
624         localPropertyArray.property.emplace_back(std::move(propertyV3));
625     }
626 
627     return SetAudioEnhanceProperty(localPropertyArray, deviceType);
628 }
629 
WriteEnhancePropertyToDb(const std::string & key,const std::string & property)630 int32_t AudioEnhanceChainManagerImpl::WriteEnhancePropertyToDb(const std::string &key, const std::string &property)
631 {
632     AudioSettingProvider &settingProvider = AudioSettingProvider::GetInstance(AUDIO_POLICY_SERVICE_ID);
633     CHECK_AND_RETURN_RET_LOG(settingProvider.CheckOsAccountReady(), ERROR, "os account not ready");
634     ErrCode ret = settingProvider.PutStringValue(key, property, "system");
635     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "Write Enhance Property to Database failed");
636     AUDIO_INFO_LOG("success, write Enhance_&_DeviceType:%{public}s is Property:%{public}s to Database",
637         key.c_str(), property.c_str());
638     return SUCCESS;
639 }
640 
GetDeviceTypeName(DeviceType deviceType,std::string & deviceName)641 void AudioEnhanceChainManagerImpl::GetDeviceTypeName(DeviceType deviceType, std::string &deviceName)
642 {
643     const std::unordered_map<DeviceType, std::string> &supportDeviceType = GetSupportedDeviceType();
644     auto item = supportDeviceType.find(deviceType);
645     if (item != supportDeviceType.end()) {
646         deviceName = item->second;
647     }
648 }
649 
GetAudioEnhanceProperty(AudioEffectPropertyArrayV3 & propertyArray,DeviceType deviceType)650 int32_t AudioEnhanceChainManagerImpl::GetAudioEnhanceProperty(AudioEffectPropertyArrayV3 &propertyArray,
651     DeviceType deviceType)
652 {
653     std::lock_guard<std::mutex> lock(chainManagerMutex_);
654     propertyArray.property.clear();
655     if (deviceType != DEVICE_TYPE_NONE) {
656         UpdateEnhancePropertyMapFromDb(deviceType);
657     }
658     for (const auto &[effect, prop] : enhancePropertyMap_) {
659         if (!prop.empty()) {
660             AUDIO_DEBUG_LOG("effect->name %{public}s prop->category %{public}s", effect.c_str(), prop.c_str());
661             propertyArray.property.emplace_back(AudioEffectPropertyV3{effect, prop, CAPTURE_EFFECT_FLAG});
662         }
663     }
664     return SUCCESS;
665 }
666 
GetAudioEnhanceProperty(AudioEnhancePropertyArray & propertyArray,DeviceType deviceType)667 int32_t AudioEnhanceChainManagerImpl::GetAudioEnhanceProperty(AudioEnhancePropertyArray &propertyArray,
668     DeviceType deviceType)
669 {
670     propertyArray.property.clear();
671     AudioEffectPropertyArrayV3 localPropertyArray = {};
672     GetAudioEnhanceProperty(localPropertyArray, deviceType);
673     for (const auto &prop : localPropertyArray.property) {
674         AudioEnhanceProperty property = { prop.name, prop.category };
675         propertyArray.property.emplace_back(std::move(property));
676     }
677 
678     return SUCCESS;
679 }
680 
UpdateExtraSceneType(const std::string & mainkey,const std::string & subkey,const std::string & extraSceneType)681 void AudioEnhanceChainManagerImpl::UpdateExtraSceneType(const std::string &mainkey, const std::string &subkey,
682     const std::string &extraSceneType)
683 {
684     uint32_t tempState = 0;
685     if (mainkey == MAINKEY_DEVICE_STATUS && subkey == SUBKEY_FOLD_STATE) {
686         AUDIO_INFO_LOG("Set fold state: %{public}s to arm", extraSceneType.c_str());
687         auto result = std::from_chars(extraSceneType.data(), extraSceneType.data() + extraSceneType.size(), tempState);
688         if (result.ec != std::errc() || result.ptr != (extraSceneType.data() + extraSceneType.size())) {
689             AUDIO_ERR_LOG("extraSceneType: %{public}s is invalid", extraSceneType.c_str());
690             return;
691         }
692     } else {
693         AUDIO_INFO_LOG("UpdateExtraSceneType failed, mainkey is %{public}s, subkey is %{public}s, "
694             "extraSceneType is %{public}s", mainkey.c_str(), subkey.c_str(), extraSceneType.c_str());
695         return;
696     }
697 
698     {
699         std::lock_guard<std::mutex> lock(chainManagerMutex_);
700         enhancePara_.foldState = tempState;
701     }
702 
703     auto chainArray = ChainPool::GetInstance().GetAllChain();
704     for (const auto &chain : chainArray) {
705         if (chain == nullptr) {
706             continue;
707         }
708         if (chain->SetFoldState(tempState) != SUCCESS) {
709             AUDIO_WARNING_LOG("Set fold state to enhance chain failed");
710             continue;
711         }
712     }
713 }
714 
SendInitCommand()715 int32_t AudioEnhanceChainManagerImpl::SendInitCommand()
716 {
717     auto chainArray = ChainPool::GetInstance().GetAllChain();
718     for (const auto &chain : chainArray) {
719         if (chain != nullptr) {
720             int32_t ret = chain->InitCommand();
721             CHECK_AND_RETURN_RET_LOG(ret == 0, ERROR,
722                 "chain: [%{public}" PRIu64 "] set init command fail", chain->GetChainId());
723         }
724     }
725     AUDIO_INFO_LOG("SendInitCommand success");
726 
727     return SUCCESS;
728 }
729 
GetInstance()730 AudioEnhanceChainManager *AudioEnhanceChainManager::GetInstance()
731 {
732     static AudioEnhanceChainManagerImpl impl;
733     return &impl;
734 }
735 } // namespace AudioStandard
736 } // namespace OHOS