Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(47)

Side by Side Diff: chrome/android/java/src/org/chromium/chrome/browser/TtsPlatformImpl.java

Issue 15012027: Android implementation of text-to-speech code for Web Speech Synthesis API (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@tts_multivoice
Patch Set: Rebase Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | chrome/browser/android/chrome_jni_registrar.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2013 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 package org.chromium.chrome.browser;
6
7 import android.content.Context;
8 import android.speech.tts.TextToSpeech;
9 import android.speech.tts.UtteranceProgressListener;
10 import java.lang.Double;
11 import java.lang.Integer;
12 import java.util.ArrayList;
13 import java.util.HashMap;
14 import java.util.Locale;
15 import org.chromium.base.CalledByNative;
16 import org.chromium.base.ThreadUtils;
17
18 /**
19 * This class is the Java counterpart to the C++ TtsPlatformImplAndroid class.
20 * It implements the Android-native text-to-speech code to support the web
21 * speech synthesis API.
22 *
23 * Threading model note: all calls from C++ must happen on the UI thread.
24 * Callbacks from Android may happen on a different thread, so we always
25 * use ThreadUtils.runOnUiThread when calling back to C++.
26 */
27 class TtsPlatformImpl {
28 private static class TtsVoice {
29 private TtsVoice(String name, String language) {
30 mName = name;
31 mLanguage = language;
32 }
33 private final String mName;
34 private final String mLanguage;
35 };
36
37 private int mNativeTtsPlatformImplAndroid;
38 private final TextToSpeech mTextToSpeech;
39 private boolean mInitialized;
40 private ArrayList<TtsVoice> mVoices;
41 private String mCurrentLanguage;
42
43 private TtsPlatformImpl(int nativeTtsPlatformImplAndroid, Context context) {
44 mInitialized = false;
45 mNativeTtsPlatformImplAndroid = nativeTtsPlatformImplAndroid;
46 mTextToSpeech = new TextToSpeech(context, new TextToSpeech.OnInitListene r() {
47 public void onInit(int status) {
48 if (status == TextToSpeech.SUCCESS) {
49 ThreadUtils.runOnUiThread(new Runnable() {
50 @Override
51 public void run() {
52 initialize();
53 }
54 });
55 }
56 }
57 });
58 mTextToSpeech.setOnUtteranceProgressListener(new UtteranceProgressListen er() {
59 public void onDone(final String utteranceId) {
60 ThreadUtils.runOnUiThread(new Runnable() {
61 @Override
62 public void run() {
63 if (mNativeTtsPlatformImplAndroid != 0) {
64 nativeOnEndEvent(mNativeTtsPlatformImplAndroid,
65 Integer.parseInt(utteranceId));
66 }
67 }
68 });
69 }
70
71 public void onError(final String utteranceId) {
72 ThreadUtils.runOnUiThread(new Runnable() {
73 @Override
74 public void run() {
75 if (mNativeTtsPlatformImplAndroid != 0) {
76 nativeOnErrorEvent(mNativeTtsPlatformImplAndroid ,
77 Integer.parseInt(utteranceId) );
78 }
79 }
80 });
81 }
82
83 public void onStart(final String utteranceId) {
84 ThreadUtils.runOnUiThread(new Runnable() {
85 @Override
86 public void run() {
87 if (mNativeTtsPlatformImplAndroid != 0) {
88 nativeOnStartEvent(mNativeTtsPlatformImplAndroid ,
89 Integer.parseInt(utteranceId) );
90 }
91 }
92 });
93 }
94 });
95 };
96
97 /**
98 * Create a TtsPlatformImpl object, which is owned by TtsPlatformImplAndroid
99 * on the C++ side.
100 *
101 * @param nativeTtsPlatformImplAndroid The C++ object that owns us.
102 * @param context The app context.
103 */
104 @CalledByNative
105 private static TtsPlatformImpl create(int nativeTtsPlatformImplAndroid,
106 Context context) {
107 return new TtsPlatformImpl(nativeTtsPlatformImplAndroid, context);
108 }
109
110 /**
111 * Called when our C++ counterpoint is deleted. Clear the handle to our
112 * native C++ object, ensuring it's never called.
113 */
114 @CalledByNative
115 private void destroy() {
116 mNativeTtsPlatformImplAndroid = 0;
117 }
118
119 /**
120 * @return true if our TextToSpeech object is initialized and we've
121 * finished scanning the list of voices.
122 */
123 @CalledByNative
124 private boolean isInitialized() {
125 return mInitialized;
126 }
127
128 /**
129 * @return the number of voices.
130 */
131 @CalledByNative
132 private int getVoiceCount() {
133 assert mInitialized == true;
134 return mVoices.size();
135 }
136
137 /**
138 * @return the name of the voice at a given index.
139 */
140 @CalledByNative
141 private String getVoiceName(int voiceIndex) {
142 assert mInitialized == true;
143 return mVoices.get(voiceIndex).mName;
144 }
145
146 /**
147 * @return the language of the voice at a given index.
148 */
149 @CalledByNative
150 private String getVoiceLanguage(int voiceIndex) {
151 assert mInitialized == true;
152 return mVoices.get(voiceIndex).mLanguage;
153 }
154
155 /**
156 * Attempt to start speaking an utterance. If it returns true, will call bac k on
157 * start and end.
158 *
159 * @param utteranceId A unique id for this utterance so that callbacks can b e tied
160 * to a particular utterance.
161 * @param text The text to speak.
162 * @param lang The language code for the text (e.g., "en-US").
163 * @param rate The speech rate, in the units expected by Android TextToSpeec h.
164 * @param pitch The speech pitch, in the units expected by Android TextToSpe ech.
165 * @param volume The speech volume, in the units expected by Android TextToS peech.
166 * @return true on success.
167 */
168 @CalledByNative
169 private boolean speak(int utteranceId, String text, String lang,
170 float rate, float pitch, float volume) {
171 assert mInitialized == true;
172 if (lang != mCurrentLanguage) {
173 mTextToSpeech.setLanguage(new Locale(lang));
174 mCurrentLanguage = lang;
175 }
176
177 mTextToSpeech.setSpeechRate(rate);
178 mTextToSpeech.setPitch(pitch);
179 HashMap<String, String> params = new HashMap<String, String>();
180 if (volume != 1.0) {
181 params.put(TextToSpeech.Engine.KEY_PARAM_VOLUME, Double.toString(vol ume));
182 }
183 params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, Integer.toString( utteranceId));
184 int result = mTextToSpeech.speak(text, TextToSpeech.QUEUE_FLUSH, params) ;
185 return (result == TextToSpeech.SUCCESS);
186 }
187
188 /**
189 * Stop the current utterance.
190 */
191 @CalledByNative
192 private void stop() {
193 assert mInitialized == true;
194 mTextToSpeech.stop();
195 }
196
197 /**
198 * Note: we enforce that this method is called on the UI thread, so
199 * we can call nativeVoicesChanged directly.
200 */
201 private void initialize() {
202 // Note: Android supports multiple speech engines, but querying the
David Trainor- moved to gerrit 2013/05/17 18:03:33 assert mNativeTtsPlatformImplAndroid != 0; ?
dmazzoni 2013/05/18 20:47:15 Done.
203 // metadata about all of them is expensive. So we deliberately only
204 // support the default speech engine, and expose the different
205 // supported languages for the default engine as different voices.
206 String defaultEngineName = mTextToSpeech.getDefaultEngine();
207 String engineLabel = defaultEngineName;
208 for (TextToSpeech.EngineInfo info : mTextToSpeech.getEngines()) {
209 if (info.name.equals(defaultEngineName)) engineLabel = info.label;
210 }
211 Locale[] locales = Locale.getAvailableLocales();
212 mVoices = new ArrayList<TtsVoice>();
213 for (int i = 0; i < locales.length; ++i) {
214 if (!locales[i].getVariant().isEmpty()) continue;
215 if (mTextToSpeech.isLanguageAvailable(locales[i]) > 0) {
216 String name = locales[i].getDisplayLanguage();
217 if (!locales[i].getCountry().isEmpty()) {
218 name += " " + locales[i].getDisplayCountry();
219 }
220 TtsVoice voice = new TtsVoice(name, locales[i].toString());
221 mVoices.add(voice);
222 }
223 }
224
225 mInitialized = true;
226 nativeVoicesChanged(mNativeTtsPlatformImplAndroid);
227 }
228
229 private native void nativeVoicesChanged(int nativeTtsPlatformImplAndroid);
230 private native void nativeOnEndEvent(int nativeTtsPlatformImplAndroid, int u tteranceId);
231 private native void nativeOnStartEvent(int nativeTtsPlatformImplAndroid, int utteranceId);
232 private native void nativeOnErrorEvent(int nativeTtsPlatformImplAndroid, int utteranceId);
233 }
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/android/chrome_jni_registrar.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698