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); |
112 | 90 if (finished_) |
113 DictionaryValue* details = new DictionaryValue(); | 91 event_delegate_ = NULL; |
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 } | 92 } |
133 | 93 |
134 void Utterance::Finish() { | 94 void Utterance::Finish() { |
135 finished_ = true; | 95 finished_ = true; |
136 } | 96 } |
137 | 97 |
138 void Utterance::set_options(const Value* options) { | 98 void Utterance::set_options(const Value* options) { |
139 options_.reset(options->DeepCopy()); | 99 options_.reset(options->DeepCopy()); |
140 } | 100 } |
141 | 101 |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
245 if (!current_utterance_ || utterance_id != current_utterance_->id()) | 205 if (!current_utterance_ || utterance_id != current_utterance_->id()) |
246 return; | 206 return; |
247 | 207 |
248 current_utterance_->OnTtsEvent(event_type, char_index, error_message); | 208 current_utterance_->OnTtsEvent(event_type, char_index, error_message); |
249 if (current_utterance_->finished()) { | 209 if (current_utterance_->finished()) { |
250 FinishCurrentUtterance(); | 210 FinishCurrentUtterance(); |
251 SpeakNextUtterance(); | 211 SpeakNextUtterance(); |
252 } | 212 } |
253 } | 213 } |
254 | 214 |
255 ListValue* TtsController::GetVoices(Profile* profile) { | 215 void TtsController::GetVoices(Profile* profile, |
256 ListValue* result_voices = new ListValue(); | 216 std::vector<VoiceData>* out_voices) { |
257 TtsPlatformImpl* platform_impl = GetPlatformImpl(); | 217 TtsPlatformImpl* platform_impl = GetPlatformImpl(); |
258 if (platform_impl && platform_impl->PlatformImplAvailable()) { | 218 if (platform_impl && platform_impl->PlatformImplAvailable()) { |
259 DictionaryValue* result_voice = new DictionaryValue(); | 219 out_voices->push_back(VoiceData()); |
260 result_voice->SetString( | 220 VoiceData& voice = out_voices->back(); |
261 constants::kVoiceNameKey, constants::kNativeVoiceName); | 221 voice.name = constants::kNativeVoiceName; |
262 if (!platform_impl->gender().empty()) | 222 voice.gender = platform_impl->gender(); |
263 result_voice->SetString(constants::kGenderKey, platform_impl->gender()); | |
264 ListValue* event_types = new ListValue(); | |
265 | 223 |
266 // All platforms must send end events, and cancelled and interrupted | 224 // All platforms must send end events, and cancelled and interrupted |
267 // events are generated from the controller. | 225 // events are generated from the controller. |
268 DCHECK(platform_impl->SendsEvent(TTS_EVENT_END)); | 226 DCHECK(platform_impl->SendsEvent(TTS_EVENT_END)); |
269 event_types->Append(Value::CreateStringValue(constants::kEventTypeEnd)); | 227 voice.events.push_back(constants::kEventTypeEnd); |
270 event_types->Append(Value::CreateStringValue( | 228 voice.events.push_back(constants::kEventTypeCancelled); |
271 constants::kEventTypeCancelled)); | 229 voice.events.push_back(constants::kEventTypeInterrupted); |
272 event_types->Append(Value::CreateStringValue( | |
273 constants::kEventTypeInterrupted)); | |
274 | 230 |
275 if (platform_impl->SendsEvent(TTS_EVENT_START)) | 231 if (platform_impl->SendsEvent(TTS_EVENT_START)) |
276 event_types->Append(Value::CreateStringValue(constants::kEventTypeStart)); | 232 voice.events.push_back(constants::kEventTypeStart); |
277 if (platform_impl->SendsEvent(TTS_EVENT_WORD)) | 233 if (platform_impl->SendsEvent(TTS_EVENT_WORD)) |
278 event_types->Append(Value::CreateStringValue(constants::kEventTypeWord)); | 234 voice.events.push_back(constants::kEventTypeWord); |
279 if (platform_impl->SendsEvent(TTS_EVENT_SENTENCE)) | 235 if (platform_impl->SendsEvent(TTS_EVENT_SENTENCE)) |
280 event_types->Append(Value::CreateStringValue( | 236 voice.events.push_back(constants::kEventTypeSentence); |
281 constants::kEventTypeSentence)); | |
282 if (platform_impl->SendsEvent(TTS_EVENT_MARKER)) | 237 if (platform_impl->SendsEvent(TTS_EVENT_MARKER)) |
283 event_types->Append(Value::CreateStringValue( | 238 voice.events.push_back(constants::kEventTypeMarker); |
284 constants::kEventTypeMarker)); | |
285 if (platform_impl->SendsEvent(TTS_EVENT_ERROR)) | 239 if (platform_impl->SendsEvent(TTS_EVENT_ERROR)) |
286 event_types->Append(Value::CreateStringValue( | 240 voice.events.push_back(constants::kEventTypeError); |
287 constants::kEventTypeError)); | |
288 result_voice->Set(constants::kEventTypesKey, event_types); | |
289 result_voices->Append(result_voice); | |
290 } | 241 } |
291 | 242 |
292 GetExtensionVoices(profile, result_voices); | 243 GetExtensionVoices(profile, out_voices); |
293 | |
294 return result_voices; | |
295 } | 244 } |
296 | 245 |
297 bool TtsController::IsSpeaking() { | 246 bool TtsController::IsSpeaking() { |
298 return current_utterance_ != NULL || GetPlatformImpl()->IsSpeaking(); | 247 return current_utterance_ != NULL || GetPlatformImpl()->IsSpeaking(); |
299 } | 248 } |
300 | 249 |
301 void TtsController::FinishCurrentUtterance() { | 250 void TtsController::FinishCurrentUtterance() { |
302 if (current_utterance_) { | 251 if (current_utterance_) { |
303 if (!current_utterance_->finished()) | 252 if (!current_utterance_->finished()) |
304 current_utterance_->OnTtsEvent(TTS_EVENT_INTERRUPTED, kInvalidCharIndex, | 253 current_utterance_->OnTtsEvent(TTS_EVENT_INTERRUPTED, kInvalidCharIndex, |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 | 292 |
344 int TtsController::QueueSize() { | 293 int TtsController::QueueSize() { |
345 return static_cast<int>(utterance_queue_.size()); | 294 return static_cast<int>(utterance_queue_.size()); |
346 } | 295 } |
347 | 296 |
348 TtsPlatformImpl* TtsController::GetPlatformImpl() { | 297 TtsPlatformImpl* TtsController::GetPlatformImpl() { |
349 if (!platform_impl_) | 298 if (!platform_impl_) |
350 platform_impl_ = TtsPlatformImpl::GetInstance(); | 299 platform_impl_ = TtsPlatformImpl::GetInstance(); |
351 return platform_impl_; | 300 return platform_impl_; |
352 } | 301 } |
OLD | NEW |