Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(354)

Side by Side Diff: chrome/browser/speech/tts_mac.mm

Issue 15108002: Add Pause and Resume to Web TTS & Extension TTS APIs (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/speech/tts_linux.cc ('k') | chrome/browser/speech/tts_message_filter.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « chrome/browser/speech/tts_linux.cc ('k') | chrome/browser/speech/tts_message_filter.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698