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 "chrome/browser/speech/tts_controller.h" | 5 #include "chrome/browser/speech/tts_controller.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/float_util.h" | 10 #include "base/float_util.h" |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
110 // TtsController | 110 // TtsController |
111 // | 111 // |
112 | 112 |
113 // static | 113 // static |
114 TtsController* TtsController::GetInstance() { | 114 TtsController* TtsController::GetInstance() { |
115 return Singleton<TtsController>::get(); | 115 return Singleton<TtsController>::get(); |
116 } | 116 } |
117 | 117 |
118 TtsController::TtsController() | 118 TtsController::TtsController() |
119 : current_utterance_(NULL), | 119 : current_utterance_(NULL), |
| 120 paused_(false), |
120 platform_impl_(NULL) { | 121 platform_impl_(NULL) { |
121 } | 122 } |
122 | 123 |
123 TtsController::~TtsController() { | 124 TtsController::~TtsController() { |
124 if (current_utterance_) { | 125 if (current_utterance_) { |
125 current_utterance_->Finish(); | 126 current_utterance_->Finish(); |
126 delete current_utterance_; | 127 delete current_utterance_; |
127 } | 128 } |
128 | 129 |
129 // Clear any queued utterances too. | 130 // Clear any queued utterances too. |
130 ClearUtteranceQueue(false); // Don't sent events. | 131 ClearUtteranceQueue(false); // Don't sent events. |
131 } | 132 } |
132 | 133 |
133 void TtsController::SpeakOrEnqueue(Utterance* utterance) { | 134 void TtsController::SpeakOrEnqueue(Utterance* utterance) { |
134 if (IsSpeaking() && utterance->can_enqueue()) { | 135 // If we're paused and we get an utterance that can't be queued, |
| 136 // flush the queue but stay in the paused state. |
| 137 if (paused_ && !utterance->can_enqueue()) { |
| 138 Stop(); |
| 139 paused_ = true; |
| 140 return; |
| 141 } |
| 142 |
| 143 if (paused_ || (IsSpeaking() && utterance->can_enqueue())) { |
135 utterance_queue_.push(utterance); | 144 utterance_queue_.push(utterance); |
136 } else { | 145 } else { |
137 Stop(); | 146 Stop(); |
138 SpeakNow(utterance); | 147 SpeakNow(utterance); |
139 } | 148 } |
140 } | 149 } |
141 | 150 |
142 void TtsController::SpeakNow(Utterance* utterance) { | 151 void TtsController::SpeakNow(Utterance* utterance) { |
143 // Get all available voices and try to find a matching voice. | 152 // Get all available voices and try to find a matching voice. |
144 std::vector<VoiceData> voices; | 153 std::vector<VoiceData> voices; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
191 utterance->OnTtsEvent(TTS_EVENT_ERROR, kInvalidCharIndex, | 200 utterance->OnTtsEvent(TTS_EVENT_ERROR, kInvalidCharIndex, |
192 GetPlatformImpl()->error()); | 201 GetPlatformImpl()->error()); |
193 delete utterance; | 202 delete utterance; |
194 return; | 203 return; |
195 } | 204 } |
196 current_utterance_ = utterance; | 205 current_utterance_ = utterance; |
197 } | 206 } |
198 } | 207 } |
199 | 208 |
200 void TtsController::Stop() { | 209 void TtsController::Stop() { |
| 210 paused_ = false; |
201 if (current_utterance_ && !current_utterance_->extension_id().empty()) { | 211 if (current_utterance_ && !current_utterance_->extension_id().empty()) { |
202 #if !defined(OS_ANDROID) | 212 #if !defined(OS_ANDROID) |
203 ExtensionTtsEngineStop(current_utterance_); | 213 ExtensionTtsEngineStop(current_utterance_); |
204 #endif | 214 #endif |
205 } else { | 215 } else { |
206 GetPlatformImpl()->clear_error(); | 216 GetPlatformImpl()->clear_error(); |
207 GetPlatformImpl()->StopSpeaking(); | 217 GetPlatformImpl()->StopSpeaking(); |
208 } | 218 } |
209 | 219 |
210 if (current_utterance_) | 220 if (current_utterance_) |
211 current_utterance_->OnTtsEvent(TTS_EVENT_INTERRUPTED, kInvalidCharIndex, | 221 current_utterance_->OnTtsEvent(TTS_EVENT_INTERRUPTED, kInvalidCharIndex, |
212 std::string()); | 222 std::string()); |
213 FinishCurrentUtterance(); | 223 FinishCurrentUtterance(); |
214 ClearUtteranceQueue(true); // Send events. | 224 ClearUtteranceQueue(true); // Send events. |
215 } | 225 } |
216 | 226 |
| 227 void TtsController::Pause() { |
| 228 paused_ = true; |
| 229 if (current_utterance_ && !current_utterance_->extension_id().empty()) { |
| 230 #if !defined(OS_ANDROID) |
| 231 ExtensionTtsEnginePause(current_utterance_); |
| 232 #endif |
| 233 } else if (current_utterance_) { |
| 234 GetPlatformImpl()->clear_error(); |
| 235 GetPlatformImpl()->Pause(); |
| 236 } |
| 237 } |
| 238 |
| 239 void TtsController::Resume() { |
| 240 paused_ = false; |
| 241 if (current_utterance_ && !current_utterance_->extension_id().empty()) { |
| 242 #if !defined(OS_ANDROID) |
| 243 ExtensionTtsEngineResume(current_utterance_); |
| 244 #endif |
| 245 } else if (current_utterance_) { |
| 246 GetPlatformImpl()->clear_error(); |
| 247 GetPlatformImpl()->Resume(); |
| 248 } else { |
| 249 SpeakNextUtterance(); |
| 250 } |
| 251 } |
| 252 |
217 void TtsController::OnTtsEvent(int utterance_id, | 253 void TtsController::OnTtsEvent(int utterance_id, |
218 TtsEventType event_type, | 254 TtsEventType event_type, |
219 int char_index, | 255 int char_index, |
220 const std::string& error_message) { | 256 const std::string& error_message) { |
221 // We may sometimes receive completion callbacks "late", after we've | 257 // We may sometimes receive completion callbacks "late", after we've |
222 // already finished the utterance (for example because another utterance | 258 // already finished the utterance (for example because another utterance |
223 // interrupted or we got a call to Stop). This is normal and we can | 259 // interrupted or we got a call to Stop). This is normal and we can |
224 // safely just ignore these events. | 260 // safely just ignore these events. |
225 if (!current_utterance_ || utterance_id != current_utterance_->id()) | 261 if (!current_utterance_ || utterance_id != current_utterance_->id()) |
226 return; | 262 return; |
(...skipping 25 matching lines...) Expand all Loading... |
252 if (current_utterance_) { | 288 if (current_utterance_) { |
253 if (!current_utterance_->finished()) | 289 if (!current_utterance_->finished()) |
254 current_utterance_->OnTtsEvent(TTS_EVENT_INTERRUPTED, kInvalidCharIndex, | 290 current_utterance_->OnTtsEvent(TTS_EVENT_INTERRUPTED, kInvalidCharIndex, |
255 std::string()); | 291 std::string()); |
256 delete current_utterance_; | 292 delete current_utterance_; |
257 current_utterance_ = NULL; | 293 current_utterance_ = NULL; |
258 } | 294 } |
259 } | 295 } |
260 | 296 |
261 void TtsController::SpeakNextUtterance() { | 297 void TtsController::SpeakNextUtterance() { |
| 298 if (paused_) |
| 299 return; |
| 300 |
262 // Start speaking the next utterance in the queue. Keep trying in case | 301 // Start speaking the next utterance in the queue. Keep trying in case |
263 // one fails but there are still more in the queue to try. | 302 // one fails but there are still more in the queue to try. |
264 while (!utterance_queue_.empty() && !current_utterance_) { | 303 while (!utterance_queue_.empty() && !current_utterance_) { |
265 Utterance* utterance = utterance_queue_.front(); | 304 Utterance* utterance = utterance_queue_.front(); |
266 utterance_queue_.pop(); | 305 utterance_queue_.pop(); |
267 SpeakNow(utterance); | 306 SpeakNow(utterance); |
268 } | 307 } |
269 } | 308 } |
270 | 309 |
271 void TtsController::RetrySpeakingQueuedUtterances() { | 310 void TtsController::RetrySpeakingQueuedUtterances() { |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
369 | 408 |
370 void TtsController::AddVoicesChangedDelegate(VoicesChangedDelegate* delegate) { | 409 void TtsController::AddVoicesChangedDelegate(VoicesChangedDelegate* delegate) { |
371 voices_changed_delegates_.insert(delegate); | 410 voices_changed_delegates_.insert(delegate); |
372 } | 411 } |
373 | 412 |
374 void TtsController::RemoveVoicesChangedDelegate( | 413 void TtsController::RemoveVoicesChangedDelegate( |
375 VoicesChangedDelegate* delegate) { | 414 VoicesChangedDelegate* delegate) { |
376 voices_changed_delegates_.erase(delegate); | 415 voices_changed_delegates_.erase(delegate); |
377 } | 416 } |
378 | 417 |
OLD | NEW |