⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 animatedaudioplayer.java

📁 使用Exlipse编写的一个语音程序
💻 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.freetts.audio;import javax.sound.sampled.*;import com.sun.speech.freetts.util.BulkTimer;/** * Provides an implementation of <code>AudioPlayer</code> that creates * javax.sound.sampled audio clips and outputs them via the * javax.sound API.  The interface provides a highly reliable audio * output package. Since audio is batched and not sent to the audio * layer until an entire utterance has been processed, this player has * higher latency (50 msecs for a typical 4 second utterance). * * The system property: * <code>	com.sun.speech.freetts.audio.AudioPlayer.debug; * </code> if set to <code>true</code> will cause this * class to emit debugging information (useful to a developer). */public class AnimatedAudioPlayer implements AudioPlayer {        private volatile boolean paused;    private volatile boolean done = false;    private volatile boolean cancelled = false;    private volatile Clip currentClip;    private float volume = 1.0f;  // the current volume    private boolean debug = false;    private BulkTimer timer = new BulkTimer();    private AudioFormat defaultFormat = // default format is 8khz	new AudioFormat(8000f, 16, 1, true, true);    private AudioFormat currentFormat = defaultFormat;    private boolean firstSample = true;    private int curIndex = 0;    private byte[] outputData;    private LineListener lineListener = new JavaClipLineListener();    private long closeDelay;	// workaround for linux sound bug	private LineListener externalLineListener; // -- added by bd 	/**	 * Constructs a default AnimatedAudioPlayer 	 * -- modified by bd	 */	public AnimatedAudioPlayer(LineListener externalLineListener) {		this.externalLineListener = externalLineListener;		debug = Boolean.getBoolean			("com.sun.speech.freetts.audio.AudioPlayer.debug");		closeDelay = Long.getLong			("com.sun.speech.freetts.audio.AudioPlayer.closeDelay",				150L).longValue();		setPaused(false);	}    /**     * Sets the audio format for this player     *     * @param format the audio format     *     * @throws UnsupportedOperationException if the line cannot be opened with     *     the given format     */    public synchronized void setAudioFormat(AudioFormat format) {	currentFormat = format;    }    /**     * Retrieves the audio format for this player     *     * @return format the audio format     */    public AudioFormat getAudioFormat() {	return currentFormat;    }    /**     * Pauses audio output.   All audio output is      * stopped. Output can be resumed at the     * current point by calling <code>resume</code>. Output can be     * aborted by calling <code> cancel </code>     */    public synchronized void pause() {	if (!isPaused()) {	    setPaused(true);	    Clip clip = currentClip;	    if (clip != null) {	        clip.stop();	    }	}    }    /**     * Resumes playing audio after a pause.     *     */    public synchronized void resume() {	if (isPaused()) {	    setPaused(false);	    Clip clip = currentClip;	    if (clip != null) {		clip.start();	    }	    notify();	}    }	    /**     * Cancels all queued audio. Any 'write' in process will return     * immediately false.     */    public synchronized void cancel() {	cancelled = true;	Clip clip = currentClip;	if (clip != null) {	    clip.close();	}    }    /**     * Prepares for another batch of output. Larger groups of output     * (such as all output associated with a single FreeTTSSpeakable)     * should be grouped between a reset/drain pair.     */    public synchronized void reset() {	timer.start("speakableOut");    }    /**     * Waits for all queued audio to be played     *     * @return <code>true</code> if the write completed successfully,      *       	<code> false </code>if the write was cancelled.     */    public boolean drain()  {	timer.stop("speakableOut");	return true;    }    /**     * Closes this audio player     */    public synchronized void close() {	done = true;	notify();    }            /**     * Returns the current volume.     * @return the current volume (between 0 and 1)     */    public float getVolume() {	return volume;    }	          /**     * Sets the current volume.     * @param volume  the current volume (between 0 and 1)     */    public void setVolume(float volume) {	if (volume > 1.0f) {	    volume = 1.0f;	}	if (volume < 0.0f) {	    volume = 0.0f;	}	this.volume = volume;	Clip clip = currentClip;	if (clip != null) {	    setVolume(clip, volume);	}    }	          /**     * Sets pause mode     * @param state true if we are paused     */    private void setPaused(boolean state) {	paused = state;    }    /**     * Returns true if we are in pause mode     *     * @return <code> true </code>if paused;      *		otherwise returns <code>false</code>     */    private boolean isPaused() {	return paused;    }    /**     * Sets the volume on the given clip     *     * @param line the line to set the volume on     * @param vol the volume (range 0 to 1)     */    private void setVolume(Clip clip, float vol) {	if (clip.isControlSupported (FloatControl.Type.MASTER_GAIN)) {	    FloatControl volumeControl = 		(FloatControl) clip.getControl (FloatControl.Type.MASTER_GAIN);	    float range = volumeControl.getMaximum() -			  volumeControl.getMinimum();	    volumeControl.setValue(vol * range + volumeControl.getMinimum());	}    }    /**     * Returns the current position in the output stream since the     * last <code>resetTime</code>      *     * Currently not supported.     *     * @return the position in the audio stream in milliseconds     *     */    public synchronized long getTime()  {        return -1L;    }    /**     * Resets the time for this audio stream to zero     */    public synchronized void resetTime() {    }        /**     *  Starts the output of a set of data. Audio data for a single     *  utterance should be grouped between begin/end pairs.     *     * @param size the size of data between now and the end     *     */    public void begin(int size) {	cancelled = false;	timer.start("utteranceOutput");	curIndex = 0;	outputData = new byte[size];    }    /**     *  Marks the end a set of data. Audio data for a single utterance should     *  be grouped between begin/end pairs.     *     *  @return <code>true</code> if the audio was output properly,      * 		<code>false </code> if the output was cancelled      *		or interrupted.     */    public synchronized boolean  end()  {	boolean ok = true;	while (!done && !cancelled && isPaused()) {	    try { 		wait();	    } catch (InterruptedException ie) {		return false;	    }	}	if (done || cancelled) {	    cancelled = false;	    return false;	}	timer.start("clipGeneration");	try {	    DataLine.Info info = new DataLine.Info(Clip.class, currentFormat);	    Clip clip = (Clip) AudioSystem.getLine(info);	    clip.addLineListener(lineListener);	    clip.addLineListener(externalLineListener); // -- added by bd	    clip.open(currentFormat, outputData, 0, outputData.length);	    setVolume(clip, volume);	    if (currentClip != null) {		throw new IllegalStateException("clip already set");	    }	    currentClip = clip;	    clip.start();	    try {		while (currentClip != null) {		    wait();	// drain does not work 		}	    } catch (InterruptedException ie) {		ok = false;	    }	} catch (LineUnavailableException lue) {	    System.err.println("Line unavailable");	    System.err.println("Format is " + currentFormat);	    ok = false;	}	timer.stop("clipGeneration");	timer.stop("utteranceOutput");	ok = !cancelled;	cancelled = false;	return ok;    }        /**     * Writes the given bytes to the audio stream     *     * @param audioData audio data to write to the device     *     * @return <code>true</code> if the write completed successfully,      *       	<code> false </code>if the write was cancelled.     */    public boolean write(byte[] audioData) {	return write(audioData, 0, audioData.length);    }        /**     * Writes the given bytes to the audio stream     *     * @param bytes audio data to write to the device     * @param offset the offset into the buffer     * @param size the size into the buffer     *     * @return <code>true</code> if the write completed successfully,      *       	<code> false </code>if the write was cancelled.     */    public boolean write(byte[] bytes, int offset, int size) {	if (firstSample) {	    firstSample = false;	    timer.stop("firstAudio");	}	System.arraycopy(bytes, offset, outputData, curIndex, size);	curIndex += size;	return true;    }    /**     * Returns the name of this audio player     *     * @return the name of the audio player     */    public String toString() {	return "JavaClipAudioPlayer";    }    /**     * Outputs the given msg if debugging is enabled for this     * audio player.     */    private void debugPrint(String msg) {	if (debug) {	    System.out.println(toString() + ": " + msg);	}    }    /**     * Shows metrics for this audio player     */    public void showMetrics() {	timer.show(toString());    }    /**     * Starts the first sample timer     */    public void startFirstSampleTimer() {	timer.start("firstAudio");	firstSample = true;    }    /**     * Provides a LineListener for this clas.     */    private class JavaClipLineListener implements LineListener {	/**	 * Implements update() method of LineListener interface. Responds	 * to the line events as appropriate.	 *	 * @param event the LineEvent to handle	 */	public void update(LineEvent event) {	    if (event.getType().equals(LineEvent.Type.START)) {		debugPrint("Event  START");	    } else if (event.getType().equals(LineEvent.Type.STOP)) {		debugPrint("Event  STOP");		// A line may be stopped for three reasons:		//    the clip has finished playing		//    the clip has been paused		//    the clip has been cancelled (i.e. closed)		// if the clip has stopped because it has finished		// playing, then we should close the clip, otherwise leave		// it alone		synchronized(AnimatedAudioPlayer.this) {		    if (!cancelled && !isPaused()) {	// BUG:	// There is a javax.sound bug that causes a crash on linux	// it is described here:	// http://developer.java.sun.com/developer/bugParade/bugs/4498848.html	// The bug seems to be related to synchronization of the close	// call on the clip.  If we delay before the close by 	// a small amount, the crash is averted.  This is a WORKAROUND	// only and should be removed once the javax.sound bug is	// fixed.  We get the delay from the property:	//	// com.sun.speech.freetts.audio.AudioPlayer.closeDelay	// 	// 			try {			    if (closeDelay > 0L) {				Thread.sleep(closeDelay);			    }		    	} catch (InterruptedException ie) {			}			currentClip.close();		    }		}	    }  else if (event.getType().equals(LineEvent.Type.OPEN)) {		debugPrint("Event OPEN");	    }  else if (event.getType().equals(LineEvent.Type.CLOSE)) {		// When a clip is closed we no longer need it, so 		// set currentClip to null and notify anyone who may		// be waiting on it.		debugPrint("EVNT CLOSE");		synchronized (AnimatedAudioPlayer.this) {		    currentClip = null;		    AnimatedAudioPlayer.this.notify();		}	    }	}    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -