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