• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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