Package

Source Code of MyVoice

/**
* Copyright 2001 Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and
* redistribution of this file, and for a DISCLAIMER OF ALL
* WARRANTIES.
*/
import java.beans.PropertyVetoException;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Enumeration;
import java.util.Locale;
import java.util.HashSet;
import java.util.Set;
import java.util.Iterator;

import javax.speech.AudioException;
import javax.speech.Central;
import javax.speech.Engine;
import javax.speech.EngineException;
import javax.speech.EngineList;
import javax.speech.synthesis.Synthesizer;
import javax.speech.synthesis.SynthesizerModeDesc;
import javax.speech.synthesis.SynthesizerProperties;
import javax.speech.synthesis.Voice;

import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.ListModel;

import com.sun.speech.engine.synthesis.SynthesizerMonitor;

/**
* Implements the text-to-speech data model of the Player application, using
* JSAPI. It should work with any JSAPI implementation.
*/
public class PlayerModelImpl implements PlayerModel {

    private Synthesizer synthesizer;
    private Monitor monitor;
    private boolean monitorVisible = false;
    private boolean paused = false;
    private boolean stopped = false;
    private boolean playingFile = false;
    private DefaultListModel playList;
    private DefaultComboBoxModel synthesizerList;
    private DefaultComboBoxModel voiceList;
    private float volume = -1;
    private static boolean debug = false;
    private Set loadedSynthesizers;

   
    /**
     * Constructs a default PlayerModelImpl.
     */
    public PlayerModelImpl() {
  playList = new DefaultListModel();
  synthesizerList = new DefaultComboBoxModel();
  voiceList = new DefaultComboBoxModel();
  loadedSynthesizers = new HashSet();
    }
   

    /**
     * Creates a FreeTTS synthesizer.
     */
    public void createSynthesizers() {
  try {
      EngineList list = Central.availableSynthesizers(null);
      Enumeration e = list.elements();

      while (e.hasMoreElements()) {
    MySynthesizerModeDesc myModeDesc =
        new MySynthesizerModeDesc
        ((SynthesizerModeDesc) e.nextElement(), this);
    debugPrint(myModeDesc.getEngineName() + " " +
         myModeDesc.getLocale() + " " +
         myModeDesc.getModeName() + " " +
         myModeDesc.getRunning());
    synthesizerList.addElement(myModeDesc);
      }
     
      if (synthesizerList.getSize() > 0) {
    setSynthesizer(0);
      } else {
    System.err.println(noSynthesizerMessage());
      }
            if (synthesizer == null) {
                System.err.println("PlayerModelImpl: Can't find synthesizer");
                System.exit(1);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Returns a "no synthesizer" message, and asks
     * the user to check if the "speech.properties" file is
     * at <code>user.home</code> or <code>java.home/lib</code>.
     *
     * @return a no synthesizer message
     */
    static private String noSynthesizerMessage() {
        String message =
            "No synthesizer created.  This may be the result of any\n" +
            "number of problems.  It's typically due to a missing\n" +
            "\"speech.properties\" file that should be at either of\n" +
            "these locations: \n\n";
        message += "user.home    : " + System.getProperty("user.home") + "\n";
        message += "java.home/lib: " + System.getProperty("java.home") +
      File.separator + "lib\n\n" +
            "Another cause of this problem might be corrupt or missing\n" +
            "voice jar files in the freetts lib directory.  This problem\n" +
            "also sometimes arises when the freetts.jar file is corrupt\n" +
            "or missing.  Sorry about that.  Please check for these\n" +
            "various conditions and then try again.\n";
        return message;
    }
     
    /**
     * Performs TTS on the given Playable.
     *
     * @param playable the Playable object to play
     */
    public void play(Playable playable) {
  if (playable != null) {
      if (playable.getType() == PlayableType.TEXT) {
    play(playable.getText());
      } else if (playable.getType() == PlayableType.JSML) {
    playJSML(playable.getText());
      } else if (playable.getType() == PlayableType.TEXT_FILE ||
           playable.getType() == PlayableType.JSML_FILE) {
    playFile(playable.getFile(), playable.getType());
      } else if (playable.getType() == PlayableType.URL) {
    try {
        playURL(new URL(playable.getName()));
    } catch (MalformedURLException mue) {
        mue.printStackTrace();
    }
      }
  }
    }


    /**
     * Performs TTS on the object at the given index of the play list.
     *
     * @param index index of the object in the playlist to play
     */
    public void play(int index) {
  if (0 <= index && index < playList.getSize()) {
      Playable playable = (Playable) playList.getElementAt(index);
      if (playable != null) {
    play(playable);
      }
  }
    }


    /**
     * Performs text-to-speech on the given text.
     *
     * @param text the text to perform TTS
     */
    private void play(String text) {
  synthesizer.speakPlainText(text, null);
    }
   

    /**
     * Performs text-to-speech on the given JSML text.
     *
     * @param text the text to perform TTS
     */
    private void playJSML(String jsmlText) {
  try {
      synthesizer.speak(jsmlText, null);
  } catch (Exception e) {
      e.printStackTrace();
  }
    }


    /**
     * Plays the text in the given File.
     *
     * @param file the File to play
     * @param type the file type
     */
    private void playFile(File file, PlayableType type) {
  try {
      FileInputStream fileStream = new FileInputStream(file);
      playInputStream(fileStream, type);
  } catch (FileNotFoundException fnfe) {
      fnfe.printStackTrace();
  }
    }
 

    /**
     * Plays the text in the given File.
     *
     * @param file the File to play
     * @param type the file type
     */
    private void playInputStream(InputStream inStream, PlayableType type) {
  playingFile = true;
  if (inStream != null) {
      try {
    BufferedReader reader = new BufferedReader
        (new InputStreamReader(inStream));
    String line = "";
    if (type == PlayableType.TEXT_FILE) {
        while (!isStopped() &&
         (line = reader.readLine()) != null) {
      if (line.length() > 0) {
          play(line);
      }
        }
    } else if (type == PlayableType.JSML_FILE) {
        String fileText = "";
        while ((line = reader.readLine()) != null) {
      fileText += line;
        }
        if (fileText != null && fileText.length() > 0) {
      playJSML(fileText);
        }
    }
    stopped = false;
      } catch (IOException ioe) {
    ioe.printStackTrace();
      }
  }
  playingFile = false;
    }


    /**
     * Plays the contents of the given URL.
     *
     * @param url the URL to play
     */
    private void playURL(URL url) {
  try {
      synthesizer.speak(url, null);
  } catch (Exception e) {
      e.printStackTrace();
  }
    }
 

    /**
     * Returns true if the player is paused.
     *
     * @return true if the player is paused, false otherwise
     */
    public synchronized boolean isPaused() {
  return paused;
    }
   

    /**
     * Pauses the player.
     */
    public synchronized void pause() {
  paused = true;
  synthesizer.pause();
    }
       

    /**
     * Resumes the player.
     */
    public synchronized void resume() {
  paused = false;
  try {
      synthesizer.resume();
  } catch (AudioException ae) {
      ae.printStackTrace();
 
    }
           

    /**
     * Stops the player if it is playing.
     */
    public synchronized void stop() {
  if (playingFile) {
      stopped = true;
  }
  synthesizer.cancelAll();
    }


    /**
     * Cancels the currently playing item.
     */
    public void cancel() {
  synthesizer.cancel();
    }

    /**
     * Close this playable
     */
    public void close() {
  for (Iterator i = loadedSynthesizers.iterator(); i.hasNext();) {
      Synthesizer synth = (Synthesizer) i.next();
      try {
    synth.deallocate();
      } catch (EngineException ee) {
    System.out.println("Trouble closing the synthesizer: " + ee);
      }
  }
    }


    /**
     * Returns true if the Player is currently being stopped.
     *
     * @return true if the Player is currently being stopped; false otherwise
     */   
    private synchronized boolean isStopped() {
  return stopped;
    }
   

    /**
     * Sets whether the Monitor is visible
     *
     * @param visible true to set the Monitor as visible
     */
    public void setMonitorVisible(boolean visible) {
  monitorVisible = visible;
  if (monitor != null) {
      monitor.setVisible(monitorVisible);
  }
    }
   

    /**
     * Tells whether the monitor is visible.
     *
     * @return true if the monitor is visible, false otherwise
     */
    public boolean isMonitorVisible() {
  return monitorVisible;
    }
           

    /**
     * Returns the monitor of the synthesizer at the given index.
     *
     * @param index the position of the synthesizer in the synthesizer list
     *
     * @return the monitor of the specified synthesizer
     */
    public Monitor getMonitor(int index) {
  MySynthesizerModeDesc myModeDesc = (MySynthesizerModeDesc)
      synthesizerList.getElementAt(index);
  Monitor monitor = null;

  if (myModeDesc != null) {
      monitor = myModeDesc.getMonitor();
  }
  return monitor;
    }


    /**
     * Returns the monitor of the current synthesizer.
     *
     * @return the monitor of the current synthesizer
     */
    public Monitor getMonitor() {
  return monitor;
    }


    /**
     * Sets the current monitor.
     *
     * @param monitor the current monitor
     */
    public void setMonitor(Monitor monitor) {
  this.monitor = monitor;
    }


    /**
     * Sets the Synthesizer at the given index to use
     *
     * @param index index of the synthesizer in the list
     */
    public void setSynthesizer(int index) {
  MySynthesizerModeDesc myModeDesc = (MySynthesizerModeDesc)
      synthesizerList.getElementAt(index);
  if (myModeDesc != null) {
      if (isMonitorVisible()) {
    if (monitor != null) {
        monitor.setVisible(false);
    }
      }
      synthesizer = myModeDesc.getSynthesizer();
      if (synthesizer == null) {
    synthesizer = myModeDesc.createSynthesizer();
    if (synthesizer == null) {
        debugPrint("still null");
    } else {
        debugPrint("created");
    }
      } else {
    debugPrint("not null");
      }
      monitor = myModeDesc.getMonitor();
      if (myModeDesc.isSynthesizerLoaded()) {
    setVoiceList(myModeDesc);
      } else {
    myModeDesc.loadSynthesizer();
      }

      loadedSynthesizers.add(synthesizer);
            synthesizerList.setSelectedItem(myModeDesc);
  }
    }
   

    /**
     * Sets the Voice at the given to use.
     *
     * @param index the index of the voice
     */
    public void setVoice(int index) {
  try {
      Voice voice = (Voice) voiceList.getElementAt(index);
      if (voice != null) {
    float oldVolume = getVolume();
    float oldSpeakingRate = getSpeakingRate();
    synthesizer.waitEngineState(Synthesizer.QUEUE_EMPTY);
    synthesizer.getSynthesizerProperties().setVoice(voice);
    setVolume(oldVolume);
    setSpeakingRate(oldSpeakingRate);
                voiceList.setSelectedItem(voice);
      }
  } catch (PropertyVetoException pve) {
      pve.printStackTrace();
  } catch (InterruptedException ie) {
      ie.printStackTrace();
  }
    }
   

    /**
     * Returns the volume, in the range of 0 to 10.
     *
     * @return the volume, or -1 if unknown, or an error occurred
     */
    public float getVolume() {
  try {
      float adjustedVolume =
    synthesizer.getSynthesizerProperties().getVolume();
      if (adjustedVolume < 0.5) {
    volume = 0;
      } else {
    volume = (float) ((adjustedVolume - 0.5) * 20);
      }
  } catch (Exception e) {
      e.printStackTrace();
  }
  return volume;
    }
   

    /**
     * Sets the volume, in the range of 0 to 10.
     *
     * @param volume the new volume
     *
     * @return true if new volume is set; false otherwise
     */
    public boolean setVolume(float volume) {
  try {
      float adjustedVolume = (float) (volume/20 + 0.5);
      if (synthesizer != null) {
    synthesizer.getSynthesizerProperties().setVolume
        (adjustedVolume);
    this.volume = volume;
    return true;
      } else {
    this.volume = volume;
    return false;
      }
  } catch (PropertyVetoException pve) {
      try {
    synthesizer.getSynthesizerProperties().setVolume(this.volume);
      } catch (PropertyVetoException pe) {
    pe.printStackTrace();
      }
      return false;
  }
    }
               

    /**
     * Returns the speaking rate.
     *
     * @return the speaking rate, or -1 if unknown or an error occurred
     */
    public float getSpeakingRate() {
  if (synthesizer != null) {
      return synthesizer.getSynthesizerProperties().getSpeakingRate();
  } else {
      return -1;
  }
    }
 

    /**
     * Sets the speaking rate in terms of words per minute.
     *
     * @param wordsPerMin the new speaking rate
     *
     * @return the speaking rate, or -1 if unknown or an error occurred
     */
    public boolean setSpeakingRate(float wordsPerMin) {
  float oldSpeed = getSpeakingRate();
  SynthesizerProperties properties =
      synthesizer.getSynthesizerProperties();
  try {
      properties.setSpeakingRate(wordsPerMin);
      return true;
  } catch (PropertyVetoException pve) {
      try {
    properties.setSpeakingRate(oldSpeed);
      } catch (PropertyVetoException pe) {
    pe.printStackTrace();
      }
      return false;
  }
    } 


    /**
     * Returns the baseline pitch for the current synthesis voice.
     *
     * @return the baseline pitch for the current synthesis voice
     */
    public float getPitch() {
  return synthesizer.getSynthesizerProperties().getPitch();
   


    /**
     * Sets the baseline pitch for the current synthesis voice.
     *
     * @param pitch the baseline pitch
     *
     * @return true if new pitch is set; false otherwise
     */
    public boolean setPitch(float pitch) {
  float oldPitch = getPitch();
  try {
      synthesizer.getSynthesizerProperties().setPitch(pitch);
      return true;
  } catch (PropertyVetoException pve) {
      try {
    synthesizer.getSynthesizerProperties().setPitch(oldPitch);
      } catch (PropertyVetoException pe) {
    pe.printStackTrace();
      }
      return false;
  }
    }
   

    /**
     * Returns the pitch range for the current synthesis voice.
     *
     * @return the pitch range for the current synthesis voice
     */
    public float getRange() {
  return synthesizer.getSynthesizerProperties().getPitchRange();
    }
   

    /**
     * Sets the pitch range for the current synthesis voice.
     *
     * @param range the pitch range
     *
     * @return true if new range is set; false otherwise
     */
    public boolean setRange(float range) {
  float oldRange = getRange();
  try {
      synthesizer.getSynthesizerProperties().setPitchRange(range);
      return true;
  } catch (PropertyVetoException pve) {
      try {
    synthesizer.getSynthesizerProperties().setPitchRange(oldRange);
      } catch (PropertyVetoException pe) {
    pe.printStackTrace();
      }
      return false;
  }
    }
        

    /**
     * Sets the list of voices using the given Synthesizer mode description.
     *
     * @param modeDesc the synthesizer mode description
     */
    public void setVoiceList(SynthesizerModeDesc modeDesc) {
  Voice[] voices = modeDesc.getVoices();
  voiceList.removeAllElements();
  for (int i = 0; i < voices.length; i++) {
      voiceList.addElement(new MyVoice(voices[i].getName(),
               voices[i].getGender(),
               voices[i].getAge(),
               voices[i].getStyle()));
  }
    }


    /**
     * Returns the play list.
     *
     * @return the play list
     */
    public ListModel getPlayList() {
  return playList;
    }


    /**
     * Returns the list of voices.
     *
     * @return the list of voices
     */
    public ListModel getVoiceList() {
  return voiceList;
    }


    /**
     * Returns the list synthesizers
     *
     * @return the synthesizer list
     */
    public ListModel getSynthesizerList() {
  return synthesizerList;
    }

   
    /**
     * Returns the Playable object at the given index of the play list.
     *
     * @return the Playable object
     */
    public Object getPlayableAt(int index) {
  return null;
    }
   

    /**
     * Adds the given Playable object to the end of the play list.
     *
     * @param playable the Playable object to add
     */
    public void addPlayable(Playable playable) {
  playList.addElement(playable);
    }


    /**
     * Removes the playable at the given position from the list
     *
     * @param index the index of the Playable to remove
     */
    public void removePlayableAt(int index) {
  if (index < playList.getSize()) {
      playList.removeElementAt(index);
  }
    }


    /**
     * Prints debug statements.
     *
     * @param statement debug statements
     */
    public static void debugPrint(String statement) {
  if (debug) {
      System.out.println(statement);
  }
    }
}


/**
* A Voice that implements the <code>toString()</code> method so that
* it returns the name of the person who owns this Voice.
*/
class MyVoice extends Voice {


    /**
     * Constructor provided with voice name, gender, age and style.
     *
     * @param name the name of the person who owns this Voice
     * @param gender the gender of the person
     * @param age the age of the person
     * @param style the style of the person
     */
    public MyVoice(String name, int gender, int age, String style) {
  super(name, gender, age, style);
    }


    /**
     * Returns the name of the person who owns this Voice.
     *
     * @param String the name of the person
     */
    public String toString() {
  return getName();
    }
}


/**
* A SynthesizerModeDesc that implements the <code>toString()</code>
* method so that it returns the name of the synthesizer.
*/
class MySynthesizerModeDesc extends SynthesizerModeDesc {

    private PlayerModel playerModel = null;
    private Synthesizer synthesizer = null;
    private Monitor monitor = null;
    private boolean synthesizerLoaded = false;
   

    /**
     * Constructs a MySynthesizerModeDesc with the attributes from
     * the given SynthesizerModeDesc.
     *
     * @param modeDesc the SynthesizerModeDesc to get attributes from
     */
    public MySynthesizerModeDesc(SynthesizerModeDesc modeDesc,
         PlayerModel playerModel) {
  super(modeDesc.getEngineName(), modeDesc.getModeName(),
        modeDesc.getLocale(), modeDesc.getRunning(),
        modeDesc.getVoices());
  this.playerModel = playerModel;
    }
   
   
    /**
     * Returns true if the synthesizer is already loaded.
     *
     * @return true if the synthesizer is already loaded
     */
    public synchronized boolean isSynthesizerLoaded() {
  if (synthesizer == null) {
      return false;
  }
  return ((synthesizer.getEngineState() & Engine.ALLOCATED) != 0);
    }
   
   
    /**
     * Returns a Synthesizer that fits the description of this
     * MySynthesizerModeDesc. If the synthesize was never loaded,
     * it is loaded in a separate thread.
     *
     * @return a Synthesizer
     */
    public synchronized Synthesizer getSynthesizer() {
  debugPrint("MyModeDesc.getSynthesizer(): " + getEngineName());
  return synthesizer;
    }


    /**
     * Creates the Synthesizer and its Monitor.
     *
     * @return the created Synthesizer
     */
    public Synthesizer createSynthesizer() {
  try {
      debugPrint("Creating " + getEngineName() + "...");
      synthesizer = Central.createSynthesizer(this);
     
      if (synthesizer == null) {
    System.out.println("Central created null synthesizer");
      } else {
    synthesizer.allocate();
    synthesizer.resume();
    monitor = new Monitor(synthesizer, getEngineName());
    debugPrint("...created monitor");
      }
  } catch (Exception e) {
      e.printStackTrace();
  }
  return synthesizer;
    }

   

    /**
     * Allocates the synthesizer if it has never been allocated. This
     * method should be called after method <code>createSynthesizer()</code>.
     * It spawns a new thread to allocate the synthesizer.
     */
    public Synthesizer loadSynthesizer() {
  try {
      if (!synthesizerLoaded) {
    debugPrint("Loading " + getEngineName() + "...");
    synthesizerLoaded = true;
    SynthesizerLoader loader = new SynthesizerLoader
        (synthesizer, this);
    loader.start();
      }
  } catch (Exception e) {
      e.printStackTrace();
  }
  return synthesizer;
    }


    /**
     * Returns the Monitor of this Synthesizer.
     *
     * @return the Monitor
     */
    public synchronized Monitor getMonitor() {
  if (monitor == null) {
      createSynthesizer();
  }
  return monitor;
    }

   
    /**
     * Returns the PlayerModel.
     *
     * @return the PlayerModel
     */
    public PlayerModel getPlayerModel() {
  return playerModel;
    }

   
    /**
     * Returns the name of the Synthesizer.
     *
     * @return the name of the Synthesizer
     */
    public String toString() {
  return getEngineName();
    }

   
    /**
     * Prints debug statements.
     *
     * @param statement debug statements
     */
    private void debugPrint(String statement) {
  PlayerModelImpl.debugPrint(statement);
    }
}


/**
* A Thread that loads the Synthesizer.
*/
class SynthesizerLoader extends Thread {
    private Synthesizer synthesizer;
    private MySynthesizerModeDesc modeDesc;
    private PlayerModel playerModel;
  
   
    /**
     * Constructs a SynthesizerLoaded which loads the given Synthesizer.
     *
     * @param synthesizer the Synthesizer to load
     * @param modeDesc the MySynthesizerModeDesc from which we can retrieve
     *    the PlayerModel
     */
    public SynthesizerLoader(Synthesizer synthesizer,
           MySynthesizerModeDesc modeDesc) {
  this.synthesizer = synthesizer;
  this.modeDesc = modeDesc;
  this.playerModel = modeDesc.getPlayerModel();
    }
   

    /**
     * Implements the <code>run()</code> method of the Thread class.
     */
    public void run() {
  try {
      System.out.println("allocating...");
      synthesizer.allocate();
      System.out.println("...allocated");
      synthesizer.resume();
      System.out.println("...resume");
      playerModel.setVoiceList(modeDesc);
  } catch (Exception e) {
      e.printStackTrace();
  }
    }
}
TOP

Related Classes of MyVoice

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.