Home | History | Annotate | Download | only in tts
      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.os.Parcel;
     20 import android.os.Parcelable;
     21 
     22 import java.util.ArrayList;
     23 import java.util.Collections;
     24 import java.util.HashSet;
     25 import java.util.Locale;
     26 import 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  */
     32 public 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 
     94     @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 
    104     @Override
    105     public int describeContents() {
    106         return 0;
    107     }
    108 
    109     public static final Parcelable.Creator<Voice> CREATOR = new Parcelable.Creator<Voice>() {
    110         @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      */
    156     public boolean isNetworkConnectionRequired() {
    157         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 }
    255