1 /* Copyright (C) 2012, 2018, 2019  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 #ifndef RHVOICE_VOICE_HPP
17 #define RHVOICE_VOICE_HPP
18 
19 #include <string>
20 #include <functional>
21 #include <set>
22 #include "RHVoice_common.h"
23 
24 #include "str.hpp"
25 #include "property.hpp"
26 #include "resource.hpp"
27 #include "params.hpp"
28 #include "language.hpp"
29 #include "sample_rate.hpp"
30 #include "hts_engine_pool.hpp"
31 #include "hts_engine_call.hpp"
32 
33 namespace RHVoice
34 {
35   class utterance;
36   class client;
37   class voice_info;
38 
39 class voice
40 {
41 public:
42   explicit voice(const voice_info& info);
43 
get_info() const44   const voice_info& get_info() const
45   {
46     return info;
47   }
48 
49   bool synthesize(const utterance& u,client& c) const;
50 
51 private:
52   voice(const voice&);
53   voice& operator=(const voice&);
54 
55   const voice_info& info;
56   mutable hts_engine_pool engine_pool;
57 };
58 
59   class voice_info: public resource_info<voice>
60   {
61   public:
62     voice_info(unsigned int fmt,const std::string& data_path,language_list& languages);
63 
get_language() const64     language_list::const_iterator get_language() const
65     {
66       return voice_language;
67     }
68 
get_alpha2_country_code() const69     const std::string& get_alpha2_country_code() const
70     {
71       return alpha2_country_code;
72     }
73 
get_alpha3_country_code() const74     const std::string& get_alpha3_country_code() const
75     {
76       return alpha3_country_code;
77     }
78 
get_sample_rate() const79     sample_rate_t get_sample_rate() const
80     {
81       return sample_rate;
82     }
83 
get_gender() const84     RHVoice_voice_gender get_gender() const
85     {
86       return gender;
87     }
88 
get_country() const89     std::string get_country() const
90     {
91       if(country.is_set())
92         return country;
93       else
94         return voice_language->get_country();
95     }
96 
get_format() const97     unsigned int get_format() const
98     {
99       return format;
100     }
101 
102     voice_params settings;
103 
104     void register_settings(config& cfg);
105 
is_enabled() const106     virtual bool is_enabled() const
107     {
108       return enabled&&voice_language->is_enabled();
109     }
110 
is_preferred() const111     bool is_preferred() const
112     {
113       return preferred;
114     }
115 
supports_utt_type(const std::string & ut) const116     bool supports_utt_type(const std::string& ut) const
117     {
118       if(ut=="s")
119         return true;
120       return extra_utt_types.includes(ut);
121 }
122 
123   private:
create_instance() const124     std::shared_ptr<voice> create_instance() const
125     {
126       return std::shared_ptr<voice>(new voice(*this));
127     }
128 
129     const unsigned int format;
130     language_list::const_iterator voice_language;
131     std::string alpha2_country_code;
132     std::string alpha3_country_code;
133     sample_rate_property sample_rate;
134     enum_property<RHVoice_voice_gender> gender;
135     bool_property enabled,preferred;
136     string_property country;
137     stringset_property extra_utt_types;
138   };
139 
140   class voice_list: public resource_list<voice_info>
141   {
142   public:
143     voice_list(const std::vector<std::string>& voice_paths,language_list& languages,const event_logger& logger);
144   };
145 
146   class voice_search_criteria: public std::unary_function<const voice_info&,bool>
147   {
148   public:
voice_search_criteria()149     voice_search_criteria():
150       voice_language(0),
151       preferred(false)
152     {
153     }
154 
add_name(const std::string & name)155     void add_name(const std::string& name)
156     {
157       names.insert(name);
158     }
159 
160     template<typename input_iterator>
add_names(input_iterator start,input_iterator end)161     void add_names(input_iterator start,input_iterator end)
162     {
163       names.insert(start,end);
164     }
165 
clear_names()166     void clear_names()
167     {
168       names.clear();
169     }
170 
set_language(const language_info & lang)171     void set_language(const language_info& lang)
172     {
173       voice_language=&lang;
174     }
175 
clear_language()176     void clear_language()
177     {
178       voice_language=0;
179     }
180 
set_preferred()181     void set_preferred()
182     {
183       preferred=true;
184     }
185 
clear_preferred()186     void clear_preferred()
187     {
188       preferred=false;
189     }
190 
191     bool operator()(const voice_info& info) const;
192 
empty() const193     bool empty() const
194     {
195       return (names.empty()&&
196               (voice_language==0)&&
197               (!preferred));
198     }
199 
200   private:
201     std::set<std::string,str::less> names;
202     const language_info* voice_language;
203     bool preferred;
204   };
205 }
206 #endif
207