summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/extensions/extension_tts_api.cc96
-rw-r--r--chrome/browser/extensions/extension_tts_api.h40
-rw-r--r--chrome/browser/extensions/extension_tts_api_chromeos.cc125
-rw-r--r--chrome/browser/extensions/extension_tts_api_gtk.cc17
-rw-r--r--chrome/browser/extensions/extension_tts_api_linux.cc58
-rw-r--r--chrome/browser/extensions/extension_tts_api_mac.mm113
-rw-r--r--chrome/browser/extensions/extension_tts_api_win.cc171
-rw-r--r--chrome/browser/extensions/extension_tts_apitest.cc2
-rw-r--r--chrome/chrome_browser.gypi9
-rw-r--r--chrome/test/data/extensions/api_test/tts/chromeos/manifest.json (renamed from chrome/test/data/extensions/api_test/tts/manifest.json)0
-rw-r--r--chrome/test/data/extensions/api_test/tts/chromeos/test.html (renamed from chrome/test/data/extensions/api_test/tts/test.html)0
-rw-r--r--chrome/test/data/extensions/api_test/tts/chromeos/test.js (renamed from chrome/test/data/extensions/api_test/tts/test.js)17
12 files changed, 434 insertions, 214 deletions
diff --git a/chrome/browser/extensions/extension_tts_api.cc b/chrome/browser/extensions/extension_tts_api.cc
index ba9c2f8..b022ec0 100644
--- a/chrome/browser/extensions/extension_tts_api.cc
+++ b/chrome/browser/extensions/extension_tts_api.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// 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.
@@ -6,16 +6,11 @@
#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.";
@@ -23,68 +18,57 @@ namespace {
bool ExtensionTtsSpeakFunction::RunImpl() {
std::string utterance;
- std::string options = "";
+ std::string language;
+ std::string gender;
+ double rate = -1.0;
+ double pitch = -1.0;
+ double volume = -1.0;
+
DictionaryValue* speak_options = NULL;
EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &utterance));
+
if (args_->GetDictionary(1, &speak_options)) {
- 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::kLanguageNameKey)) {
+ speak_options->GetString(util::kLanguageNameKey, &language);
}
- 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, &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 (speak_options->HasKey(util::kGenderKey)) {
+ speak_options->GetString(util::kGenderKey, &gender);
}
- 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::kRateKey, &rate)) {
+ if (!base::IsFinite(rate) || rate < 0.0 || rate > 1.0) {
+ rate = -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);
+
+ if (util::ReadNumberByKey(speak_options, util::kPitchKey, &pitch)) {
+ if (!base::IsFinite(pitch) || pitch < 0.0 || pitch > 1.0) {
+ pitch = -1.0;
+ }
}
- }
- if (chromeos::CrosLibrary::Get()->EnsureLoaded()) {
- if (!options.empty()) {
- chromeos::CrosLibrary::Get()->GetSpeechSynthesisLibrary()->
- SetSpeakProperties(options.c_str());
+
+ if (util::ReadNumberByKey(speak_options, util::kVolumeKey, &volume)) {
+ if (!base::IsFinite(volume) || volume < 0.0 || volume > 1.0) {
+ volume = -1.0;
+ }
}
- bool ret = chromeos::CrosLibrary::Get()->GetSpeechSynthesisLibrary()->
- Speak(utterance.c_str());
- result_.reset();
- return ret;
}
- error_ = kCrosLibraryNotLoadedError;
- return false;
+
+ ExtensionTtsPlatformImpl* impl = ExtensionTtsPlatformImpl::GetInstance();
+ impl->clear_error();
+ return impl->Speak(utterance, language, gender, rate, pitch, volume);
}
bool ExtensionTtsStopSpeakingFunction::RunImpl() {
- if (chromeos::CrosLibrary::Get()->EnsureLoaded()) {
- return chromeos::CrosLibrary::Get()->GetSpeechSynthesisLibrary()->
- StopSpeaking();
- }
- error_ = kCrosLibraryNotLoadedError;
- return false;
+ ExtensionTtsPlatformImpl* impl = ExtensionTtsPlatformImpl::GetInstance();
+ impl->clear_error();
+ return impl->StopSpeaking();
}
bool ExtensionTtsIsSpeakingFunction::RunImpl() {
- if (chromeos::CrosLibrary::Get()->EnsureLoaded()) {
- result_.reset(Value::CreateBooleanValue(
- chromeos::CrosLibrary::Get()->GetSpeechSynthesisLibrary()->
- IsSpeaking()));
- return true;
- }
- error_ = kCrosLibraryNotLoadedError;
- return false;
+ ExtensionTtsPlatformImpl* impl = ExtensionTtsPlatformImpl::GetInstance();
+ impl->clear_error();
+ result_.reset(Value::CreateBooleanValue(impl->IsSpeaking()));
+ return true;
}
diff --git a/chrome/browser/extensions/extension_tts_api.h b/chrome/browser/extensions/extension_tts_api.h
index 84fa384..73fc887 100644
--- a/chrome/browser/extensions/extension_tts_api.h
+++ b/chrome/browser/extensions/extension_tts_api.h
@@ -8,6 +8,46 @@
#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
new file mode 100644
index 0000000..a183612
--- /dev/null
+++ b/chrome/browser/extensions/extension_tts_api_chromeos.cc
@@ -0,0 +1,125 @@
+// 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
deleted file mode 100644
index 6804f92..0000000
--- a/chrome/browser/extensions/extension_tts_api_gtk.cc
+++ /dev/null
@@ -1,17 +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 "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
new file mode 100644
index 0000000..15f1af1
--- /dev/null
+++ b/chrome/browser/extensions/extension_tts_api_linux.cc
@@ -0,0 +1,58 @@
+// 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 1b45380..2e97aca 100644
--- a/chrome/browser/extensions/extension_tts_api_mac.mm
+++ b/chrome/browser/extensions/extension_tts_api_mac.mm
@@ -6,6 +6,7 @@
#include <string>
+#include "base/singleton.h"
#include "base/values.h"
#include "chrome/browser/extensions/extension_function.h"
@@ -13,57 +14,87 @@
namespace util = extension_tts_api_util;
-static NSSpeechSynthesizer* speech_synthesizer_;
+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);
-void InitializeSpeechSynthesizer() {
- if (!speech_synthesizer_)
- speech_synthesizer_ = [[NSSpeechSynthesizer alloc] init];
+ 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();
}
-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];
- }
+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];
}
- return
- [speech_synthesizer_ startSpeakingString:
- [NSString stringWithUTF8String: utterance.c_str()]];
+ 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()]];
}
-bool ExtensionTtsStopSpeakingFunction::RunImpl() {
- InitializeSpeechSynthesizer();
+bool ExtensionTtsPlatformImplMac::StopSpeaking() {
[speech_synthesizer_ stopSpeaking];
return true;
}
-bool ExtensionTtsIsSpeakingFunction::RunImpl() {
- InitializeSpeechSynthesizer();
+bool ExtensionTtsPlatformImplMac::IsSpeaking() {
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 480880b..a9a6062 100644
--- a/chrome/browser/extensions/extension_tts_api_win.cc
+++ b/chrome/browser/extensions/extension_tts_api_win.cc
@@ -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;
- }
-
- if (paused_)
- speech_synthesizer_->Resume();
- return true;
- }
+ virtual bool StopSpeaking();
- ScopedComPtr<ISpVoice> speech_synthesizer() {
- return speech_synthesizer_;
- }
+ virtual bool IsSpeaking();
- bool paused() {
- return paused_;
- }
-
- void paused(bool state) {
- paused_ = state;
- }
+ // Get the single instance of this class.
+ static ExtensionTtsPlatformImplWin* GetInstance();
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;
-
-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;
+// 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));
}
- 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();
+}
diff --git a/chrome/browser/extensions/extension_tts_apitest.cc b/chrome/browser/extensions/extension_tts_apitest.cc
index 5acda10..dcdfb9d5 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")) << message_;
+ ASSERT_TRUE(RunExtensionTest("tts/chromeos")) << message_;
}
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 59f2055..6ee4855 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -1543,7 +1543,8 @@
'browser/extensions/extension_test_api.h',
'browser/extensions/extension_tts_api.cc',
'browser/extensions/extension_tts_api.h',
- 'browser/extensions/extension_tts_api_gtk.cc',
+ 'browser/extensions/extension_tts_api_chromeos.cc',
+ 'browser/extensions/extension_tts_api_linux.cc',
'browser/extensions/extension_tts_api_mac.mm',
'browser/extensions/extension_tts_api_util.cc',
'browser/extensions/extension_tts_api_util.h',
@@ -3294,7 +3295,7 @@
['exclude', 'browser/dom_ui/filebrowse_ui.cc'],
['exclude', 'browser/dom_ui/mediaplayer_ui.cc'],
['exclude', 'browser/dom_ui/slideshow_ui.cc'],
- ['exclude', 'browser/extensions/extension_tts_api.cc'],
+ ['exclude', 'browser/extensions/extension_tts_api_chromeos.cc'],
['exclude', 'browser/renderer_host/offline_resource_handler.cc'],
['exclude', 'browser/renderer_host/offline_resource_handler.h'],
],
@@ -3960,13 +3961,11 @@
# non-ChromeOS views Linux builds.
['OS=="linux" and toolkit_views==1 and chromeos==0', {
'sources/': [
- ['exclude', '^browser/extensions/extension_tts_api.cc'],
['include', '^browser/gtk/dialogs_gtk.cc'],
['include', '^browser/gtk/external_protocol_dialog_gtk.cc'],
['include', '^browser/gtk/external_protocol_dialog_gtk.h'],
['include', '^browser/views/notifications/balloon_view.cc'],
['include', '^browser/views/notifications/balloon_view.h'],
-
['exclude', '^browser/views/select_file_dialog.cc'],
],
}],
@@ -3983,7 +3982,7 @@
}],
['OS=="linux" and chromeos==1',{
'sources/': [
- ['exclude', '^browser/extensions/extension_tts_api_gtk.cc'],
+ ['exclude', '^browser/extensions/extension_tts_api_linux.cc'],
['exclude', '^browser/notifications/balloon_collection.cc'],
['exclude', '^browser/notifications/balloon_collection_impl.h'],
['exclude', '^browser/notifications/balloon_collection_linux.cc'],
diff --git a/chrome/test/data/extensions/api_test/tts/manifest.json b/chrome/test/data/extensions/api_test/tts/chromeos/manifest.json
index a43bc3d..a43bc3d 100644
--- a/chrome/test/data/extensions/api_test/tts/manifest.json
+++ b/chrome/test/data/extensions/api_test/tts/chromeos/manifest.json
diff --git a/chrome/test/data/extensions/api_test/tts/test.html b/chrome/test/data/extensions/api_test/tts/chromeos/test.html
index 46f4d74..46f4d74 100644
--- a/chrome/test/data/extensions/api_test/tts/test.html
+++ b/chrome/test/data/extensions/api_test/tts/chromeos/test.html
diff --git a/chrome/test/data/extensions/api_test/tts/test.js b/chrome/test/data/extensions/api_test/tts/chromeos/test.js
index df5837b..0cf73bc0 100644
--- a/chrome/test/data/extensions/api_test/tts/test.js
+++ b/chrome/test/data/extensions/api_test/tts/chromeos/test.js
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// TTS api test for Chrome. This is currently limited to ChromeOS.
-// browser_tests.exe --gtest_filter=ExtensionApiTest.Tts
+// TTS api test for Chrome on ChromeOS.
+// browser_tests.exe --gtest_filter=ExtensionApiTest.TtsOnChromeOs
chrome.test.runTests([
function testSpeak() {
@@ -20,12 +20,13 @@ chrome.test.runTests([
function testIsSpeaking() {
for (var i = 0; i < 3; i++) {
chrome.experimental.tts.isSpeaking(function(speaking) {
- chrome.test.assertTrue(speaking);
- });
+ chrome.test.assertTrue(speaking);
+ });
}
chrome.experimental.tts.isSpeaking(function(speaking) {
- chrome.test.assertFalse(speaking);
- chrome.test.succeed();
- });
+ chrome.test.assertFalse(speaking);
+ chrome.test.succeed();
+ });
}
-]); \ No newline at end of file
+
+]);