00001 package edu.stanford.hci.r3.actions.types;
00002
00003 import java.beans.PropertyVetoException;
00004 import java.util.Locale;
00005
00006 import javax.speech.AudioException;
00007 import javax.speech.Central;
00008 import javax.speech.EngineException;
00009 import javax.speech.EngineStateError;
00010 import javax.speech.synthesis.Synthesizer;
00011 import javax.speech.synthesis.SynthesizerModeDesc;
00012 import javax.speech.synthesis.Voice;
00013
00014 import edu.stanford.hci.r3.actions.R3Action;
00015
00027 public class TextToSpeechAction implements R3Action {
00028
00029 private static final String DEFAULT_FREETTS_VOICE = "kevin16";
00030
00031 private static TextToSpeechAction instance;
00032
00036 public static TextToSpeechAction getInstance() {
00037 if (instance == null) {
00038 instance = new TextToSpeechAction();
00039 instance.initialize();
00040 }
00041 return instance;
00042 }
00043
00044 private boolean initialized;
00045
00049 private String savedText;
00050
00051 private Synthesizer synthesizer;
00052
00053 private String voiceName = DEFAULT_FREETTS_VOICE;
00054
00058 public TextToSpeechAction() {
00059 this("");
00060 }
00061
00065 public TextToSpeechAction(String wordsToSay) {
00066 savedText = wordsToSay;
00067
00068 }
00069
00073 public void close() {
00074 try {
00075 synthesizer.deallocate();
00076 } catch (EngineException e) {
00077 e.printStackTrace();
00078 } catch (EngineStateError e) {
00079 e.printStackTrace();
00080 }
00081 initialized = false;
00082 }
00083
00087 public void initialize() {
00088 if (initialized) {
00089 return;
00090 }
00091
00092 initialized = true;
00093 try {
00094 voiceName = DEFAULT_FREETTS_VOICE;
00095 SynthesizerModeDesc desc = new SynthesizerModeDesc(null,
00096 "general",
00097 Locale.US,
00098 null,
00099 null);
00100 synthesizer = Central.createSynthesizer(desc);
00101
00102
00103 synthesizer.allocate();
00104 synthesizer.resume();
00105
00106
00107 desc = (SynthesizerModeDesc) synthesizer.getEngineModeDesc();
00108 Voice[] voices = desc.getVoices();
00109 Voice voice = null;
00110 for (Voice v : voices) {
00111 if (v.getName().equals(voiceName)) {
00112 voice = v;
00113 break;
00114 }
00115 }
00116 if (voice == null) {
00117 System.err.println("Synthesizer does not have a voice named " + voiceName
00118 + ". Choosing the first available voice.");
00119 voice = voices[0];
00120 }
00121 synthesizer.getSynthesizerProperties().setVoice(voice);
00122 } catch (IllegalArgumentException e) {
00123 e.printStackTrace();
00124 } catch (EngineException e) {
00125 e.printStackTrace();
00126 } catch (AudioException e) {
00127 e.printStackTrace();
00128 } catch (EngineStateError e) {
00129 e.printStackTrace();
00130 } catch (PropertyVetoException e) {
00131 e.printStackTrace();
00132 }
00133 }
00134
00142 public void invoke() {
00143 initialize();
00144 speak();
00145 close();
00146 }
00147
00151 public void speak() {
00152 speak(savedText);
00153 }
00154
00158 public void speak(String wordsToSpeak) {
00159
00160 try {
00161 synthesizer.speakPlainText(wordsToSpeak, null);
00162 synthesizer.waitEngineState(Synthesizer.QUEUE_EMPTY);
00163 } catch (IllegalArgumentException e) {
00164 e.printStackTrace();
00165 } catch (InterruptedException e) {
00166 e.printStackTrace();
00167 }
00168 }
00169 }