1 /*
2 * Copyright (c) 2023 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 #include "audio_effect_manager.h"
17 #include <unordered_set>
18
19 namespace OHOS {
20 namespace AudioStandard {
AudioEffectManager()21 AudioEffectManager::AudioEffectManager()
22 {
23 AUDIO_INFO_LOG("AudioEffectManager ctor");
24 }
25
~AudioEffectManager()26 AudioEffectManager::~AudioEffectManager()
27 {
28 }
29
EffectManagerInit()30 void AudioEffectManager::EffectManagerInit()
31 {
32 // load XML
33 std::unique_ptr<AudioEffectConfigParser> effectConfigParser = std::make_unique<AudioEffectConfigParser>();
34 int32_t ret = effectConfigParser->LoadEffectConfig(oriEffectConfig_);
35 if (ret != 0) {
36 AUDIO_ERR_LOG("AudioEffectManager->effectConfigParser failed: %{public}d", ret);
37 return;
38 }
39 }
40
GetAvailableEffects(std::vector<Effect> & availableEffects)41 void AudioEffectManager::GetAvailableEffects(std::vector<Effect> &availableEffects)
42 {
43 availableEffects = availableEffects_;
44 }
45
GetOriginalEffectConfig(OriginalEffectConfig & oriEffectConfig)46 void AudioEffectManager::GetOriginalEffectConfig(OriginalEffectConfig &oriEffectConfig)
47 {
48 oriEffectConfig = oriEffectConfig_;
49 }
50
UpdateAvailableEffects(std::vector<Effect> & newAvailableEffects)51 void AudioEffectManager::UpdateAvailableEffects(std::vector<Effect> &newAvailableEffects)
52 {
53 availableEffects_ = newAvailableEffects;
54 }
55
QueryEffectManagerSceneMode(SupportedEffectConfig & supportedEffectConfig)56 int32_t AudioEffectManager::QueryEffectManagerSceneMode(SupportedEffectConfig &supportedEffectConfig)
57 {
58 supportedEffectConfig = supportedEffectConfig_;
59 return existDefault_;
60 }
61
GetSupportedEffectConfig(SupportedEffectConfig & supportedEffectConfig)62 void AudioEffectManager::GetSupportedEffectConfig(SupportedEffectConfig &supportedEffectConfig)
63 {
64 supportedEffectConfig = supportedEffectConfig_;
65 }
66
UpdateUnsupportedScene(std::string & scene)67 static int32_t UpdateUnsupportedScene(std::string &scene)
68 {
69 int32_t isSupported = 0;
70 if ((scene != "SCENE_MUSIC") &&
71 (scene != "SCENE_MOVIE") &&
72 (scene != "SCENE_GAME") &&
73 (scene != "SCENE_SPEECH") &&
74 (scene != "SCENE_RING") &&
75 (scene != "SCENE_OTHERS")) {
76 AUDIO_INFO_LOG("[supportedEffectConfig LOG9]:stream-> The scene of %{public}s is unsupported, \
77 and this scene is deleted!", scene.c_str());
78 isSupported = -1;
79 }
80 return isSupported;
81 }
82
UpdateUnsupportedDevicePre(Preprocess & pp,Stream & stream,const std::string & mode,int32_t i,int32_t j)83 static void UpdateUnsupportedDevicePre(Preprocess &pp, Stream &stream, const std::string &mode, int32_t i, int32_t j)
84 {
85 StreamEffectMode streamEffectMode;
86 streamEffectMode.mode = mode;
87 j = 0;
88 for (auto &device: pp.device) {
89 if (i == j) {
90 for (auto &eachDevice: device) {
91 streamEffectMode.devicePort.push_back(eachDevice);
92 }
93 break;
94 }
95 j += 1;
96 }
97 stream.streamEffectMode.push_back(streamEffectMode);
98 }
99
UpdateUnsupportedModePre(Preprocess & pp,Stream & stream,std::string & mode,int32_t i)100 static void UpdateUnsupportedModePre(Preprocess &pp, Stream &stream, std::string &mode, int32_t i)
101 {
102 int32_t isSupported = 0;
103 if ((mode != "EFFECT_NONE") &&
104 (mode != "EFFECT_DEFAULT")) {
105 AUDIO_INFO_LOG("[supportedEffectConfig LOG10]:mode-> The %{public}s mode of %{public}s is unsupported, \
106 and this mode is deleted!", mode.c_str(), stream.scene.c_str());
107 isSupported = -1;
108 }
109 if (isSupported == 0) {
110 int32_t j = 0;
111 UpdateUnsupportedDevicePre(pp, stream, mode, i, j);
112 }
113 }
114
UpdateUnsupportedDevicePost(Postprocess & pp,Stream & stream,const std::string & mode,int32_t i)115 static void UpdateUnsupportedDevicePost(Postprocess &pp, Stream &stream, const std::string &mode, int32_t i)
116 {
117 StreamEffectMode streamEffectMode;
118 streamEffectMode.mode = mode;
119 int32_t j = 0;
120 for (auto &device: pp.device) {
121 if (i == j) {
122 for (auto &a: device) {
123 streamEffectMode.devicePort.push_back(a);
124 }
125 break;
126 }
127 j += 1;
128 }
129 stream.streamEffectMode.push_back(streamEffectMode);
130 }
131
UpdateUnsupportedModePost(Postprocess & pp,Stream & stream,std::string & mode,int32_t i)132 static void UpdateUnsupportedModePost(Postprocess &pp, Stream &stream, std::string &mode, int32_t i)
133 {
134 int32_t isSupported = 0;
135 if ((mode != "EFFECT_NONE") &&
136 (mode != "EFFECT_DEFAULT")) {
137 AUDIO_INFO_LOG("[supportedEffectConfig LOG10]:mode-> The %{public}s mode of %{public}s is unsupported, \
138 and this mode is deleted!", mode.c_str(), stream.scene.c_str());
139 isSupported = -1;
140 }
141 if (isSupported == 0) {
142 UpdateUnsupportedDevicePost(pp, stream, mode, i);
143 }
144 }
145
UpdateAvailableStreamPre(ProcessNew & preProcessNew,Preprocess & pp)146 static int32_t UpdateAvailableStreamPre(ProcessNew &preProcessNew, Preprocess &pp)
147 {
148 bool isDuplicate = 0;
149 int32_t isSupported = UpdateUnsupportedScene(pp.stream);
150 auto it = std::find_if(preProcessNew.stream.begin(), preProcessNew.stream.end(), [&pp](const Stream& x) {
151 return x.scene == pp.stream;
152 });
153 if ((it == preProcessNew.stream.end()) && (isSupported == 0)) {
154 Stream stream;
155 stream.scene = pp.stream;
156 int32_t i = 0;
157 for (auto &mode: pp.mode) {
158 UpdateUnsupportedModePre(pp, stream, mode, i);
159 }
160 preProcessNew.stream.push_back(stream);
161 } else if (it != preProcessNew.stream.end()) {
162 isDuplicate = 1;
163 }
164 return isDuplicate;
165 }
166
UpdateAvailableStreamPost(ProcessNew & postProcessNew,Postprocess & pp)167 static int32_t UpdateAvailableStreamPost(ProcessNew &postProcessNew, Postprocess &pp)
168 {
169 bool isDuplicate = 0;
170 int32_t isSupported = UpdateUnsupportedScene(pp.stream);
171 auto it = std::find_if(postProcessNew.stream.begin(), postProcessNew.stream.end(), [&pp](const Stream& x) {
172 return x.scene == pp.stream;
173 });
174 if ((it == postProcessNew.stream.end()) && (isSupported == 0)) {
175 Stream stream;
176 stream.scene = pp.stream;
177 int32_t i = 0;
178 for (auto &mode: pp.mode) {
179 UpdateUnsupportedModePost(pp, stream, mode, i);
180 }
181 postProcessNew.stream.push_back(stream);
182 } else if (it != postProcessNew.stream.end()) {
183 isDuplicate = 1;
184 }
185 return isDuplicate;
186 }
187
UpdateEffectChains(std::vector<std::string> & availableLayout)188 void AudioEffectManager::UpdateEffectChains(std::vector<std::string> &availableLayout)
189 {
190 int32_t count = 0;
191 std::vector<int> deviceDelIdx;
192 for (const auto &ec: supportedEffectConfig_.effectChains) {
193 for (auto &effectName: ec.apply) {
194 auto it = std::find_if(availableEffects_.begin(), availableEffects_.end(),
195 [&effectName](const Effect& effect) {
196 return effect.name == effectName;
197 });
198 if (it == availableEffects_.end()) {
199 deviceDelIdx.emplace_back(count);
200 break;
201 }
202 }
203 count += 1;
204 }
205 for (auto it = deviceDelIdx.rbegin(); it != deviceDelIdx.rend(); ++it) {
206 supportedEffectConfig_.effectChains.erase(supportedEffectConfig_.effectChains.begin() + *it);
207 }
208 if (supportedEffectConfig_.effectChains.empty()) {
209 AUDIO_INFO_LOG("[supportedEffectConfig LOG1]:effectChains-> all effectChains are unavailable");
210 }
211 for (auto ec: supportedEffectConfig_.effectChains) {
212 availableLayout.emplace_back(ec.name);
213 }
214 }
215
UpdateAvailableAEConfig(OriginalEffectConfig & aeConfig)216 void AudioEffectManager::UpdateAvailableAEConfig(OriginalEffectConfig &aeConfig)
217 {
218 bool isDuplicate = 0;
219 bool ret;
220 supportedEffectConfig_.effectChains = aeConfig.effectChains;
221 ProcessNew preProcessNew;
222 for (Preprocess &pp: aeConfig.preProcess) {
223 ret = UpdateAvailableStreamPre(preProcessNew, pp);
224 if (ret == 1) {
225 isDuplicate = 1;
226 }
227 }
228 ProcessNew postProcessNew;
229 for (Postprocess &pp: aeConfig.postProcess) {
230 ret = UpdateAvailableStreamPost(postProcessNew, pp);
231 if (ret == 1) {
232 isDuplicate = 1;
233 }
234 }
235 if (isDuplicate == 1) {
236 AUDIO_INFO_LOG("[supportedEffectConfig LOG2]:stream-> The duplicate stream is deleted, \
237 and the first configuration is retained!");
238 }
239 supportedEffectConfig_.preProcessNew = preProcessNew;
240 supportedEffectConfig_.postProcessNew = postProcessNew;
241 }
242
UpdateDuplicateBypassMode(ProcessNew & preProcessNew)243 void AudioEffectManager::UpdateDuplicateBypassMode(ProcessNew &preProcessNew)
244 {
245 int32_t flag = 0;
246 std::vector<int32_t> deviceDelIdx;
247 for (auto &stream: preProcessNew.stream) {
248 int32_t count = 0;
249 deviceDelIdx.clear();
250 for (const auto &streamEffectMode: stream.streamEffectMode) {
251 if (streamEffectMode.mode == "EFFECT_NONE") {
252 deviceDelIdx.push_back(count);
253 }
254 count += 1;
255 }
256 for (auto it = deviceDelIdx.rbegin(); it != deviceDelIdx.rend(); ++it) {
257 stream.streamEffectMode[*it].devicePort = {};
258 flag = -1;
259 }
260 }
261 if (flag == -1) {
262 AUDIO_INFO_LOG("[supportedEffectConfig LOG3]:mode-> EFFECT_NONE can not configure by deveploer!");
263 }
264 }
265
UpdateDuplicateMode(ProcessNew & preProcessNew)266 void AudioEffectManager::UpdateDuplicateMode(ProcessNew &preProcessNew)
267 {
268 std::unordered_set<std::string> seen;
269 std::vector<int32_t> toRemove;
270 uint32_t i;
271 for (auto &stream: preProcessNew.stream) {
272 seen.clear();
273 toRemove.clear();
274 for (i = 0; i < stream.streamEffectMode.size(); i++) {
275 if (seen.count(stream.streamEffectMode[i].mode)) {
276 toRemove.push_back(i);
277 } else {
278 seen.insert(stream.streamEffectMode[i].mode);
279 }
280 }
281 for (auto it = toRemove.rbegin(); it != toRemove.rend(); ++it) {
282 AUDIO_INFO_LOG("[supportedEffectConfig LOG4]:mode-> The duplicate mode of %{public}s configuration \
283 is deleted, and the first configuration is retained!", stream.scene.c_str());
284 stream.streamEffectMode.erase(stream.streamEffectMode.begin() + *it);
285 }
286 }
287 }
288
UpdateDuplicateDeviceRecord(StreamEffectMode & streamEffectMode,Stream & stream)289 static void UpdateDuplicateDeviceRecord(StreamEffectMode &streamEffectMode, Stream &stream)
290 {
291 uint32_t i;
292 std::unordered_set<std::string> seen;
293 std::vector<int32_t> toRemove;
294 seen.clear();
295 toRemove.clear();
296 for (i = 0; i < streamEffectMode.devicePort.size(); i++) {
297 if (seen.count(streamEffectMode.devicePort[i].type)) {
298 toRemove.push_back(i);
299 } else {
300 seen.insert(streamEffectMode.devicePort[i].type);
301 }
302 }
303 for (auto it = toRemove.rbegin(); it != toRemove.rend(); ++it) {
304 AUDIO_INFO_LOG("[supportedEffectConfig LOG5]:device-> The duplicate device of %{public}s's %{public}s \
305 mode configuration is deleted, and the first configuration is retained!",
306 stream.scene.c_str(), streamEffectMode.mode.c_str());
307 streamEffectMode.devicePort.erase(streamEffectMode.devicePort.begin() + *it);
308 }
309 }
310
UpdateDuplicateDevice(ProcessNew & preProcessNew)311 void AudioEffectManager::UpdateDuplicateDevice(ProcessNew &preProcessNew)
312 {
313 for (auto &stream: preProcessNew.stream) {
314 for (auto &streamEffectMode: stream.streamEffectMode) {
315 UpdateDuplicateDeviceRecord(streamEffectMode, stream);
316 }
317 }
318 }
319
UpdateUnavailableModes(std::vector<int32_t> & modeDelIdx,Stream & stream)320 static int32_t UpdateUnavailableModes(std::vector<int32_t> &modeDelIdx, Stream &stream)
321 {
322 int32_t ret = 0;
323 for (auto it = modeDelIdx.rbegin(); it != modeDelIdx.rend(); ++it) {
324 AUDIO_INFO_LOG("[supportedEffectConfig LOG7]:mode-> %{public}s's %{public}s mode is deleted!",
325 stream.scene.c_str(), stream.streamEffectMode[*it].mode.c_str());
326 if (stream.streamEffectMode[*it].mode == "PLAYBACK_DEAFULT") {
327 ret = -1;
328 }
329 stream.streamEffectMode.erase(stream.streamEffectMode.begin() + *it);
330 if (stream.streamEffectMode.empty()) {
331 AUDIO_INFO_LOG("[supportedEffectConfig LOG8]:mode-> %{public}s's mode is only EFFECT_NONE!",
332 stream.scene.c_str());
333 StreamEffectMode streamEffectMode;
334 streamEffectMode.mode = "EFFECT_NONE";
335 stream.streamEffectMode.push_back(streamEffectMode);
336 }
337 }
338 if (stream.streamEffectMode.empty()) {
339 AUDIO_INFO_LOG("[supportedEffectConfig LOG8]:mode-> %{public}s's mode is only EFFECT_NONE!",
340 stream.scene.c_str());
341 StreamEffectMode streamEffectMode;
342 streamEffectMode.mode = "EFFECT_NONE";
343 stream.streamEffectMode.push_back(streamEffectMode);
344 }
345 return ret;
346 }
347
UpdateUnavailableEffectChainsRecord(std::vector<std::string> & availableLayout,Stream & stream,StreamEffectMode & streamEffectMode,std::vector<int32_t> & modeDelIdx,int32_t modeCount)348 static void UpdateUnavailableEffectChainsRecord(std::vector<std::string> &availableLayout, Stream &stream,
349 StreamEffectMode &streamEffectMode, std::vector<int32_t> &modeDelIdx, int32_t modeCount)
350 {
351 std::vector<int32_t> deviceDelIdx;
352 deviceDelIdx.clear();
353 int32_t deviceCount = 0;
354 if (streamEffectMode.devicePort.empty()) {
355 modeDelIdx.push_back(modeCount);
356 }
357 for (auto &devicePort: streamEffectMode.devicePort) {
358 auto index = std::find(availableLayout.begin(), availableLayout.end(), devicePort.chain);
359 if (index == availableLayout.end()) {
360 deviceDelIdx.push_back(deviceCount);
361 }
362 deviceCount += 1;
363 }
364 if (streamEffectMode.devicePort.size() != deviceDelIdx.size() && deviceDelIdx.size() != 0) {
365 AUDIO_INFO_LOG("[supportedEffectConfig LOG6]:device-> The unavailable effectChain \
366 of %{public}s's %{public}s mode are set to LAYOUT_BYPASS!",
367 stream.scene.c_str(), streamEffectMode.mode.c_str());
368 for (auto it = deviceDelIdx.rbegin(); it != deviceDelIdx.rend(); ++it) {
369 streamEffectMode.devicePort[*it].chain = "LAYOUT_BYPASS";
370 }
371 } else {
372 for (auto it = deviceDelIdx.rbegin(); it != deviceDelIdx.rend(); ++it) {
373 streamEffectMode.devicePort.erase(streamEffectMode.devicePort.begin() + *it);
374 if (streamEffectMode.devicePort.empty()) {
375 modeDelIdx.push_back(modeCount);
376 }
377 }
378 }
379 }
380
UpdateUnavailableEffectChains(std::vector<std::string> & availableLayout,ProcessNew & processNew)381 int32_t AudioEffectManager::UpdateUnavailableEffectChains(std::vector<std::string> &availableLayout,
382 ProcessNew &processNew)
383 {
384 int32_t ret;
385
386 std::vector<int32_t> modeDelIdx;
387 for (auto &stream: processNew.stream) {
388 modeDelIdx.clear();
389 int32_t modeCount = 0;
390 for (auto &streamEffectMode: stream.streamEffectMode) {
391 UpdateUnavailableEffectChainsRecord(availableLayout, stream, streamEffectMode, modeDelIdx, modeCount);
392 }
393 ret = UpdateUnavailableModes(modeDelIdx, stream);
394 }
395 return ret;
396 }
397
BuildAvailableAEConfig()398 void AudioEffectManager::BuildAvailableAEConfig()
399 {
400 int32_t ret;
401 std::vector<std::string> availableLayout;
402 existDefault_ = 1;
403 if (oriEffectConfig_.effectChains.size() == 0) {
404 AUDIO_INFO_LOG("[supportedEffectConfig LOG12]: effectChains is none!");
405 }
406 if (oriEffectConfig_.preProcess.size() == 0) {
407 AUDIO_INFO_LOG("[supportedEffectConfig LOG11]: preProcess is none!");
408 }
409 if (oriEffectConfig_.postProcess.size() == 0) {
410 AUDIO_INFO_LOG("[supportedEffectConfig LOG13]: postProcess is none!");
411 }
412
413 // Update duplicate defined modes, devices, and unsupported effect chain.
414 UpdateAvailableAEConfig(oriEffectConfig_);
415 UpdateEffectChains(availableLayout);
416
417 UpdateDuplicateBypassMode(supportedEffectConfig_.preProcessNew);
418 UpdateDuplicateMode(supportedEffectConfig_.preProcessNew);
419 UpdateDuplicateDevice(supportedEffectConfig_.preProcessNew);
420 ret = UpdateUnavailableEffectChains(availableLayout, supportedEffectConfig_.preProcessNew);
421 if (ret != 0) {
422 existDefault_ = -1;
423 }
424
425 UpdateDuplicateBypassMode(supportedEffectConfig_.postProcessNew);
426 UpdateDuplicateMode(supportedEffectConfig_.postProcessNew);
427 UpdateDuplicateDevice(supportedEffectConfig_.postProcessNew);
428 ret = UpdateUnavailableEffectChains(availableLayout, supportedEffectConfig_.postProcessNew);
429 if (ret != 0) {
430 existDefault_ = -1;
431 }
432 }
433
SetMasterSinkAvailable()434 void AudioEffectManager::SetMasterSinkAvailable()
435 {
436 isMasterSinkAvailable_ = true;
437 }
438
SetEffectChainManagerAvailable()439 void AudioEffectManager::SetEffectChainManagerAvailable()
440 {
441 isEffectChainManagerAvailable_ = true;
442 }
443
CanLoadEffectSinks()444 bool AudioEffectManager::CanLoadEffectSinks()
445 {
446 return (isMasterSinkAvailable_ && isEffectChainManagerAvailable_);
447 }
448
449 template <typename T>
AddKeyValueIntoMap(std::unordered_map<T,std::string> & map,std::string & key,std::string & value)450 void AddKeyValueIntoMap(std::unordered_map<T, std::string> &map, std::string &key, std::string &value)
451 {
452 if (map.count(key)) { // if the key already register in map
453 return;
454 }
455 map[key] = value;
456 }
457
ConstructSceneTypeToEffectChainNameMap(std::unordered_map<std::string,std::string> & map)458 void AudioEffectManager::ConstructSceneTypeToEffectChainNameMap(std::unordered_map<std::string, std::string> &map)
459 {
460 std::string sceneType;
461 std::string sceneMode;
462 std::string key;
463 for (auto &scene: supportedEffectConfig_.postProcessNew.stream) {
464 sceneType = scene.scene;
465 for (auto &mode: scene.streamEffectMode) {
466 sceneMode = mode.mode;
467 for (auto &device: mode.devicePort) {
468 key = sceneType + "_&_" + sceneMode + "_&_" + device.type;
469 AddKeyValueIntoMap(map, key, device.chain);
470 }
471 }
472 }
473 AUDIO_INFO_LOG("Constructed SceneTypeAndModeToEffectChainNameMap at policy, size is %{public}d",
474 (int32_t)map.size());
475 }
476
CheckEffectSinkName(std::string & sinkName)477 bool AudioEffectManager::CheckEffectSinkName(std::string &sinkName)
478 {
479 for (auto it = AUDIO_SUPPORTED_SCENE_TYPES.begin(); it != AUDIO_SUPPORTED_SCENE_TYPES.end(); ++it) {
480 if (it->second == sinkName) {
481 return true;
482 }
483 }
484 return false;
485 }
486
487 } // namespce AudioStandard
488 } // namespace OHOS