OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <math.h> | 5 #include <math.h> |
6 #include <sapi.h> | 6 #include <sapi.h> |
7 | 7 |
8 #include "base/memory/singleton.h" | 8 #include "base/memory/singleton.h" |
9 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
10 #include "base/utf_string_conversions.h" | 10 #include "base/utf_string_conversions.h" |
(...skipping 10 matching lines...) Expand all Loading... |
21 | 21 |
22 virtual bool Speak( | 22 virtual bool Speak( |
23 int utterance_id, | 23 int utterance_id, |
24 const std::string& utterance, | 24 const std::string& utterance, |
25 const std::string& lang, | 25 const std::string& lang, |
26 const VoiceData& voice, | 26 const VoiceData& voice, |
27 const UtteranceContinuousParameters& params); | 27 const UtteranceContinuousParameters& params); |
28 | 28 |
29 virtual bool StopSpeaking(); | 29 virtual bool StopSpeaking(); |
30 | 30 |
| 31 virtual void Pause(); |
| 32 |
| 33 virtual void Resume(); |
| 34 |
31 virtual bool IsSpeaking(); | 35 virtual bool IsSpeaking(); |
32 | 36 |
33 virtual void GetVoices(std::vector<VoiceData>* out_voices) OVERRIDE; | 37 virtual void GetVoices(std::vector<VoiceData>* out_voices) OVERRIDE; |
34 | 38 |
35 // Get the single instance of this class. | 39 // Get the single instance of this class. |
36 static TtsPlatformImplWin* GetInstance(); | 40 static TtsPlatformImplWin* GetInstance(); |
37 | 41 |
38 static void __stdcall SpeechEventCallback(WPARAM w_param, LPARAM l_param); | 42 static void __stdcall SpeechEventCallback(WPARAM w_param, LPARAM l_param); |
39 | 43 |
40 private: | 44 private: |
41 TtsPlatformImplWin(); | 45 TtsPlatformImplWin(); |
42 virtual ~TtsPlatformImplWin() {} | 46 virtual ~TtsPlatformImplWin() {} |
43 | 47 |
44 void OnSpeechEvent(); | 48 void OnSpeechEvent(); |
45 | 49 |
46 base::win::ScopedComPtr<ISpVoice> speech_synthesizer_; | 50 base::win::ScopedComPtr<ISpVoice> speech_synthesizer_; |
47 | 51 |
48 // These apply to the current utterance only. | 52 // These apply to the current utterance only. |
49 std::wstring utterance_; | 53 std::wstring utterance_; |
50 int utterance_id_; | 54 int utterance_id_; |
51 int prefix_len_; | 55 int prefix_len_; |
52 ULONG stream_number_; | 56 ULONG stream_number_; |
53 int char_position_; | 57 int char_position_; |
| 58 bool paused_; |
54 | 59 |
55 friend struct DefaultSingletonTraits<TtsPlatformImplWin>; | 60 friend struct DefaultSingletonTraits<TtsPlatformImplWin>; |
56 | 61 |
57 DISALLOW_COPY_AND_ASSIGN(TtsPlatformImplWin); | 62 DISALLOW_COPY_AND_ASSIGN(TtsPlatformImplWin); |
58 }; | 63 }; |
59 | 64 |
60 // static | 65 // static |
61 TtsPlatformImpl* TtsPlatformImpl::GetInstance() { | 66 TtsPlatformImpl* TtsPlatformImpl::GetInstance() { |
62 return TtsPlatformImplWin::GetInstance(); | 67 return TtsPlatformImplWin::GetInstance(); |
63 } | 68 } |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 bool TtsPlatformImplWin::StopSpeaking() { | 123 bool TtsPlatformImplWin::StopSpeaking() { |
119 if (speech_synthesizer_.get()) { | 124 if (speech_synthesizer_.get()) { |
120 // Clear the stream number so that any further events relating to this | 125 // Clear the stream number so that any further events relating to this |
121 // utterance are ignored. | 126 // utterance are ignored. |
122 stream_number_ = 0; | 127 stream_number_ = 0; |
123 | 128 |
124 if (IsSpeaking()) { | 129 if (IsSpeaking()) { |
125 // Stop speech by speaking the empty string with the purge flag. | 130 // Stop speech by speaking the empty string with the purge flag. |
126 speech_synthesizer_->Speak(L"", SPF_ASYNC | SPF_PURGEBEFORESPEAK, NULL); | 131 speech_synthesizer_->Speak(L"", SPF_ASYNC | SPF_PURGEBEFORESPEAK, NULL); |
127 } | 132 } |
| 133 if (paused_) { |
| 134 speech_synthesizer_->Resume(); |
| 135 paused_ = false; |
| 136 } |
128 } | 137 } |
129 return true; | 138 return true; |
130 } | 139 } |
131 | 140 |
| 141 void TtsPlatformImplWin::Pause() { |
| 142 if (speech_synthesizer_.get() && utterance_id_ && !paused_) { |
| 143 speech_synthesizer_->Pause(); |
| 144 paused_ = true; |
| 145 TtsController::GetInstance()->OnTtsEvent( |
| 146 utterance_id_, TTS_EVENT_PAUSE, char_position_, ""); |
| 147 } |
| 148 } |
| 149 |
| 150 void TtsPlatformImplWin::Resume() { |
| 151 if (speech_synthesizer_.get() && utterance_id_ && paused_) { |
| 152 speech_synthesizer_->Resume(); |
| 153 paused_ = false; |
| 154 TtsController::GetInstance()->OnTtsEvent( |
| 155 utterance_id_, TTS_EVENT_RESUME, char_position_, ""); |
| 156 } |
| 157 } |
| 158 |
132 bool TtsPlatformImplWin::IsSpeaking() { | 159 bool TtsPlatformImplWin::IsSpeaking() { |
133 if (speech_synthesizer_.get()) { | 160 if (speech_synthesizer_.get()) { |
134 SPVOICESTATUS status; | 161 SPVOICESTATUS status; |
135 HRESULT result = speech_synthesizer_->GetStatus(&status, NULL); | 162 HRESULT result = speech_synthesizer_->GetStatus(&status, NULL); |
136 if (result == S_OK) { | 163 if (result == S_OK) { |
137 if (status.dwRunningState == 0 || // 0 == waiting to speak | 164 if (status.dwRunningState == 0 || // 0 == waiting to speak |
138 status.dwRunningState == SPRS_IS_SPEAKING) { | 165 status.dwRunningState == SPRS_IS_SPEAKING) { |
139 return true; | 166 return true; |
140 } | 167 } |
141 } | 168 } |
142 } | 169 } |
143 return false; | 170 return false; |
144 } | 171 } |
145 | 172 |
146 void TtsPlatformImplWin::GetVoices( | 173 void TtsPlatformImplWin::GetVoices( |
147 std::vector<VoiceData>* out_voices) { | 174 std::vector<VoiceData>* out_voices) { |
148 // TODO: get all voices, not just default voice. | 175 // TODO: get all voices, not just default voice. |
149 // http://crbug.com/88059 | 176 // http://crbug.com/88059 |
150 out_voices->push_back(VoiceData()); | 177 out_voices->push_back(VoiceData()); |
151 VoiceData& voice = out_voices->back(); | 178 VoiceData& voice = out_voices->back(); |
152 voice.native = true; | 179 voice.native = true; |
153 voice.name = "native"; | 180 voice.name = "native"; |
154 voice.events.insert(TTS_EVENT_START); | 181 voice.events.insert(TTS_EVENT_START); |
155 voice.events.insert(TTS_EVENT_END); | 182 voice.events.insert(TTS_EVENT_END); |
156 voice.events.insert(TTS_EVENT_MARKER); | 183 voice.events.insert(TTS_EVENT_MARKER); |
157 voice.events.insert(TTS_EVENT_WORD); | 184 voice.events.insert(TTS_EVENT_WORD); |
158 voice.events.insert(TTS_EVENT_SENTENCE); | 185 voice.events.insert(TTS_EVENT_SENTENCE); |
| 186 voice.events.insert(TTS_EVENT_PAUSE); |
| 187 voice.events.insert(TTS_EVENT_RESUME); |
159 } | 188 } |
160 | 189 |
161 void TtsPlatformImplWin::OnSpeechEvent() { | 190 void TtsPlatformImplWin::OnSpeechEvent() { |
162 TtsController* controller = TtsController::GetInstance(); | 191 TtsController* controller = TtsController::GetInstance(); |
163 SPEVENT event; | 192 SPEVENT event; |
164 while (S_OK == speech_synthesizer_->GetEvents(1, &event, NULL)) { | 193 while (S_OK == speech_synthesizer_->GetEvents(1, &event, NULL)) { |
165 if (event.ulStreamNum != stream_number_) | 194 if (event.ulStreamNum != stream_number_) |
166 continue; | 195 continue; |
167 | 196 |
168 switch (event.eEventId) { | 197 switch (event.eEventId) { |
(...skipping 23 matching lines...) Expand all Loading... |
192 std::string()); | 221 std::string()); |
193 break; | 222 break; |
194 } | 223 } |
195 } | 224 } |
196 } | 225 } |
197 | 226 |
198 TtsPlatformImplWin::TtsPlatformImplWin() | 227 TtsPlatformImplWin::TtsPlatformImplWin() |
199 : utterance_id_(0), | 228 : utterance_id_(0), |
200 prefix_len_(0), | 229 prefix_len_(0), |
201 stream_number_(0), | 230 stream_number_(0), |
202 char_position_(0) { | 231 char_position_(0), |
| 232 paused_(false) { |
203 speech_synthesizer_.CreateInstance(CLSID_SpVoice); | 233 speech_synthesizer_.CreateInstance(CLSID_SpVoice); |
204 if (speech_synthesizer_.get()) { | 234 if (speech_synthesizer_.get()) { |
205 ULONGLONG event_mask = | 235 ULONGLONG event_mask = |
206 SPFEI(SPEI_START_INPUT_STREAM) | | 236 SPFEI(SPEI_START_INPUT_STREAM) | |
207 SPFEI(SPEI_TTS_BOOKMARK) | | 237 SPFEI(SPEI_TTS_BOOKMARK) | |
208 SPFEI(SPEI_WORD_BOUNDARY) | | 238 SPFEI(SPEI_WORD_BOUNDARY) | |
209 SPFEI(SPEI_SENTENCE_BOUNDARY) | | 239 SPFEI(SPEI_SENTENCE_BOUNDARY) | |
210 SPFEI(SPEI_END_INPUT_STREAM); | 240 SPFEI(SPEI_END_INPUT_STREAM); |
211 speech_synthesizer_->SetInterest(event_mask, event_mask); | 241 speech_synthesizer_->SetInterest(event_mask, event_mask); |
212 speech_synthesizer_->SetNotifyCallbackFunction( | 242 speech_synthesizer_->SetNotifyCallbackFunction( |
213 TtsPlatformImplWin::SpeechEventCallback, 0, 0); | 243 TtsPlatformImplWin::SpeechEventCallback, 0, 0); |
214 } | 244 } |
215 } | 245 } |
216 | 246 |
217 // static | 247 // static |
218 TtsPlatformImplWin* TtsPlatformImplWin::GetInstance() { | 248 TtsPlatformImplWin* TtsPlatformImplWin::GetInstance() { |
219 return Singleton<TtsPlatformImplWin, | 249 return Singleton<TtsPlatformImplWin, |
220 LeakySingletonTraits<TtsPlatformImplWin> >::get(); | 250 LeakySingletonTraits<TtsPlatformImplWin> >::get(); |
221 } | 251 } |
222 | 252 |
223 // static | 253 // static |
224 void TtsPlatformImplWin::SpeechEventCallback( | 254 void TtsPlatformImplWin::SpeechEventCallback( |
225 WPARAM w_param, LPARAM l_param) { | 255 WPARAM w_param, LPARAM l_param) { |
226 GetInstance()->OnSpeechEvent(); | 256 GetInstance()->OnSpeechEvent(); |
227 } | 257 } |
OLD | NEW |