diff options
Diffstat (limited to 'chrome/browser/extensions/extension_tts_api_win.cc')
-rw-r--r-- | chrome/browser/extensions/extension_tts_api_win.cc | 171 |
1 files changed, 86 insertions, 85 deletions
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(); -} |