blob: 16b9a976c80db45c5045031035966658647117aa [file] [log] [blame]
Przemyslaw Szczepaniak90d15d22013-06-14 12:02:53 +01001package android.speech.tts;
2
3import android.os.Bundle;
4import android.os.Parcel;
5import android.os.Parcelable;
6
7import java.util.Locale;
8
9/**
10 * Characteristics and features of a Text-To-Speech Voice. Each TTS Engine can expose
11 * multiple voices for multiple locales, with different set of features.
12 *
Przemyslaw Szczepaniak97cd6472013-10-25 12:04:47 +010013 * Each VoiceInfo has an unique name. This name can be obtained using the {@link #getName()} method
14 * and will persist until the client is asked to re-evaluate the list of available voices in the
Przemyslaw Szczepaniak90d15d22013-06-14 12:02:53 +010015 * {@link TextToSpeechClient.ConnectionCallbacks#onEngineStatusChange(android.speech.tts.TextToSpeechClient.EngineStatus)}
Przemyslaw Szczepaniak97cd6472013-10-25 12:04:47 +010016 * callback. The name can be used to reference a VoiceInfo in an instance of {@link RequestConfig};
17 * the {@link TextToSpeechClient.Params#FALLBACK_VOICE_NAME} voice parameter is an example of this.
18 * It is recommended that the voice name never change during the TTS service lifetime.
Przemyslaw Szczepaniak90d15d22013-06-14 12:02:53 +010019 */
20public final class VoiceInfo implements Parcelable {
21 /** Very low, but still intelligible quality of speech synthesis */
22 public static final int QUALITY_VERY_LOW = 100;
23
24 /** Low, not human-like quality of speech synthesis */
25 public static final int QUALITY_LOW = 200;
26
27 /** Normal quality of speech synthesis */
28 public static final int QUALITY_NORMAL = 300;
29
30 /** High, human-like quality of speech synthesis */
31 public static final int QUALITY_HIGH = 400;
32
33 /** Very high, almost human-indistinguishable quality of speech synthesis */
34 public static final int QUALITY_VERY_HIGH = 500;
35
36 /** Very low expected synthesizer latency (< 20ms) */
37 public static final int LATENCY_VERY_LOW = 100;
38
39 /** Low expected synthesizer latency (~20ms) */
40 public static final int LATENCY_LOW = 200;
41
42 /** Normal expected synthesizer latency (~50ms) */
43 public static final int LATENCY_NORMAL = 300;
44
45 /** Network based expected synthesizer latency (~200ms) */
46 public static final int LATENCY_HIGH = 400;
47
48 /** Very slow network based expected synthesizer latency (> 200ms) */
49 public static final int LATENCY_VERY_HIGH = 500;
50
51 /** Additional feature key, with string value, gender of the speaker */
52 public static final String FEATURE_SPEAKER_GENDER = "speakerGender";
53
54 /** Additional feature key, with integer value, speaking speed in words per minute
55 * when {@link TextToSpeechClient.Params#SPEECH_SPEED} parameter is set to {@code 1.0} */
56 public static final String FEATURE_WORDS_PER_MINUTE = "wordsPerMinute";
57
58 /**
59 * Additional feature key, with boolean value, that indicates that voice may need to
60 * download additional data if used for synthesis.
61 *
62 * Making a request with a voice that has this feature may result in a
63 * {@link TextToSpeechClient.Status#ERROR_DOWNLOADING_ADDITIONAL_DATA} error. It's recommended
Przemyslaw Szczepaniak97cd6472013-10-25 12:04:47 +010064 * to set the {@link TextToSpeechClient.Params#FALLBACK_VOICE_NAME} voice parameter to reference
Przemyslaw Szczepaniak90d15d22013-06-14 12:02:53 +010065 * a fully installed voice (or network voice) that can serve as replacement.
66 *
67 * Note: It's a good practice for a TTS engine to provide a sensible fallback voice as the
Przemyslaw Szczepaniak97cd6472013-10-25 12:04:47 +010068 * default value for {@link TextToSpeechClient.Params#FALLBACK_VOICE_NAME} parameter if this
Przemyslaw Szczepaniak90d15d22013-06-14 12:02:53 +010069 * feature is present.
70 */
71 public static final String FEATURE_MAY_AUTOINSTALL = "mayAutoInstall";
72
Przemyslaw Szczepaniak97cd6472013-10-25 12:04:47 +010073 private final String mName;
Przemyslaw Szczepaniak90d15d22013-06-14 12:02:53 +010074 private final Locale mLocale;
75 private final int mQuality;
76 private final int mLatency;
77 private final boolean mRequiresNetworkConnection;
78 private final Bundle mParams;
79 private final Bundle mAdditionalFeatures;
80
81 private VoiceInfo(Parcel in) {
Przemyslaw Szczepaniak97cd6472013-10-25 12:04:47 +010082 this.mName = in.readString();
Przemyslaw Szczepaniak90d15d22013-06-14 12:02:53 +010083 String[] localesData = new String[3];
84 in.readStringArray(localesData);
85 this.mLocale = new Locale(localesData[0], localesData[1], localesData[2]);
86
87 this.mQuality = in.readInt();
88 this.mLatency = in.readInt();
89 this.mRequiresNetworkConnection = (in.readByte() == 1);
90
91 this.mParams = in.readBundle();
92 this.mAdditionalFeatures = in.readBundle();
93 }
94
Przemyslaw Szczepaniak97cd6472013-10-25 12:04:47 +010095 private VoiceInfo(String name,
Przemyslaw Szczepaniak90d15d22013-06-14 12:02:53 +010096 Locale locale,
97 int quality,
98 int latency,
99 boolean requiresNetworkConnection,
100 Bundle params,
101 Bundle additionalFeatures) {
Przemyslaw Szczepaniak97cd6472013-10-25 12:04:47 +0100102 this.mName = name;
Przemyslaw Szczepaniak90d15d22013-06-14 12:02:53 +0100103 this.mLocale = locale;
104 this.mQuality = quality;
105 this.mLatency = latency;
106 this.mRequiresNetworkConnection = requiresNetworkConnection;
107 this.mParams = params;
108 this.mAdditionalFeatures = additionalFeatures;
109 }
110
111 /** Builder, allows TTS engines to create VoiceInfo instances. */
112 public static final class Builder {
Przemyslaw Szczepaniak97cd6472013-10-25 12:04:47 +0100113 private String name;
Przemyslaw Szczepaniak90d15d22013-06-14 12:02:53 +0100114 private Locale locale;
115 private int quality = VoiceInfo.QUALITY_NORMAL;
116 private int latency = VoiceInfo.LATENCY_NORMAL;
117 private boolean requiresNetworkConnection;
118 private Bundle params;
119 private Bundle additionalFeatures;
120
121 public Builder() {
122
123 }
124
125 /**
126 * Copy fields from given VoiceInfo instance.
127 */
128 public Builder(VoiceInfo voiceInfo) {
Przemyslaw Szczepaniak97cd6472013-10-25 12:04:47 +0100129 this.name = voiceInfo.mName;
Przemyslaw Szczepaniak90d15d22013-06-14 12:02:53 +0100130 this.locale = voiceInfo.mLocale;
131 this.quality = voiceInfo.mQuality;
132 this.latency = voiceInfo.mLatency;
133 this.requiresNetworkConnection = voiceInfo.mRequiresNetworkConnection;
134 this.params = (Bundle)voiceInfo.mParams.clone();
135 this.additionalFeatures = (Bundle) voiceInfo.mAdditionalFeatures.clone();
136 }
137
138 /**
Przemyslaw Szczepaniak97cd6472013-10-25 12:04:47 +0100139 * Sets the voice's unique name. It will be used by clients to reference the voice used by a
Przemyslaw Szczepaniak90d15d22013-06-14 12:02:53 +0100140 * request.
Przemyslaw Szczepaniak97cd6472013-10-25 12:04:47 +0100141 *
142 * It's recommended that each voice use the same consistent name during the TTS service
143 * lifetime.
Przemyslaw Szczepaniak90d15d22013-06-14 12:02:53 +0100144 */
Przemyslaw Szczepaniak97cd6472013-10-25 12:04:47 +0100145 public Builder setName(String name) {
146 this.name = name;
Przemyslaw Szczepaniak90d15d22013-06-14 12:02:53 +0100147 return this;
148 }
149
150 /**
151 * Sets voice locale. This has to be a valid locale, built from ISO 639-1 and ISO 3166-1
152 * two letter codes.
153 */
154 public Builder setLocale(Locale locale) {
155 this.locale = locale;
156 return this;
157 }
158
159 /**
160 * Sets map of all available request parameters with their default values.
161 * Some common parameter names can be found in {@link TextToSpeechClient.Params} static
162 * members.
163 */
164 public Builder setParamsWithDefaults(Bundle params) {
165 this.params = params;
166 return this;
167 }
168
169 /**
170 * Sets map of additional voice features. Some common feature names can be found in
171 * {@link VoiceInfo} static members.
172 */
173 public Builder setAdditionalFeatures(Bundle additionalFeatures) {
174 this.additionalFeatures = additionalFeatures;
175 return this;
176 }
177
178 /**
179 * Sets the voice quality (higher is better).
180 */
181 public Builder setQuality(int quality) {
182 this.quality = quality;
183 return this;
184 }
185
186 /**
187 * Sets the voice latency (lower is better).
188 */
189 public Builder setLatency(int latency) {
190 this.latency = latency;
191 return this;
192 }
193
194 /**
195 * Sets whether the voice requires network connection to work properly.
196 */
197 public Builder setRequiresNetworkConnection(boolean requiresNetworkConnection) {
198 this.requiresNetworkConnection = requiresNetworkConnection;
199 return this;
200 }
201
202 /**
Przemyslaw Szczepaniak97cd6472013-10-25 12:04:47 +0100203 * @return The built VoiceInfo instance.
Przemyslaw Szczepaniak90d15d22013-06-14 12:02:53 +0100204 */
205 public VoiceInfo build() {
Przemyslaw Szczepaniak97cd6472013-10-25 12:04:47 +0100206 if (name == null || name.isEmpty()) {
207 throw new IllegalStateException("Name can't be null or empty");
208 }
Przemyslaw Szczepaniak90d15d22013-06-14 12:02:53 +0100209 if (locale == null) {
210 throw new IllegalStateException("Locale can't be null");
211 }
212
Przemyslaw Szczepaniak97cd6472013-10-25 12:04:47 +0100213 return new VoiceInfo(name, locale, quality, latency,
Przemyslaw Szczepaniak90d15d22013-06-14 12:02:53 +0100214 requiresNetworkConnection,
215 ((params == null) ? new Bundle() :
216 (Bundle)params.clone()),
217 ((additionalFeatures == null) ? new Bundle() :
218 (Bundle)additionalFeatures.clone()));
219 }
220 }
221
222 /**
223 * @hide
224 */
225 @Override
226 public int describeContents() {
227 return 0;
228 }
229
230 /**
231 * @hide
232 */
233 @Override
234 public void writeToParcel(Parcel dest, int flags) {
Przemyslaw Szczepaniak97cd6472013-10-25 12:04:47 +0100235 dest.writeString(mName);
Przemyslaw Szczepaniak90d15d22013-06-14 12:02:53 +0100236 String[] localesData = new String[]{mLocale.getLanguage(), mLocale.getCountry(), mLocale.getVariant()};
237 dest.writeStringArray(localesData);
238 dest.writeInt(mQuality);
239 dest.writeInt(mLatency);
240 dest.writeByte((byte) (mRequiresNetworkConnection ? 1 : 0));
241 dest.writeBundle(mParams);
242 dest.writeBundle(mAdditionalFeatures);
243 }
244
245 /**
246 * @hide
247 */
248 public static final Parcelable.Creator<VoiceInfo> CREATOR = new Parcelable.Creator<VoiceInfo>() {
249 @Override
250 public VoiceInfo createFromParcel(Parcel in) {
251 return new VoiceInfo(in);
252 }
253
254 @Override
255 public VoiceInfo[] newArray(int size) {
256 return new VoiceInfo[size];
257 }
258 };
259
260 /**
261 * @return The voice's locale
262 */
263 public Locale getLocale() {
264 return mLocale;
265 }
266
267 /**
268 * @return The voice's quality (higher is better)
269 */
270 public int getQuality() {
271 return mQuality;
272 }
273
274 /**
275 * @return The voice's latency (lower is better)
276 */
277 public int getLatency() {
278 return mLatency;
279 }
280
281 /**
282 * @return Does the Voice require a network connection to work.
283 */
284 public boolean getRequiresNetworkConnection() {
285 return mRequiresNetworkConnection;
286 }
287
288 /**
289 * @return Bundle of all available parameters with their default values.
290 */
291 public Bundle getParamsWithDefaults() {
292 return mParams;
293 }
294
295 /**
Przemyslaw Szczepaniak97cd6472013-10-25 12:04:47 +0100296 * @return Unique voice name.
Przemyslaw Szczepaniak90d15d22013-06-14 12:02:53 +0100297 *
Przemyslaw Szczepaniak97cd6472013-10-25 12:04:47 +0100298 * Each VoiceInfo has an unique name, that persists until client is asked to re-evaluate the
Przemyslaw Szczepaniak90d15d22013-06-14 12:02:53 +0100299 * set of the available languages in the {@link TextToSpeechClient.ConnectionCallbacks#onEngineStatusChange(android.speech.tts.TextToSpeechClient.EngineStatus)}
Przemyslaw Szczepaniak97cd6472013-10-25 12:04:47 +0100300 * callback (Voice may disappear from the set if voice was removed by the user).
Przemyslaw Szczepaniak90d15d22013-06-14 12:02:53 +0100301 */
Przemyslaw Szczepaniak97cd6472013-10-25 12:04:47 +0100302 public String getName() {
303 return mName;
Przemyslaw Szczepaniak90d15d22013-06-14 12:02:53 +0100304 }
305
306 /**
307 * @return Additional features of the voice.
308 */
309 public Bundle getAdditionalFeatures() {
310 return mAdditionalFeatures;
311 }
312
313 @Override
314 public String toString() {
315 StringBuilder builder = new StringBuilder(64);
Przemyslaw Szczepaniak97cd6472013-10-25 12:04:47 +0100316 return builder.append("VoiceInfo[Name: ").append(mName)
Przemyslaw Szczepaniak90d15d22013-06-14 12:02:53 +0100317 .append(" ,locale: ").append(mLocale)
318 .append(" ,quality: ").append(mQuality)
319 .append(" ,latency: ").append(mLatency)
320 .append(" ,requiresNetwork: ").append(mRequiresNetworkConnection)
321 .append(" ,paramsWithDefaults: ").append(mParams.toString())
322 .append(" ,additionalFeatures: ").append(mAdditionalFeatures.toString())
323 .append("]").toString();
324 }
325}