diff options
author | dmazzoni@chromium.org <dmazzoni@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-12 16:24:45 +0000 |
---|---|---|
committer | dmazzoni@chromium.org <dmazzoni@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-12 16:24:45 +0000 |
commit | 4535dbc797d69d7e9e2a5ecff93ca94c8878a5f0 (patch) | |
tree | dafc78abbf21cbe1916cd809e3ef0309d89d7d2a /chrome/browser/extensions | |
parent | 68daddd38c577e36367456becd005daaf6f2934a (diff) | |
download | chromium_src-4535dbc797d69d7e9e2a5ecff93ca94c8878a5f0.zip chromium_src-4535dbc797d69d7e9e2a5ecff93ca94c8878a5f0.tar.gz chromium_src-4535dbc797d69d7e9e2a5ecff93ca94c8878a5f0.tar.bz2 |
Revert 62283 - Refactored TTS extension code so that the platform-specific TTS
implementation code is separate from the extension API code.
That will make it easier to add more functionality that's shared
by all platforms next.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/3640001
TBR=dmazzoni@chromium.org
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@62284 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/extensions')
-rw-r--r-- | chrome/browser/extensions/extension_tts_api.cc | 96 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_tts_api.h | 40 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_tts_api_chromeos.cc | 125 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_tts_api_gtk.cc | 17 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_tts_api_linux.cc | 58 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_tts_api_mac.mm | 113 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_tts_api_win.cc | 171 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_tts_apitest.cc | 2 |
8 files changed, 201 insertions, 421 deletions
diff --git a/chrome/browser/extensions/extension_tts_api.cc b/chrome/browser/extensions/extension_tts_api.cc index b022ec0..ba9c2f8 100644 --- a/chrome/browser/extensions/extension_tts_api.cc +++ b/chrome/browser/extensions/extension_tts_api.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2009 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -6,11 +6,16 @@ #include <string> -#include "base/float_util.h" #include "base/values.h" +#include "base/string_number_conversions.h" + +#include "chrome/browser/chromeos/cros/cros_library.h" +#include "chrome/browser/chromeos/cros/speech_synthesis_library.h" namespace util = extension_tts_api_util; +using base::DoubleToString; + namespace { const char kCrosLibraryNotLoadedError[] = "Cros shared library not loaded."; @@ -18,57 +23,68 @@ namespace { bool ExtensionTtsSpeakFunction::RunImpl() { std::string utterance; - std::string language; - std::string gender; - double rate = -1.0; - double pitch = -1.0; - double volume = -1.0; - + std::string options = ""; DictionaryValue* speak_options = NULL; EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &utterance)); - if (args_->GetDictionary(1, &speak_options)) { - if (speak_options->HasKey(util::kLanguageNameKey)) { - speak_options->GetString(util::kLanguageNameKey, &language); + std::string str_value; + double real_value; + if (speak_options->HasKey(util::kLanguageNameKey) && + speak_options->GetString(util::kLanguageNameKey, &str_value)) { + util::AppendSpeakOption( + std::string(util::kNameKey), str_value, &options); } - - if (speak_options->HasKey(util::kGenderKey)) { - speak_options->GetString(util::kGenderKey, &gender); + if (speak_options->HasKey(util::kGenderKey) && + speak_options->GetString(util::kGenderKey, &str_value)) { + util::AppendSpeakOption( + std::string(util::kGenderKey), str_value, &options); } - - if (util::ReadNumberByKey(speak_options, util::kRateKey, &rate)) { - if (!base::IsFinite(rate) || rate < 0.0 || rate > 1.0) { - rate = -1.0; - } + if (util::ReadNumberByKey(speak_options, util::kRateKey, &real_value)) { + // The TTS service allows a range of 0 to 5 for speech rate. + util::AppendSpeakOption(std::string(util::kRateKey), + DoubleToString(real_value * 5), &options); } - - if (util::ReadNumberByKey(speak_options, util::kPitchKey, &pitch)) { - if (!base::IsFinite(pitch) || pitch < 0.0 || pitch > 1.0) { - pitch = -1.0; - } + if (util::ReadNumberByKey(speak_options, util::kPitchKey, &real_value)) { + // The TTS service allows a range of 0 to 2 for speech pitch. + util::AppendSpeakOption(std::string(util::kPitchKey), + DoubleToString(real_value * 2), &options); } - - if (util::ReadNumberByKey(speak_options, util::kVolumeKey, &volume)) { - if (!base::IsFinite(volume) || volume < 0.0 || volume > 1.0) { - volume = -1.0; - } + if (util::ReadNumberByKey(speak_options, util::kVolumeKey, &real_value)) { + // The TTS service allows a range of 0 to 5 for speech volume. + util::AppendSpeakOption(std::string(util::kVolumeKey), + DoubleToString(real_value * 5), &options); } } - - ExtensionTtsPlatformImpl* impl = ExtensionTtsPlatformImpl::GetInstance(); - impl->clear_error(); - return impl->Speak(utterance, language, gender, rate, pitch, volume); + if (chromeos::CrosLibrary::Get()->EnsureLoaded()) { + if (!options.empty()) { + chromeos::CrosLibrary::Get()->GetSpeechSynthesisLibrary()-> + SetSpeakProperties(options.c_str()); + } + bool ret = chromeos::CrosLibrary::Get()->GetSpeechSynthesisLibrary()-> + Speak(utterance.c_str()); + result_.reset(); + return ret; + } + error_ = kCrosLibraryNotLoadedError; + return false; } bool ExtensionTtsStopSpeakingFunction::RunImpl() { - ExtensionTtsPlatformImpl* impl = ExtensionTtsPlatformImpl::GetInstance(); - impl->clear_error(); - return impl->StopSpeaking(); + if (chromeos::CrosLibrary::Get()->EnsureLoaded()) { + return chromeos::CrosLibrary::Get()->GetSpeechSynthesisLibrary()-> + StopSpeaking(); + } + error_ = kCrosLibraryNotLoadedError; + return false; } bool ExtensionTtsIsSpeakingFunction::RunImpl() { - ExtensionTtsPlatformImpl* impl = ExtensionTtsPlatformImpl::GetInstance(); - impl->clear_error(); - result_.reset(Value::CreateBooleanValue(impl->IsSpeaking())); - return true; + if (chromeos::CrosLibrary::Get()->EnsureLoaded()) { + result_.reset(Value::CreateBooleanValue( + chromeos::CrosLibrary::Get()->GetSpeechSynthesisLibrary()-> + IsSpeaking())); + return true; + } + error_ = kCrosLibraryNotLoadedError; + return false; } diff --git a/chrome/browser/extensions/extension_tts_api.h b/chrome/browser/extensions/extension_tts_api.h index 73fc887..84fa384 100644 --- a/chrome/browser/extensions/extension_tts_api.h +++ b/chrome/browser/extensions/extension_tts_api.h @@ -8,46 +8,6 @@ #include "chrome/browser/extensions/extension_function.h" #include "chrome/browser/extensions/extension_tts_api_util.h" -// Abstract class that defines the native platform TTS interface. -class ExtensionTtsPlatformImpl { - public: - static ExtensionTtsPlatformImpl* GetInstance(); - - // Speak the given utterance with the given parameters if possible, - // and return true on success. Utterance will always be nonempty. - // If the user does not specify the other values, language and gender - // will be empty strings, and rate, pitch, and volume will be -1.0. - virtual bool Speak( - const std::string& utterance, - const std::string& language, - const std::string& gender, - double rate, - double pitch, - double volume) = 0; - - // Stop speaking immediately and return true on success. - virtual bool StopSpeaking() = 0; - - // Return true if the synthesis engine is currently speaking. - virtual bool IsSpeaking() = 0; - - virtual std::string error() { return error_; } - virtual void clear_error() { error_ = std::string(); } - virtual void set_error(const std::string& error) { error_ = error; } - - protected: - ExtensionTtsPlatformImpl() {} - virtual ~ExtensionTtsPlatformImpl() {} - - std::string error_; - - DISALLOW_COPY_AND_ASSIGN(ExtensionTtsPlatformImpl); -}; - -// -// Extension API function definitions -// - class ExtensionTtsSpeakFunction : public SyncExtensionFunction { ~ExtensionTtsSpeakFunction() {} virtual bool RunImpl(); diff --git a/chrome/browser/extensions/extension_tts_api_chromeos.cc b/chrome/browser/extensions/extension_tts_api_chromeos.cc deleted file mode 100644 index a183612..0000000 --- a/chrome/browser/extensions/extension_tts_api_chromeos.cc +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/extensions/extension_tts_api.h" - -#include "base/singleton.h" -#include "base/string_number_conversions.h" -#include "chrome/browser/chromeos/cros/cros_library.h" -#include "chrome/browser/chromeos/cros/speech_synthesis_library.h" - -namespace util = extension_tts_api_util; - -using base::DoubleToString; - -namespace { -const char kCrosLibraryNotLoadedError[] = "Cros shared library not loaded."; -}; - -class ExtensionTtsPlatformImplChromeOs : public ExtensionTtsPlatformImpl { - public: - virtual bool Speak( - const std::string& utterance, - const std::string& language, - const std::string& gender, - double rate, - double pitch, - double volume); - - virtual bool StopSpeaking(); - - virtual bool IsSpeaking(); - - // Get the single instance of this class. - static ExtensionTtsPlatformImplChromeOs* GetInstance(); - - private: - ExtensionTtsPlatformImplChromeOs() {} - virtual ~ExtensionTtsPlatformImplChromeOs() {} - - friend struct DefaultSingletonTraits<ExtensionTtsPlatformImplChromeOs>; - - DISALLOW_COPY_AND_ASSIGN(ExtensionTtsPlatformImplChromeOs); -}; - -// static -ExtensionTtsPlatformImpl* ExtensionTtsPlatformImpl::GetInstance() { - return ExtensionTtsPlatformImplChromeOs::GetInstance(); -} - -bool ExtensionTtsPlatformImplChromeOs::Speak( - const std::string& utterance, - const std::string& language, - const std::string& gender, - double rate, - double pitch, - double volume) { - chromeos::CrosLibrary* cros_library = chromeos::CrosLibrary::Get(); - if (!cros_library->EnsureLoaded()) { - set_error(kCrosLibraryNotLoadedError); - return false; - } - - std::string options; - - if (!language.empty()) { - util::AppendSpeakOption( - std::string(util::kNameKey), language, &options); - } - - if (!gender.empty()) { - util::AppendSpeakOption( - std::string(util::kGenderKey), gender, &options); - } - - if (rate >= 0.0) { - util::AppendSpeakOption( - std::string(util::kRateKey), DoubleToString(rate * 5), &options); - } - - if (pitch >= 0.0) { - // The TTS service allows a range of 0 to 2 for speech pitch. - util::AppendSpeakOption( - std::string(util::kPitchKey), DoubleToString(pitch * 2), &options); - } - - if (volume >= 0.0) { - // The TTS service allows a range of 0 to 5 for speech volume. - util::AppendSpeakOption( - std::string(util::kVolumeKey), DoubleToString(volume * 5), &options); - } - - if (!options.empty()) { - cros_library->GetSpeechSynthesisLibrary()->SetSpeakProperties( - options.c_str()); - } - - return cros_library->GetSpeechSynthesisLibrary()->Speak(utterance.c_str()); -} - -bool ExtensionTtsPlatformImplChromeOs::StopSpeaking() { - if (chromeos::CrosLibrary::Get()->EnsureLoaded()) { - return chromeos::CrosLibrary::Get()->GetSpeechSynthesisLibrary()-> - StopSpeaking(); - } - - set_error(kCrosLibraryNotLoadedError); - return false; -} - -bool ExtensionTtsPlatformImplChromeOs::IsSpeaking() { - if (chromeos::CrosLibrary::Get()->EnsureLoaded()) { - return chromeos::CrosLibrary::Get()->GetSpeechSynthesisLibrary()-> - IsSpeaking(); - } - - set_error(kCrosLibraryNotLoadedError); - return false; -} - -// static -ExtensionTtsPlatformImplChromeOs* -ExtensionTtsPlatformImplChromeOs::GetInstance() { - return Singleton<ExtensionTtsPlatformImplChromeOs>::get(); -} diff --git a/chrome/browser/extensions/extension_tts_api_gtk.cc b/chrome/browser/extensions/extension_tts_api_gtk.cc new file mode 100644 index 0000000..6804f92 --- /dev/null +++ b/chrome/browser/extensions/extension_tts_api_gtk.cc @@ -0,0 +1,17 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "extension_tts_api.h"
+
+bool ExtensionTtsSpeakFunction::RunImpl() {
+ return false;
+}
+
+bool ExtensionTtsStopSpeakingFunction::RunImpl() {
+ return false;
+}
+
+bool ExtensionTtsIsSpeakingFunction::RunImpl() {
+ return false;
+}
diff --git a/chrome/browser/extensions/extension_tts_api_linux.cc b/chrome/browser/extensions/extension_tts_api_linux.cc deleted file mode 100644 index 15f1af1..0000000 --- a/chrome/browser/extensions/extension_tts_api_linux.cc +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/extensions/extension_tts_api.h" - -#include "base/singleton.h" -#include "chrome/browser/chromeos/cros/cros_library.h" -#include "chrome/browser/chromeos/cros/speech_synthesis_library.h" - -namespace util = extension_tts_api_util; - -namespace { -const char kNotSupportedError[] = - "Native speech synthesis not supported on this platform."; -}; - -class ExtensionTtsPlatformImplLinux : public ExtensionTtsPlatformImpl { - public: - virtual bool Speak( - const std::string& utterance, - const std::string& language, - const std::string& gender, - double rate, - double pitch, - double volume) { - error_ = kNotSupportedError; - return false; - } - - virtual bool StopSpeaking() { - error_ = kNotSupportedError; - return false; - } - - virtual bool IsSpeaking() { - error_ = kNotSupportedError; - return false; - } - - // Get the single instance of this class. - static ExtensionTtsPlatformImplLinux* GetInstance() { - return ExtensionTtsPlatformImplLinux::GetInstance(); - } - - private: - ExtensionTtsPlatformImplLinux() {} - virtual ~ExtensionTtsPlatformImplLinux() {} - - friend struct DefaultSingletonTraits<ExtensionTtsPlatformImplLinux>; - - DISALLOW_COPY_AND_ASSIGN(ExtensionTtsPlatformImplLinux); -}; - -// static -ExtensionTtsPlatformImpl* ExtensionTtsPlatformImpl::GetInstance() { - return ExtensionTtsPlatformImplLinux::GetInstance(); -} diff --git a/chrome/browser/extensions/extension_tts_api_mac.mm b/chrome/browser/extensions/extension_tts_api_mac.mm index 2e97aca..1b45380 100644 --- a/chrome/browser/extensions/extension_tts_api_mac.mm +++ b/chrome/browser/extensions/extension_tts_api_mac.mm @@ -6,7 +6,6 @@ #include <string> -#include "base/singleton.h" #include "base/values.h" #include "chrome/browser/extensions/extension_function.h" @@ -14,87 +13,57 @@ namespace util = extension_tts_api_util; -class ExtensionTtsPlatformImplMac : public ExtensionTtsPlatformImpl { - public: - virtual bool Speak( - const std::string& utterance, - const std::string& language, - const std::string& gender, - double rate, - double pitch, - double volume); +static NSSpeechSynthesizer* speech_synthesizer_; - virtual bool StopSpeaking(); - - virtual bool IsSpeaking(); - - // Get the single instance of this class. - static ExtensionTtsPlatformImplMac* GetInstance(); - - private: - ExtensionTtsPlatformImplMac(); - virtual ~ExtensionTtsPlatformImplMac() {} - - NSSpeechSynthesizer* speech_synthesizer_; - - friend struct DefaultSingletonTraits<ExtensionTtsPlatformImplMac>; - - DISALLOW_COPY_AND_ASSIGN(ExtensionTtsPlatformImplMac); -}; - -// static -ExtensionTtsPlatformImpl* ExtensionTtsPlatformImpl::GetInstance() { - return ExtensionTtsPlatformImplMac::GetInstance(); +void InitializeSpeechSynthesizer() { + if (!speech_synthesizer_) + speech_synthesizer_ = [[NSSpeechSynthesizer alloc] init]; } -bool ExtensionTtsPlatformImplMac::Speak( - const std::string& utterance, - const std::string& language, - const std::string& gender, - double rate, - double pitch, - double volume) { - // NSSpeechSynthesizer equivalents for kGenderKey and kLanguageNameKey do - // not exist and thus are not supported. - - if (rate >= 0.0) { - // The TTS api defines rate via words per minute. - [speech_synthesizer_ - setObject:[NSNumber numberWithInt:rate * 400] - forProperty:NSSpeechRateProperty error:nil]; +bool ExtensionTtsSpeakFunction::RunImpl() { + InitializeSpeechSynthesizer(); + std::string utterance; + EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &utterance)); + DictionaryValue* speak_options = NULL; + + // Parse speech properties. + if (args_->GetDictionary(1, &speak_options)) { + std::string str_value; + double real_value; + // NSSpeechSynthesizer equivalents for kGenderKey and kLanguageNameKey do + // not exist and thus are not supported. + if (util::ReadNumberByKey(speak_options, util::kRateKey, &real_value)) { + // The TTS api defines rate via words per minute. + [speech_synthesizer_ + setObject:[NSNumber numberWithInt:real_value*400] + forProperty:NSSpeechRateProperty error:nil]; + } + if (util::ReadNumberByKey(speak_options, util::kPitchKey, &real_value)) { + // The TTS api allows an approximate range of 30 to 65 for speech pitch. + [speech_synthesizer_ + setObject: [NSNumber numberWithInt:(real_value*35 + 30)] + forProperty:NSSpeechPitchBaseProperty error:nil]; + } + if (util::ReadNumberByKey(speak_options, util::kVolumeKey, &real_value)) { + // The TTS api allows a range of 0.0 to 1.0 for speech volume. + [speech_synthesizer_ + setObject: [NSNumber numberWithFloat:real_value] + forProperty:NSSpeechVolumeProperty error:nil]; + } } - if (pitch >= 0.0) { - // The TTS api allows an approximate range of 30 to 65 for speech pitch. - [speech_synthesizer_ - setObject: [NSNumber numberWithInt:(pitch * 35 + 30)] - forProperty:NSSpeechPitchBaseProperty error:nil]; - } - - if (volume >= 0.0) { - [speech_synthesizer_ - setObject: [NSNumber numberWithFloat:volume] - forProperty:NSSpeechVolumeProperty error:nil]; - } - - return [speech_synthesizer_ startSpeakingString: - [NSString stringWithUTF8String: utterance.c_str()]]; + return + [speech_synthesizer_ startSpeakingString: + [NSString stringWithUTF8String: utterance.c_str()]]; } -bool ExtensionTtsPlatformImplMac::StopSpeaking() { +bool ExtensionTtsStopSpeakingFunction::RunImpl() { + InitializeSpeechSynthesizer(); [speech_synthesizer_ stopSpeaking]; return true; } -bool ExtensionTtsPlatformImplMac::IsSpeaking() { +bool ExtensionTtsIsSpeakingFunction::RunImpl() { + InitializeSpeechSynthesizer(); return [speech_synthesizer_ isSpeaking]; } - -ExtensionTtsPlatformImplMac::ExtensionTtsPlatformImplMac() { - speech_synthesizer_ = [[NSSpeechSynthesizer alloc] init]; -} - -// static -ExtensionTtsPlatformImplMac* ExtensionTtsPlatformImplMac::GetInstance() { - return Singleton<ExtensionTtsPlatformImplMac>::get(); -} diff --git a/chrome/browser/extensions/extension_tts_api_win.cc b/chrome/browser/extensions/extension_tts_api_win.cc index a9a6062..480880b 100644 --- a/chrome/browser/extensions/extension_tts_api_win.cc +++ b/chrome/browser/extensions/extension_tts_api_win.cc @@ -11,112 +11,113 @@ #include "base/scoped_comptr_win.h" #include "base/singleton.h" #include "base/string_number_conversions.h" -#include "base/utf_string_conversions.h" #include "base/values.h" namespace util = extension_tts_api_util; -class ExtensionTtsPlatformImplWin : public ExtensionTtsPlatformImpl { +class SpeechSynthesizerWrapper { public: - virtual bool Speak( - const std::string& utterance, - const std::string& language, - const std::string& gender, - double rate, - double pitch, - double volume); + SpeechSynthesizerWrapper() : speech_synthesizer_(NULL), + paused_(false), + permanent_failure_(false) { + InitializeSpeechSynthesizer(); + } - virtual bool StopSpeaking(); + bool InitializeSpeechSynthesizer() { + if (!SUCCEEDED(CoCreateInstance(CLSID_SpVoice, + NULL, + CLSCTX_SERVER, + IID_ISpVoice, + reinterpret_cast<void**>( + &speech_synthesizer_)))) { + permanent_failure_ = true; + return false; + } + + if (paused_) + speech_synthesizer_->Resume(); + return true; + } - virtual bool IsSpeaking(); + ScopedComPtr<ISpVoice> speech_synthesizer() { + return speech_synthesizer_; + } - // Get the single instance of this class. - static ExtensionTtsPlatformImplWin* GetInstance(); + bool paused() { + return paused_; + } - private: - ExtensionTtsPlatformImplWin(); - virtual ~ExtensionTtsPlatformImplWin() {} + void paused(bool state) { + paused_ = state; + } + private: ScopedComPtr<ISpVoice> speech_synthesizer_; bool paused_; - - friend struct DefaultSingletonTraits<ExtensionTtsPlatformImplWin>; - - DISALLOW_COPY_AND_ASSIGN(ExtensionTtsPlatformImplWin); + // Indicates an error retrieving the SAPI COM interface. + bool permanent_failure_; }; -// static -ExtensionTtsPlatformImpl* ExtensionTtsPlatformImpl::GetInstance() { - return ExtensionTtsPlatformImplWin::GetInstance(); -} - -bool ExtensionTtsPlatformImplWin::Speak( - const std::string& src_utterance, - const std::string& language, - const std::string& gender, - double rate, - double pitch, - double volume) { - std::wstring utterance = UTF8ToUTF16(src_utterance); - - if (!speech_synthesizer_) - return false; - - // Speech API equivalents for kGenderKey and kLanguageNameKey do not - // exist and thus are not supported. - - if (rate >= 0.0) { - // The TTS api allows a range of -10 to 10 for speech rate. - speech_synthesizer_->SetRate(static_cast<int32>(rate * 20 - 10)); - } - - if (pitch >= 0.0) { - // The TTS api allows a range of -10 to 10 for speech pitch. - // TODO(dtseng): cleanup if we ever use any other properties that - // require xml. - std::wstring pitch_value = - base::IntToString16(static_cast<int>(pitch * 20 - 10)); - utterance = L"<pitch absmiddle=\"" + pitch_value + L"\">" + - utterance + L"</pitch>"; +typedef Singleton<SpeechSynthesizerWrapper> SpeechSynthesizerSingleton; + +bool ExtensionTtsSpeakFunction::RunImpl() { + ScopedComPtr<ISpVoice> speech_synthesizer = + SpeechSynthesizerSingleton::get()->speech_synthesizer(); + if (speech_synthesizer) { + std::wstring utterance; + EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &utterance)); + + std::string options = ""; + DictionaryValue* speak_options = NULL; + + // Parse speech properties. + if (args_->GetDictionary(1, &speak_options)) { + std::string str_value; + double real_value; + // Speech API equivalents for kGenderKey and kLanguageNameKey do not + // exist and thus are not supported. + if (util::ReadNumberByKey(speak_options, util::kRateKey, &real_value)) { + // The TTS api allows a range of -10 to 10 for speech rate. + speech_synthesizer->SetRate(static_cast<int32>(real_value*20 - 10)); + } + if (util::ReadNumberByKey(speak_options, util::kPitchKey, &real_value)) { + // The TTS api allows a range of -10 to 10 for speech pitch. + // TODO(dtseng): cleanup if we ever + // use any other properties that require xml. + std::wstring pitch_value = + base::IntToString16(static_cast<int>(real_value*20 - 10)); + utterance = L"<pitch absmiddle=\"" + pitch_value + L"\">" + + utterance + L"</pitch>"; + } + if (util::ReadNumberByKey( + speak_options, util::kVolumeKey, &real_value)) { + // The TTS api allows a range of 0 to 100 for speech volume. + speech_synthesizer->SetVolume(static_cast<uint16>(real_value * 100)); + } + } + + if (SpeechSynthesizerSingleton::get()->paused()) + speech_synthesizer->Resume(); + speech_synthesizer->Speak( + utterance.c_str(), SPF_ASYNC | SPF_PURGEBEFORESPEAK, NULL); + return true; } - if (volume >= 0.0) { - // The TTS api allows a range of 0 to 100 for speech volume. - speech_synthesizer_->SetVolume(static_cast<uint16>(volume * 100)); - } - - if (paused_) - speech_synthesizer_->Resume(); - speech_synthesizer_->Speak( - utterance.c_str(), SPF_ASYNC | SPF_PURGEBEFORESPEAK, NULL); - - return true; + return false; } -bool ExtensionTtsPlatformImplWin::StopSpeaking() { - if (!speech_synthesizer_ && !paused_) { - speech_synthesizer_->Pause(); - paused_ = true; +bool ExtensionTtsStopSpeakingFunction::RunImpl() { + // We need to keep track of the paused state since SAPI doesn't have a stop + // method. + ScopedComPtr<ISpVoice> speech_synthesizer = + SpeechSynthesizerSingleton::get()->speech_synthesizer(); + if (speech_synthesizer && !SpeechSynthesizerSingleton::get()->paused()) { + speech_synthesizer->Pause(); + SpeechSynthesizerSingleton::get()->paused(true); } return true; } -bool ExtensionTtsPlatformImplWin::IsSpeaking() { +bool ExtensionTtsIsSpeakingFunction::RunImpl() { return false; } - -ExtensionTtsPlatformImplWin::ExtensionTtsPlatformImplWin() - : speech_synthesizer_(NULL), - paused_(false) { - CoCreateInstance( - CLSID_SpVoice, - NULL, - CLSCTX_SERVER, - IID_ISpVoice, - reinterpret_cast<void**>(&speech_synthesizer_)); -} - -// static -ExtensionTtsPlatformImplWin* ExtensionTtsPlatformImplWin::GetInstance() { - return Singleton<ExtensionTtsPlatformImplWin>::get(); -} diff --git a/chrome/browser/extensions/extension_tts_apitest.cc b/chrome/browser/extensions/extension_tts_apitest.cc index dcdfb9d5..5acda10 100644 --- a/chrome/browser/extensions/extension_tts_apitest.cc +++ b/chrome/browser/extensions/extension_tts_apitest.cc @@ -22,5 +22,5 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_Tts) { crosMock.InitMockSpeechSynthesisLibrary(); crosMock.SetSpeechSynthesisLibraryExpectations(); - ASSERT_TRUE(RunExtensionTest("tts/chromeos")) << message_; + ASSERT_TRUE(RunExtensionTest("tts")) << message_; } |