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" |
11 #include "base/json/json_writer.h" | |
12 #include "base/values.h" | 11 #include "base/values.h" |
13 #include "chrome/browser/extensions/event_router.h" | |
14 #include "chrome/browser/extensions/extension_system.h" | 12 #include "chrome/browser/extensions/extension_system.h" |
15 #include "chrome/browser/profiles/profile.h" | 13 #include "chrome/browser/profiles/profile.h" |
16 #include "chrome/browser/speech/extension_api/tts_engine_extension_api.h" | 14 #include "chrome/browser/speech/extension_api/tts_engine_extension_api.h" |
17 #include "chrome/browser/speech/extension_api/tts_extension_api.h" | 15 #include "chrome/browser/speech/extension_api/tts_extension_api.h" |
18 #include "chrome/browser/speech/extension_api/tts_extension_api_constants.h" | 16 #include "chrome/browser/speech/extension_api/tts_extension_api_constants.h" |
19 #include "chrome/browser/speech/tts_platform.h" | 17 #include "chrome/browser/speech/tts_platform.h" |
20 #include "chrome/common/extensions/api/speech/tts_engine_manifest_handler.h" | 18 #include "chrome/common/extensions/api/speech/tts_engine_manifest_handler.h" |
21 #include "chrome/common/extensions/extension.h" | 19 #include "chrome/common/extensions/extension.h" |
22 | 20 |
23 namespace constants = tts_extension_api_constants; | 21 namespace constants = tts_extension_api_constants; |
24 | 22 |
25 namespace { | 23 namespace { |
26 | |
27 // A value to be used to indicate that there is no char index available. | 24 // A value to be used to indicate that there is no char index available. |
28 const int kInvalidCharIndex = -1; | 25 const int kInvalidCharIndex = -1; |
26 } // namespace | |
29 | 27 |
30 namespace events { | |
31 const char kOnEvent[] = "tts.onEvent"; | |
32 }; // namespace events | |
33 | 28 |
34 std::string TtsEventTypeToString(TtsEventType event_type) { | 29 bool IsFinalTtsEventType(TtsEventType event_type) { |
35 switch (event_type) { | 30 return (event_type == TTS_EVENT_END || |
36 case TTS_EVENT_START: | 31 event_type == TTS_EVENT_INTERRUPTED || |
37 return constants::kEventTypeStart; | 32 event_type == TTS_EVENT_CANCELLED || |
38 case TTS_EVENT_END: | 33 event_type == TTS_EVENT_ERROR); |
39 return constants::kEventTypeEnd; | |
40 case TTS_EVENT_WORD: | |
41 return constants::kEventTypeWord; | |
42 case TTS_EVENT_SENTENCE: | |
43 return constants::kEventTypeSentence; | |
44 case TTS_EVENT_MARKER: | |
45 return constants::kEventTypeMarker; | |
46 case TTS_EVENT_INTERRUPTED: | |
47 return constants::kEventTypeInterrupted; | |
48 case TTS_EVENT_CANCELLED: | |
49 return constants::kEventTypeCancelled; | |
50 case TTS_EVENT_ERROR: | |
51 return constants::kEventTypeError; | |
52 default: | |
53 NOTREACHED(); | |
54 return std::string(); | |
55 } | |
56 } | 34 } |
57 | 35 |
58 } // namespace | |
59 | 36 |
60 // | 37 // |
61 // UtteranceContinuousParameters | 38 // UtteranceContinuousParameters |
62 // | 39 // |
63 | 40 |
64 | 41 |
65 UtteranceContinuousParameters::UtteranceContinuousParameters() | 42 UtteranceContinuousParameters::UtteranceContinuousParameters() |
66 : rate(-1), | 43 : rate(-1), |
67 pitch(-1), | 44 pitch(-1), |
68 volume(-1) {} | 45 volume(-1) {} |
69 | 46 |
70 | 47 |
71 // | 48 // |
49 // VoiceData | |
50 // | |
51 | |
52 | |
53 VoiceData::VoiceData() {} | |
54 | |
55 VoiceData::~VoiceData() {} | |
56 | |
57 | |
58 // | |
72 // Utterance | 59 // Utterance |
73 // | 60 // |
74 | 61 |
75 // static | 62 // static |
76 int Utterance::next_utterance_id_ = 0; | 63 int Utterance::next_utterance_id_ = 0; |
77 | 64 |
78 Utterance::Utterance(Profile* profile) | 65 Utterance::Utterance(Profile* profile) |
79 : profile_(profile), | 66 : profile_(profile), |
80 id_(next_utterance_id_++), | 67 id_(next_utterance_id_++), |
81 src_id_(-1), | 68 src_id_(-1), |
69 event_delegate_(NULL), | |
82 can_enqueue_(false), | 70 can_enqueue_(false), |
83 char_index_(0), | 71 char_index_(0), |
84 finished_(false) { | 72 finished_(false) { |
85 options_.reset(new DictionaryValue()); | 73 options_.reset(new DictionaryValue()); |
86 } | 74 } |
87 | 75 |
88 Utterance::~Utterance() { | 76 Utterance::~Utterance() { |
89 DCHECK(finished_); | 77 DCHECK(finished_); |
90 } | 78 } |
91 | 79 |
92 void Utterance::OnTtsEvent(TtsEventType event_type, | 80 void Utterance::OnTtsEvent(TtsEventType event_type, |
93 int char_index, | 81 int char_index, |
94 const std::string& error_message) { | 82 const std::string& error_message) { |
95 std::string event_type_string = TtsEventTypeToString(event_type); | |
96 if (char_index >= 0) | 83 if (char_index >= 0) |
97 char_index_ = char_index; | 84 char_index_ = char_index; |
98 if (event_type == TTS_EVENT_END || | 85 if (IsFinalTtsEventType(event_type)) |
99 event_type == TTS_EVENT_INTERRUPTED || | |
100 event_type == TTS_EVENT_CANCELLED || | |
101 event_type == TTS_EVENT_ERROR) { | |
102 finished_ = true; | 86 finished_ = true; |
103 } | |
104 if (desired_event_types_.size() > 0 && | |
105 desired_event_types_.find(event_type_string) == | |
106 desired_event_types_.end()) { | |
107 return; | |
108 } | |
109 | 87 |
110 if (src_id_ < 0) | 88 if (event_delegate_) |
111 return; | 89 event_delegate_->OnTtsEvent(this, event_type, char_index, error_message); |
tommi (sloooow) - chröme
2013/03/07 13:04:46
if finished_ is true, then should we set the event
dmazzoni
2013/03/19 17:30:22
Good idea, done.
| |
112 | |
113 DictionaryValue* details = new DictionaryValue(); | |
114 if (char_index != kInvalidCharIndex) | |
115 details->SetInteger(constants::kCharIndexKey, char_index); | |
116 details->SetString(constants::kEventTypeKey, event_type_string); | |
117 if (event_type == TTS_EVENT_ERROR) { | |
118 details->SetString(constants::kErrorMessageKey, error_message); | |
119 } | |
120 details->SetInteger(constants::kSrcIdKey, src_id_); | |
121 details->SetBoolean(constants::kIsFinalEventKey, finished_); | |
122 | |
123 scoped_ptr<ListValue> arguments(new ListValue()); | |
124 arguments->Set(0, details); | |
125 | |
126 scoped_ptr<extensions::Event> event(new extensions::Event( | |
127 events::kOnEvent, arguments.Pass())); | |
128 event->restrict_to_profile = profile_; | |
129 event->event_url = src_url_; | |
130 extensions::ExtensionSystem::Get(profile_)->event_router()-> | |
131 DispatchEventToExtension(src_extension_id_, event.Pass()); | |
132 } | 90 } |
133 | 91 |
134 void Utterance::Finish() { | 92 void Utterance::Finish() { |
135 finished_ = true; | 93 finished_ = true; |
136 } | 94 } |
137 | 95 |
138 void Utterance::set_options(const Value* options) { | 96 void Utterance::set_options(const Value* options) { |
139 options_.reset(options->DeepCopy()); | 97 options_.reset(options->DeepCopy()); |
140 } | 98 } |
141 | 99 |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
245 if (!current_utterance_ || utterance_id != current_utterance_->id()) | 203 if (!current_utterance_ || utterance_id != current_utterance_->id()) |
246 return; | 204 return; |
247 | 205 |
248 current_utterance_->OnTtsEvent(event_type, char_index, error_message); | 206 current_utterance_->OnTtsEvent(event_type, char_index, error_message); |
249 if (current_utterance_->finished()) { | 207 if (current_utterance_->finished()) { |
250 FinishCurrentUtterance(); | 208 FinishCurrentUtterance(); |
251 SpeakNextUtterance(); | 209 SpeakNextUtterance(); |
252 } | 210 } |
253 } | 211 } |
254 | 212 |
255 ListValue* TtsController::GetVoices(Profile* profile) { | 213 void TtsController::GetVoices(Profile* profile, |
256 ListValue* result_voices = new ListValue(); | 214 std::vector<VoiceData>* out_voices) { |
257 TtsPlatformImpl* platform_impl = GetPlatformImpl(); | 215 TtsPlatformImpl* platform_impl = GetPlatformImpl(); |
258 if (platform_impl && platform_impl->PlatformImplAvailable()) { | 216 if (platform_impl && platform_impl->PlatformImplAvailable()) { |
hans
2013/03/09 14:19:52
maybe return early instead when this false?
oh, n
| |
259 DictionaryValue* result_voice = new DictionaryValue(); | 217 out_voices->push_back(VoiceData()); |
260 result_voice->SetString( | 218 VoiceData* voice = &out_voices->back(); |
hans
2013/03/09 14:19:52
i would have gone for a reference here, but no big
dmazzoni
2013/03/19 17:30:22
Done.
| |
261 constants::kVoiceNameKey, constants::kNativeVoiceName); | 219 voice->name = constants::kNativeVoiceName; |
262 if (!platform_impl->gender().empty()) | 220 voice->gender = platform_impl->gender(); |
263 result_voice->SetString(constants::kGenderKey, platform_impl->gender()); | |
264 ListValue* event_types = new ListValue(); | |
265 | 221 |
266 // All platforms must send end events, and cancelled and interrupted | 222 // All platforms must send end events, and cancelled and interrupted |
267 // events are generated from the controller. | 223 // events are generated from the controller. |
268 DCHECK(platform_impl->SendsEvent(TTS_EVENT_END)); | 224 DCHECK(platform_impl->SendsEvent(TTS_EVENT_END)); |
269 event_types->Append(Value::CreateStringValue(constants::kEventTypeEnd)); | 225 voice->events.push_back(constants::kEventTypeEnd); |
270 event_types->Append(Value::CreateStringValue( | 226 voice->events.push_back(constants::kEventTypeCancelled); |
271 constants::kEventTypeCancelled)); | 227 voice->events.push_back(constants::kEventTypeInterrupted); |
272 event_types->Append(Value::CreateStringValue( | |
273 constants::kEventTypeInterrupted)); | |
274 | 228 |
275 if (platform_impl->SendsEvent(TTS_EVENT_START)) | 229 if (platform_impl->SendsEvent(TTS_EVENT_START)) |
276 event_types->Append(Value::CreateStringValue(constants::kEventTypeStart)); | 230 voice->events.push_back(constants::kEventTypeStart); |
277 if (platform_impl->SendsEvent(TTS_EVENT_WORD)) | 231 if (platform_impl->SendsEvent(TTS_EVENT_WORD)) |
278 event_types->Append(Value::CreateStringValue(constants::kEventTypeWord)); | 232 voice->events.push_back(constants::kEventTypeWord); |
279 if (platform_impl->SendsEvent(TTS_EVENT_SENTENCE)) | 233 if (platform_impl->SendsEvent(TTS_EVENT_SENTENCE)) |
280 event_types->Append(Value::CreateStringValue( | 234 voice->events.push_back(constants::kEventTypeSentence); |
281 constants::kEventTypeSentence)); | |
282 if (platform_impl->SendsEvent(TTS_EVENT_MARKER)) | 235 if (platform_impl->SendsEvent(TTS_EVENT_MARKER)) |
283 event_types->Append(Value::CreateStringValue( | 236 voice->events.push_back(constants::kEventTypeMarker); |
284 constants::kEventTypeMarker)); | |
285 if (platform_impl->SendsEvent(TTS_EVENT_ERROR)) | 237 if (platform_impl->SendsEvent(TTS_EVENT_ERROR)) |
286 event_types->Append(Value::CreateStringValue( | 238 voice->events.push_back(constants::kEventTypeError); |
287 constants::kEventTypeError)); | |
288 result_voice->Set(constants::kEventTypesKey, event_types); | |
289 result_voices->Append(result_voice); | |
290 } | 239 } |
291 | 240 |
292 GetExtensionVoices(profile, result_voices); | 241 GetExtensionVoices(profile, out_voices); |
293 | |
294 return result_voices; | |
295 } | 242 } |
296 | 243 |
297 bool TtsController::IsSpeaking() { | 244 bool TtsController::IsSpeaking() { |
298 return current_utterance_ != NULL || GetPlatformImpl()->IsSpeaking(); | 245 return current_utterance_ != NULL || GetPlatformImpl()->IsSpeaking(); |
299 } | 246 } |
300 | 247 |
301 void TtsController::FinishCurrentUtterance() { | 248 void TtsController::FinishCurrentUtterance() { |
302 if (current_utterance_) { | 249 if (current_utterance_) { |
303 if (!current_utterance_->finished()) | 250 if (!current_utterance_->finished()) |
304 current_utterance_->OnTtsEvent(TTS_EVENT_INTERRUPTED, kInvalidCharIndex, | 251 current_utterance_->OnTtsEvent(TTS_EVENT_INTERRUPTED, kInvalidCharIndex, |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
343 | 290 |
344 int TtsController::QueueSize() { | 291 int TtsController::QueueSize() { |
345 return static_cast<int>(utterance_queue_.size()); | 292 return static_cast<int>(utterance_queue_.size()); |
346 } | 293 } |
347 | 294 |
348 TtsPlatformImpl* TtsController::GetPlatformImpl() { | 295 TtsPlatformImpl* TtsController::GetPlatformImpl() { |
349 if (!platform_impl_) | 296 if (!platform_impl_) |
350 platform_impl_ = TtsPlatformImpl::GetInstance(); | 297 platform_impl_ = TtsPlatformImpl::GetInstance(); |
351 return platform_impl_; | 298 return platform_impl_; |
352 } | 299 } |
OLD | NEW |