1 /* Copyright (C) 2012  Olga Yakovleva <yakovleva.o.v@gmail.com> */
2 
3 /* This program is free software: you can redistribute it and/or modify */
4 /* it under the terms of the GNU Lesser General Public License as published by */
5 /* the Free Software Foundation, either version 2.1 of the License, or */
6 /* (at your option) any later version. */
7 
8 /* This program is distributed in the hope that it will be useful, */
9 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
10 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the */
11 /* GNU Lesser General Public License for more details. */
12 
13 /* You should have received a copy of the GNU Lesser General Public License */
14 /* along with this program.  If not, see <http://www.gnu.org/licenses/>. */
15 
16 #include <vector>
17 #include <fstream>
18 #include <iterator>
19 #include <algorithm>
20 #include "rapidxml/rapidxml_iterators.hpp"
21 #include "core/io.hpp"
22 #include "core/phoneme_set.hpp"
23 
24 namespace RHVoice
25 {
phoneme_set(const std::string & file_path)26   phoneme_set::phoneme_set(const std::string& file_path)
27   {
28     std::ifstream infile;
29     io::open_ifstream(infile,file_path);
30     std::vector<char> text;
31     std::copy(std::istreambuf_iterator<char>(infile),std::istreambuf_iterator<char>(),std::back_inserter(text));
32     text.push_back('\0');
33     rapidxml::xml_document<> doc;
34     doc.parse<0>(&text[0]);
35     std::string err_msg("Phoneme set format is incorrect");
36     rapidxml::xml_node<>* root_node=doc.first_node("phonemes");
37     if((root_node==0)||(root_node->type()!=rapidxml::node_element))
38       throw file_format_error(err_msg);
39     rapidxml::node_iterator<char> last_node;
40     rapidxml::attribute_iterator<char> last_attr;
41     std::string attr_name;
42     for(rapidxml::node_iterator<char> node_iter(root_node);node_iter!=last_node;++node_iter)
43       {
44         if(node_iter->type()!=rapidxml::node_element)
45           continue;
46         for(rapidxml::attribute_iterator<char> attr_iter(&(*node_iter));attr_iter!=last_attr;++attr_iter)
47           {
48             attr_name.assign(attr_iter->name(),attr_iter->name_size());
49             if(attr_name!="name")
50               feature_set.insert(attr_name);
51           }
52       }
53     for(rapidxml::node_iterator<char> node_iter(root_node);node_iter!=last_node;++node_iter)
54       {
55         if(node_iter->type()!=rapidxml::node_element)
56           continue;
57         phoneme ph(&(*node_iter),feature_set);
58         phonemes.insert(phoneme_map::value_type(ph.get_name(),ph));
59       }
60   }
61 
phoneme(rapidxml::xml_node<> * element,const phoneme_feature_set & feature_set)62   phoneme::phoneme(rapidxml::xml_node<>* element,const phoneme_feature_set& feature_set)
63   {
64     for(phoneme_feature_set::const_iterator iter(feature_set.begin());iter!=feature_set.end();++iter)
65       {
66         features.insert(phoneme_feature_map::value_type(*iter,"0"));
67       }
68     rapidxml::attribute_iterator<char> last_attr;
69     std::string attr_name;
70     for(rapidxml::attribute_iterator<char> attr_iter(element);attr_iter!=last_attr;++attr_iter)
71       {
72         attr_name.assign(attr_iter->name(),attr_iter->name_size());
73         if(attr_name=="name")
74           name=attr_iter->value();
75         else
76           features[attr_name]=attr_iter->value();
77       }
78   }
79 }
80