1 /* Copyright (C) 2013, 2020  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/voice.hpp"
17 #include "core/hts_label.hpp"
18 
19 namespace RHVoice
20 {
calculate_speech_param(double absolute_change,double relative_change,const numeric_property<double> & default_setting,const numeric_property<double> & min_setting,const numeric_property<double> & max_setting,bool clip) const21   double hts_label::calculate_speech_param(double absolute_change,double relative_change,const numeric_property<double>& default_setting,const numeric_property<double>& min_setting,const numeric_property<double>& max_setting,bool clip) const
22   {
23     double default_value=default_setting;
24     double min_value=min_setting;
25     double max_value=max_setting;
26     if(!(min_value<=max_value))
27       return 1;
28     if(default_value>max_value)
29       default_value=max_value;
30     else if(default_value<min_value)
31       default_value=min_value;
32     double result=default_value;
33     if(absolute_change>0)
34       {
35         if(absolute_change>=1)
36           result=max_value;
37         else
38           result+=absolute_change*(max_value-default_value);
39       }
40     else if(absolute_change<0)
41       {
42         if(absolute_change<=-1)
43           result=min_value;
44         else
45           result+=absolute_change*(default_value-min_value);
46       }
47     result*=relative_change;
48     if(!clip)
49       {
50         min_value=min_setting.get_min();
51         max_value=max_setting.get_max();
52 }
53     if(result<min_value)
54       result=min_value;
55     else if(result>max_value)
56       result=max_value;
57     return result;
58   }
59 
get_token() const60   const item* hts_label::get_token() const
61   {
62     if(segment->in("Transcription"))
63       return &(segment->as("Transcription").parent().as("TokStructure").parent());
64     else if(segment->has_next())
65       return &(segment->next().as("Transcription").parent().as("TokStructure").parent());
66     else if(segment->has_prev())
67       return &(segment->prev().as("Transcription").parent().as("TokStructure").parent());
68     else
69       return 0;
70   }
71 
get_rate() const72   double hts_label::get_rate() const
73   {
74     const utterance& utt=segment->get_relation().get_utterance();
75     const voice_params&voice_settings=utt.get_voice().get_info().settings;
76     double absolute_rate=utt.get_absolute_rate();
77     double relative_rate=utt.get_relative_rate();
78     bool clip_rate=(utt.get_flags()&RHVoice_synth_flag_dont_clip_rate)?false:true;
79     double rate=calculate_speech_param(absolute_rate,
80                                         relative_rate,
81                                         voice_settings.default_rate,
82                                        voice_settings.min_rate,
83                                        voice_settings.max_rate,
84 clip_rate);
85     return rate;
86   }
87 
get_pitch() const88   double hts_label::get_pitch() const
89   {
90     const utterance& utt=segment->get_relation().get_utterance();
91     const voice_params&voice_settings=utt.get_voice().get_info().settings;
92     double absolute_pitch=utt.get_absolute_pitch();
93     double relative_pitch=utt.get_relative_pitch();
94     if(const item* token=get_token())
95       if(token->get("verbosity").as<verbosity_t>()&verbosity_pitch)
96         relative_pitch*=voice_settings.cap_pitch_factor;
97     double pitch=calculate_speech_param(absolute_pitch,
98                                         relative_pitch,
99                                         voice_settings.default_pitch,
100                                         voice_settings.min_pitch,
101                                         voice_settings.max_pitch,
102 true);
103     return pitch;
104   }
105 
get_volume() const106   double hts_label::get_volume() const
107   {
108     const utterance& utt=segment->get_relation().get_utterance();
109     const voice_params&voice_settings=utt.get_voice().get_info().settings;
110     double absolute_volume=utt.get_absolute_volume();
111     double relative_volume=utt.get_relative_volume();
112     double volume=calculate_speech_param(absolute_volume,
113                                         relative_volume,
114                                         voice_settings.default_volume,
115                                         voice_settings.min_volume,
116                                          voice_settings.max_volume,
117 true);
118     return volume;
119   }
120 
is_marked_by_sound_icon() const121   bool hts_label::is_marked_by_sound_icon() const
122   {
123     if(segment->in("Transcription"))
124       {
125         const item& seg_in_word=segment->as("Transcription");
126         if(!seg_in_word.has_prev())
127           {
128             const item& word=seg_in_word.parent().as("TokStructure");
129             if(!word.has_prev())
130               {
131                 const item& token=word.parent();
132                 if(token.get("verbosity").as<verbosity_t>()&verbosity_sound)
133                   return true;
134               }
135           }
136       }
137     return false;
138   }
139 
get_name() const140   const std::string& hts_label::get_name() const
141     {
142       if(name.empty())
143         {
144           const hts_labeller& labeller=segment->get_relation().get_utterance().get_language().get_hts_labeller();
145           name=labeller.eval_segment_label(*segment);
146         }
147       return name;
148     }
149 }
150