| 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 |