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