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