1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Use of this source code is governed by a BSD-style license that can be 3731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// found in the LICENSE file. 4731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 5731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/browser/extensions/extension_tts_api.h" 6731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 7ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/singleton.h" 8731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/string_number_conversions.h" 9731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/browser/chromeos/cros/cros_library.h" 10731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/browser/chromeos/cros/speech_synthesis_library.h" 11731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 12731df977c0511bca2206b5f333555b1205ff1f43Iain Merricknamespace util = extension_tts_api_util; 13731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 14731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickusing base::DoubleToString; 15731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 16731df977c0511bca2206b5f333555b1205ff1f43Iain Merricknamespace { 17731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickconst char kCrosLibraryNotLoadedError[] = "Cros shared library not loaded."; 18731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}; 19731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 20731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickclass ExtensionTtsPlatformImplChromeOs : public ExtensionTtsPlatformImpl { 21731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick public: 22731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick virtual bool Speak( 23731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const std::string& utterance, 2421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const std::string& locale, 25731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const std::string& gender, 26731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick double rate, 27731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick double pitch, 28731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick double volume); 29731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 30731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick virtual bool StopSpeaking(); 31731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 32731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick virtual bool IsSpeaking(); 33731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 34731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Get the single instance of this class. 35731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick static ExtensionTtsPlatformImplChromeOs* GetInstance(); 36731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 37731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick private: 38731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ExtensionTtsPlatformImplChromeOs() {} 39731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick virtual ~ExtensionTtsPlatformImplChromeOs() {} 40731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 4121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen void AppendSpeakOption(std::string key, 4221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen std::string value, 4321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen std::string* options); 4421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 45731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick friend struct DefaultSingletonTraits<ExtensionTtsPlatformImplChromeOs>; 46731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 47731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DISALLOW_COPY_AND_ASSIGN(ExtensionTtsPlatformImplChromeOs); 48731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}; 49731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 50731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// static 51731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickExtensionTtsPlatformImpl* ExtensionTtsPlatformImpl::GetInstance() { 52731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return ExtensionTtsPlatformImplChromeOs::GetInstance(); 53731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 54731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 55731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool ExtensionTtsPlatformImplChromeOs::Speak( 56731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const std::string& utterance, 5721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const std::string& locale, 58731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const std::string& gender, 59731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick double rate, 60731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick double pitch, 61731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick double volume) { 62731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick chromeos::CrosLibrary* cros_library = chromeos::CrosLibrary::Get(); 63731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!cros_library->EnsureLoaded()) { 64731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick set_error(kCrosLibraryNotLoadedError); 65731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 66731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 67731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 68731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::string options; 69731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 7021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (!locale.empty()) { 7121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen AppendSpeakOption( 7221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen chromeos::SpeechSynthesisLibrary::kSpeechPropertyLocale, 7321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen locale, 7421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen &options); 75731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 76731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 77731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!gender.empty()) { 7821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen AppendSpeakOption( 7921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen chromeos::SpeechSynthesisLibrary::kSpeechPropertyGender, 8021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen gender, 8121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen &options); 82731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 83731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 84731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (rate >= 0.0) { 8521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen AppendSpeakOption( 8621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen chromeos::SpeechSynthesisLibrary::kSpeechPropertyRate, 8721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DoubleToString(rate * 5), 8821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen &options); 89731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 90731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 91731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (pitch >= 0.0) { 92731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // The TTS service allows a range of 0 to 2 for speech pitch. 9321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen AppendSpeakOption( 9421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen chromeos::SpeechSynthesisLibrary::kSpeechPropertyPitch, 9521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DoubleToString(pitch * 2), 9621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen &options); 97731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 98731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 99731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (volume >= 0.0) { 100731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // The TTS service allows a range of 0 to 5 for speech volume. 10121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen AppendSpeakOption( 10221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen chromeos::SpeechSynthesisLibrary::kSpeechPropertyVolume, 10321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DoubleToString(volume * 5), 10421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen &options); 105731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 106731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 107731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!options.empty()) { 108731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick cros_library->GetSpeechSynthesisLibrary()->SetSpeakProperties( 109731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick options.c_str()); 110731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 111731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 112731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return cros_library->GetSpeechSynthesisLibrary()->Speak(utterance.c_str()); 113731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 114731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 115731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool ExtensionTtsPlatformImplChromeOs::StopSpeaking() { 116731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (chromeos::CrosLibrary::Get()->EnsureLoaded()) { 117731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return chromeos::CrosLibrary::Get()->GetSpeechSynthesisLibrary()-> 118731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick StopSpeaking(); 119731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 120731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 121731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick set_error(kCrosLibraryNotLoadedError); 122731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 123731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 124731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 125731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool ExtensionTtsPlatformImplChromeOs::IsSpeaking() { 126731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (chromeos::CrosLibrary::Get()->EnsureLoaded()) { 127731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return chromeos::CrosLibrary::Get()->GetSpeechSynthesisLibrary()-> 128731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick IsSpeaking(); 129731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 130731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 131731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick set_error(kCrosLibraryNotLoadedError); 132731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 133731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 134731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 13521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid ExtensionTtsPlatformImplChromeOs::AppendSpeakOption( 13621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen std::string key, 13721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen std::string value, 13821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen std::string* options) { 13921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen *options += 14021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen key + 14121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen chromeos::SpeechSynthesisLibrary::kSpeechPropertyEquals + 14221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen value + 14321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen chromeos::SpeechSynthesisLibrary::kSpeechPropertyDelimiter; 14421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 14521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 146731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// static 147731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickExtensionTtsPlatformImplChromeOs* 148731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickExtensionTtsPlatformImplChromeOs::GetInstance() { 149731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return Singleton<ExtensionTtsPlatformImplChromeOs>::get(); 150731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 151