extension_tts_api_win.cc revision 731df977c0511bca2206b5f333555b1205ff1f43
1// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/extensions/extension_tts_api.h"
6
7#include <atlbase.h>
8#include <atlcom.h>
9#include <sapi.h>
10
11#include "base/scoped_comptr_win.h"
12#include "base/singleton.h"
13#include "base/string_number_conversions.h"
14#include "base/utf_string_conversions.h"
15#include "base/values.h"
16
17namespace util = extension_tts_api_util;
18
19class ExtensionTtsPlatformImplWin : public ExtensionTtsPlatformImpl {
20 public:
21  virtual bool Speak(
22      const std::string& utterance,
23      const std::string& language,
24      const std::string& gender,
25      double rate,
26      double pitch,
27      double volume);
28
29  virtual bool StopSpeaking();
30
31  virtual bool IsSpeaking();
32
33  // Get the single instance of this class.
34  static ExtensionTtsPlatformImplWin* GetInstance();
35
36 private:
37  ExtensionTtsPlatformImplWin();
38  virtual ~ExtensionTtsPlatformImplWin() {}
39
40  ScopedComPtr<ISpVoice> speech_synthesizer_;
41  bool paused_;
42
43  friend struct DefaultSingletonTraits<ExtensionTtsPlatformImplWin>;
44
45  DISALLOW_COPY_AND_ASSIGN(ExtensionTtsPlatformImplWin);
46};
47
48// static
49ExtensionTtsPlatformImpl* ExtensionTtsPlatformImpl::GetInstance() {
50  return ExtensionTtsPlatformImplWin::GetInstance();
51}
52
53bool ExtensionTtsPlatformImplWin::Speak(
54    const std::string& src_utterance,
55    const std::string& language,
56    const std::string& gender,
57    double rate,
58    double pitch,
59    double volume) {
60  std::wstring utterance = UTF8ToUTF16(src_utterance);
61
62  if (!speech_synthesizer_)
63    return false;
64
65  // Speech API equivalents for kGenderKey and kLanguageNameKey do not
66  // exist and thus are not supported.
67
68  if (rate >= 0.0) {
69    // The TTS api allows a range of -10 to 10 for speech rate.
70    speech_synthesizer_->SetRate(static_cast<int32>(rate * 20 - 10));
71  }
72
73  if (pitch >= 0.0) {
74    // The TTS api allows a range of -10 to 10 for speech pitch.
75    // TODO(dtseng): cleanup if we ever use any other properties that
76    // require xml.
77    std::wstring pitch_value =
78        base::IntToString16(static_cast<int>(pitch * 20 - 10));
79    utterance = L"<pitch absmiddle=\"" + pitch_value + L"\">" +
80        utterance + L"</pitch>";
81  }
82
83  if (volume >= 0.0) {
84    // The TTS api allows a range of 0 to 100 for speech volume.
85    speech_synthesizer_->SetVolume(static_cast<uint16>(volume * 100));
86  }
87
88  if (paused_)
89    speech_synthesizer_->Resume();
90  speech_synthesizer_->Speak(
91      utterance.c_str(), SPF_ASYNC | SPF_PURGEBEFORESPEAK, NULL);
92
93  return true;
94}
95
96bool ExtensionTtsPlatformImplWin::StopSpeaking() {
97  if (!speech_synthesizer_ && !paused_) {
98    speech_synthesizer_->Pause();
99    paused_ = true;
100  }
101  return true;
102}
103
104bool ExtensionTtsPlatformImplWin::IsSpeaking() {
105  return false;
106}
107
108ExtensionTtsPlatformImplWin::ExtensionTtsPlatformImplWin()
109  : speech_synthesizer_(NULL),
110    paused_(false) {
111  CoCreateInstance(
112      CLSID_SpVoice,
113      NULL,
114      CLSCTX_SERVER,
115      IID_ISpVoice,
116      reinterpret_cast<void**>(&speech_synthesizer_));
117}
118
119// static
120ExtensionTtsPlatformImplWin* ExtensionTtsPlatformImplWin::GetInstance() {
121  return Singleton<ExtensionTtsPlatformImplWin>::get();
122}
123