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 General Public License as published by */
5 /* the Free Software Foundation, either version 2 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 General Public License for more details. */
12 
13 /* You should have received a copy of the GNU General Public License */
14 /* along with this program.  If not, see <http://www.gnu.org/licenses/>. */
15 
16 #ifndef RHVOICE_SD_SPEECH_PLAYER_HPP
17 #define RHVOICE_SD_SPEECH_PLAYER_HPP
18 
19 #include <vector>
20 
21 #include "core/threading.hpp"
22 #include "base.hpp"
23 #include "state.hpp"
24 
25 namespace RHVoice
26 {
27   namespace sd
28   {
29     class synth_result: public base
30     {
31     public:
~synth_result()32       virtual ~synth_result()
33       {
34       }
35 
36       virtual void output()=0;
37 
38     protected:
39       enum event_id
40         {
41           event_index_mark=700,
42           event_begin=701,
43           event_end=702,
44           event_stop=703,
45           event_pause=704
46         };
47 
48       struct event
49       {
50         event_id id;
51         std::string name;
52         std::string content;
53 
eventRHVoice::sd::synth_result::event54         event(event_id id_,const std::string& name_,const std::string& content_=""):
55           id(id_),
56           name(name_),
57           content(content_)
58         {
59         }
60       };
61 
62       static const event started_speaking;
63       static const event stopped_speaking;
64       static const event paused_speaking;
65       static const event finished_speaking;
66 
67       struct reached_index_mark: public event
68       {
reached_index_markRHVoice::sd::synth_result::reached_index_mark69         explicit reached_index_mark(const std::string& mark):
70           event(event_index_mark,"INDEX MARK",mark)
71         {
72         }
73       };
74 
75       void report_event(const event& e);
76     };
77 
78     typedef std::shared_ptr<synth_result> synth_result_ptr;
79 
80     class start_of_speech: public synth_result
81     {
82     public:
83       void output();
84     };
85 
86     class end_of_speech: public synth_result
87     {
88     public:
89       void output();
90 
91     private:
92       event which_event();
93       void clear_state();
94 
95     };
96 
97     class speech_chunk: public synth_result
98     {
99     public:
speech_chunk(const short * samples,std::size_t count)100       explicit speech_chunk(const short* samples,std::size_t count):
101         data(samples,samples+count)
102       {
103       }
104 
105       void output();
106 
107     private:
108       std::vector<short> data;
109     };
110 
111     class sample_rate_setting: public synth_result
112     {
113     public:
sample_rate_setting(int sr)114       explicit sample_rate_setting(int sr):
115         sample_rate(sr)
116       {
117       }
118 
119       void output();
120 
121     private:
122       int sample_rate;
123     };
124 
125 
126     class index_mark: public synth_result
127     {
128     public:
index_mark(const std::string & name)129       explicit index_mark(const std::string& name):
130         mark(name)
131       {
132       }
133 
134       void output();
135 
136     private:
check_state()137       bool check_state()
138       {
139         state s;
140         if(s.test(state::stopped)||s.test(state::paused))
141           return false;
142         if(s.test(state::pausing))
143           {
144             s.clear(state::pausing);
145             s.set(state::paused);
146           }
147         return true;
148       }
149 
150       std::string mark;
151     };
152 
153     class speech_player: public base,public threading::thread
154     {
155     public:
enqueue(const synth_result_ptr & ptr)156       void enqueue(const synth_result_ptr& ptr)
157       {
158         speech_queue.push(ptr);
159       }
160 
stop()161       void stop()
162       {
163         speech_queue.stop();
164       }
165 
166     private:
167       void run();
168 
169       threading::queue<synth_result_ptr> speech_queue;
170     };
171   }
172 }
173 #endif
174