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 #ifndef LOG_TAG
16 #define LOG_TAG "AudioEffectConfigParser"
17 #endif
18 
19 #include "audio_effect_config_parser.h"
20 #include <libxml/tree.h>
21 #ifdef USE_CONFIG_POLICY
22 #include "config_policy_utils.h"
23 #endif
24 #include "media_monitor_manager.h"
25 
26 namespace OHOS {
27 namespace AudioStandard {
28 #ifdef USE_CONFIG_POLICY
29 static constexpr char AUDIO_EFFECT_CONFIG_FILE[] = "etc/audio/audio_effect_config.xml";
30 #else
31 static constexpr char AUDIO_EFFECT_CONFIG_FILE[] = "system/etc/audio/audio_effect_config.xml";
32 #endif
33 static const std::string EFFECT_CONFIG_NAME[5] = {"libraries", "effects", "effectChains", "preProcess", "postProcess"};
34 static constexpr int32_t FILE_CONTENT_ERROR = -2;
35 static constexpr int32_t FILE_PARSE_ERROR = -3;
36 static constexpr int32_t INDEX_LIBRARIES = 0;
37 static constexpr int32_t INDEX_EFFECS = 1;
38 static constexpr int32_t INDEX_EFFECTCHAINE = 2;
39 static constexpr int32_t INDEX_PREPROCESS = 3;
40 static constexpr int32_t INDEX_POSTPROCESS = 4;
41 static constexpr int32_t INDEX_EXCEPTION = 5;
42 static constexpr int32_t NODE_SIZE = 6;
43 static constexpr int32_t MODULE_SIZE = 5;
44 static constexpr uint32_t XML_PARSE_NOERROR = 1 << 5;
45 static constexpr uint32_t XML_PARSE_NOWARNING = 1 << 6;
46 
AudioEffectConfigParser()47 AudioEffectConfigParser::AudioEffectConfigParser()
48 {
49     AUDIO_INFO_LOG("AudioEffectConfigParser created");
50 }
51 
~AudioEffectConfigParser()52 AudioEffectConfigParser::~AudioEffectConfigParser()
53 {
54 }
55 
ParseEffectConfigFile(xmlDoc * & doc)56 static int32_t ParseEffectConfigFile(xmlDoc* &doc)
57 {
58 #ifdef USE_CONFIG_POLICY
59     CfgFiles *cfgFiles = GetCfgFiles(AUDIO_EFFECT_CONFIG_FILE);
60     if (cfgFiles == nullptr) {
61         AUDIO_ERR_LOG("Not found audio_effect_config.xml!");
62         std::shared_ptr<Media::MediaMonitor::EventBean> bean = std::make_shared<Media::MediaMonitor::EventBean>(
63             Media::MediaMonitor::AUDIO, Media::MediaMonitor::LOAD_CONFIG_ERROR,
64             Media::MediaMonitor::FAULT_EVENT);
65         bean->Add("CATEGORY", Media::MediaMonitor::AUDIO_EFFECT_CONFIG);
66         Media::MediaMonitor::MediaMonitorManager::GetInstance().WriteLogMsg(bean);
67         return FILE_PARSE_ERROR;
68     }
69 
70     for (int32_t i = MAX_CFG_POLICY_DIRS_CNT - 1; i >= 0; i--) {
71         if (cfgFiles->paths[i] && *(cfgFiles->paths[i]) != '\0') {
72             AUDIO_INFO_LOG("effect config file path:%{public}s", cfgFiles->paths[i]);
73             doc = xmlReadFile(cfgFiles->paths[i], nullptr, XML_PARSE_NOERROR | XML_PARSE_NOWARNING);
74             break;
75         }
76     }
77     FreeCfgFiles(cfgFiles);
78 #else
79     AUDIO_INFO_LOG("use default audio effect config file path: %{public}s", AUDIO_EFFECT_CONFIG_FILE);
80     doc = xmlReadFile(AUDIO_EFFECT_CONFIG_FILE, nullptr, XML_PARSE_NOERROR | XML_PARSE_NOWARNING);
81 #endif
82     if (doc == nullptr) {
83         std::shared_ptr<Media::MediaMonitor::EventBean> bean = std::make_shared<Media::MediaMonitor::EventBean>(
84             Media::MediaMonitor::AUDIO, Media::MediaMonitor::LOAD_CONFIG_ERROR,
85             Media::MediaMonitor::FAULT_EVENT);
86         bean->Add("CATEGORY", Media::MediaMonitor::AUDIO_EFFECT_CONFIG);
87         Media::MediaMonitor::MediaMonitorManager::GetInstance().WriteLogMsg(bean);
88     }
89     CHECK_AND_RETURN_RET_LOG(doc != nullptr, FILE_PARSE_ERROR, "load audio effect config fail");
90     return 0;
91 }
92 
LoadConfigCheck(xmlDoc * doc,xmlNode * currNode)93 static int32_t LoadConfigCheck(xmlDoc *doc, xmlNode *currNode)
94 {
95     CHECK_AND_RETURN_RET_LOG(currNode != nullptr, FILE_PARSE_ERROR, "error: could not parse file");
96     if (xmlStrcmp(currNode->name, reinterpret_cast<const xmlChar*>("audio_effects_conf"))) {
97         AUDIO_ERR_LOG("Missing tag - audio_effects_conf");
98         xmlFreeDoc(doc);
99         return FILE_CONTENT_ERROR;
100     }
101 
102     if (currNode->xmlChildrenNode) {
103         return 0;
104     } else {
105         AUDIO_ERR_LOG("Missing node - audio_effects_conf");
106         xmlFreeDoc(doc);
107         return FILE_CONTENT_ERROR;
108     }
109 }
110 
LoadConfigVersion(OriginalEffectConfig & result,xmlNode * currNode)111 static void LoadConfigVersion(OriginalEffectConfig &result, xmlNode *currNode)
112 {
113     bool ret = xmlHasProp(currNode, reinterpret_cast<const xmlChar*>("version"));
114     CHECK_AND_RETURN_LOG(ret, "missing information: audio_effects_conf node has no version attribute");
115 
116     result.version = reinterpret_cast<char *>(xmlGetProp(currNode, reinterpret_cast<const xmlChar *>("version")));
117 }
118 
LoadLibrary(OriginalEffectConfig & result,xmlNode * secondNode)119 static void LoadLibrary(OriginalEffectConfig &result, xmlNode *secondNode)
120 {
121     xmlNode *currNode = secondNode;
122     int32_t countLibrary = 0;
123     while (currNode != nullptr) {
124         CHECK_AND_RETURN_LOG(countLibrary < AUDIO_EFFECT_COUNT_UPPER_LIMIT,
125             "the number of library nodes exceeds limit: %{public}d", AUDIO_EFFECT_COUNT_UPPER_LIMIT);
126         if (currNode->type != XML_ELEMENT_NODE) {
127             currNode = currNode->next;
128             continue;
129         }
130         if (!xmlStrcmp(currNode->name, reinterpret_cast<const xmlChar*>("library"))) {
131             if (!xmlHasProp(currNode, reinterpret_cast<const xmlChar*>("name"))) {
132                 AUDIO_ERR_LOG("missing information: library has no name attribute");
133             } else if (!xmlHasProp(currNode, reinterpret_cast<const xmlChar*>("path"))) {
134                 AUDIO_ERR_LOG("missing information: library has no path attribute");
135             } else {
136                 std::string pLibName = reinterpret_cast<char*>
137                                       (xmlGetProp(currNode, reinterpret_cast<const xmlChar*>("name")));
138                 std::string pLibPath = reinterpret_cast<char*>
139                                       (xmlGetProp(currNode, reinterpret_cast<const xmlChar*>("path")));
140                 Library tmp = {pLibName, pLibPath};
141                 result.libraries.push_back(tmp);
142             }
143         } else {
144             AUDIO_WARNING_LOG("wrong name: %{public}s, should be library", currNode->name);
145         }
146         countLibrary++;
147         currNode = currNode->next;
148     }
149     if (countLibrary == 0) {
150         AUDIO_WARNING_LOG("missing information: libraries have no child library");
151     }
152 }
153 
LoadEffectConfigLibraries(OriginalEffectConfig & result,const xmlNode * currNode,int32_t (& countFirstNode)[NODE_SIZE])154 static void LoadEffectConfigLibraries(OriginalEffectConfig &result, const xmlNode *currNode,
155                                       int32_t (&countFirstNode)[NODE_SIZE])
156 {
157     if (countFirstNode[INDEX_LIBRARIES] >= AUDIO_EFFECT_COUNT_FIRST_NODE_UPPER_LIMIT) {
158         if (countFirstNode[INDEX_LIBRARIES] == AUDIO_EFFECT_COUNT_FIRST_NODE_UPPER_LIMIT) {
159             countFirstNode[INDEX_LIBRARIES]++;
160             AUDIO_WARNING_LOG("the number of libraries nodes exceeds limit: %{public}d",
161                 AUDIO_EFFECT_COUNT_FIRST_NODE_UPPER_LIMIT);
162         }
163     } else if (currNode->xmlChildrenNode) {
164         LoadLibrary(result, currNode->xmlChildrenNode);
165         countFirstNode[INDEX_LIBRARIES]++;
166     } else {
167         AUDIO_WARNING_LOG("missing information: libraries have no child library");
168         countFirstNode[INDEX_LIBRARIES]++;
169     }
170 }
171 
LoadEffectProperty(OriginalEffectConfig & result,const xmlNode * thirdNode,const int32_t effectIdx)172 static void LoadEffectProperty(OriginalEffectConfig &result, const xmlNode *thirdNode, const int32_t effectIdx)
173 {
174     CHECK_AND_RETURN_LOG(thirdNode->xmlChildrenNode, "effect '%{public}s' does not support effectProperty settings.",
175         result.effects[effectIdx].name.c_str());
176     int32_t countProperty = 0;
177     xmlNode *currNode = thirdNode->xmlChildrenNode;
178     while (currNode != nullptr) {
179         CHECK_AND_RETURN_LOG(countProperty < AUDIO_EFFECT_COUNT_UPPER_LIMIT,
180             "the number of effectProperty nodes exceeds limit: %{public}d", AUDIO_EFFECT_COUNT_UPPER_LIMIT);
181         if (currNode->type != XML_ELEMENT_NODE) {
182             currNode = currNode->next;
183             continue;
184         }
185         if (!xmlStrcmp(currNode->name, reinterpret_cast<const xmlChar*>("effectProperty"))) {
186             if (!xmlHasProp(currNode, reinterpret_cast<const xmlChar*>("mode"))) {
187                 AUDIO_WARNING_LOG("missing information: EFFECTPROPERTY has no MODE attribute");
188             } else {
189                 std::string pMode = reinterpret_cast<char*>
190                                      (xmlGetProp(currNode, reinterpret_cast<const xmlChar*>("mode")));
191                 result.effects[effectIdx].effectProperty.push_back(pMode);
192             }
193         } else {
194             AUDIO_WARNING_LOG("wrong name: %{public}s, should be effectProperty", currNode->name);
195         }
196         countProperty++;
197         currNode = currNode->next;
198     }
199     if (countProperty == 0) {
200         AUDIO_WARNING_LOG("effect '%{public}s' does not support effectProperty settings.",
201             result.effects[effectIdx].name.c_str());
202     }
203 }
204 
LoadEffect(OriginalEffectConfig & result,xmlNode * secondNode)205 static void LoadEffect(OriginalEffectConfig &result, xmlNode *secondNode)
206 {
207     xmlNode *currNode = secondNode;
208     int32_t countEffect = 0;
209     std::vector<std::string> effectProperty = {};
210     int32_t effectIdx = 0;
211     while (currNode != nullptr) {
212         CHECK_AND_RETURN_LOG(countEffect < AUDIO_EFFECT_COUNT_UPPER_LIMIT,
213             "the number of effect nodes exceeds limit: %{public}d", AUDIO_EFFECT_COUNT_UPPER_LIMIT);
214         if (currNode->type != XML_ELEMENT_NODE) {
215             currNode = currNode->next;
216             continue;
217         }
218         if (!xmlStrcmp(currNode->name, reinterpret_cast<const xmlChar*>("effect"))) {
219             if (!xmlHasProp(currNode, reinterpret_cast<const xmlChar*>("name"))) {
220                 AUDIO_ERR_LOG("missing information: effect has no name attribute");
221             } else if (!xmlHasProp(currNode, reinterpret_cast<const xmlChar*>("library"))) {
222                 AUDIO_ERR_LOG("missing information: effect has no library attribute");
223             } else {
224                 std::string pEffectName = reinterpret_cast<char*>
225                               (xmlGetProp(currNode, reinterpret_cast<const xmlChar*>("name")));
226                 std::string pEffectLib = reinterpret_cast<char*>
227                              (xmlGetProp(currNode, reinterpret_cast<const xmlChar*>("library")));
228                 Effect tmp = {pEffectName, pEffectLib, effectProperty};
229                 result.effects.push_back(tmp);
230                 LoadEffectProperty(result, currNode, effectIdx);
231                 effectIdx++;
232             }
233         } else {
234             AUDIO_WARNING_LOG("wrong name: %{public}s, should be effect", currNode->name);
235         }
236         countEffect++;
237         currNode = currNode->next;
238     }
239     if (countEffect == 0) {
240         AUDIO_WARNING_LOG("missing information: effects have no child effect");
241     }
242 }
243 
LoadEffectConfigEffects(OriginalEffectConfig & result,const xmlNode * currNode,int32_t (& countFirstNode)[NODE_SIZE])244 static void LoadEffectConfigEffects(OriginalEffectConfig &result, const xmlNode *currNode,
245                                     int32_t (&countFirstNode)[NODE_SIZE])
246 {
247     if (countFirstNode[INDEX_EFFECS] >= AUDIO_EFFECT_COUNT_FIRST_NODE_UPPER_LIMIT) {
248         if (countFirstNode[INDEX_EFFECS] == AUDIO_EFFECT_COUNT_FIRST_NODE_UPPER_LIMIT) {
249             countFirstNode[INDEX_EFFECS]++;
250             AUDIO_WARNING_LOG("the number of effects nodes exceeds limit: %{public}d",
251                 AUDIO_EFFECT_COUNT_FIRST_NODE_UPPER_LIMIT);
252         }
253     } else if (currNode->xmlChildrenNode) {
254         LoadEffect(result, currNode->xmlChildrenNode);
255         countFirstNode[INDEX_EFFECS]++;
256     } else {
257         AUDIO_WARNING_LOG("missing information: effects have no child effect");
258         countFirstNode[INDEX_EFFECS]++;
259     }
260 }
261 
LoadApply(OriginalEffectConfig & result,const xmlNode * thirdNode,const int32_t segInx)262 static void LoadApply(OriginalEffectConfig &result, const xmlNode *thirdNode, const int32_t segInx)
263 {
264     CHECK_AND_RETURN_LOG(thirdNode->xmlChildrenNode, "missing information: effectChain has no child apply");
265     int32_t countApply = 0;
266     xmlNode *currNode = thirdNode->xmlChildrenNode;
267     while (currNode != nullptr) {
268         CHECK_AND_RETURN_LOG(countApply < AUDIO_EFFECT_COUNT_UPPER_LIMIT,
269             "the number of apply nodes exceeds limit: %{public}d", AUDIO_EFFECT_COUNT_UPPER_LIMIT);
270         if (currNode->type != XML_ELEMENT_NODE) {
271             currNode = currNode->next;
272             continue;
273         }
274         if (!xmlStrcmp(currNode->name, reinterpret_cast<const xmlChar*>("apply"))) {
275             if (!xmlHasProp(currNode, reinterpret_cast<const xmlChar*>("effect"))) {
276                 AUDIO_WARNING_LOG("missing information: apply has no effect attribute");
277             } else {
278                 std::string ppValue = reinterpret_cast<char*>
279                                      (xmlGetProp(currNode, reinterpret_cast<const xmlChar*>("effect")));
280                 result.effectChains[segInx].apply.push_back(ppValue);
281             }
282         } else {
283             AUDIO_WARNING_LOG("wrong name: %{public}s, should be apply", currNode->name);
284         }
285         countApply++;
286         currNode = currNode->next;
287     }
288     if (countApply == 0) {
289         AUDIO_WARNING_LOG("missing information: effectChain has no child apply");
290     }
291 }
292 
LoadEffectChain(OriginalEffectConfig & result,xmlNode * secondNode)293 static void LoadEffectChain(OriginalEffectConfig &result, xmlNode *secondNode)
294 {
295     xmlNode *currNode = secondNode;
296     int32_t countEffectChain = 0;
297     int32_t segInx = 0;
298     std::vector<std::string> apply;
299     while (currNode != nullptr) {
300         CHECK_AND_RETURN_LOG(countEffectChain < AUDIO_EFFECT_COUNT_UPPER_LIMIT,
301             "the number of effectChain nodes exceeds limit: %{public}d", AUDIO_EFFECT_COUNT_UPPER_LIMIT);
302         if (currNode->type != XML_ELEMENT_NODE) {
303             currNode = currNode->next;
304             continue;
305         }
306         if (!xmlStrcmp(currNode->name, reinterpret_cast<const xmlChar*>("effectChain"))) {
307             std::string label = "";
308             if (xmlHasProp(currNode, reinterpret_cast<const xmlChar*>("label"))) {
309                 label = reinterpret_cast<char*>(xmlGetProp(currNode, reinterpret_cast<const xmlChar*>("label")));
310             }
311             if (!xmlHasProp(currNode, reinterpret_cast<const xmlChar*>("name"))) {
312                 AUDIO_WARNING_LOG("missing information: effectChain has no name attribute");
313             } else {
314                 std::string peffectChainName = reinterpret_cast<char*>
315                                    (xmlGetProp(currNode, reinterpret_cast<const xmlChar*>("name")));
316                 EffectChain tmp = {peffectChainName, apply, label};
317                 result.effectChains.push_back(tmp);
318                 LoadApply(result, currNode, segInx);
319                 segInx++;
320             }
321         } else {
322             AUDIO_WARNING_LOG("wrong name: %{public}s, should be effectChain", currNode->name);
323         }
324         countEffectChain++;
325         currNode = currNode->next;
326     }
327     if (countEffectChain == 0) {
328         AUDIO_WARNING_LOG("missing information: effectChains have no child effectChain");
329     }
330 }
331 
LoadEffectConfigEffectChains(OriginalEffectConfig & result,const xmlNode * currNode,int32_t (& countFirstNode)[NODE_SIZE])332 static void LoadEffectConfigEffectChains(OriginalEffectConfig &result, const xmlNode *currNode,
333                                          int32_t (&countFirstNode)[NODE_SIZE])
334 {
335     if (countFirstNode[INDEX_EFFECTCHAINE] >= AUDIO_EFFECT_COUNT_FIRST_NODE_UPPER_LIMIT) {
336         if (countFirstNode[INDEX_EFFECTCHAINE] == AUDIO_EFFECT_COUNT_FIRST_NODE_UPPER_LIMIT) {
337             countFirstNode[INDEX_EFFECTCHAINE]++;
338             AUDIO_WARNING_LOG("the number of effectChains nodes exceeds limit: %{public}d",
339                 AUDIO_EFFECT_COUNT_FIRST_NODE_UPPER_LIMIT);
340         }
341     } else if (currNode->xmlChildrenNode) {
342         LoadEffectChain(result, currNode->xmlChildrenNode);
343         countFirstNode[INDEX_EFFECTCHAINE]++;
344     } else {
345         AUDIO_WARNING_LOG("missing information: effectChains have no child effectChain");
346         countFirstNode[INDEX_EFFECTCHAINE]++;
347     }
348 }
349 
LoadPreDevice(std::vector<Device> & devices,const xmlNode * fifthNode)350 static void LoadPreDevice(std::vector<Device> &devices, const xmlNode *fifthNode)
351 {
352     CHECK_AND_RETURN_LOG(fifthNode->xmlChildrenNode, "missing information: streamEffectMode has no child devicePort");
353     int32_t countDevice = 0;
354     xmlNode *currNode = fifthNode->xmlChildrenNode;
355     while (currNode != nullptr) {
356         CHECK_AND_RETURN_LOG(countDevice < AUDIO_EFFECT_COUNT_UPPER_LIMIT,
357             "the number of devicePort nodes exceeds limit: %{public}d", AUDIO_EFFECT_COUNT_UPPER_LIMIT);
358         if (currNode->type != XML_ELEMENT_NODE) {
359             currNode = currNode->next;
360             continue;
361         }
362         if (!xmlStrcmp(currNode->name, reinterpret_cast<const xmlChar*>("devicePort"))) {
363             if (!xmlHasProp(currNode, reinterpret_cast<const xmlChar*>("type"))) {
364                 AUDIO_ERR_LOG("missing information: devicePort has no type attribute");
365             } else if (!xmlHasProp(currNode, reinterpret_cast<const xmlChar*>("effectChain"))) {
366                 AUDIO_ERR_LOG("missing information: devicePort has no effectChain attribute");
367             } else {
368                 std::string pDevType = reinterpret_cast<char*>
369                            (xmlGetProp(currNode, reinterpret_cast<const xmlChar*>("type")));
370                 std::string pChain = reinterpret_cast<char*>
371                          (xmlGetProp(currNode, reinterpret_cast<const xmlChar*>("effectChain")));
372                 Device tmpdev = {pDevType, pChain};
373                 devices.push_back(tmpdev);
374             }
375         } else {
376             AUDIO_WARNING_LOG("wrong name: %{public}s, should be devicePort", currNode->name);
377         }
378         countDevice++;
379         currNode = currNode->next;
380     }
381     if (countDevice == 0) {
382         AUDIO_WARNING_LOG("missing information: streamEffectMode has no child devicePort");
383     }
384 }
385 
LoadPreMode(PreStreamScene & scene,const xmlNode * fourthNode)386 static void LoadPreMode(PreStreamScene &scene, const xmlNode *fourthNode)
387 {
388     CHECK_AND_RETURN_LOG(fourthNode->xmlChildrenNode,
389         "missing information: stream has no child streamEffectMode");
390     int32_t countMode = 0;
391     int32_t modeNum = 0;
392     xmlNode *currNode = fourthNode->xmlChildrenNode;
393     while (currNode != nullptr) {
394         CHECK_AND_RETURN_LOG(countMode < AUDIO_EFFECT_COUNT_UPPER_LIMIT,
395             "the number of streamEffectMode nodes exceeds limit: %{public}d", AUDIO_EFFECT_COUNT_UPPER_LIMIT);
396         if (currNode->type != XML_ELEMENT_NODE) {
397             currNode = currNode->next;
398             continue;
399         }
400         if (!xmlStrcmp(currNode->name, reinterpret_cast<const xmlChar*>("streamEffectMode"))) {
401             if (!xmlHasProp(currNode, reinterpret_cast<const xmlChar*>("mode"))) {
402                 AUDIO_WARNING_LOG("missing information: streamEffectMode has no mode attribute");
403             } else {
404                 std::string pStreamAEMode = reinterpret_cast<char*>
405                                 (xmlGetProp(currNode, reinterpret_cast<const xmlChar*>("mode")));
406                 scene.mode.push_back(pStreamAEMode);
407                 scene.device.push_back({});
408                 LoadPreDevice(scene.device[modeNum], currNode);
409                 modeNum++;
410             }
411         } else {
412             AUDIO_WARNING_LOG("wrong name: %{public}s, should be streamEffectMode", currNode->name);
413         }
414         countMode++;
415         currNode = currNode->next;
416     }
417     if (countMode == 0) {
418         AUDIO_WARNING_LOG("missing information: stream has no child streamEffectMode");
419     }
420 }
421 
LoadPreStreamScenes(std::vector<PreStreamScene> & scenes,xmlNode * thirdNode)422 static void LoadPreStreamScenes(std::vector<PreStreamScene> &scenes, xmlNode *thirdNode)
423 {
424     std::string stream;
425     std::vector<std::string> mode;
426     std::vector<std::vector<Device>> device;
427     PreStreamScene tmp = {stream, mode, device};
428     xmlNode *currNode = thirdNode;
429     int32_t countPreprocess = 0;
430     int32_t streamNum = 0;
431     while (currNode != nullptr) {
432         CHECK_AND_RETURN_LOG(countPreprocess < AUDIO_EFFECT_COUNT_UPPER_LIMIT,
433             "the number of stream nodes exceeds limit: %{public}d", AUDIO_EFFECT_COUNT_UPPER_LIMIT);
434         if (currNode->type != XML_ELEMENT_NODE) {
435             currNode = currNode->next;
436             continue;
437         }
438         if (!xmlStrcmp(currNode->name, reinterpret_cast<const xmlChar*>("stream"))) {
439             if (!xmlHasProp(currNode, reinterpret_cast<const xmlChar*>("scene"))) {
440                 AUDIO_WARNING_LOG("missing information: stream has no scene attribute");
441             } else {
442                 std::string pStreamType = reinterpret_cast<char*>
443                                          (xmlGetProp(currNode, reinterpret_cast<const xmlChar*>("scene")));
444                 tmp.stream = pStreamType;
445                 scenes.push_back(tmp);
446                 LoadPreMode(scenes[streamNum], currNode);
447                 streamNum++;
448             }
449         } else {
450             AUDIO_WARNING_LOG("wrong name: %{public}s, should be stream", currNode->name);
451         }
452         countPreprocess++;
453         currNode = currNode->next;
454     }
455     if (countPreprocess == 0) {
456         AUDIO_WARNING_LOG("missing information: preProcess has no child stream");
457     }
458 }
459 
LoadPreStreamScenesCheck(std::vector<PreStreamScene> & scenes,const xmlNode * currNode,int32_t & nodeCounter)460 static void LoadPreStreamScenesCheck(std::vector<PreStreamScene> &scenes, const xmlNode *currNode,
461                                      int32_t &nodeCounter)
462 {
463     if (nodeCounter >= AUDIO_EFFECT_COUNT_PRE_SECOND_NODE_UPPER_LIMIT) {
464         if (nodeCounter == AUDIO_EFFECT_COUNT_PRE_SECOND_NODE_UPPER_LIMIT) {
465             nodeCounter++;
466             AUDIO_WARNING_LOG("the number of preprocessStreams nodes exceeds limit: %{public}d",
467                 AUDIO_EFFECT_COUNT_PRE_SECOND_NODE_UPPER_LIMIT);
468         }
469     } else if (currNode->xmlChildrenNode) {
470         LoadPreStreamScenes(scenes, currNode->xmlChildrenNode);
471         nodeCounter++;
472     } else {
473         AUDIO_WARNING_LOG("missing information: preprocessStreams has no child stream");
474         nodeCounter++;
475     }
476 }
477 
LoadPreprocessExceptionCheck(OriginalEffectConfig & result,const xmlNode * currNode,int32_t (& countPreSecondNode)[NODE_SIZE_PRE])478 static void LoadPreprocessExceptionCheck(OriginalEffectConfig &result, const xmlNode *currNode,
479                                          int32_t (&countPreSecondNode)[NODE_SIZE_PRE])
480 {
481     if (countPreSecondNode[INDEX_PRE_EXCEPTION] >= AUDIO_EFFECT_COUNT_PRE_SECOND_NODE_UPPER_LIMIT) {
482         if (countPreSecondNode[INDEX_PRE_EXCEPTION] == AUDIO_EFFECT_COUNT_PRE_SECOND_NODE_UPPER_LIMIT) {
483             countPreSecondNode[INDEX_PRE_EXCEPTION]++;
484             AUDIO_ERR_LOG("the number of postprocess nodes with wrong name exceeds limit: %{public}d",
485                 AUDIO_EFFECT_COUNT_PRE_SECOND_NODE_UPPER_LIMIT);
486         }
487     } else {
488         AUDIO_WARNING_LOG("wrong name: %{public}s", currNode->name);
489         countPreSecondNode[INDEX_PRE_EXCEPTION]++;
490     }
491 }
492 
LoadPreProcessCfg(OriginalEffectConfig & result,xmlNode * secondNode)493 static void LoadPreProcessCfg(OriginalEffectConfig &result, xmlNode *secondNode)
494 {
495     int32_t countPreSecondNode[NODE_SIZE_PRE] = {0};
496     xmlNode *currNode = secondNode;
497     while (currNode != nullptr) {
498         if (currNode->type != XML_ELEMENT_NODE) {
499             currNode = currNode->next;
500             continue;
501         }
502 
503         if (!xmlStrcmp(currNode->name, reinterpret_cast<const xmlChar*>("defaultScene"))) {
504             LoadPreStreamScenesCheck(result.preProcess.defaultScenes, currNode,
505                 countPreSecondNode[INDEX_PRE_DEFAULT_SCENE]);
506         } else if (!xmlStrcmp(currNode->name, reinterpret_cast<const xmlChar*>("priorScene"))) {
507             LoadPreStreamScenesCheck(result.preProcess.priorScenes, currNode,
508                 countPreSecondNode[INDEX_PRE_PRIOR_SCENE]);
509         } else if (!xmlStrcmp(currNode->name, reinterpret_cast<const xmlChar*>("normalScene"))) {
510             int32_t maxExtraNum = 0;
511             if (xmlHasProp(currNode, reinterpret_cast<const xmlChar*>("maxExtSceneNumber"))) {
512                 maxExtraNum = atoi(reinterpret_cast<char*>(xmlGetProp(currNode,
513                     reinterpret_cast<const xmlChar*>("maxExtSceneNumber"))));
514             }
515             result.preProcess.maxExtSceneNum = static_cast<uint32_t>(maxExtraNum);
516             LoadPreStreamScenesCheck(result.preProcess.normalScenes, currNode,
517                 countPreSecondNode[INDEX_PRE_NORMAL_SCENE]);
518         } else {
519             LoadPreprocessExceptionCheck(result, currNode, countPreSecondNode);
520         }
521         currNode = currNode->next;
522     }
523 }
524 
LoadEffectConfigPreProcessCfg(OriginalEffectConfig & result,const xmlNode * currNode,int32_t (& countFirstNode)[NODE_SIZE])525 static void LoadEffectConfigPreProcessCfg(OriginalEffectConfig &result,
526     const xmlNode *currNode, int32_t (&countFirstNode)[NODE_SIZE])
527 {
528     if (countFirstNode[INDEX_PREPROCESS] >= AUDIO_EFFECT_COUNT_FIRST_NODE_UPPER_LIMIT) {
529         if (countFirstNode[INDEX_PREPROCESS] == AUDIO_EFFECT_COUNT_FIRST_NODE_UPPER_LIMIT) {
530             countFirstNode[INDEX_PREPROCESS]++;
531             AUDIO_WARNING_LOG("the number of preProcess nodes exceeds limit: %{public}d",
532                 AUDIO_EFFECT_COUNT_FIRST_NODE_UPPER_LIMIT);
533         }
534     } else if (currNode->xmlChildrenNode) {
535         LoadPreProcessCfg(result, currNode->xmlChildrenNode);
536         countFirstNode[INDEX_PREPROCESS]++;
537     } else {
538         AUDIO_WARNING_LOG("missing information: preProcess has no child stream");
539         countFirstNode[INDEX_PREPROCESS]++;
540     }
541 }
542 
LoadStreamUsageMapping(OriginalEffectConfig & result,xmlNode * thirdNode)543 static void LoadStreamUsageMapping(OriginalEffectConfig &result, xmlNode *thirdNode)
544 {
545     SceneMappingItem tmp;
546     xmlNode *currNode = thirdNode;
547     int32_t countUsage = 0;
548     while (currNode != nullptr) {
549         CHECK_AND_RETURN_LOG(countUsage < AUDIO_EFFECT_COUNT_STREAM_USAGE_UPPER_LIMIT,
550             "streamUsage map item exceeds limit: %{public}d", AUDIO_EFFECT_COUNT_STREAM_USAGE_UPPER_LIMIT);
551         if (currNode->type != XML_ELEMENT_NODE) {
552             currNode = currNode->next;
553             continue;
554         }
555         if (!xmlStrcmp(currNode->name, reinterpret_cast<const xmlChar*>("streamUsage"))) {
556             if (!xmlHasProp(currNode, reinterpret_cast<const xmlChar*>("name")) ||
557                 !xmlHasProp(currNode, reinterpret_cast<const xmlChar*>("scene"))) {
558                 AUDIO_WARNING_LOG("missing information: streamUsage misses attribute");
559             } else {
560                 tmp.name = reinterpret_cast<char*>(
561                     xmlGetProp(currNode, reinterpret_cast<const xmlChar*>("name")));
562                 tmp.sceneType = reinterpret_cast<char*>(
563                     xmlGetProp(currNode, reinterpret_cast<const xmlChar*>("scene")));
564                 result.postProcess.sceneMap.push_back(tmp);
565             }
566         } else {
567             AUDIO_WARNING_LOG("wrong name: %{public}s, should be streamUsage", currNode->name);
568         }
569         countUsage++;
570         currNode = currNode->next;
571     }
572     if (countUsage == 0) {
573         AUDIO_WARNING_LOG("missing information: sceneMap has no child streamUsage");
574     }
575 }
576 
LoadPostDevice(std::vector<Device> & devices,const xmlNode * fifthNode)577 static void LoadPostDevice(std::vector<Device> &devices, const xmlNode *fifthNode)
578 {
579     CHECK_AND_RETURN_LOG(fifthNode->xmlChildrenNode, "missing information: streamEffectMode has no child devicePort");
580     int32_t countDevice = 0;
581     xmlNode *currNode = fifthNode->xmlChildrenNode;
582     while (currNode != nullptr) {
583         CHECK_AND_RETURN_LOG(countDevice < AUDIO_EFFECT_COUNT_UPPER_LIMIT,
584             "the number of devicePort nodes exceeds limit: %{public}d", AUDIO_EFFECT_COUNT_UPPER_LIMIT);
585         if (currNode->type != XML_ELEMENT_NODE) {
586             currNode = currNode->next;
587             continue;
588         }
589         if (!xmlStrcmp(currNode->name, reinterpret_cast<const xmlChar*>("devicePort"))) {
590             if (!xmlHasProp(currNode, reinterpret_cast<const xmlChar*>("type"))) {
591                 AUDIO_WARNING_LOG("missing information: devicePort has no type attribute");
592             } else if (!xmlHasProp(currNode, reinterpret_cast<const xmlChar*>("effectChain"))) {
593                 AUDIO_WARNING_LOG("missing information: devicePort has no effectChain attribute");
594             } else {
595                 std::string pDevType = reinterpret_cast<char*>
596                            (xmlGetProp(currNode, reinterpret_cast<const xmlChar*>("type")));
597                 std::string pChain = reinterpret_cast<char*>
598                          (xmlGetProp(currNode, reinterpret_cast<const xmlChar*>("effectChain")));
599                 Device tmpdev = {pDevType, pChain};
600                 devices.push_back(tmpdev);
601             }
602         } else {
603             AUDIO_WARNING_LOG("wrong name: %{public}s, should be devicePort", currNode->name);
604         }
605         countDevice++;
606         currNode = currNode->next;
607     }
608     if (countDevice == 0) {
609         AUDIO_WARNING_LOG("missing information: streamEffectMode has no child devicePort");
610     }
611 }
612 
LoadPostMode(PostStreamScene & scene,const xmlNode * fourthNode)613 static void LoadPostMode(PostStreamScene &scene, const xmlNode *fourthNode)
614 {
615     CHECK_AND_RETURN_LOG(fourthNode->xmlChildrenNode,
616         "missing information: stream has no child streamEffectMode");
617     int32_t countMode = 0;
618     int32_t modeNum = 0;
619     xmlNode *currNode = fourthNode->xmlChildrenNode;
620     while (currNode != nullptr) {
621         CHECK_AND_RETURN_LOG(countMode < AUDIO_EFFECT_COUNT_UPPER_LIMIT,
622             "the number of streamEffectMode nodes exceeds limit: %{public}d", AUDIO_EFFECT_COUNT_UPPER_LIMIT);
623         if (currNode->type != XML_ELEMENT_NODE) {
624             currNode = currNode->next;
625             continue;
626         }
627         if (!xmlStrcmp(currNode->name, reinterpret_cast<const xmlChar*>("streamEffectMode"))) {
628             if (!xmlHasProp(currNode, reinterpret_cast<const xmlChar*>("mode"))) {
629                 AUDIO_ERR_LOG("missing information: streamEffectMode has no mode attribute");
630             } else {
631                 std::string pStreamAEMode = reinterpret_cast<char*>
632                                 (xmlGetProp(currNode, reinterpret_cast<const xmlChar*>("mode")));
633                 scene.mode.push_back(pStreamAEMode);
634                 scene.device.push_back({});
635                 LoadPostDevice(scene.device[modeNum], currNode);
636                 modeNum++;
637             }
638         } else {
639             AUDIO_WARNING_LOG("wrong name: %{public}s, should be streamEffectMode", currNode->name);
640         }
641         countMode++;
642         currNode = currNode->next;
643     }
644     if (countMode == 0) {
645         AUDIO_WARNING_LOG("missing information: stream has no child streamEffectMode");
646     }
647 }
648 
LoadPostStreamScenes(std::vector<PostStreamScene> & scenes,xmlNode * thirdNode)649 static void LoadPostStreamScenes(std::vector<PostStreamScene> &scenes, xmlNode *thirdNode)
650 {
651     std::string stream;
652     std::vector<std::string> mode;
653     std::vector<std::vector<Device>> device;
654     PostStreamScene tmp = {stream, mode, device};
655     xmlNode *currNode = thirdNode;
656     int32_t countPostProcess = 0;
657     int32_t streamNum = 0;
658     while (currNode != nullptr) {
659         CHECK_AND_RETURN_LOG(countPostProcess < AUDIO_EFFECT_COUNT_UPPER_LIMIT,
660             "the number of stream nodes exceeds limit: %{public}d", AUDIO_EFFECT_COUNT_UPPER_LIMIT);
661         if (currNode->type != XML_ELEMENT_NODE) {
662             currNode = currNode->next;
663             continue;
664         }
665         if (!xmlStrcmp(currNode->name, reinterpret_cast<const xmlChar*>("stream"))) {
666             if (!xmlHasProp(currNode, reinterpret_cast<const xmlChar*>("scene"))) {
667                 AUDIO_WARNING_LOG("missing information: stream has no scene attribute");
668             } else {
669                 std::string pStreamType = reinterpret_cast<char*>
670                                          (xmlGetProp(currNode, reinterpret_cast<const xmlChar*>("scene")));
671                 tmp.stream = pStreamType;
672                 scenes.push_back(tmp);
673                 LoadPostMode(scenes[streamNum], currNode);
674                 streamNum++;
675             }
676         } else {
677             AUDIO_WARNING_LOG("wrong name: %{public}s, should be stream", currNode->name);
678         }
679         countPostProcess++;
680         currNode = currNode->next;
681     }
682     if (countPostProcess == 0) {
683         AUDIO_WARNING_LOG("missing information: postProcess has no child stream");
684     }
685 }
686 
LoadPostStreamScenesCheck(std::vector<PostStreamScene> & scenes,const xmlNode * currNode,int32_t & nodeCounter)687 static void LoadPostStreamScenesCheck(std::vector<PostStreamScene> &scenes, const xmlNode *currNode,
688                                       int32_t &nodeCounter)
689 {
690     if (nodeCounter >= AUDIO_EFFECT_COUNT_POST_SECOND_NODE_UPPER_LIMIT) {
691         if (nodeCounter == AUDIO_EFFECT_COUNT_POST_SECOND_NODE_UPPER_LIMIT) {
692             nodeCounter++;
693             AUDIO_WARNING_LOG("the number of postprocessStreams nodes exceeds limit: %{public}d",
694                 AUDIO_EFFECT_COUNT_POST_SECOND_NODE_UPPER_LIMIT);
695         }
696     } else if (currNode->xmlChildrenNode) {
697         LoadPostStreamScenes(scenes, currNode->xmlChildrenNode);
698         nodeCounter++;
699     } else {
700         AUDIO_WARNING_LOG("missing information: postprocessStreams has no child stream");
701         nodeCounter++;
702     }
703 }
704 
LoadStreamUsageMappingCheck(OriginalEffectConfig & result,const xmlNode * currNode,int32_t (& countPostSecondNode)[NODE_SIZE_POST])705 static void LoadStreamUsageMappingCheck(OriginalEffectConfig &result, const xmlNode *currNode,
706                                         int32_t (&countPostSecondNode)[NODE_SIZE_POST])
707 {
708     if (countPostSecondNode[INDEX_POST_MAPPING] >= AUDIO_EFFECT_COUNT_POST_SECOND_NODE_UPPER_LIMIT) {
709         if (countPostSecondNode[INDEX_POST_MAPPING] == AUDIO_EFFECT_COUNT_POST_SECOND_NODE_UPPER_LIMIT) {
710             countPostSecondNode[INDEX_POST_MAPPING]++;
711             AUDIO_WARNING_LOG("the number of sceneMap nodes exceeds limit: %{public}d",
712                 AUDIO_EFFECT_COUNT_POST_SECOND_NODE_UPPER_LIMIT);
713         }
714     } else if (currNode->xmlChildrenNode) {
715         LoadStreamUsageMapping(result, currNode->xmlChildrenNode);
716         countPostSecondNode[INDEX_POST_MAPPING]++;
717     } else {
718         AUDIO_WARNING_LOG("missing information: sceneMap has no child stream");
719         countPostSecondNode[INDEX_POST_MAPPING]++;
720     }
721 }
722 
LoadPostprocessExceptionCheck(OriginalEffectConfig & result,const xmlNode * currNode,int32_t (& countPostSecondNode)[NODE_SIZE_POST])723 static void LoadPostprocessExceptionCheck(OriginalEffectConfig &result, const xmlNode *currNode,
724                                           int32_t (&countPostSecondNode)[NODE_SIZE_POST])
725 {
726     if (countPostSecondNode[INDEX_POST_EXCEPTION] >= AUDIO_EFFECT_COUNT_POST_SECOND_NODE_UPPER_LIMIT) {
727         if (countPostSecondNode[INDEX_POST_EXCEPTION] == AUDIO_EFFECT_COUNT_POST_SECOND_NODE_UPPER_LIMIT) {
728             countPostSecondNode[INDEX_POST_EXCEPTION]++;
729             AUDIO_ERR_LOG("the number of postprocess nodes with wrong name exceeds limit: %{public}d",
730                 AUDIO_EFFECT_COUNT_POST_SECOND_NODE_UPPER_LIMIT);
731         }
732     } else {
733         AUDIO_WARNING_LOG("wrong name: %{public}s", currNode->name);
734         countPostSecondNode[INDEX_POST_EXCEPTION]++;
735     }
736 }
737 
LoadPostProcessCfg(OriginalEffectConfig & result,xmlNode * secondNode)738 static void LoadPostProcessCfg(OriginalEffectConfig &result, xmlNode *secondNode)
739 {
740     int32_t countPostSecondNode[NODE_SIZE_POST] = {0};
741     xmlNode *currNode = secondNode;
742     while (currNode != nullptr) {
743         if (currNode->type != XML_ELEMENT_NODE) {
744             currNode = currNode->next;
745             continue;
746         }
747 
748         if (!xmlStrcmp(currNode->name, reinterpret_cast<const xmlChar*>("defaultScene"))) {
749             LoadPostStreamScenesCheck(result.postProcess.defaultScenes, currNode,
750                 countPostSecondNode[INDEX_POST_DEFAULT_SCENE]);
751         } else if (!xmlStrcmp(currNode->name, reinterpret_cast<const xmlChar*>("priorScene"))) {
752             LoadPostStreamScenesCheck(result.postProcess.priorScenes, currNode,
753                 countPostSecondNode[INDEX_POST_PRIOR_SCENE]);
754         } else if (!xmlStrcmp(currNode->name, reinterpret_cast<const xmlChar*>("normalScene"))) {
755             int32_t maxExtraNum = 0;
756             if (xmlHasProp(currNode, reinterpret_cast<const xmlChar*>("maxExtSceneNumber"))) {
757                 maxExtraNum = atoi(reinterpret_cast<char*>(xmlGetProp(currNode,
758                     reinterpret_cast<const xmlChar*>("maxExtSceneNumber"))));
759             }
760             result.postProcess.maxExtSceneNum = static_cast<uint32_t>(maxExtraNum);
761             LoadPostStreamScenesCheck(result.postProcess.normalScenes, currNode,
762                 countPostSecondNode[INDEX_POST_NORMAL_SCENE]);
763         } else if (!xmlStrcmp(currNode->name, reinterpret_cast<const xmlChar*>("effectSceneStreams"))) {
764             // TO BE COMPATIBLE WITH OLDER VERSION XML
765             LoadPostStreamScenesCheck(result.postProcess.normalScenes, currNode,
766                 countPostSecondNode[INDEX_POST_NORMAL_SCENE]);
767         } else if (!xmlStrcmp(currNode->name, reinterpret_cast<const xmlChar*>("sceneMap"))) {
768             LoadStreamUsageMappingCheck(result, currNode, countPostSecondNode);
769         } else {
770             LoadPostprocessExceptionCheck(result, currNode, countPostSecondNode);
771         }
772         currNode = currNode->next;
773     }
774 }
775 
LoadEffectConfigPostProcessCfg(OriginalEffectConfig & result,const xmlNode * currNode,int32_t (& countFirstNode)[NODE_SIZE])776 static void LoadEffectConfigPostProcessCfg(OriginalEffectConfig &result, const xmlNode *currNode,
777                                            int32_t (&countFirstNode)[NODE_SIZE])
778 {
779     if (countFirstNode[INDEX_POSTPROCESS] >= AUDIO_EFFECT_COUNT_FIRST_NODE_UPPER_LIMIT) {
780         if (countFirstNode[INDEX_POSTPROCESS] == AUDIO_EFFECT_COUNT_FIRST_NODE_UPPER_LIMIT) {
781             countFirstNode[INDEX_POSTPROCESS]++;
782             AUDIO_WARNING_LOG("the number of postProcess nodes exceeds limit: %{public}d",
783                 AUDIO_EFFECT_COUNT_FIRST_NODE_UPPER_LIMIT);
784         }
785     } else if (currNode->xmlChildrenNode) {
786         LoadPostProcessCfg(result, currNode->xmlChildrenNode);
787         countFirstNode[INDEX_POSTPROCESS]++;
788     } else {
789         AUDIO_WARNING_LOG("missing information: postProcess has no child stream");
790         countFirstNode[INDEX_POSTPROCESS]++;
791     }
792 }
793 
LoadEffectConfigException(OriginalEffectConfig & result,const xmlNode * currNode,int32_t (& countFirstNode)[NODE_SIZE])794 static void LoadEffectConfigException(OriginalEffectConfig &result, const xmlNode *currNode,
795                                       int32_t (&countFirstNode)[NODE_SIZE])
796 {
797     if (countFirstNode[INDEX_EXCEPTION] >= AUDIO_EFFECT_COUNT_UPPER_LIMIT) {
798         if (countFirstNode[INDEX_EXCEPTION] == AUDIO_EFFECT_COUNT_UPPER_LIMIT) {
799             countFirstNode[INDEX_EXCEPTION]++;
800             AUDIO_ERR_LOG("the number of nodes with wrong name exceeds limit: %{public}d",
801                 AUDIO_EFFECT_COUNT_UPPER_LIMIT);
802         }
803     } else {
804         AUDIO_WARNING_LOG("wrong name: %{public}s", currNode->name);
805         countFirstNode[INDEX_EXCEPTION]++;
806     }
807 }
808 
LoadEffectConfig(OriginalEffectConfig & result)809 int32_t AudioEffectConfigParser::LoadEffectConfig(OriginalEffectConfig &result)
810 {
811     int32_t countFirstNode[NODE_SIZE] = {0};
812     xmlDoc *doc = nullptr;
813     xmlNode *rootElement = nullptr;
814 
815     int32_t ret = ParseEffectConfigFile(doc);
816     CHECK_AND_RETURN_RET_LOG(ret == 0, ret, "error: could not parse audio effect config file");
817 
818     rootElement = xmlDocGetRootElement(doc);
819     xmlNode *currNode = rootElement;
820 
821     if (LoadConfigCheck(doc, currNode) == 0) {
822         LoadConfigVersion(result, currNode);
823         currNode = currNode->xmlChildrenNode;
824     } else {
825         return FILE_CONTENT_ERROR;
826     }
827 
828     while (currNode != nullptr) {
829         if (currNode->type != XML_ELEMENT_NODE) {
830             currNode = currNode->next;
831             continue;
832         }
833 
834         if (!xmlStrcmp(currNode->name, reinterpret_cast<const xmlChar*>("libraries"))) {
835             LoadEffectConfigLibraries(result, currNode, countFirstNode);
836         } else if (!xmlStrcmp(currNode->name, reinterpret_cast<const xmlChar*>("effects"))) {
837             LoadEffectConfigEffects(result, currNode, countFirstNode);
838         } else if (!xmlStrcmp(currNode->name, reinterpret_cast<const xmlChar*>("effectChains"))) {
839             LoadEffectConfigEffectChains(result, currNode, countFirstNode);
840         } else if (!xmlStrcmp(currNode->name, reinterpret_cast<const xmlChar*>("preProcess"))) {
841             LoadEffectConfigPreProcessCfg(result, currNode, countFirstNode);
842         } else if (!xmlStrcmp(currNode->name, reinterpret_cast<const xmlChar*>("postProcess"))) {
843             LoadEffectConfigPostProcessCfg(result, currNode, countFirstNode);
844         } else {
845             LoadEffectConfigException(result, currNode, countFirstNode);
846         }
847 
848         currNode = currNode->next;
849     }
850 
851     for (int32_t i = 0; i < MODULE_SIZE; i++) {
852         if (countFirstNode[i] == 0) {
853             AUDIO_WARNING_LOG("missing information: %{public}s", EFFECT_CONFIG_NAME[i].c_str());
854         }
855     }
856 
857     if (doc) {
858         xmlFreeDoc(doc);
859     }
860     return 0;
861 }
862 } // namespace AudioStandard
863 } // namespace OHOS