1 /*
2 * Copyright (c) 2022 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 #include "audio_tone_parser.h"
16
17 namespace OHOS {
18 namespace AudioStandard {
AudioToneParser()19 AudioToneParser::AudioToneParser()
20 {
21 AUDIO_INFO_LOG("AudioToneParser ctor");
22 }
23
~AudioToneParser()24 AudioToneParser::~AudioToneParser()
25 {
26 }
27
LoadConfig(std::unordered_map<int32_t,std::shared_ptr<ToneInfo>> & toneDescriptorMap)28 int32_t AudioToneParser::LoadConfig(std::unordered_map<int32_t, std::shared_ptr<ToneInfo>> &toneDescriptorMap)
29 {
30 xmlDoc *doc = nullptr;
31 xmlNode *rootElement = nullptr;
32 AUDIO_ERR_LOG("AudioToneParser::LoadConfig");
33 if ((doc = xmlReadFile(AUDIO_TONE_CONFIG_FILE, nullptr, 0)) == nullptr) {
34 AUDIO_ERR_LOG("error: could not parse file %s", AUDIO_TONE_CONFIG_FILE);
35 return ERROR;
36 }
37 rootElement = xmlDocGetRootElement(doc);
38 xmlNode *currNode = rootElement;
39 CHECK_AND_RETURN_RET_LOG(currNode != nullptr, ERROR, "root element is null");
40 if (xmlStrcmp(currNode->name, reinterpret_cast<const xmlChar*>("DTMF"))) {
41 AUDIO_ERR_LOG("Missing tag - DTMF: %s", AUDIO_TONE_CONFIG_FILE);
42 xmlFreeDoc(doc);
43 xmlCleanupParser();
44 return ERROR;
45 }
46 if (currNode->xmlChildrenNode) {
47 currNode = currNode->xmlChildrenNode;
48 } else {
49 AUDIO_ERR_LOG("Missing child - DTMF: %s", AUDIO_TONE_CONFIG_FILE);
50 xmlFreeDoc(doc);
51 xmlCleanupParser();
52 return ERROR;
53 }
54
55 while (currNode != nullptr) {
56 if ((currNode->type == XML_ELEMENT_NODE) &&
57 (!xmlStrcmp(currNode->name, reinterpret_cast<const xmlChar*>("Tones")))) {
58 currNode = currNode->xmlChildrenNode;
59 } else if ((currNode->type == XML_ELEMENT_NODE) &&
60 (!xmlStrcmp(currNode->name, reinterpret_cast<const xmlChar*>("ToneInfo")))) {
61 ParseToneInfo(currNode, toneDescriptorMap);
62 break;
63 } else {
64 currNode = currNode->next;
65 }
66 }
67 if (currNode == nullptr) {
68 AUDIO_ERR_LOG("Missing tag - Tones, ToneInfo: %s", AUDIO_TONE_CONFIG_FILE);
69 }
70 xmlFreeDoc(doc);
71 xmlCleanupParser();
72 return SUCCESS;
73 }
74
ParseToneInfoAttribute(xmlNode * sNode,std::shared_ptr<ToneInfo> ltoneDesc)75 void AudioToneParser::ParseToneInfoAttribute(xmlNode *sNode, std::shared_ptr<ToneInfo> ltoneDesc)
76 {
77 int segCnt = 0;
78 int segInx = 0;
79 while (sNode != nullptr) {
80 if (sNode->type != XML_ELEMENT_NODE) {
81 sNode = sNode->next;
82 continue;
83 }
84 char *pValue = nullptr;
85 if (!xmlStrcmp(sNode->name, reinterpret_cast<const xmlChar*>("RepeatCount"))) {
86 AUDIO_DEBUG_LOG("RepeatCount node type: Element, name: %{public}s", sNode->name);
87 pValue = reinterpret_cast<char*>(xmlGetProp(sNode,
88 reinterpret_cast<xmlChar*>(const_cast<char*>("value"))));
89 if (!xmlStrcmp(reinterpret_cast<const xmlChar*>(pValue), reinterpret_cast<const xmlChar*>("INF"))) {
90 ltoneDesc->repeatCnt = TONEINFO_INF;
91 } else {
92 ltoneDesc->repeatCnt = atoi(pValue);
93 }
94 AUDIO_DEBUG_LOG("ParseToneInfo repeatCnt %{public}d", ltoneDesc->repeatCnt);
95 } else if (!xmlStrcmp(sNode->name, reinterpret_cast<const xmlChar*>("RepeatSegment"))) {
96 AUDIO_DEBUG_LOG("RepeatSegment node type: Element, name: %{public}s", sNode->name);
97 pValue = reinterpret_cast<char*>(xmlGetProp(sNode,
98 reinterpret_cast<xmlChar*>(const_cast<char*>("value"))));
99 ltoneDesc->repeatSegment = atoi(pValue);
100 AUDIO_DEBUG_LOG("ParseToneInfo repeatSegment %{public}d", ltoneDesc->repeatSegment);
101 } else if (!xmlStrcmp(sNode->name, reinterpret_cast<const xmlChar*>("SegmentCount"))) {
102 AUDIO_DEBUG_LOG("SegmentCount node type: Element, name: %{public}s", sNode->name);
103 pValue = reinterpret_cast<char*>(xmlGetProp(sNode,
104 reinterpret_cast<xmlChar*>(const_cast<char*>("value"))));
105 segCnt = atoi(pValue);
106 ltoneDesc->segmentCnt = segCnt;
107 AUDIO_DEBUG_LOG("ParseToneInfo segmentCnt %{public}d", ltoneDesc->segmentCnt);
108 } else if (!xmlStrcmp(sNode->name, reinterpret_cast<const xmlChar*>("Segment"))) {
109 if (segInx < segCnt) {
110 ParseSegment(sNode, segInx, ltoneDesc);
111 segInx++;
112 }
113 }
114 if (pValue != nullptr) {
115 xmlFree(pValue);
116 }
117 sNode = sNode->next;
118 }
119 }
ParseToneInfo(xmlNode * node,std::unordered_map<int32_t,std::shared_ptr<ToneInfo>> & toneDescriptorMap)120 void AudioToneParser::ParseToneInfo(xmlNode *node, std::unordered_map<int32_t,
121 std::shared_ptr<ToneInfo>> &toneDescriptorMap)
122 {
123 xmlNode *currNode = node;
124 while (currNode != nullptr) {
125 if (currNode->type != XML_ELEMENT_NODE) {
126 currNode = currNode->next;
127 continue;
128 }
129 if (!xmlStrcmp(currNode->name, reinterpret_cast<const xmlChar*>("ToneInfo"))) {
130 std::shared_ptr<ToneInfo> ltoneDesc = std::make_shared<ToneInfo>(); // new ToneInfo();
131 AUDIO_DEBUG_LOG("node type: Element, name: %s", currNode->name);
132 char *pToneType = reinterpret_cast<char*>(xmlGetProp(currNode,
133 reinterpret_cast<xmlChar*>(const_cast<char*>("toneType"))));
134 int toneType = atoi(pToneType);
135 AUDIO_DEBUG_LOG("ParseToneInfo toneType %{public}d", toneType);
136 xmlFree(pToneType);
137 if (currNode->xmlChildrenNode) {
138 xmlNode *sNode = currNode->xmlChildrenNode;
139 ParseToneInfoAttribute(sNode, ltoneDesc);
140 }
141 toneDescriptorMap[toneType] = ltoneDesc;
142 }
143 currNode = currNode->next;
144 }
145 }
146
ParseSegment(xmlNode * node,int SegInx,std::shared_ptr<ToneInfo> ltoneDesc)147 void AudioToneParser::ParseSegment(xmlNode *node, int SegInx, std::shared_ptr<ToneInfo> ltoneDesc)
148 {
149 xmlNode *currNode = node;
150 for (uint32_t i = 0; i < TONEINFO_MAX_WAVES + 1; i++) {
151 ltoneDesc->segments[SegInx].waveFreq[i]=0;
152 }
153 if ((currNode->type == XML_ELEMENT_NODE) && (!xmlStrcmp(currNode->name,
154 reinterpret_cast<const xmlChar*>("Segment")))) {
155 char *pValue = reinterpret_cast<char*>(xmlGetProp(currNode,
156 reinterpret_cast<xmlChar*>(const_cast<char*>("duration"))));
157 if (!xmlStrcmp(reinterpret_cast<const xmlChar*>(pValue), reinterpret_cast<const xmlChar*>("INF"))) {
158 ltoneDesc->segments[SegInx].duration = TONEINFO_INF;
159 } else {
160 ltoneDesc->segments[SegInx].duration = atoi(pValue);
161 }
162 AUDIO_DEBUG_LOG("duration: %{public}d", ltoneDesc->segments[SegInx].duration);
163 xmlFree(pValue);
164 pValue = reinterpret_cast<char*>(xmlGetProp(currNode,
165 reinterpret_cast<xmlChar*>(const_cast<char*>("loopCount"))));
166 ltoneDesc->segments[SegInx].loopCnt = atoi(pValue);
167 AUDIO_DEBUG_LOG("loopCnt: %{public}d", ltoneDesc->segments[SegInx].loopCnt);
168 xmlFree(pValue);
169 pValue = reinterpret_cast<char*>(xmlGetProp(currNode,
170 reinterpret_cast<xmlChar*>(const_cast<char*>("loopIndex"))));
171 ltoneDesc->segments[SegInx].loopIndx = atoi(pValue);
172 AUDIO_DEBUG_LOG("loopIndx: %{public}d", ltoneDesc->segments[SegInx].loopIndx);
173 xmlFree(pValue);
174 pValue = reinterpret_cast<char*>(xmlGetProp(currNode,
175 reinterpret_cast<xmlChar*>(const_cast<char*>("freq"))));
176 ParseFrequency(pValue, ltoneDesc->segments[SegInx]);
177 xmlFree(pValue);
178 }
179 }
180
ParseFrequency(std::string freqList,ToneSegment & ltonesegment)181 void AudioToneParser::ParseFrequency (std::string freqList, ToneSegment <onesegment)
182 {
183 std::vector<int> vect;
184 std::stringstream ss(freqList);
185
186 for (int i; ss >> i;) {
187 vect.push_back(i);
188 if (ss.peek() == ',') {
189 ss.ignore();
190 }
191 }
192
193 for (std::size_t i = 0; i < vect.size(); i++) {
194 AUDIO_DEBUG_LOG("Freq: %{public}d", vect[i]);
195 ltonesegment.waveFreq[i] = vect[i];
196 }
197 }
198 } // namespace AudioStandard
199 } // namespace OHOS
200