upstream version 1.2.2
[debian/freetts] / demo / freetts / ClientServer / SocketAudioPlayer.java
1 /**
2  * Copyright 2001 Sun Microsystems, Inc.
3  * 
4  * See the file "license.terms" for information on usage and
5  * redistribution of this file, and for a DISCLAIMER OF ALL 
6  * WARRANTIES.
7  */
8
9 import com.sun.speech.freetts.audio.AudioPlayer;
10 import com.sun.speech.freetts.util.Utilities;
11
12 import java.io.DataOutputStream;
13 import java.io.IOException;
14
15 import java.net.Socket;
16
17 import javax.sound.sampled.AudioFormat;
18
19
20 /**
21  * Implements the AudioPlayer for the freetts Client/Server demo.
22  * This SocketAudioPlayer basically sends synthesized wave bytes to the
23  * client.
24  */
25 public class SocketAudioPlayer implements AudioPlayer {
26
27     private AudioFormat audioFormat;
28     private Socket socket;
29     private DataOutputStream dataOutputStream;
30     private boolean debug = false;
31     private int bytesToPlay = 0;
32     private int bytesPlayed = 0;
33     private boolean firstByteSent = false;
34     private long firstByteTime = -1;
35
36
37     /**
38      * Constructs a SocketAudioPlayer that will send wave bytes to the
39      * given Socket.
40      *
41      * @param socket the Socket to which synthesized wave bytes will be sent
42      */
43     public SocketAudioPlayer(Socket socket) {
44         this.socket = socket;
45         try {
46             this.dataOutputStream = new DataOutputStream
47                 (socket.getOutputStream());
48             debug = Utilities.getBoolean("debug");
49         } catch (IOException ioe) {
50             ioe.printStackTrace();
51         }
52     }
53
54
55     /**
56      * Sets the audio format to use for the next set of outputs. Since
57      * an audio player can be shared by a number of voices, and since
58      * voices can have different AudioFormats (sample rates for
59      * example), it is necessary to allow clients to dynamically set
60      * the audio format for the player.
61      *
62      * @param format the audio format
63      */
64     public void setAudioFormat(AudioFormat format) {
65         this.audioFormat = format;
66     }
67
68
69     /**
70      * Retrieves the audio format for this player
71      *
72      * @return the current audio format
73      *
74      */
75     public AudioFormat getAudioFormat() {
76         return this.audioFormat;
77     }
78
79
80     /**
81      * Pauses all audio output on this player. Play can be resumed
82      * with a call to resume. Not implemented in this Player.
83      */
84     public void pause() {}
85
86
87     /**
88      * Resumes audio output on this player. Not implemented in this Player.
89      */
90     public void resume() {}
91
92
93     /**
94      * Prepares for another batch of output. Larger groups of output
95      * (such as all output associated with a single FreeTTSSpeakable)
96      * should be grouped between a reset/drain pair.
97      */
98     public void reset() {}
99
100
101     /**
102      * Flushes all the audio data to the Socket.
103      *
104      * @return <code>true</code> all the time
105      */
106     public boolean drain() {
107         try {
108             dataOutputStream.flush();
109         } catch (IOException ioe) {
110             ioe.printStackTrace();
111         }
112         return true;
113     }
114
115
116     /**
117      *  Starts the output of a set of data. Audio data for a single
118      *  utterance should be grouped between begin/end pairs.
119      *
120      * @param size the size of data in bytes to be output before
121      *    <code>end</code> is called.
122      */
123     public void begin(int size) {
124         try {
125             bytesToPlay = size;
126             firstByteSent = false;
127             dataOutputStream.writeBytes(String.valueOf(size) + "\n");
128             dataOutputStream.flush();
129             if (debug) {
130                 System.out.println("begin: " + size);
131             }
132         } catch (IOException ioe) {
133             ioe.printStackTrace();
134         }
135     }
136
137
138     /**
139      * Starts the first sample timer (none in this player)
140      */
141     public void startFirstSampleTimer() {
142     }
143
144
145     /**
146      *  Signals the end of a set of data. Audio data for a single 
147      *  utterance should be groupd between <code> begin/end </code> pairs.
148      *
149      *  @return <code>true</code> if the audio was output properly, 
150      *          <code> false</code> if the output was cancelled 
151      *          or interrupted.
152      *
153      */
154     public boolean end() {
155         if (debug) {
156             System.out.println("end");
157         }
158         if (bytesPlayed < bytesToPlay) {
159             int bytesNotPlayed = bytesToPlay - bytesPlayed;
160             write(new byte[bytesNotPlayed], 0, bytesNotPlayed);
161         }
162
163         bytesToPlay = 0;
164         bytesPlayed = 0;
165         return true;
166     }
167     
168     
169     /**
170      * Cancels all queued output. All 'write' calls until the next
171      * reset will return false. Not implemented in this Player.
172      *
173      */
174     public void cancel() {}
175
176     
177     /**
178      * Waits for all audio playback to stop, and closes this AudioPlayer.
179      * Not implemented in this Player.
180      */
181     public void close() {}
182
183
184     /**
185      * Returns the current volume. The volume is specified as a number
186      * between 0.0 and 1.0, where 1.0 is the maximum volume and 0.0 is
187      * the minimum volume. Not implemented in this Player.
188      *
189      * @return the current volume (between 0 and 1)
190      */
191     public float getVolume() {
192         return -1;
193     }
194
195
196     /**
197      * Sets the current volume. The volume is specified as a number
198      * between 0.0 and 1.0, where 1.0 is the maximum volume and 0.0 is
199      * the minimum volume. Not implemented in this Player.
200      *
201      * @param volume the new volume (between 0 and 1)
202      */
203     public void setVolume(float volume) {}
204
205
206     /**
207      * Gets the amount of audio played since the last resetTime.
208      * Not implemented in this Player.
209      *
210      * @returns the amount of audio in milliseconds
211      */
212     public long getTime() {
213         return -1;
214     }
215
216
217     /**
218      * Resets the audio clock. Not implemented in this Player.
219      */
220     public void resetTime() {}
221     
222
223     /**
224      * Writes the given bytes to the audio stream
225      *
226      * @param audioData audio data to write to the device
227      *
228      * @return <code>true</code> of the write completed successfully, 
229      *          <code> false </code>if the write was cancelled.
230      */
231     public boolean write(byte[] audioData) {
232         return write(audioData, 0, audioData.length);
233     }
234
235
236     /**
237      * Writes the given bytes to the audio stream
238      *
239      * @param audioData audio data to write to the device
240      * @param offset the offset into the buffer
241      * @param size the number of bytes to write.
242      *
243      * @return <code>true</code> of the write completed successfully, 
244      *          <code> false </code>if the write was cancelled.
245      */
246     public boolean write(byte[] audioData, int offset, int size) {
247         try {
248             if (!firstByteSent) {
249                 firstByteTime = System.currentTimeMillis();
250                 firstByteSent = true;
251             }
252             
253             bytesPlayed += size;
254             dataOutputStream.write(audioData, offset, size);
255             dataOutputStream.flush();
256
257             if (debug) {
258                 System.out.println("sent " + size + " bytes " +
259                                    audioData[0] + " " + audioData[size/2]);
260             }
261             return true;
262         } catch (IOException ioe) {
263             ioe.printStackTrace();
264             return false;
265         }
266     }
267
268
269     /**
270      * Shows metrics for this audio player. Not implemented in this Player.
271      */
272     public void showMetrics() {}
273
274     
275     /**
276      * Returns the first byte sent time in milliseconds, the last time it
277      * was recorded.
278      *
279      * @return the last first byte sent time in milliseconds
280      */
281     public long getFirstByteSentTime() {
282         return firstByteTime;
283     }
284 }