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

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: Address feedback 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
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 public class TtsPlatformImpl {
bulach 2013/05/16 11:10:28 nit: if this class is only used as a bridge to c++
dmazzoni 2013/05/16 16:36:40 I'm not sure I understand - I thought a top-level
bulach 2013/05/17 10:09:04 sorry, my bad. :) I meant the class would be "pack
24 private class TtsVoice {
bulach 2013/05/16 11:10:28 nit: static
dmazzoni 2013/05/16 16:36:40 Done.
25 public String name;
bulach 2013/05/16 11:10:28 nit: mName, mLanguage also, they don't need to be
dmazzoni 2013/05/16 16:36:40 Done.
26 public String language;
27 };
28
29 private int mNativeTtsPlatformImplAndroid;
30 private TextToSpeech mTextToSpeech;
31 private boolean mInitialized;
32 private ArrayList<TtsVoice> mVoices;
33 private String mCurrentLanguage;
34
35 private TtsPlatformImpl(int nativeTtsPlatformImplAndroid, Context context) {
36 mInitialized = false;
37 mNativeTtsPlatformImplAndroid = nativeTtsPlatformImplAndroid;
38 mTextToSpeech = new TextToSpeech(context, new TextToSpeech.OnInitListene r() {
39 public void onInit(int status) {
40 if (status == TextToSpeech.SUCCESS) {
41 initialize();
bulach 2013/05/16 11:10:28 not clear to me what is the threading model here.
dmazzoni 2013/05/16 16:36:40 I added a class comment to clarify: all C++ calls
42 }
43 }
44 });
45 mTextToSpeech.setOnUtteranceProgressListener(new UtteranceProgressListen er() {
46 public void onDone(final String utteranceId) {
47 ThreadUtils.runOnUiThread(new Runnable() {
48 @Override
49 public void run() {
50 if (mNativeTtsPlatformImplAndroid != 0) {
51 nativeOnEndEvent(mNativeTtsPlatformImplAndroid,
52 Integer.parseInt(utteranceId));
53 }
54 }
55 });
56 }
57
58 public void onError(final String utteranceId) {
59 ThreadUtils.runOnUiThread(new Runnable() {
60 @Override
61 public void run() {
62 if (mNativeTtsPlatformImplAndroid != 0) {
63 nativeOnErrorEvent(mNativeTtsPlatformImplAndroid ,
64 Integer.parseInt(utteranceId) );
65 }
66 }
67 });
68 }
69
70 public void onStart(final String utteranceId) {
71 ThreadUtils.runOnUiThread(new Runnable() {
72 @Override
73 public void run() {
74 if (mNativeTtsPlatformImplAndroid != 0) {
75 nativeOnStartEvent(mNativeTtsPlatformImplAndroid ,
76 Integer.parseInt(utteranceId) );
77 }
78 }
79 });
80 }
81 });
82 };
83
84 /**
85 * Create a TtsPlatformImpl object, which is owned by TtsPlatformImplAndroid
86 * on the C++ side.
87 *
88 * @param nativeTtsPlatformImplAndroid The C++ object that owns us.
89 * @param context The app context.
90 */
91 @CalledByNative
92 public static TtsPlatformImpl create(int nativeTtsPlatformImplAndroid,
93 Context context) {
94 return new TtsPlatformImpl(nativeTtsPlatformImplAndroid, context);
95 }
96
97 /**
98 * Called when our C++ counterpoint is deleted. Clear the handle to our
99 * native C++ object, ensuring it's never called.
100 */
101 @CalledByNative
102 public void destroy() {
103 mNativeTtsPlatformImplAndroid = 0;
104 }
105
106 /**
107 * @return true if our TextToSpeech object is initialized and we've
108 * finished scanning the list of voices.
109 */
110 @CalledByNative
111 public boolean isInitialized() {
112 return mInitialized;
113 }
114
115 /**
116 * @return the number of voices.
117 */
118 @CalledByNative
119 public int getVoiceCount() {
120 assert mInitialized == true;
121 return mVoices.size();
122 }
123
124 /**
125 * @return the name of the voice at a given index.
126 */
127 @CalledByNative
128 public String getVoiceName(int voiceIndex) {
129 assert mInitialized == true;
130 return mVoices.get(voiceIndex).name;
131 }
132
133 /**
134 * @return the language of the voice at a given index.
135 */
136 @CalledByNative
137 public String getVoiceLanguage(int voiceIndex) {
138 assert mInitialized == true;
139 return mVoices.get(voiceIndex).language;
140 }
141
142 /**
143 * Attempt to start speaking an utterance. If it returns true, will call bac k on
144 * start and end.
145 *
146 * @param utteranceId A unique id for this utterance so that callbacks can b e tied
147 * to a particular utterance.
148 * @param text The text to speak.
149 * @param lang The language code for the text (e.g., "en-US").
150 * @param rate The speech rate, in the units expected by Android TextToSpeec h.
151 * @param pitch The speech pitch, in the units expected by Android TextToSpe ech.
152 * @param volume The speech volume, in the units expected by Android TextToS peech.
153 * @return true on success.
154 */
155 @CalledByNative
156 public boolean speak(int utteranceId, String text, String lang,
157 float rate, float pitch, float volume) {
158 assert mInitialized == true;
159 if (lang != mCurrentLanguage) {
160 mTextToSpeech.setLanguage(new Locale(lang));
161 mCurrentLanguage = lang;
162 }
163
164 mTextToSpeech.setSpeechRate(rate);
165 mTextToSpeech.setPitch(pitch);
166 HashMap<String, String> params = new HashMap<String, String>();
167 if (volume != 1.0) {
168 params.put(TextToSpeech.Engine.KEY_PARAM_VOLUME, Double.toString(vol ume));
169 }
170 params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, Integer.toString( utteranceId));
171 int result = mTextToSpeech.speak(text, TextToSpeech.QUEUE_FLUSH, params) ;
172 return (result == TextToSpeech.SUCCESS);
173 }
174
175 /**
176 * Stop the current utterance.
177 */
178 @CalledByNative
179 public void stop() {
180 assert mInitialized == true;
181 mTextToSpeech.stop();
182 }
183
184 private void initialize() {
185 // Note: Android supports multiple speech engines, but querying the
186 // metadata about all of them is expensive. So we deliberately only
187 // support the default speech engine, and expose the different
188 // supported languages for the default engine as different voices.
189 String defaultEngineName = mTextToSpeech.getDefaultEngine();
190 String engineLabel = defaultEngineName;
191 for (TextToSpeech.EngineInfo info : mTextToSpeech.getEngines()) {
192 if (info.name.equals(defaultEngineName)) engineLabel = info.label;
193 }
194 Locale[] locales = Locale.getAvailableLocales();
195 mVoices = new ArrayList<TtsVoice>();
196 for (int i = 0; i < locales.length; ++i) {
197 if (!locales[i].getVariant().isEmpty()) continue;
198 if (mTextToSpeech.isLanguageAvailable(locales[i]) > 0) {
199 TtsVoice voice = new TtsVoice();
200 voice.name = locales[i].getDisplayLanguage();
201 if (!locales[i].getCountry().isEmpty()) {
202 voice.name += " " + locales[i].getDisplayCountry();
203 }
204 voice.language = locales[i].toString();
205 mVoices.add(voice);
206 }
207 }
208
209 mInitialized = true;
210
211 ThreadUtils.runOnUiThread(new Runnable() {
212 @Override
213 public void run() {
214 if (mNativeTtsPlatformImplAndroid != 0) {
215 nativeVoicesChanged(mNativeTtsPlatformImplAndroid);
216 }
217 }
218 });
219 }
220
221 private native void nativeVoicesChanged(int nativeTtsPlatformImplAndroid);
222 private native void nativeOnEndEvent(int nativeTtsPlatformImplAndroid, int u tteranceId);
223 private native void nativeOnStartEvent(int nativeTtsPlatformImplAndroid, int utteranceId);
224 private native void nativeOnErrorEvent(int nativeTtsPlatformImplAndroid, int utteranceId);
225 }
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/android/chrome_jni_registrar.cc » ('j') | chrome/browser/speech/tts_android.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698