blob: fefc35e775e3c628d5d44b5eb8ebff87d9f67a74 [file] [log] [blame]
Przemyslaw Szczepaniakad6df742014-07-01 17:04:25 +01001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 * use this file except in compliance with the License. You may obtain a copy of
6 * the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations under
14 * the License.
15 */
16
17package android.speech.tts;
18
19import android.os.Parcel;
20import android.os.Parcelable;
21
22import java.util.ArrayList;
23import java.util.Collections;
24import java.util.HashSet;
25import java.util.Locale;
26import java.util.Set;
27
28/**
29 * Characteristics and features of a Text-To-Speech Voice. Each TTS Engine can expose
30 * multiple voices for each locale, with different set of features.
31 */
32public class Voice implements Parcelable {
33 /** Very low, but still intelligible quality of speech synthesis */
34 public static final int QUALITY_VERY_LOW = 100;
35
36 /** Low, not human-like quality of speech synthesis */
37 public static final int QUALITY_LOW = 200;
38
39 /** Normal quality of speech synthesis */
40 public static final int QUALITY_NORMAL = 300;
41
42 /** High, human-like quality of speech synthesis */
43 public static final int QUALITY_HIGH = 400;
44
45 /** Very high, almost human-indistinguishable quality of speech synthesis */
46 public static final int QUALITY_VERY_HIGH = 500;
47
48 /** Very low expected synthesizer latency (< 20ms) */
49 public static final int LATENCY_VERY_LOW = 100;
50
51 /** Low expected synthesizer latency (~20ms) */
52 public static final int LATENCY_LOW = 200;
53
54 /** Normal expected synthesizer latency (~50ms) */
55 public static final int LATENCY_NORMAL = 300;
56
57 /** Network based expected synthesizer latency (~200ms) */
58 public static final int LATENCY_HIGH = 400;
59
60 /** Very slow network based expected synthesizer latency (> 200ms) */
61 public static final int LATENCY_VERY_HIGH = 500;
62
63 private final String mName;
64 private final Locale mLocale;
65 private final int mQuality;
66 private final int mLatency;
67 private final boolean mRequiresNetworkConnection;
68 private final Set<String> mFeatures;
69
70 public Voice(String name,
71 Locale locale,
72 int quality,
73 int latency,
74 boolean requiresNetworkConnection,
75 Set<String> features) {
76 this.mName = name;
77 this.mLocale = locale;
78 this.mQuality = quality;
79 this.mLatency = latency;
80 this.mRequiresNetworkConnection = requiresNetworkConnection;
81 this.mFeatures = features;
82 }
83
84 private Voice(Parcel in) {
85 this.mName = in.readString();
86 this.mLocale = (Locale)in.readSerializable();
87 this.mQuality = in.readInt();
88 this.mLatency = in.readInt();
89 this.mRequiresNetworkConnection = (in.readByte() == 1);
90 this.mFeatures = new HashSet<String>();
91 Collections.addAll(this.mFeatures, in.readStringArray());
92 }
93
Przemyslaw Szczepaniakad6df742014-07-01 17:04:25 +010094 @Override
95 public void writeToParcel(Parcel dest, int flags) {
96 dest.writeString(mName);
97 dest.writeSerializable(mLocale);
98 dest.writeInt(mQuality);
99 dest.writeInt(mLatency);
100 dest.writeByte((byte) (mRequiresNetworkConnection ? 1 : 0));
101 dest.writeStringList(new ArrayList<String>(mFeatures));
102 }
103
Przemyslaw Szczepaniakad6df742014-07-01 17:04:25 +0100104 @Override
105 public int describeContents() {
106 return 0;
107 }
108
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -0700109 public static final @android.annotation.NonNull Parcelable.Creator<Voice> CREATOR = new Parcelable.Creator<Voice>() {
Przemyslaw Szczepaniakad6df742014-07-01 17:04:25 +0100110 @Override
111 public Voice createFromParcel(Parcel in) {
112 return new Voice(in);
113 }
114
115 @Override
116 public Voice[] newArray(int size) {
117 return new Voice[size];
118 }
119 };
120
121
122 /**
123 * @return The voice's locale
124 */
125 public Locale getLocale() {
126 return mLocale;
127 }
128
129 /**
130 * @return The voice's quality (higher is better)
131 * @see #QUALITY_VERY_HIGH
132 * @see #QUALITY_HIGH
133 * @see #QUALITY_NORMAL
134 * @see #QUALITY_LOW
135 * @see #QUALITY_VERY_LOW
136 */
137 public int getQuality() {
138 return mQuality;
139 }
140
141 /**
142 * @return The voice's latency (lower is better)
143 * @see #LATENCY_VERY_LOW
144 * @see #LATENCY_LOW
145 * @see #LATENCY_NORMAL
146 * @see #LATENCY_HIGH
147 * @see #LATENCY_VERY_HIGH
148 */
149 public int getLatency() {
150 return mLatency;
151 }
152
153 /**
154 * @return Does the Voice require a network connection to work.
155 */
Przemyslaw Szczepaniak35c76982014-09-05 15:36:49 +0100156 public boolean isNetworkConnectionRequired() {
Przemyslaw Szczepaniakad6df742014-07-01 17:04:25 +0100157 return mRequiresNetworkConnection;
158 }
159
160 /**
161 * @return Unique voice name.
162 */
163 public String getName() {
164 return mName;
165 }
166
167 /**
168 * Returns the set of features it supports for a given voice.
169 * Features can either be framework defined, e.g.
170 * {@link TextToSpeech.Engine#KEY_FEATURE_NETWORK_TIMEOUT_MS} or engine specific.
171 * Engine specific keys must be prefixed by the name of the engine they
172 * are intended for. These keys can be used as parameters to
173 * {@link TextToSpeech#speak(String, int, java.util.HashMap)} and
174 * {@link TextToSpeech#synthesizeToFile(String, java.util.HashMap, String)}.
175 *
176 * Features values are strings and their values must met restrictions described in their
177 * documentation.
178 *
179 * @return Set instance. May return {@code null} on error.
180 */
181 public Set<String> getFeatures() {
182 return mFeatures;
183 }
184
185 @Override
186 public String toString() {
187 StringBuilder builder = new StringBuilder(64);
188 return builder.append("Voice[Name: ").append(mName)
189 .append(", locale: ").append(mLocale)
190 .append(", quality: ").append(mQuality)
191 .append(", latency: ").append(mLatency)
192 .append(", requiresNetwork: ").append(mRequiresNetworkConnection)
193 .append(", features: ").append(mFeatures.toString())
194 .append("]").toString();
195 }
196
197 @Override
198 public int hashCode() {
199 final int prime = 31;
200 int result = 1;
201 result = prime * result + ((mFeatures == null) ? 0 : mFeatures.hashCode());
202 result = prime * result + mLatency;
203 result = prime * result + ((mLocale == null) ? 0 : mLocale.hashCode());
204 result = prime * result + ((mName == null) ? 0 : mName.hashCode());
205 result = prime * result + mQuality;
206 result = prime * result + (mRequiresNetworkConnection ? 1231 : 1237);
207 return result;
208 }
209
210 @Override
211 public boolean equals(Object obj) {
212 if (this == obj) {
213 return true;
214 }
215 if (obj == null) {
216 return false;
217 }
218 if (getClass() != obj.getClass()) {
219 return false;
220 }
221 Voice other = (Voice) obj;
222 if (mFeatures == null) {
223 if (other.mFeatures != null) {
224 return false;
225 }
226 } else if (!mFeatures.equals(other.mFeatures)) {
227 return false;
228 }
229 if (mLatency != other.mLatency) {
230 return false;
231 }
232 if (mLocale == null) {
233 if (other.mLocale != null) {
234 return false;
235 }
236 } else if (!mLocale.equals(other.mLocale)) {
237 return false;
238 }
239 if (mName == null) {
240 if (other.mName != null) {
241 return false;
242 }
243 } else if (!mName.equals(other.mName)) {
244 return false;
245 }
246 if (mQuality != other.mQuality) {
247 return false;
248 }
249 if (mRequiresNetworkConnection != other.mRequiresNetworkConnection) {
250 return false;
251 }
252 return true;
253 }
254}