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

Side by Side Diff: chrome/browser/extensions/extension_tts_api_win.cc

Issue 3640001: Refactored TTS extension code so that the platform-specific TTS... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 2 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
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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/extensions/extension_tts_api.h" 5 #include "chrome/browser/extensions/extension_tts_api.h"
6 6
7 #include <atlbase.h> 7 #include <atlbase.h>
8 #include <atlcom.h> 8 #include <atlcom.h>
9 #include <sapi.h> 9 #include <sapi.h>
10 10
11 #include "base/scoped_comptr_win.h" 11 #include "base/scoped_comptr_win.h"
12 #include "base/singleton.h" 12 #include "base/singleton.h"
13 #include "base/string_number_conversions.h" 13 #include "base/string_number_conversions.h"
14 #include "base/utf_string_conversions.h"
14 #include "base/values.h" 15 #include "base/values.h"
15 16
16 namespace util = extension_tts_api_util; 17 namespace util = extension_tts_api_util;
17 18
18 class SpeechSynthesizerWrapper { 19 class ExtensionTtsPlatformImplWin : public ExtensionTtsPlatformImpl {
19 public: 20 public:
20 SpeechSynthesizerWrapper() : speech_synthesizer_(NULL), 21 virtual bool Speak(
21 paused_(false), 22 const std::string& utterance,
22 permanent_failure_(false) { 23 const std::string& language,
23 InitializeSpeechSynthesizer(); 24 const std::string& gender,
25 double rate,
26 double pitch,
27 double volume);
28
29 virtual bool StopSpeaking();
30
31 virtual bool IsSpeaking();
32
33 // Get the single instance of this class.
34 static ExtensionTtsPlatformImplWin* GetInstance();
35
36 private:
37 ExtensionTtsPlatformImplWin();
38 virtual ~ExtensionTtsPlatformImplWin() {}
39
40 ScopedComPtr<ISpVoice> speech_synthesizer_;
41 bool paused_;
42
43 friend struct DefaultSingletonTraits<ExtensionTtsPlatformImplWin>;
44
45 DISALLOW_COPY_AND_ASSIGN(ExtensionTtsPlatformImplWin);
46 };
47
48 // static
49 ExtensionTtsPlatformImpl* ExtensionTtsPlatformImpl::GetInstance() {
50 return ExtensionTtsPlatformImplWin::GetInstance();
51 }
52
53 bool ExtensionTtsPlatformImplWin::Speak(
54 const std::string& src_utterance,
55 const std::string& language,
56 const std::string& gender,
57 double rate,
58 double pitch,
59 double volume) {
60 std::wstring utterance = UTF8ToUTF16(src_utterance);
61
62 if (!speech_synthesizer_)
63 return false;
64
65 // Speech API equivalents for kGenderKey and kLanguageNameKey do not
66 // exist and thus are not supported.
67
68 if (rate >= 0.0) {
69 // The TTS api allows a range of -10 to 10 for speech rate.
70 speech_synthesizer_->SetRate(static_cast<int32>(rate * 20 - 10));
24 } 71 }
25 72
26 bool InitializeSpeechSynthesizer() { 73 if (pitch >= 0.0) {
27 if (!SUCCEEDED(CoCreateInstance(CLSID_SpVoice, 74 // The TTS api allows a range of -10 to 10 for speech pitch.
28 NULL, 75 // TODO(dtseng): cleanup if we ever use any other properties that
29 CLSCTX_SERVER, 76 // require xml.
30 IID_ISpVoice, 77 std::wstring pitch_value =
31 reinterpret_cast<void**>( 78 base::IntToString16(static_cast<int>(pitch * 20 - 10));
32 &speech_synthesizer_)))) { 79 utterance = L"<pitch absmiddle=\"" + pitch_value + L"\">" +
33 permanent_failure_ = true; 80 utterance + L"</pitch>";
34 return false;
35 }
36
37 if (paused_)
38 speech_synthesizer_->Resume();
39 return true;
40 } 81 }
41 82
42 ScopedComPtr<ISpVoice> speech_synthesizer() { 83 if (volume >= 0.0) {
43 return speech_synthesizer_; 84 // The TTS api allows a range of 0 to 100 for speech volume.
85 speech_synthesizer_->SetVolume(static_cast<uint16>(volume * 100));
44 } 86 }
45 87
46 bool paused() { 88 if (paused_)
47 return paused_; 89 speech_synthesizer_->Resume();
48 } 90 speech_synthesizer_->Speak(
91 utterance.c_str(), SPF_ASYNC | SPF_PURGEBEFORESPEAK, NULL);
49 92
50 void paused(bool state) { 93 return true;
51 paused_ = state;
52 }
53
54 private:
55 ScopedComPtr<ISpVoice> speech_synthesizer_;
56 bool paused_;
57 // Indicates an error retrieving the SAPI COM interface.
58 bool permanent_failure_;
59 };
60
61 typedef Singleton<SpeechSynthesizerWrapper> SpeechSynthesizerSingleton;
62
63 bool ExtensionTtsSpeakFunction::RunImpl() {
64 ScopedComPtr<ISpVoice> speech_synthesizer =
65 SpeechSynthesizerSingleton::get()->speech_synthesizer();
66 if (speech_synthesizer) {
67 std::wstring utterance;
68 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &utterance));
69
70 std::string options = "";
71 DictionaryValue* speak_options = NULL;
72
73 // Parse speech properties.
74 if (args_->GetDictionary(1, &speak_options)) {
75 std::string str_value;
76 double real_value;
77 // Speech API equivalents for kGenderKey and kLanguageNameKey do not
78 // exist and thus are not supported.
79 if (util::ReadNumberByKey(speak_options, util::kRateKey, &real_value)) {
80 // The TTS api allows a range of -10 to 10 for speech rate.
81 speech_synthesizer->SetRate(static_cast<int32>(real_value*20 - 10));
82 }
83 if (util::ReadNumberByKey(speak_options, util::kPitchKey, &real_value)) {
84 // The TTS api allows a range of -10 to 10 for speech pitch.
85 // TODO(dtseng): cleanup if we ever
86 // use any other properties that require xml.
87 std::wstring pitch_value =
88 base::IntToString16(static_cast<int>(real_value*20 - 10));
89 utterance = L"<pitch absmiddle=\"" + pitch_value + L"\">" +
90 utterance + L"</pitch>";
91 }
92 if (util::ReadNumberByKey(
93 speak_options, util::kVolumeKey, &real_value)) {
94 // The TTS api allows a range of 0 to 100 for speech volume.
95 speech_synthesizer->SetVolume(static_cast<uint16>(real_value * 100));
96 }
97 }
98
99 if (SpeechSynthesizerSingleton::get()->paused())
100 speech_synthesizer->Resume();
101 speech_synthesizer->Speak(
102 utterance.c_str(), SPF_ASYNC | SPF_PURGEBEFORESPEAK, NULL);
103 return true;
104 }
105
106 return false;
107 } 94 }
108 95
109 bool ExtensionTtsStopSpeakingFunction::RunImpl() { 96 bool ExtensionTtsPlatformImplWin::StopSpeaking() {
110 // We need to keep track of the paused state since SAPI doesn't have a stop 97 if (!speech_synthesizer_ && !paused_) {
111 // method. 98 speech_synthesizer_->Pause();
112 ScopedComPtr<ISpVoice> speech_synthesizer = 99 paused_ = true;
113 SpeechSynthesizerSingleton::get()->speech_synthesizer();
114 if (speech_synthesizer && !SpeechSynthesizerSingleton::get()->paused()) {
115 speech_synthesizer->Pause();
116 SpeechSynthesizerSingleton::get()->paused(true);
117 } 100 }
118 return true; 101 return true;
119 } 102 }
120 103
121 bool ExtensionTtsIsSpeakingFunction::RunImpl() { 104 bool ExtensionTtsPlatformImplWin::IsSpeaking() {
122 return false; 105 return false;
123 } 106 }
107
108 ExtensionTtsPlatformImplWin::ExtensionTtsPlatformImplWin()
109 : speech_synthesizer_(NULL),
110 paused_(false) {
111 CoCreateInstance(
112 CLSID_SpVoice,
113 NULL,
114 CLSCTX_SERVER,
115 IID_ISpVoice,
116 reinterpret_cast<void**>(&speech_synthesizer_));
117 }
118
119 // static
120 ExtensionTtsPlatformImplWin* ExtensionTtsPlatformImplWin::GetInstance() {
121 return Singleton<ExtensionTtsPlatformImplWin>::get();
122 }
OLDNEW
« no previous file with comments | « chrome/browser/extensions/extension_tts_api_mac.mm ('k') | chrome/browser/extensions/extension_tts_apitest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698