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