1 /* Copyright (C) 2012, 2018 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 "core/path.hpp" 17 #include "core/exception.hpp" 18 #include "core/config.hpp" 19 #include "core/voice.hpp" 20 #include "core/event_logger.hpp" 21 22 namespace RHVoice 23 { voice(const voice_info & info_)24 voice::voice(const voice_info& info_): 25 info(info_), 26 engine_pool(info_) 27 { 28 } 29 synthesize(const utterance & u,client & c) const30 bool voice::synthesize(const utterance& u,client& c) const 31 { 32 hts_engine_call call(engine_pool,u,c); 33 return call.execute(); 34 } 35 voice_info(unsigned int fmt,const std::string & data_path,language_list & languages)36 voice_info::voice_info(unsigned int fmt,const std::string& data_path,language_list& languages): 37 format(fmt), 38 gender("gender",RHVoice_voice_gender_unknown), 39 enabled("enabled",true), 40 preferred("preferred",false), 41 country("country"), 42 extra_utt_types("extra_utt_types") 43 { 44 gender.define("male",RHVoice_voice_gender_male); 45 gender.define("female",RHVoice_voice_gender_female); 46 set_data_path(data_path); 47 string_property name("name"); 48 enum_string_property language_name("language"); 49 for(language_list::const_iterator it(languages.begin());it!=languages.end();++it) 50 { 51 language_name.define(it->get_name()); 52 } 53 config cfg; 54 cfg.register_setting(name); 55 cfg.register_setting(language_name); 56 cfg.register_setting(country); 57 cfg.register_setting(sample_rate); 58 cfg.register_setting(gender); 59 cfg.register_setting(extra_utt_types); 60 cfg.load(path::join(data_path,"voice.info")); 61 if(!name.is_set()) 62 throw file_format_error("Voice name is not set"); 63 set_name(name); 64 if(!language_name.is_set()) 65 throw file_format_error("Voice language is not set"); 66 language_list::iterator lang=languages.find(language_name); 67 voice_language=lang; 68 settings.default_to(voice_language->voice_settings); 69 std::string c(get_country()); 70 if(c.size()>=3) 71 { 72 alpha3_country_code=c.substr(c.size()-3,3); 73 if(c.size()==6) 74 alpha2_country_code=c.substr(0,2); 75 } 76 } 77 register_settings(config & cfg)78 void voice_info::register_settings(config& cfg) 79 { 80 std::string prefix("voices."+get_name()); 81 settings.register_self(cfg,prefix); 82 cfg.register_setting(enabled,prefix); 83 cfg.register_setting(preferred,prefix); 84 } 85 voice_list(const std::vector<std::string> & voice_paths,language_list & languages,const event_logger & logger)86 voice_list::voice_list(const std::vector<std::string>& voice_paths,language_list& languages,const event_logger& logger) 87 { 88 std::string tag("voice_list"); 89 for(std::vector<std::string>::const_iterator it=voice_paths.begin();it!=voice_paths.end();++it) 90 { 91 if(path::isdir(*it)) 92 { 93 logger.log(tag,RHVoice_log_level_info,std::string("Path: ")+(*it)); 94 std::shared_ptr<voice_info> v; 95 version_info ver; 96 try 97 { 98 resource_description desc("voice",*it); 99 logger.log(tag,RHVoice_log_level_info,std::string("Voice resource: ")+desc.name.get()+std::string(", format: ")+str::to_string(desc.format.get())+std::string(", revision: ")+str::to_string(desc.revision.get())); 100 ver=version_info(desc.format,desc.revision); 101 if(desc.format>=3&&can_add(desc.name,ver)) 102 v.reset(new voice_info(desc.format,*it,languages)); 103 else 104 logger.log(tag,RHVoice_log_level_error,"Unsupported voice format"); 105 } 106 catch(...) 107 { 108 logger.log(tag,RHVoice_log_level_error,"Voice info creation failed"); 109 } 110 if(v) 111 add(v,ver); 112 } 113 } 114 } 115 operator ()(const voice_info & info) const116 bool voice_search_criteria::operator()(const voice_info& info) const 117 { 118 const language_info& lang=*(info.get_language()); 119 if((voice_language==0)||(voice_language==&lang)) 120 if(names.empty()||(names.find(info.get_name())!=names.end())) 121 if(!preferred||info.is_preferred()) 122 return true; 123 return false; 124 } 125 } 126