Package com.sun.speech.freetts.audio

# Class JavaStreamingAudioPlayer

java.lang.Object
com.sun.speech.freetts.audio.JavaStreamingAudioPlayer

All Implemented Interfaces:
  `AudioPlayer`

public class JavaStreamingAudioPlayer extends Object implements AudioPlayer
Streams audio to java audio. This class provides a low latency method of sending audio output through the javax.sound audio API. Audio data is sent in small sets to the audio system allowing it to be played soon after it is generated. Unfortunately, the current release of the JDK (JDK 1.4 beta 2) has a bug or two in the implementation of 'SourceDataLine.drain'. A workaround solution that sleep/waits on SourceDataLine.isActive is used here instead. To disable the work around (i.e use the real 'drain') set the property:

`com.sun.speech.freetts.audio.AudioPlayer.drainWorksProperly;` to `true`. If the workaround is enabled, the line.isActive method will be performed periodically. The period of the test can be controlled with:

`com.sun.speech.freetts.audio.AudioPlayer.drainDelay"`

The default if 5ms.

The property `com.sun.speech.freetts.audio.AudioPlayer.bufferSize"`

Controls the audio buffer size, it defaults to 8192

Even with this drain work around, there are some issues with this class. The workaround drain is not completely reliable. A `resume` following a `pause` does not always continue at the proper position in the audio. On a rare occasion, sound output will be repeated a number of times. This may be related to bug 4421330 in the Bug Parade database.

## Constructor Summary

Constructors
Constructor
Description
`JavaStreamingAudioPlayer()`
Constructs a default JavaStreamingAudioPlayer

## Method Summary

Modifier and Type
Method
Description
`void`
`begin(int size)`
Starts the output of a set of data.
`void`
`cancel()`
Cancels currently playing audio.
`void`
`close()`
Closes this audio player
`boolean`
`drain()`
Waits for all queued audio to be played
`boolean`
`end()`
Marks the end of a set of data.
`AudioFormat`
`getAudioFormat()`
Gets the audio format for this player
`long`
`getTime()`
Gets the amount of played since the last mark
`float`
`getVolume()`
Returns the current volume.
`void`
`pause()`
Pauses audio output
`void`
`reset()`
Prepares for another batch of output.
`void`
`resetTime()`
Resets the audio clock
`void`
`resume()`
Resumes audio output
`void`
`setAudioFormat(AudioFormat format)`
Sets the audio format for this player
`void`
`setVolume(float volume)`
Sets the current volume.
`void`
`showMetrics()`
Shows metrics for this audio player
`void`
`startFirstSampleTimer()`
Starts the first sample timer
`String`
`toString()`
Returns the name of this audioplayer
`boolean`
`write(byte[] audioData)`
Writes the given bytes to the audio stream
`boolean`
`write(byte[] bytes, int offset, int size)`
Writes the given bytes to the audio stream

### Methods inherited from class java.lang.Object

`clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait`

## Constructor Details

### JavaStreamingAudioPlayer

public JavaStreamingAudioPlayer()
Constructs a default JavaStreamingAudioPlayer

## Method Details

### setAudioFormat

public void setAudioFormat(AudioFormat format)
Sets the audio format for this player

Specified by:
  `setAudioFormat` in interface `AudioPlayer`
Parameters:
  `format` - the audio format
Throws:
  `UnsupportedOperationException` - if the line cannot be opened with the given format

### getAudioFormat

public AudioFormat getAudioFormat()
Gets the audio format for this player

Specified by:
  `getAudioFormat` in interface `AudioPlayer`
Returns:
  format the audio format

### startFirstSampleTimer

public void startFirstSampleTimer()
Starts the first sample timer

Specified by:
  `startFirstSampleTimer` in interface `AudioPlayer`

### pause

public void pause()
Pauses audio output

Specified by:
  `pause` in interface `AudioPlayer`

### resume

public void resume()
Resumes audio output

Specified by:
  `resume` in interface `AudioPlayer`

### cancel

public void cancel()
Cancels currently playing audio.

Specified by:
  `cancel` in interface `AudioPlayer`

### reset

public void reset()
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.

Specified by:
  `reset` in interface `AudioPlayer`

### close

public void close()
Closes this audio player

Specified by:
  `close` in interface `AudioPlayer`

### getVolume

public float getVolume()
Returns the current volume.

Specified by:
  `getVolume` in interface `AudioPlayer`
Returns:
  the current volume (between 0 and 1)

### setVolume

public void setVolume(float volume)
Sets the current volume.

Specified by:
  `setVolume` in interface `AudioPlayer`
Parameters:
  `volume` - the current volume (between 0 and 1)

### begin

public void begin(int size)
Starts the output of a set of data. For this JavaStreamingAudioPlayer, it actually opens the audio line. Since this is a streaming audio player, the `size` parameter has no meaning and effect at all, so any value can be used. Audio data for a single utterance should be grouped between begin/end pairs.

Specified by:
  `begin` in interface `AudioPlayer`
Parameters:
  `size` - supposedly the size of data between now and the end, but since this is a streaming audio player, this parameter has no meaning and effect at all

### end

public boolean end()
Marks the end of a set of data. Audio data for a single utterance should be groupd between begin/end pairs.

Specified by:
  `end` in interface `AudioPlayer`
Returns:
  true if the audio was output properly, false if the output was cancelled or interrupted.

### drain

public boolean drain()
Waits for all queued audio to be played

Specified by:
  `drain` in interface `AudioPlayer`
Returns:
  true if the audio played to completion, false if the audio was stopped [[[ WORKAROUND TODO The javax.sound.sampled drain is almost working properly. On linux, there is still a little bit of sound that needs to go out, even after drain is called. Thus, the drainDelay. We wait for a few hundred milliseconds while the data is really drained out of the system ]]]

### getTime

public long getTime()
Gets the amount of played since the last mark

Specified by:
  `getTime` in interface `AudioPlayer`
Returns:
  the amount of audio in milliseconds

### resetTime

public void resetTime()
Resets the audio clock

Specified by:
  `resetTime` in interface `AudioPlayer`

### write

public boolean write(byte[] audioData)
Writes the given bytes to the audio stream

Specified by:
  `write` in interface `AudioPlayer`
Parameters:
  `audioData` - audio data to write to the device
Returns:
  `true` of the write completed successfully, `false` if the write was cancelled.

### write

public boolean write(byte[] bytes, int offset, int size)
Writes the given bytes to the audio stream

Specified by:
  `write` in interface `AudioPlayer`
Parameters:
  `bytes` - audio data to write to the device
  `offset` - the offset into the buffer
  `size` - the size into the buffer
Returns:
  `true` of the write completed successfully, `false` if the write was cancelled.

### toString

public String toString()
Returns the name of this audioplayer

Overrides:
  `toString` in class `Object`
Returns:
  the name of the audio player

### showMetrics

public void showMetrics()
Shows metrics for this audio player

Specified by:
  `showMetrics` in interface `AudioPlayer`