2 * Copyright 2003 Sun Microsystems, Inc.
4 * See the file "license.terms" for information on usage and
5 * redistribution of this file, and for a DISCLAIMER OF ALL
8 package com.sun.speech.freetts.jsapi;
10 import java.util.Locale;
11 import java.util.Vector;
13 import javax.speech.EngineCentral;
14 import javax.speech.EngineList;
15 import javax.speech.EngineModeDesc;
17 import com.sun.speech.freetts.ValidationException;
21 * Supports the EngineCentral JSAPI 1.0 interface for the
22 * FreeTTSSynthesizer. To use a FreeTTSSynthesizer, you should place
23 * a line into the speech.properties file as so:
26 * FreeTTSSynthEngineCentral=com.sun.speech.freetts.jsapi.FreeTTSEngineCentral
31 public class FreeTTSEngineCentral implements EngineCentral {
32 private String engineName = "FreeTTS Synthesizer";
35 * Creates a FreeTTSEngineCentral
37 public FreeTTSEngineCentral() throws Exception {
38 // Note that the JSAPI layer currently is silent
39 // about any exceptions thrown from here, so we are noisy here
43 * Returns a list containing references to all matching
44 * synthesizers. The mapping of FreeTTS VoiceDirectories and
45 * Voices to JSAPI Synthesizers and Voices is as follows:
48 * <li>Each FreeTTS VoiceDirectory specifies the list of FreeTTS
49 * Voices supported by that directory. Each Voice in that
50 * directory specifies its name (e.g., "kevin" "kevin16" "alan"),
51 * domain (e.g., "general" or "time") and locale (e.g., Locale.US).
52 * <li>For all FreeTTS Voices from all VoiceDirectories discovered
53 * by the VoiceManager, this method will group the Voices
54 * according to those that have both a common locale and domain
55 * (e.g, all "general" domain voices for the US local will be
57 * <li>For each group of voices that shares a common locale and
58 * domain, this method generates a new JSAPI SynthesizerModeDesc
59 * with the following attributes:
61 * <li>The engine name is of the form: "FreeTTS <locale>
62 * <domain> synthesizer" For example, "FreeTTS en_us general
64 * <li>The locale is the locale shared by all the voices (e.g.,
66 * <li>The mode name is the domain shared by all the voices
69 * <li>The JSAPI Voices for each resulting Synthesizer will have
70 * the name of the FreeTTS Voice (e.g. "kevin" "kevin16").
73 * @param require an engine mode that describes the desired
76 * @return an engineList containing matching engines, or null if
77 * no matching engines are found
79 public EngineList createEngineList(EngineModeDesc require) {
80 EngineList el = new EngineList();
82 com.sun.speech.freetts.VoiceManager voiceManager =
83 com.sun.speech.freetts.VoiceManager.getInstance();
85 com.sun.speech.freetts.Voice[] voices = voiceManager.getVoices();
87 // We want to get all combinations of domains and locales
88 Vector domainLocaleVector = new Vector();
89 for (int i = 0; i < voices.length; i++) {
91 new DomainLocale(voices[i].getDomain(), voices[i].getLocale());
92 DomainLocale dlentry = (DomainLocale)
93 getItem(domainLocaleVector, dl);
94 if (dlentry == null) {
95 domainLocaleVector.add(dl);
98 dlentry.addVoice(voices[i]);
101 // build list of SynthesizerModeDesc's for each domain/locale
103 for (int i = 0; i < domainLocaleVector.size(); i++) {
104 DomainLocale dl = (DomainLocale) domainLocaleVector.get(i);
106 FreeTTSSynthesizerModeDesc desc = new
107 FreeTTSSynthesizerModeDesc("FreeTTS "
108 + dl.getLocale().toString() + " " + dl.getDomain()
109 + " synthesizer", dl.getDomain(), dl.getLocale());
111 // iterate through the voices in a different order
112 voices = dl.getVoices();
113 for (int j = 0; j < voices.length; j++) {
114 FreeTTSVoice jsapiVoice = new FreeTTSVoice(voices[j], null);
115 desc.addVoice(jsapiVoice);
118 if (require == null || desc.match(require)) {
122 } catch (ValidationException ve) {
123 System.err.println(ve.getMessage());
128 if (el.size() == 0) {
135 * Gets an item out of a vector.
136 * Warning: linear search
138 * @param vector the vector to search
139 * @param o the object to look for using vector.get(i).equals(o)
141 * @return the item if it exists in the vector, else null
143 private Object getItem(Vector vector, Object o) {
144 for (int i = 0; i < vector.size(); i++) {
145 if (vector.get(i).equals(o)) {
146 return vector.get(i);
155 * Used to be able to generate a list of voices based on unique
156 * combinations of domain/locale pairs.
159 private String domain;
160 private Locale locale;
161 private Vector voices;
166 * @param domain the domain to use
167 * @param locale the locale to use
169 public DomainLocale(String domain, Locale locale) {
170 this.domain = domain;
171 this.locale = locale;
172 this.voices = new Vector();
176 * See if two DomainLocale objects are equal.
177 * The voices are NOT compared.
179 * @param o, the object to compare to
181 * @return true if the domain and locale are both equal, else
184 public boolean equals(Object o) {
185 if (! (o instanceof DomainLocale)) {
188 return (domain.equals(((DomainLocale) o).getDomain())
189 && locale.equals(((DomainLocale) o).getLocale()));
196 public String getDomain() {
204 public Locale getLocale() {
209 * Adds a voice to this instance.
211 * @param voice the voice to add
213 public void addVoice(com.sun.speech.freetts.Voice voice) {
218 * Gets the voices of this instance.
220 * @return all of the voices that have been added to this
223 public com.sun.speech.freetts.Voice[] getVoices() {
224 com.sun.speech.freetts.Voice[] voiceArray =
225 new com.sun.speech.freetts.Voice[voices.size()];
226 return (com.sun.speech.freetts.Voice[]) voices.toArray(voiceArray);