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 #ifndef LOG_TAG
17 #define LOG_TAG "AudioEnhanceChainManager"
18 #endif
19
20 #include "audio_enhance_chain_manager.h"
21
22 #include "securec.h"
23 #include "audio_effect_log.h"
24 #include "audio_errors.h"
25 #include "audio_enhance_chain_adapter.h"
26
27 using namespace OHOS::AudioStandard;
28
29 namespace OHOS {
30 namespace AudioStandard {
31
FindEnhanceLib(const std::string & enhance,const std::vector<std::shared_ptr<AudioEffectLibEntry>> & enhanceLibraryList,std::shared_ptr<AudioEffectLibEntry> & libEntry,std::string & libName)32 static int32_t FindEnhanceLib(const std::string &enhance,
33 const std::vector<std::shared_ptr<AudioEffectLibEntry>> &enhanceLibraryList,
34 std::shared_ptr<AudioEffectLibEntry> &libEntry, std::string &libName)
35 {
36 for (const std::shared_ptr<AudioEffectLibEntry> &lib : enhanceLibraryList) {
37 if (lib->libraryName == enhance) {
38 libName = lib->libraryName;
39 libEntry = lib;
40 return SUCCESS;
41 }
42 }
43 return ERROR;
44 }
45
CheckValidEnhanceLibEntry(const std::shared_ptr<AudioEffectLibEntry> & libEntry,const std::string & enhance,const std::string & libName)46 static int32_t CheckValidEnhanceLibEntry(const std::shared_ptr<AudioEffectLibEntry> &libEntry,
47 const std::string &enhance, const std::string &libName)
48 {
49 CHECK_AND_RETURN_RET_LOG(libEntry, ERROR, "Enhance [%{public}s] in lib [%{public}s] is nullptr",
50 enhance.c_str(), libName.c_str());
51 CHECK_AND_RETURN_RET_LOG(libEntry->audioEffectLibHandle, ERROR,
52 "AudioEffectLibHandle of Enhance [%{public}s] in lib [%{public}s] is nullptr",
53 enhance.c_str(), libName.c_str());
54 CHECK_AND_RETURN_RET_LOG(libEntry->audioEffectLibHandle->createEffect, ERROR,
55 "CreateEffect function of Enhance [%{public}s] in lib [%{public}s] is nullptr",
56 enhance.c_str(), libName.c_str());
57 CHECK_AND_RETURN_RET_LOG(libEntry->audioEffectLibHandle->releaseEffect, ERROR,
58 "ReleaseEffect function of Enhance [%{public}s] in lib [%{public}s] is nullptr",
59 enhance.c_str(), libName.c_str());
60 return SUCCESS;
61 }
62
AudioEnhanceChainManager()63 AudioEnhanceChainManager::AudioEnhanceChainManager()
64 {
65 sceneTypeToEnhanceChainMap_.clear();
66 sceneTypeToEnhanceChainCountMap_.clear();
67 sceneTypeAndModeToEnhanceChainNameMap_.clear();
68 enhanceChainToEnhancesMap_.clear();
69 enhanceToLibraryEntryMap_.clear();
70 enhanceToLibraryNameMap_.clear();
71 isInitialized_ = false;
72 upAndDownDevice_ = "";
73 }
74
~AudioEnhanceChainManager()75 AudioEnhanceChainManager::~AudioEnhanceChainManager()
76 {
77 AUDIO_INFO_LOG("~AudioEnhanceChainManager destroy");
78 }
79
GetInstance()80 AudioEnhanceChainManager *AudioEnhanceChainManager::GetInstance()
81 {
82 static AudioEnhanceChainManager audioEnhanceChainManager;
83 return &audioEnhanceChainManager;
84 }
85
InitAudioEnhanceChainManager(std::vector<EffectChain> & enhanceChains,const EffectChainManagerParam & managerParam,std::vector<std::shared_ptr<AudioEffectLibEntry>> & enhanceLibraryList)86 void AudioEnhanceChainManager::InitAudioEnhanceChainManager(std::vector<EffectChain> &enhanceChains,
87 const EffectChainManagerParam &managerParam, std::vector<std::shared_ptr<AudioEffectLibEntry>> &enhanceLibraryList)
88 {
89 const std::unordered_map<std::string, std::string> &enhanceChainNameMap = managerParam.sceneTypeToChainNameMap;
90 std::lock_guard<std::mutex> lock(chainManagerMutex_);
91 std::set<std::string> enhanceSet;
92 for (EffectChain enhanceChain : enhanceChains) {
93 for (std::string enhance : enhanceChain.apply) {
94 enhanceSet.insert(enhance);
95 }
96 }
97 // Construct enhanceToLibraryEntryMap_ that stores libEntry for each effect name
98 std::shared_ptr<AudioEffectLibEntry> libEntry = nullptr;
99 std::string libName;
100 for (std::string enhance : enhanceSet) {
101 int32_t ret = FindEnhanceLib(enhance, enhanceLibraryList, libEntry, libName);
102 CHECK_AND_CONTINUE_LOG(ret != ERROR, "Couldn't find libEntry of effect %{public}s", enhance.c_str());
103 ret = CheckValidEnhanceLibEntry(libEntry, enhance, libName);
104 enhanceToLibraryEntryMap_[enhance] = libEntry;
105 enhanceToLibraryNameMap_[enhance] = libName;
106 }
107 // Construct enhanceChainToEnhancesMap_ that stores all effect names of each effect chain
108 for (EffectChain enhanceChain : enhanceChains) {
109 std::string key = enhanceChain.name;
110 std::vector<std::string> enhances;
111 for (std::string enhanceName : enhanceChain.apply) {
112 enhances.emplace_back(enhanceName);
113 }
114 enhanceChainToEnhancesMap_[key] = enhances;
115 }
116 // Construct sceneTypeAndModeToEnhanceChainNameMap_ that stores effectMode associated with the effectChainName
117 for (auto item = enhanceChainNameMap.begin(); item != enhanceChainNameMap.end(); item++) {
118 sceneTypeAndModeToEnhanceChainNameMap_[item->first] = item->second;
119 }
120 AUDIO_INFO_LOG("enhanceToLibraryEntryMap_ size %{public}zu \
121 enhanceToLibraryNameMap_ size %{public}zu \
122 sceneTypeAndModeToEnhanceChainNameMap_ size %{public}zu",
123 enhanceToLibraryEntryMap_.size(),
124 enhanceChainToEnhancesMap_.size(),
125 sceneTypeAndModeToEnhanceChainNameMap_.size());
126 isInitialized_ = true;
127 }
128
CreateAudioEnhanceChainDynamic(const std::string & sceneType,const std::string & enhanceMode,const std::string & upAndDownDevice)129 int32_t AudioEnhanceChainManager::CreateAudioEnhanceChainDynamic(const std::string &sceneType,
130 const std::string &enhanceMode, const std::string &upAndDownDevice)
131 {
132 std::lock_guard<std::mutex> lock(chainManagerMutex_);
133 upAndDownDevice_ = upAndDownDevice;
134 std::string sceneTypeAndDeviceKey = sceneType + "_&_" + upAndDownDevice;
135 std::shared_ptr<AudioEnhanceChain> audioEnhanceChain = nullptr;
136 if (sceneTypeToEnhanceChainMap_.count(sceneTypeAndDeviceKey)) {
137 if (!sceneTypeToEnhanceChainCountMap_.count(sceneTypeAndDeviceKey) ||
138 sceneTypeToEnhanceChainCountMap_[sceneTypeAndDeviceKey] < 1) {
139 sceneTypeToEnhanceChainCountMap_.erase(sceneTypeAndDeviceKey);
140 sceneTypeToEnhanceChainMap_.erase(sceneTypeAndDeviceKey);
141 return ERROR;
142 }
143 sceneTypeToEnhanceChainCountMap_[sceneTypeAndDeviceKey]++;
144 return SUCCESS;
145 } else {
146 audioEnhanceChain = std::make_shared<AudioEnhanceChain>(sceneType);
147 sceneTypeToEnhanceChainMap_.insert(std::make_pair(sceneTypeAndDeviceKey, audioEnhanceChain));
148 if (!sceneTypeToEnhanceChainCountMap_.count(sceneTypeAndDeviceKey)) {
149 sceneTypeToEnhanceChainCountMap_.insert(std::make_pair(sceneTypeAndDeviceKey, 1));
150 } else {
151 sceneTypeToEnhanceChainCountMap_[sceneTypeAndDeviceKey] = 1;
152 }
153 }
154 if (SetAudioEnhanceChainDynamic(sceneType, enhanceMode, upAndDownDevice) != SUCCESS) {
155 return ERROR;
156 }
157 AUDIO_INFO_LOG("%{public}s create success", sceneTypeAndDeviceKey.c_str());
158 return SUCCESS;
159 }
160
SetAudioEnhanceChainDynamic(const std::string & sceneType,const std::string & enhanceMode,const std::string & upAndDownDevice)161 int32_t AudioEnhanceChainManager::SetAudioEnhanceChainDynamic(const std::string &sceneType,
162 const std::string &enhanceMode, const std::string &upAndDownDevice)
163 {
164 std::string sceneTypeAndDeviceKey = sceneType + "_&_" + upAndDownDevice;
165 CHECK_AND_RETURN_RET_LOG(sceneTypeToEnhanceChainMap_.count(sceneTypeAndDeviceKey), ERROR,
166 "SceneType [%{public}s] does not exist, fail to set.", sceneTypeAndDeviceKey.c_str());
167
168 std::shared_ptr<AudioEnhanceChain> audioEnhanceChain = sceneTypeToEnhanceChainMap_[sceneTypeAndDeviceKey];
169
170 std::string enhanceChain;
171 std::string enhanceChainKey = sceneType + "_&_" + enhanceMode;
172 std::string enhanceNone = AUDIO_SUPPORTED_SCENE_MODES.find(EFFECT_NONE)->second;
173 if (!sceneTypeAndModeToEnhanceChainNameMap_.count(enhanceChainKey)) {
174 AUDIO_ERR_LOG("EnhanceChain key [%{public}s] does not exist, auto set to %{public}s",
175 enhanceChainKey.c_str(), enhanceNone.c_str());
176 enhanceChain = enhanceNone;
177 } else {
178 enhanceChain = sceneTypeAndModeToEnhanceChainNameMap_[enhanceChainKey];
179 }
180
181 if (enhanceChain != enhanceNone && !enhanceChainToEnhancesMap_.count(enhanceChain)) {
182 AUDIO_ERR_LOG("EnhanceChain name [%{public}s] does not exist, auto set to %{public}s",
183 enhanceChain.c_str(), enhanceNone.c_str());
184 enhanceChain = enhanceNone;
185 }
186
187 audioEnhanceChain->SetEnhanceMode(enhanceMode);
188 for (std::string enhance : enhanceChainToEnhancesMap_[enhanceChain]) {
189 AudioEffectHandle handle = nullptr;
190 AudioEffectDescriptor descriptor;
191 descriptor.libraryName = enhanceToLibraryNameMap_[enhance];
192 descriptor.effectName = enhance;
193
194 AUDIO_INFO_LOG("libraryName: %{public}s effectName:%{public}s",
195 descriptor.libraryName.c_str(), descriptor.effectName.c_str());
196 int32_t ret = enhanceToLibraryEntryMap_[enhance]->audioEffectLibHandle->createEffect(descriptor, &handle);
197 CHECK_AND_CONTINUE_LOG(ret == 0, "EnhanceToLibraryEntryMap[%{public}s] createEffect fail",
198 enhance.c_str());
199 audioEnhanceChain->AddEnhanceHandle(handle, enhanceToLibraryEntryMap_[enhance]->audioEffectLibHandle);
200 }
201
202 if (audioEnhanceChain->IsEmptyEnhanceHandles()) {
203 AUDIO_ERR_LOG("EnhanceChain is empty, copy bufIn to bufOut like EFFECT_NONE mode");
204 return ERROR;
205 }
206 return SUCCESS;
207 }
208
ReleaseAudioEnhanceChainDynamic(const std::string & sceneType,const std::string & upAndDownDevice)209 int32_t AudioEnhanceChainManager::ReleaseAudioEnhanceChainDynamic(const std::string &sceneType,
210 const std::string &upAndDownDevice)
211 {
212 std::lock_guard<std::mutex> lock(chainManagerMutex_);
213 CHECK_AND_RETURN_RET_LOG(isInitialized_, ERROR, "has not been initialized");
214 CHECK_AND_RETURN_RET_LOG(sceneType != "", ERROR, "null sceneType");
215
216 std::string sceneTypeAndDeviceKey = sceneType + "_&_" + upAndDownDevice;
217 if (!sceneTypeToEnhanceChainMap_.count(sceneTypeAndDeviceKey)) {
218 sceneTypeToEnhanceChainCountMap_.erase(sceneTypeAndDeviceKey);
219 return SUCCESS;
220 } else if (sceneTypeToEnhanceChainCountMap_.count(sceneTypeAndDeviceKey) &&
221 sceneTypeToEnhanceChainCountMap_[sceneTypeAndDeviceKey] > 1) {
222 sceneTypeToEnhanceChainCountMap_[sceneTypeAndDeviceKey]--;
223 return SUCCESS;
224 }
225 sceneTypeToEnhanceChainCountMap_.erase(sceneTypeAndDeviceKey);
226 sceneTypeToEnhanceChainMap_.erase(sceneTypeAndDeviceKey);
227 AUDIO_INFO_LOG("release %{public}s", sceneTypeAndDeviceKey.c_str());
228 return SUCCESS;
229 }
230
ApplyAudioEnhanceChain(const std::string & sceneType,EnhanceBufferAttr * enhanceBufferAttr)231 int32_t AudioEnhanceChainManager::ApplyAudioEnhanceChain(const std::string &sceneType,
232 EnhanceBufferAttr *enhanceBufferAttr)
233 {
234 CHECK_AND_RETURN_RET_LOG(enhanceBufferAttr != nullptr, ERROR, "enhance buffer is null");
235 std::lock_guard<std::mutex> lock(chainManagerMutex_);
236 std::string sceneTypeAndDeviceKey = sceneType + "_&_" + GetUpAndDownDevice();
237 if (!sceneTypeToEnhanceChainMap_.count(sceneTypeAndDeviceKey)) {
238 uint32_t totalLen = enhanceBufferAttr->byteLenPerFrame * enhanceBufferAttr->outNum;
239 CHECK_AND_RETURN_RET_LOG(memcpy_s(enhanceBufferAttr->output, totalLen, enhanceBufferAttr->input,
240 totalLen) == 0, ERROR, "memcpy error in apply enhance");
241 AUDIO_ERR_LOG("Can not find %{public}s in sceneTypeToEnhanceChainMap_", sceneTypeAndDeviceKey.c_str());
242 return ERROR;
243 }
244 auto audioEnhanceChain = sceneTypeToEnhanceChainMap_[sceneTypeAndDeviceKey];
245 if (audioEnhanceChain->ApplyEnhanceChain(enhanceBufferAttr) != SUCCESS) {
246 AUDIO_ERR_LOG("Apply %{public}s failed.", sceneTypeAndDeviceKey.c_str());
247 return ERROR;
248 }
249 AUDIO_INFO_LOG("Apply %{public}s success", sceneTypeAndDeviceKey.c_str());
250 return SUCCESS;
251 }
252
ExistAudioEnhanceChain(const std::string & sceneType)253 bool AudioEnhanceChainManager::ExistAudioEnhanceChain(const std::string &sceneType)
254 {
255 std::lock_guard<std::mutex> lock(chainManagerMutex_);
256 if (!isInitialized_) {
257 AUDIO_ERR_LOG("audioEnhanceChainManager has not been initialized.");
258 return false;
259 }
260 CHECK_AND_RETURN_RET(sceneType != "", false);
261 CHECK_AND_RETURN_RET_LOG(GetUpAndDownDevice() != "", false, "null device");
262
263 std::string sceneTypeAndDeviceKey = sceneType + "_&_" + GetUpAndDownDevice();
264 if (!sceneTypeToEnhanceChainMap_.count(sceneTypeAndDeviceKey)) {
265 return false;
266 }
267 auto audioEnhanceChain = sceneTypeToEnhanceChainMap_[sceneTypeAndDeviceKey];
268 CHECK_AND_RETURN_RET_LOG(audioEnhanceChain != nullptr, false, "null sceneTypeToEnhanceChainMap_[%{public}s]",
269 sceneTypeAndDeviceKey.c_str());
270 return !audioEnhanceChain->IsEmptyEnhanceHandles();
271 }
272
GetUpAndDownDevice()273 std::string AudioEnhanceChainManager::GetUpAndDownDevice()
274 {
275 return upAndDownDevice_;
276 }
277
278 } // namespace AudioStandard
279 } // namespace OHOS