2 * Copyright 2001 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
8 package com.sun.speech.freetts.audio;
10 import java.io.ByteArrayInputStream;
12 import java.io.IOException;
13 import java.io.InputStream;
14 import java.io.SequenceInputStream;
15 import java.util.Vector;
17 import javax.sound.sampled.AudioFileFormat;
18 import javax.sound.sampled.AudioFormat;
19 import javax.sound.sampled.AudioInputStream;
20 import javax.sound.sampled.AudioSystem;
22 import com.sun.speech.freetts.util.Utilities;
25 * Streams audio to a file.
29 public class SingleFileAudioPlayer implements AudioPlayer {
30 private AudioFormat currentFormat = null;
31 private String baseName;
32 private byte[] outputData;
33 private int curIndex = 0;
34 private int totBytes = 0;
35 private AudioFileFormat.Type outputType;
36 private Vector outputList;
40 * Constructs a FileAudioPlayer
42 * @param baseName the base name of the audio file
43 * @param type the type of audio output
46 public SingleFileAudioPlayer(String baseName, AudioFileFormat.Type type) {
47 this.baseName = baseName + "." + type.getExtension();
48 this.outputType = type;
50 outputList = new Vector();
54 * Creates a default audio player for an AudioFileFormat of type
55 * WAVE. Reads the "com.sun.speech.freetts.AudioPlayer.baseName"
56 * property for the base filename to use, and will produce a file
57 * of the form <baseName>.wav. The default value for the
58 * base name is "freetts".
60 public SingleFileAudioPlayer() {
61 this(Utilities.getProperty(
62 "com.sun.speech.freetts.AudioPlayer.baseName", "freetts"),
63 AudioFileFormat.Type.WAVE);
67 * Sets the audio format for this player
69 * @param format the audio format
71 * @throws UnsupportedOperationException if the line cannot be opened with
74 public synchronized void setAudioFormat(AudioFormat format) {
75 currentFormat = format;
80 * Gets the audio format for this player
82 * @return format the audio format
84 public AudioFormat getAudioFormat() {
96 * Resumes audio output
98 public synchronized void resume() {
104 * Cancels currently playing audio
106 public synchronized void cancel() {
110 * Prepares for another batch of output. Larger groups of output
111 * (such as all output associated with a single FreeTTSSpeakable)
112 * should be grouped between a reset/drain pair.
114 public synchronized void reset() {
119 * Starts the first sample timer
121 public void startFirstSampleTimer() {
125 * Closes this audio player
127 public synchronized void close() {
129 File file = new File(baseName);
130 InputStream is = new SequenceInputStream(outputList.elements());
131 AudioInputStream ais = new AudioInputStream(is,
132 currentFormat, totBytes / currentFormat.getFrameSize());
134 System.out.println("Avail " + ais.available());
135 System.out.println("totBytes " + totBytes);
136 System.out.println("FS " + currentFormat.getFrameSize());
138 System.out.println("Wrote synthesized speech to " + baseName);
139 AudioSystem.write(ais, outputType, file);
140 } catch (IOException ioe) {
141 System.err.println("Can't write audio to " + baseName);
142 } catch (IllegalArgumentException iae) {
143 System.err.println("Can't write audio type " + outputType);
149 * Returns the current volume.
151 * @return the current volume (between 0 and 1)
153 public float getVolume() {
158 * Sets the current volume.
160 * @param volume the current volume (between 0 and 1)
162 public void setVolume(float volume) {
169 * Starts the output of a set of data. Audio data for a single
170 * utterance should be grouped between begin/end pairs.
172 * @param size the size of data between now and the end
174 public void begin(int size) {
175 outputData = new byte[size];
180 * Marks the end of a set of data. Audio data for a single
181 * utterance should be groupd between begin/end pairs.
183 * @return true if the audio was output properly, false if the
184 * output was cancelled or interrupted.
187 public boolean end() {
188 outputList.add(new ByteArrayInputStream(outputData));
189 totBytes += outputData.length;
195 * Waits for all queued audio to be played
197 * @return true if the audio played to completion, false if
198 * the audio was stopped
200 public boolean drain() {
205 * Gets the amount of played since the last mark
207 * @return the amount of audio in milliseconds
209 public synchronized long getTime() {
215 * Resets the audio clock
217 public synchronized void resetTime() {
223 * Writes the given bytes to the audio stream
225 * @param audioData audio data to write to the device
227 * @return <code>true</code> of the write completed successfully,
228 * <code> false </code>if the write was cancelled.
230 public boolean write(byte[] audioData) {
231 return write(audioData, 0, audioData.length);
235 * Writes the given bytes to the audio stream
237 * @param bytes audio data to write to the device
238 * @param offset the offset into the buffer
239 * @param size the size into the buffer
241 * @return <code>true</code> of the write completed successfully,
242 * <code> false </code>if the write was cancelled.
244 public boolean write(byte[] bytes, int offset, int size) {
245 System.arraycopy(bytes, offset, outputData, curIndex, size);
251 * Returns the name of this audioplayer
253 * @return the name of the audio player
255 public String toString() {
256 return "FileAudioPlayer";
260 * Shows metrics for this audio player
262 public void showMetrics() {