| Index: chrome/browser/extensions/extension_tts_api_win.cc
|
| ===================================================================
|
| --- chrome/browser/extensions/extension_tts_api_win.cc (revision 62145)
|
| +++ chrome/browser/extensions/extension_tts_api_win.cc (working copy)
|
| @@ -11,113 +11,112 @@
|
| #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 SpeechSynthesizerWrapper {
|
| +class ExtensionTtsPlatformImplWin : public ExtensionTtsPlatformImpl {
|
| public:
|
| - SpeechSynthesizerWrapper() : speech_synthesizer_(NULL),
|
| - paused_(false),
|
| - permanent_failure_(false) {
|
| - InitializeSpeechSynthesizer();
|
| - }
|
| + virtual bool Speak(
|
| + const std::string& utterance,
|
| + const std::string& language,
|
| + const std::string& gender,
|
| + double rate,
|
| + double pitch,
|
| + double volume);
|
|
|
| - bool InitializeSpeechSynthesizer() {
|
| - if (!SUCCEEDED(CoCreateInstance(CLSID_SpVoice,
|
| - NULL,
|
| - CLSCTX_SERVER,
|
| - IID_ISpVoice,
|
| - reinterpret_cast<void**>(
|
| - &speech_synthesizer_)))) {
|
| - permanent_failure_ = true;
|
| - return false;
|
| - }
|
| + virtual bool StopSpeaking();
|
|
|
| - 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_;
|
| - }
|
| -
|
| - void paused(bool state) {
|
| - paused_ = state;
|
| - }
|
| -
|
| private:
|
| + ExtensionTtsPlatformImplWin();
|
| + virtual ~ExtensionTtsPlatformImplWin() {}
|
| +
|
| ScopedComPtr<ISpVoice> speech_synthesizer_;
|
| bool paused_;
|
| - // Indicates an error retrieving the SAPI COM interface.
|
| - bool permanent_failure_;
|
| +
|
| + friend struct DefaultSingletonTraits<ExtensionTtsPlatformImplWin>;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(ExtensionTtsPlatformImplWin);
|
| };
|
|
|
| -typedef Singleton<SpeechSynthesizerWrapper> SpeechSynthesizerSingleton;
|
| +// static
|
| +ExtensionTtsPlatformImpl* ExtensionTtsPlatformImpl::GetInstance() {
|
| + return ExtensionTtsPlatformImplWin::GetInstance();
|
| +}
|
|
|
| -bool ExtensionTtsSpeakFunction::RunImpl() {
|
| - ScopedComPtr<ISpVoice> speech_synthesizer =
|
| - SpeechSynthesizerSingleton::get()->speech_synthesizer();
|
| - if (speech_synthesizer) {
|
| - std::wstring utterance;
|
| - EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &utterance));
|
| +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);
|
|
|
| - std::string options = "";
|
| - DictionaryValue* speak_options = NULL;
|
| + if (!speech_synthesizer_)
|
| + return false;
|
|
|
| - // 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));
|
| - }
|
| - }
|
| + // Speech API equivalents for kGenderKey and kLanguageNameKey do not
|
| + // exist and thus are not supported.
|
|
|
| - if (SpeechSynthesizerSingleton::get()->paused())
|
| - speech_synthesizer->Resume();
|
| - speech_synthesizer->Speak(
|
| - utterance.c_str(), SPF_ASYNC | SPF_PURGEBEFORESPEAK, NULL);
|
| - return true;
|
| + 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));
|
| }
|
|
|
| - return false;
|
| + 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>";
|
| + }
|
| +
|
| + 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;
|
| }
|
|
|
| -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);
|
| +bool ExtensionTtsPlatformImplWin::StopSpeaking() {
|
| + if (!speech_synthesizer_ && !paused_) {
|
| + speech_synthesizer_->Pause();
|
| + paused_ = true;
|
| }
|
| return true;
|
| }
|
|
|
| -bool ExtensionTtsIsSpeakingFunction::RunImpl() {
|
| +bool ExtensionTtsPlatformImplWin::IsSpeaking() {
|
| 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();
|
| +}
|
|
|