📄 textsynthesizer.java
字号:
/** * 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. */package com.sun.speech.engine.synthesis.text;import java.net.URL;import java.util.Vector;import java.util.Enumeration;import javax.speech.Engine;import javax.speech.EngineStateError;import javax.speech.synthesis.Speakable;import javax.speech.synthesis.SpeakableEvent;import javax.speech.synthesis.SynthesizerModeDesc;import com.sun.speech.engine.synthesis.BaseSynthesizer;import com.sun.speech.engine.synthesis.BaseSynthesizerQueueItem;/** * Supports a simple text-output-only JSAPI 1.0 <code>Synthesizer</code>. * Intended for demonstration purposes for those developing JSAPI * implementations. It may also be useful to developers who want a * JSAPI synthesizer that doesn't produce any noise. */public class TextSynthesizer extends BaseSynthesizer { /** * Reference to output thread. */ OutputHandler outputHandler = null; /** * Creates a new Synthesizer in the DEALLOCATED state. * * @param desc the operating mode */ public TextSynthesizer(SynthesizerModeDesc desc) { super(desc); outputHandler = new OutputHandler(); } /** * Starts the output thread. */ protected void handleAllocate() { long states[]; synchronized (engineStateLock) { long newState = ALLOCATED | RESUMED; newState |= (outputHandler.isQueueEmpty() ? QUEUE_EMPTY : QUEUE_NOT_EMPTY); states = setEngineState(CLEAR_ALL_STATE, newState); } outputHandler.start(); postEngineAllocated(states[0], states[1]); } /** * Stops the output thread. */ protected void handleDeallocate() { long[] states = setEngineState(CLEAR_ALL_STATE, DEALLOCATED); cancelAll(); outputHandler.terminate(); postEngineDeallocated(states[0], states[1]); } /** * Creates a TextSynthesizerQueueItem. * * @return a TextSynthesizerQueueItem */ protected BaseSynthesizerQueueItem createQueueItem() { return new TextSynthesizerQueueItem(); } /** * Returns an enumeration of the queue. * * @return * an <code>Enumeration</code> of the speech output queue or * <code>null</code>. * * @throws EngineStateError * if this <code>Synthesizer</code> in the <code>DEALLOCATED</code> or * <code>DEALLOCATING_RESOURCES</code> states */ public Enumeration enumerateQueue() throws EngineStateError { checkEngineState(DEALLOCATED | DEALLOCATING_RESOURCES); return outputHandler.enumerateQueue(); } /** * Puts an item on the speaking queue and sends a queue updated * event. Expects only <code>TextSynthesizerQueueItems</code>. * * @param item the item to add to the queue * */ protected void appendQueue(BaseSynthesizerQueueItem item) { outputHandler.appendQueue((TextSynthesizerQueueItem) item); } /** * Cancels the item at the top of the queue. * * @throws EngineStateError * if this <code>Synthesizer</code> in the <code>DEALLOCATED</code> or * <code>DEALLOCATING_RESOURCES</code> states */ public void cancel() throws EngineStateError { checkEngineState(DEALLOCATED | DEALLOCATING_RESOURCES); outputHandler.cancelItem(); } /** * Cancels a specific object on the queue. * * @param source * object to be removed from the speech output queue * * @throws IllegalArgumentException * if the source object is not found in the speech output queue. * @throws EngineStateError * if this <code>Synthesizer</code> in the <code>DEALLOCATED</code> or * <code>DEALLOCATING_RESOURCES</code> states */ public void cancel(Object source) throws IllegalArgumentException, EngineStateError { checkEngineState(DEALLOCATED | DEALLOCATING_RESOURCES); outputHandler.cancelItem(source); } /** * Cancels all items on the output queue. * * @throws EngineStateError * if this <code>Synthesizer</code> in the <code>DEALLOCATED</code> or * <code>DEALLOCATING_RESOURCES</code> states */ public void cancelAll() throws EngineStateError { checkEngineState(DEALLOCATED | DEALLOCATING_RESOURCES); outputHandler.cancelAllItems(); } /** * Pauses the output. */ protected void handlePause() { outputHandler.pauseItem(); } /** * Resumes the output. */ protected void handleResume() { outputHandler.resumeItem(); } /** * The output device for a <code>TextSynthesizer</code>. Sends * all text to standard out. */ public class OutputHandler extends Thread { protected boolean done = false; /** * Internal speech output queue that will contain a set of * TextSynthesizerQueueItems. * * @see BaseSynthesizerQueueItem */ protected Vector queue; /** * The current item to speak. */ TextSynthesizerQueueItem currentItem; /** * Object to lock on for setting the current item. */ protected Object currentItemLock = new Object(); /** * Current output "speaking" rate. * Updated as /rate[166.3]/ controls are detected in the output text. */ int rate = 100; /** * For the item at the top of the queue, the output command reflects * whether item should be PAUSE, RESUME, CANCEL. */ protected int command; protected final static int PAUSE = 0; protected final static int RESUME = 1; protected final static int CANCEL = 2; protected final static int CANCEL_ALL = 3; protected final static int CANCEL_COMPLETE = 4; /** * Object on which accesses to the command must synchronize. */ protected Object commandLock = new Object(); /** * Class constructor. */ public OutputHandler() { queue = new Vector(); currentItem = null; } /** * Stops execution of the Thread. */ public void terminate() { done = true; } /** * Returns the current queue. * * @return the current queue */ public Enumeration enumerateQueue() { synchronized(queue) { return queue.elements(); } } /** * Determines if the queue is empty. * * @return <code>true</code> if the queue is empty */ public boolean isQueueEmpty() { synchronized(queue) { return queue.size() == 0; } } /** * Adds an item to be spoken to the output queue. * * @param item the item to be added */ public void appendQueue(TextSynthesizerQueueItem item) { boolean topOfQueueChanged; synchronized(queue) { topOfQueueChanged = (queue.size() == 0); queue.addElement(item); queue.notifyAll(); } if (topOfQueueChanged) { long[] states = setEngineState(QUEUE_EMPTY, QUEUE_NOT_EMPTY); postQueueUpdated(topOfQueueChanged, states[0], states[1]); } } /** * Cancels the current item. */ protected void cancelItem() { cancelItem(CANCEL); } /** * Cancels all items. */ protected void cancelAllItems() { cancelItem(CANCEL_ALL); } /** * Cancels all or just the current item. * * @param cancelType <code>CANCEL</code> or <code>CANCEL_ALL</code> */ protected void cancelItem(int cancelType) { synchronized(queue) { if (queue.size() == 0) { return; } } synchronized(commandLock) { command = cancelType; commandLock.notifyAll(); while (command != CANCEL_COMPLETE) { try { commandLock.wait(); } catch (InterruptedException e) { // Ignore interrupts and we'll loop around } } if (testEngineState(Engine.PAUSED)) { command = PAUSE; } else { command = RESUME; } commandLock.notifyAll(); } } /** * Cancels the given item. * * @param source the item to cancel */ protected void cancelItem(Object source) {// synchronized(currentItemLock) {// if (currentItem.getSource() == source) {// cancelItem();// } else {// boolean queueEmptied;// synchronized(queue) {// for (int i = 0; i < queue.size(); i++) {// BaseSynthesizerQueueItem item =// (BaseSynthesizerQueueItem)(queue.elementAt(i));// if (item.getSource() == source) {// item.postSpeakableCancelled();// queue.removeElementAt(i);// }// }// queueEmptied = queue.size() == 0;// queue.notifyAll();// }// if (queueEmptied) {// long[] states = setEngineState(QUEUE_NOT_EMPTY,// QUEUE_EMPTY);// postQueueEmptied(states[0], states[1]);// } else { // long[] states = setEngineState(QUEUE_NOT_EMPTY,// QUEUE_NOT_EMPTY);// postQueueUpdated(false, states[0], states[1]);// }// }// } } /** * Pauses the output. */ protected void pauseItem() { synchronized(commandLock) { if (command != PAUSE) { command = PAUSE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -