| 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 <string> | 5 #include <string> |
| 6 | 6 |
| 7 #include "base/memory/scoped_nsobject.h" | 7 #include "base/memory/scoped_nsobject.h" |
| 8 #include "base/memory/singleton.h" | 8 #include "base/memory/singleton.h" |
| 9 #include "base/strings/sys_string_conversions.h" | 9 #include "base/strings/sys_string_conversions.h" |
| 10 #include "base/values.h" | 10 #include "base/values.h" |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 56 | 56 |
| 57 virtual bool Speak( | 57 virtual bool Speak( |
| 58 int utterance_id, | 58 int utterance_id, |
| 59 const std::string& utterance, | 59 const std::string& utterance, |
| 60 const std::string& lang, | 60 const std::string& lang, |
| 61 const VoiceData& voice, | 61 const VoiceData& voice, |
| 62 const UtteranceContinuousParameters& params) OVERRIDE; | 62 const UtteranceContinuousParameters& params) OVERRIDE; |
| 63 | 63 |
| 64 virtual bool StopSpeaking() OVERRIDE; | 64 virtual bool StopSpeaking() OVERRIDE; |
| 65 | 65 |
| 66 virtual void Pause() OVERRIDE; |
| 67 |
| 68 virtual void Resume() OVERRIDE; |
| 69 |
| 66 virtual bool IsSpeaking() OVERRIDE; | 70 virtual bool IsSpeaking() OVERRIDE; |
| 67 | 71 |
| 68 virtual void GetVoices(std::vector<VoiceData>* out_voices) OVERRIDE; | 72 virtual void GetVoices(std::vector<VoiceData>* out_voices) OVERRIDE; |
| 69 | 73 |
| 70 // Called by ChromeTtsDelegate when we get a callback from the | 74 // Called by ChromeTtsDelegate when we get a callback from the |
| 71 // native speech engine. | 75 // native speech engine. |
| 72 void OnSpeechEvent(NSSpeechSynthesizer* sender, | 76 void OnSpeechEvent(NSSpeechSynthesizer* sender, |
| 73 TtsEventType event_type, | 77 TtsEventType event_type, |
| 74 int char_index, | 78 int char_index, |
| 75 const std::string& error_message); | 79 const std::string& error_message); |
| 76 | 80 |
| 77 // Get the single instance of this class. | 81 // Get the single instance of this class. |
| 78 static TtsPlatformImplMac* GetInstance(); | 82 static TtsPlatformImplMac* GetInstance(); |
| 79 | 83 |
| 80 private: | 84 private: |
| 81 TtsPlatformImplMac(); | 85 TtsPlatformImplMac(); |
| 82 virtual ~TtsPlatformImplMac(); | 86 virtual ~TtsPlatformImplMac(); |
| 83 | 87 |
| 84 scoped_nsobject<SingleUseSpeechSynthesizer> speech_synthesizer_; | 88 scoped_nsobject<SingleUseSpeechSynthesizer> speech_synthesizer_; |
| 85 scoped_nsobject<ChromeTtsDelegate> delegate_; | 89 scoped_nsobject<ChromeTtsDelegate> delegate_; |
| 86 int utterance_id_; | 90 int utterance_id_; |
| 87 std::string utterance_; | 91 std::string utterance_; |
| 88 bool sent_start_event_; | 92 bool sent_start_event_; |
| 93 int last_char_index_; |
| 94 bool paused_; |
| 89 | 95 |
| 90 friend struct DefaultSingletonTraits<TtsPlatformImplMac>; | 96 friend struct DefaultSingletonTraits<TtsPlatformImplMac>; |
| 91 | 97 |
| 92 DISALLOW_COPY_AND_ASSIGN(TtsPlatformImplMac); | 98 DISALLOW_COPY_AND_ASSIGN(TtsPlatformImplMac); |
| 93 }; | 99 }; |
| 94 | 100 |
| 95 // static | 101 // static |
| 96 TtsPlatformImpl* TtsPlatformImpl::GetInstance() { | 102 TtsPlatformImpl* TtsPlatformImpl::GetInstance() { |
| 97 return TtsPlatformImplMac::GetInstance(); | 103 return TtsPlatformImplMac::GetInstance(); |
| 98 } | 104 } |
| 99 | 105 |
| 100 bool TtsPlatformImplMac::Speak( | 106 bool TtsPlatformImplMac::Speak( |
| 101 int utterance_id, | 107 int utterance_id, |
| 102 const std::string& utterance, | 108 const std::string& utterance, |
| 103 const std::string& lang, | 109 const std::string& lang, |
| 104 const VoiceData& voice, | 110 const VoiceData& voice, |
| 105 const UtteranceContinuousParameters& params) { | 111 const UtteranceContinuousParameters& params) { |
| 106 // TODO: convert SSML to SAPI xml. http://crbug.com/88072 | 112 // TODO: convert SSML to SAPI xml. http://crbug.com/88072 |
| 107 utterance_ = utterance; | 113 utterance_ = utterance; |
| 114 paused_ = false; |
| 108 | 115 |
| 109 NSString* utterance_nsstring = | 116 NSString* utterance_nsstring = |
| 110 [NSString stringWithUTF8String:utterance_.c_str()]; | 117 [NSString stringWithUTF8String:utterance_.c_str()]; |
| 111 | 118 |
| 112 // Deliberately construct a new speech synthesizer every time Speak is | 119 // Deliberately construct a new speech synthesizer every time Speak is |
| 113 // called, otherwise there's no way to know whether calls to the delegate | 120 // called, otherwise there's no way to know whether calls to the delegate |
| 114 // apply to the current utterance or a previous utterance. In | 121 // apply to the current utterance or a previous utterance. In |
| 115 // experimentation, the overhead of constructing and destructing a | 122 // experimentation, the overhead of constructing and destructing a |
| 116 // NSSpeechSynthesizer is minimal. | 123 // NSSpeechSynthesizer is minimal. |
| 117 speech_synthesizer_.reset( | 124 speech_synthesizer_.reset( |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 158 } | 165 } |
| 159 | 166 |
| 160 return [speech_synthesizer_ startSpeakingRetainedUtterance]; | 167 return [speech_synthesizer_ startSpeakingRetainedUtterance]; |
| 161 } | 168 } |
| 162 | 169 |
| 163 bool TtsPlatformImplMac::StopSpeaking() { | 170 bool TtsPlatformImplMac::StopSpeaking() { |
| 164 if (speech_synthesizer_.get()) { | 171 if (speech_synthesizer_.get()) { |
| 165 [speech_synthesizer_ stopSpeaking]; | 172 [speech_synthesizer_ stopSpeaking]; |
| 166 speech_synthesizer_.reset(nil); | 173 speech_synthesizer_.reset(nil); |
| 167 } | 174 } |
| 175 paused_ = false; |
| 168 return true; | 176 return true; |
| 169 } | 177 } |
| 170 | 178 |
| 179 void TtsPlatformImplMac::Pause() { |
| 180 if (speech_synthesizer_.get() && utterance_id_ && !paused_) { |
| 181 [speech_synthesizer_ pauseSpeakingAtBoundary:NSSpeechImmediateBoundary]; |
| 182 paused_ = true; |
| 183 TtsController::GetInstance()->OnTtsEvent( |
| 184 utterance_id_, TTS_EVENT_PAUSE, last_char_index_, ""); |
| 185 } |
| 186 } |
| 187 |
| 188 void TtsPlatformImplMac::Resume() { |
| 189 if (speech_synthesizer_.get() && utterance_id_ && paused_) { |
| 190 [speech_synthesizer_ continueSpeaking]; |
| 191 paused_ = false; |
| 192 TtsController::GetInstance()->OnTtsEvent( |
| 193 utterance_id_, TTS_EVENT_RESUME, last_char_index_, ""); |
| 194 } |
| 195 } |
| 196 |
| 171 bool TtsPlatformImplMac::IsSpeaking() { | 197 bool TtsPlatformImplMac::IsSpeaking() { |
| 172 return [NSSpeechSynthesizer isAnyApplicationSpeaking]; | 198 return [NSSpeechSynthesizer isAnyApplicationSpeaking]; |
| 173 } | 199 } |
| 174 | 200 |
| 175 void TtsPlatformImplMac::GetVoices(std::vector<VoiceData>* outVoices) { | 201 void TtsPlatformImplMac::GetVoices(std::vector<VoiceData>* outVoices) { |
| 176 NSArray* voices = [NSSpeechSynthesizer availableVoices]; | 202 NSArray* voices = [NSSpeechSynthesizer availableVoices]; |
| 177 | 203 |
| 178 // Create a new temporary array of the available voices with | 204 // Create a new temporary array of the available voices with |
| 179 // the default voice first. | 205 // the default voice first. |
| 180 NSMutableArray* orderedVoices = | 206 NSMutableArray* orderedVoices = |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 216 else if ([gender isEqualToString:NSVoiceGenderFemale]) | 242 else if ([gender isEqualToString:NSVoiceGenderFemale]) |
| 217 data.gender = TTS_GENDER_FEMALE; | 243 data.gender = TTS_GENDER_FEMALE; |
| 218 else | 244 else |
| 219 data.gender = TTS_GENDER_NONE; | 245 data.gender = TTS_GENDER_NONE; |
| 220 data.events.insert(TTS_EVENT_START); | 246 data.events.insert(TTS_EVENT_START); |
| 221 data.events.insert(TTS_EVENT_END); | 247 data.events.insert(TTS_EVENT_END); |
| 222 data.events.insert(TTS_EVENT_WORD); | 248 data.events.insert(TTS_EVENT_WORD); |
| 223 data.events.insert(TTS_EVENT_ERROR); | 249 data.events.insert(TTS_EVENT_ERROR); |
| 224 data.events.insert(TTS_EVENT_CANCELLED); | 250 data.events.insert(TTS_EVENT_CANCELLED); |
| 225 data.events.insert(TTS_EVENT_INTERRUPTED); | 251 data.events.insert(TTS_EVENT_INTERRUPTED); |
| 252 data.events.insert(TTS_EVENT_PAUSE); |
| 253 data.events.insert(TTS_EVENT_RESUME); |
| 226 } | 254 } |
| 227 } | 255 } |
| 228 | 256 |
| 229 void TtsPlatformImplMac::OnSpeechEvent( | 257 void TtsPlatformImplMac::OnSpeechEvent( |
| 230 NSSpeechSynthesizer* sender, | 258 NSSpeechSynthesizer* sender, |
| 231 TtsEventType event_type, | 259 TtsEventType event_type, |
| 232 int char_index, | 260 int char_index, |
| 233 const std::string& error_message) { | 261 const std::string& error_message) { |
| 234 // Don't send events from an utterance that's already completed. | 262 // Don't send events from an utterance that's already completed. |
| 235 // This depends on the fact that we construct a new NSSpeechSynthesizer | 263 // This depends on the fact that we construct a new NSSpeechSynthesizer |
| 236 // each time we call Speak. | 264 // each time we call Speak. |
| 237 if (sender != speech_synthesizer_.get()) | 265 if (sender != speech_synthesizer_.get()) |
| 238 return; | 266 return; |
| 239 | 267 |
| 240 if (event_type == TTS_EVENT_END) | 268 if (event_type == TTS_EVENT_END) |
| 241 char_index = utterance_.size(); | 269 char_index = utterance_.size(); |
| 242 TtsController* controller = TtsController::GetInstance(); | 270 TtsController* controller = TtsController::GetInstance(); |
| 243 if (event_type == TTS_EVENT_WORD && !sent_start_event_) { | 271 if (event_type == TTS_EVENT_WORD && !sent_start_event_) { |
| 244 controller->OnTtsEvent( | 272 controller->OnTtsEvent( |
| 245 utterance_id_, TTS_EVENT_START, 0, ""); | 273 utterance_id_, TTS_EVENT_START, 0, ""); |
| 246 sent_start_event_ = true; | 274 sent_start_event_ = true; |
| 247 } | 275 } |
| 248 controller->OnTtsEvent( | 276 controller->OnTtsEvent( |
| 249 utterance_id_, event_type, char_index, error_message); | 277 utterance_id_, event_type, char_index, error_message); |
| 278 last_char_index_ = char_index; |
| 250 } | 279 } |
| 251 | 280 |
| 252 TtsPlatformImplMac::TtsPlatformImplMac() { | 281 TtsPlatformImplMac::TtsPlatformImplMac() { |
| 253 utterance_id_ = -1; | 282 utterance_id_ = -1; |
| 254 sent_start_event_ = true; | 283 sent_start_event_ = true; |
| 284 paused_ = false; |
| 255 | 285 |
| 256 delegate_.reset([[ChromeTtsDelegate alloc] initWithPlatformImplMac:this]); | 286 delegate_.reset([[ChromeTtsDelegate alloc] initWithPlatformImplMac:this]); |
| 257 } | 287 } |
| 258 | 288 |
| 259 TtsPlatformImplMac::~TtsPlatformImplMac() { | 289 TtsPlatformImplMac::~TtsPlatformImplMac() { |
| 260 } | 290 } |
| 261 | 291 |
| 262 // static | 292 // static |
| 263 TtsPlatformImplMac* TtsPlatformImplMac::GetInstance() { | 293 TtsPlatformImplMac* TtsPlatformImplMac::GetInstance() { |
| 264 return Singleton<TtsPlatformImplMac>::get(); | 294 return Singleton<TtsPlatformImplMac>::get(); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 313 didSpeak_ = true; | 343 didSpeak_ = true; |
| 314 return [super startSpeakingString:utterance_]; | 344 return [super startSpeakingString:utterance_]; |
| 315 } | 345 } |
| 316 | 346 |
| 317 - (bool)startSpeakingString:(NSString*)utterance { | 347 - (bool)startSpeakingString:(NSString*)utterance { |
| 318 CHECK(false); | 348 CHECK(false); |
| 319 return false; | 349 return false; |
| 320 } | 350 } |
| 321 | 351 |
| 322 @end | 352 @end |
| OLD | NEW |