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
9 import java.util.Locale;
10 import java.beans.PropertyChangeEvent;
11 import java.beans.PropertyChangeListener;
13 import javax.speech.Central;
14 import javax.speech.Engine;
15 import javax.speech.EngineException;
16 import javax.speech.synthesis.Synthesizer;
17 import javax.speech.synthesis.SynthesizerModeDesc;
18 import javax.speech.synthesis.SynthesizerProperties;
19 import javax.speech.synthesis.Voice;
20 import javax.speech.synthesis.Speakable;
21 import javax.speech.synthesis.SpeakableAdapter;
22 import javax.speech.synthesis.SpeakableEvent;
25 * Sample program that demonstrates how multiple voices
26 * and synthesizers can be used.
28 public class MixedVoices {
30 private final static void usage() {
31 System.out.println("MixedVoices [-showEvents] [-showPropertyChanges]");
35 * Returns a "no synthesizer" message, and asks
36 * the user to check if the "speech.properties" file is
37 * at <code>user.home</code> or <code>java.home/lib</code>.
39 * @return a no synthesizer message
41 static private String noSynthesizerMessage(String synthesizer) {
43 "Cannot find " + synthesizer + ".\n" +
44 "This may be the result of any number of problems. It's\n" +
45 "typically due to a missing \"speech.properties\" file that\n" +
46 "should be at either of these locations: \n\n";
47 message += "user.home : " + System.getProperty("user.home") + "\n";
48 message += "java.home/lib: " + System.getProperty("java.home") +
49 File.separator + "lib\n\n" +
50 "Another cause of this problem might be corrupt or missing\n" +
51 "voice jar files in the freetts lib directory. This problem\n" +
52 "also sometimes arises when the freetts.jar file is corrupt\n" +
53 "or missing. Sorry about that. Please check for these\n" +
54 "various conditions and then try again.\n";
58 public static void main(String[] argv) {
59 boolean showEvents = false;
60 boolean showPropertyChanges = false;
62 for (int i = 0; i < argv.length; i++) {
63 if (argv[i].equals("-showEvents")) {
65 } else if (argv[i].equals("-showPropertyChanges")) {
66 showPropertyChanges = true;
73 System.out.println(" ** Mixed Voices - JSAPI Demonstration program **");
74 /* alan is a limited-domain voice that only knows how talk
75 * about the time of day.
77 Voice alan = new Voice("alan",
78 Voice.GENDER_DONT_CARE, Voice.AGE_DONT_CARE, null);
80 /* kevin in an 8khz general domain diphone voice
82 Voice kevin = new Voice("kevin",
83 Voice.GENDER_DONT_CARE, Voice.AGE_DONT_CARE, null);
85 /* kevin16 in a 16khz general domain diphone voice
87 Voice kevinHQ = new Voice("kevin16",
88 Voice.GENDER_DONT_CARE, Voice.AGE_DONT_CARE, null);
91 /* Find a synthesizer that has the general domain voice
92 * we are looking for. NOTE: this uses the Central class
93 * of JSAPI to find a Synthesizer. The Central class
94 * expects to find a speech.properties file in user.home
97 * If your situation doesn't allow you to set up a
98 * speech.properties file, you can circumvent the Central
99 * class and do a very non-JSAPI thing by talking to
100 * FreeTTSEngineCentral directly. See the WebStartClock
101 * demo for an example of how to do this.
103 SynthesizerModeDesc generalDesc = new SynthesizerModeDesc(
105 "general", // mode name
110 final Synthesizer synthesizer1 =
111 Central.createSynthesizer(generalDesc);
113 if (synthesizer1 == null) {
115 noSynthesizerMessage("general domain synthesizer"));
119 /* Find a synthesizer that has the time domain voice.
121 SynthesizerModeDesc limitedDesc = new SynthesizerModeDesc(
128 final Synthesizer synthesizer2 =
129 Central.createSynthesizer(limitedDesc);
131 if (synthesizer2 == null) {
133 noSynthesizerMessage("time domain synthesizer"));
137 System.out.print(" Allocating synthesizers...");
138 synthesizer1.allocate();
139 synthesizer2.allocate();
141 /* get general domain synthesizer ready to speak
143 System.out.print("Loading voices...");
144 synthesizer1.getSynthesizerProperties().setVoice(kevinHQ);
145 synthesizer1.getSynthesizerProperties().setVoice(kevin);
147 if (showPropertyChanges) {
148 synthesizer1.getSynthesizerProperties().addPropertyChangeListener(
149 new PropertyChangeListener() {
150 public void propertyChange(
151 PropertyChangeEvent pce) {
152 if (pce.getNewValue() instanceof Voice) {
154 ((Voice) pce.getNewValue()).getName();
156 " PCE Voice changed to " + newVoice);
159 " PCE " + pce.getPropertyName()
161 + pce.getOldValue() + " to " +
162 pce.getNewValue() + ".");
169 synthesizer1.addSpeakableListener(
170 new SpeakableAdapter() {
171 public void markerReached(SpeakableEvent e) {
174 public void speakableCancelled(SpeakableEvent e) {
177 public void speakableEnded(SpeakableEvent e) {
180 public void speakablePaused(SpeakableEvent e) {
183 public void speakableResumed(SpeakableEvent e) {
186 public void speakableStarted(SpeakableEvent e) {
189 public void topOfQueue(SpeakableEvent e) {
192 public void wordStarted(SpeakableEvent e) {
195 private void dumpEvent(SpeakableEvent e) {
196 System.out.println(" EVT: " + e.paramString()
197 + " source: " + e.getSource());
202 System.out.println("And here we go!");
203 synthesizer1.resume();
204 synthesizer2.resume();
206 // speak the "Hello world" string
207 synthesizer1.speakPlainText("Hello! My name is Kevin.", null);
208 synthesizer1.speakPlainText("I am a die phone synthesizer", null);
209 synthesizer1.speakPlainText("I have a friend named Alan.", null);
210 synthesizer1.speakPlainText("Listen to him count!", null);
212 // get synth2 ready to speak
213 synthesizer2.waitEngineState(Synthesizer.ALLOCATED);
214 synthesizer2.resume();
216 synthesizer1.waitEngineState(Synthesizer.QUEUE_EMPTY);
217 synthesizer2.speakPlainText("1 2 3 4 5 6 7 8 9 ten", null);
219 synthesizer2.waitEngineState(Synthesizer.QUEUE_EMPTY);
221 synthesizer1.speakPlainText("Now listen to me count!", null);
222 synthesizer1.speakPlainText("1 2 3 4 5 6 7 8 9 10.", null);
224 synthesizer1.speakPlainText(
225 "Now, let's try that a little bit faster.", null);
226 synthesizer1.waitEngineState(Synthesizer.QUEUE_EMPTY);
228 synthesizer1.getSynthesizerProperties().setSpeakingRate(240.0f);
229 synthesizer1.speakPlainText("1 2 3 4 5 6 7 8 9 10.", null);
230 synthesizer1.speakPlainText("That's pretty fast.", null);
231 synthesizer1.speakPlainText("Now lets go very slow.", null);
232 synthesizer1.waitEngineState(Synthesizer.QUEUE_EMPTY);
234 synthesizer1.getSynthesizerProperties().setSpeakingRate(80.0f);
235 synthesizer1.speakPlainText("1 2 3 4 5 6 7 8 9 10.", null);
236 synthesizer1.speakPlainText("That is pretty slow.", null);
237 synthesizer1.waitEngineState(Synthesizer.QUEUE_EMPTY);
239 synthesizer1.getSynthesizerProperties().setSpeakingRate(150.0f);
240 synthesizer1.speakPlainText("Now back to normal", null);
241 synthesizer1.waitEngineState(Synthesizer.QUEUE_EMPTY);
243 synthesizer1.getSynthesizerProperties().setPitch(200);
244 synthesizer1.speakPlainText("I can talk very high.", null);
245 synthesizer1.waitEngineState(Synthesizer.QUEUE_EMPTY);
247 synthesizer1.getSynthesizerProperties().setPitch(50);
248 synthesizer1.speakPlainText("and I can talk very low.", null);
249 synthesizer1.waitEngineState(Synthesizer.QUEUE_EMPTY);
251 synthesizer1.getSynthesizerProperties().setPitch(100);
252 synthesizer1.getSynthesizerProperties().setVolume(.8f);
253 synthesizer1.speakPlainText("and I can talk very softly.", null);
254 synthesizer1.waitEngineState(Synthesizer.QUEUE_EMPTY);
256 synthesizer1.getSynthesizerProperties().setVolume(1.0f);
257 synthesizer1.speakPlainText(
258 "I can talk with a higher quality voice", null);
259 synthesizer1.speakPlainText(
260 "Here is a low quality tongue twister. "
261 + "She sells seashells by the seashore.", null);
262 synthesizer1.waitEngineState(Synthesizer.QUEUE_EMPTY);
264 synthesizer1.getSynthesizerProperties().setVoice(kevinHQ);
265 synthesizer1.speakPlainText("And this is high quality. "
266 + "She sells seashells by the seashore.", null);
267 synthesizer1.speakPlainText(
268 "The funny thing is, I do not have a tongue.", null);
269 synthesizer1.speakPlainText(
270 "Hey Alan, what time is it where you are right now?", null);
271 synthesizer1.waitEngineState(Synthesizer.QUEUE_EMPTY);
273 synthesizer2.speakPlainText(
274 "the time is now twenty past six.", null);
275 synthesizer2.waitEngineState(Synthesizer.QUEUE_EMPTY);
277 synthesizer1.speakPlainText("Is that the exact time?", null);
278 synthesizer1.waitEngineState(Synthesizer.QUEUE_EMPTY);
280 synthesizer2.speakPlainText("Almost", null);
281 synthesizer2.waitEngineState(Synthesizer.QUEUE_EMPTY);
283 synthesizer1.speakPlainText(
284 "Is it twenty past six In the morning or the evening?", null);
285 synthesizer1.waitEngineState(Synthesizer.QUEUE_EMPTY);
287 synthesizer2.speakPlainText("in the morning.", null);
288 synthesizer2.waitEngineState(Synthesizer.QUEUE_EMPTY);
290 synthesizer1.speakPlainText(
291 "Alan and I can talk at the same time", null);
292 synthesizer1.waitEngineState(Synthesizer.QUEUE_EMPTY);
294 synthesizer1.speakPlainText("1 2 3 4 5 6 7 8 9 11 12", null);
295 synthesizer2.speakPlainText("1 2 3 4 5 6 7 8 9", null);
296 synthesizer1.waitEngineState(Synthesizer.QUEUE_EMPTY);
297 synthesizer2.waitEngineState(Synthesizer.QUEUE_EMPTY);
299 synthesizer1.speakPlainText( "That is a bit confusing.", null);
300 synthesizer1.speakPlainText( "Well, thanks. This was fun.", null);
301 synthesizer1.speakPlainText("Goodbye everyone.", null);
302 synthesizer1.waitEngineState(Synthesizer.QUEUE_EMPTY);
305 synthesizer1.deallocate();
306 synthesizer2.deallocate();
308 catch (Exception e) {