com.groovemanager.sampled
Class AudioPlayer

java.lang.Object
  extended by com.groovemanager.sampled.AudioPlayer
All Implemented Interfaces:
java.util.EventListener, org.eclipse.jface.util.IPropertyChangeListener, java.lang.Runnable

public class AudioPlayer
extends java.lang.Object
implements java.lang.Runnable, org.eclipse.jface.util.IPropertyChangeListener

This class can be used for playing or recording Audio data in a new Thread.

Author:
Manu Robledo

Nested Class Summary
private  class AudioPlayer.OneLoop
          A helper class for calculation if the current play position
 
Field Summary
protected  int actualLength
          The number of frames currently read from the last provided AudioInputStream.
protected  java.util.ArrayList aisLengths
          List containing an OneLoop instances for each complete read AudioInputStream during this playback phase.
protected  AudioManager audioManager
          The AudioManager. used for getting the selected in and out Mixers
protected  int bufferSize
          The buffer size to be used when opening lines.
protected  ConfigManager configManager
          The ConfigManager.
protected  boolean cont
          Break condition for the play/record Thread
static int CONTINUED
          Possible values for status changes
protected  boolean endReached
          Flag indicating if the Thread has already been requested to stop.
protected  javax.sound.sampled.AudioInputStream in
          The stream from which data is read
protected  int lastStart
          The start position of the last provided AudioInputStream.
protected  java.util.ArrayList listeners
          The List of registered AudioPlayerListeners
protected  boolean loop
          Flag indicating if the playback should be looped or not
static int NOT_READY
          Possible values for player status
static int PAUSE_PLAY
          Possible values for player status
static int PAUSE_REC
          Possible values for player status
static int PAUSED
          Possible values for status changes
private  java.lang.Thread playAndRecordThread
          Thread for playback and recording
static int PLAYING
          Possible values for player status
protected  int priority
          The thread priority to be assigned to the play/rec threads
protected  AudioPlayerProvider provider
          The AudioPlayerProvider which provides thsi player with audio data and receives recorded audio data if capable for recording
static int PROVIDER_REMOVED
          Possible values for status changes
static int PROVIDER_SET
          Possible values for status changes
protected  byte[] readBuffer
          The byte[] buffer used for reading and writing audio data
static int READY_FOR_PLAY
          Possible values for player status
static int READY_FOR_REC
          Possible values for player status
static int RECORDING
          Possible values for player status
protected  javax.sound.sampled.SourceDataLine sourceLine
          Audio output line
static int STARTED
          Possible values for status changes
protected  int status
          The current player status
protected  boolean stopped
          Tells if the stop method has been invoked
static int STOPPED
          Possible values for status changes
protected  javax.sound.sampled.AudioFormat targetFormat
          The AudioFormat in which the Audio data must be written to the line (in play situations) or to the provider (in rec situations)
protected  javax.sound.sampled.TargetDataLine targetLine
          Audio input line
 
Constructor Summary
AudioPlayer()
          Constructs a new AudioPlayer using the default ConfigManager and the default Audiomanager
AudioPlayer(ConfigManager configManager)
          Constructs a new AudioPlayer using the given ConfigManager and a new AudioManager using this ConfigManager too
AudioPlayer(ConfigManager configManager, AudioManager audioManager)
          Constructs a new AudioPlayer using the given ConfigManager and AudioManager
 
Method Summary
 void addAudioPlayerListener(AudioPlayerListener listener)
          Register an AudioPlayerListener
 void cont()
          Continue playback or recording after pause
protected  javax.sound.sampled.DataLine createLine(javax.sound.sampled.AudioFormat format, boolean isTarget)
          Get the line from the currently selected Mixer that best supports the specified AudioFormat
protected  void end()
          Tell the Thread that it should come to its end.
protected  void freeRessources()
          Free all ressources
 int getBufferFillLevel()
          Gets the fill level of the line“s buffer
 int getFramePosition()
          Get the current position inside audio source considering passed loops and the startPosition provided by the AudioPlayerProvider
 boolean getLoop()
          Tell if the player is currently in loop mode or not
 AudioPlayerProvider getProvider()
          Get the currently assigned AudioPlayerProvider
 int getRealBufferSize()
          Ask for the real buffer size used by the line
 javax.sound.sampled.AudioFormat getRealFormat()
          Get the AudioFormat which the currently active Line is using.
 int getStatus()
          Get the current status
static java.lang.String getStatusName(int status)
          Get a String description of the given player status
protected static javax.sound.sampled.AudioFormat getUsableFormat(javax.sound.sampled.DataLine line, javax.sound.sampled.AudioFormat sourceFormat, boolean isTarget)
          Tries to get an AudioFormat which is supported by the line and is as near as possible to the specified sourceFormat
protected static boolean isFormatComplete(javax.sound.sampled.AudioFormat format)
          Checks if the given AudioFormat is fully specified and doesn't contain any AudioSystem.NOT_SPECIFIED values
private  void notifyListeners(int type)
          Notify all registered listeners about a status change
private  void notifyListenersLoop(boolean loop)
          Notify all registered listeners about a loop change
 void pause()
          Pause playback or recording, but stay prepared for immediate continuing
 void play()
          Start playback
 void propertyChange(org.eclipse.jface.util.PropertyChangeEvent event)
          React to changes of the buffer size
 void rec()
          Start recording
 void removeAudioPlayerListener(AudioPlayerListener listener)
          Remove a registered AudioPlayerListener
 void removeProvider()
          Remove the AudioPlayerProvider
 void run()
           
 void setLoop(boolean loop)
          Enable or disable looping
 void setPriority(int p)
          Set the priority of the playback/record Thread.
 void setProvider(AudioPlayerProvider p)
          Set the provider, which provides the data for playing and - if supported - processes recorded data
 void stop()
          Stop recording or playback
 void switchLoop()
          Switch the current loop state
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

actualLength

protected int actualLength
The number of frames currently read from the last provided AudioInputStream. Needed for getFramePosition()


aisLengths

protected java.util.ArrayList aisLengths
List containing an OneLoop instances for each complete read AudioInputStream during this playback phase. Needed in loop situations for getFramePosition()


audioManager

protected AudioManager audioManager
The AudioManager. used for getting the selected in and out Mixers


bufferSize

protected int bufferSize
The buffer size to be used when opening lines. Is retreived from the ConfigManager“s "audio_play_buffer" property.


configManager

protected ConfigManager configManager
The ConfigManager. Currently only used for the bufferSize


cont

protected boolean cont
Break condition for the play/record Thread


CONTINUED

public static final int CONTINUED
Possible values for status changes

See Also:
Constant Field Values

endReached

protected boolean endReached
Flag indicating if the Thread has already been requested to stop. Is needed to avoid endless loops in the stop() method.


in

protected javax.sound.sampled.AudioInputStream in
The stream from which data is read


lastStart

protected int lastStart
The start position of the last provided AudioInputStream. Needed for getFramePosition()


listeners

protected java.util.ArrayList listeners
The List of registered AudioPlayerListeners


loop

protected boolean loop
Flag indicating if the playback should be looped or not


NOT_READY

public static final int NOT_READY
Possible values for player status

See Also:
Constant Field Values

PAUSE_PLAY

public static final int PAUSE_PLAY
Possible values for player status

See Also:
Constant Field Values

PAUSE_REC

public static final int PAUSE_REC
Possible values for player status

See Also:
Constant Field Values

PAUSED

public static final int PAUSED
Possible values for status changes

See Also:
Constant Field Values

playAndRecordThread

private java.lang.Thread playAndRecordThread
Thread for playback and recording


PLAYING

public static final int PLAYING
Possible values for player status

See Also:
Constant Field Values

priority

protected int priority
The thread priority to be assigned to the play/rec threads


provider

protected AudioPlayerProvider provider
The AudioPlayerProvider which provides thsi player with audio data and receives recorded audio data if capable for recording


PROVIDER_REMOVED

public static final int PROVIDER_REMOVED
Possible values for status changes

See Also:
Constant Field Values

PROVIDER_SET

public static final int PROVIDER_SET
Possible values for status changes

See Also:
Constant Field Values

readBuffer

protected byte[] readBuffer
The byte[] buffer used for reading and writing audio data


READY_FOR_PLAY

public static final int READY_FOR_PLAY
Possible values for player status

See Also:
Constant Field Values

READY_FOR_REC

public static final int READY_FOR_REC
Possible values for player status

See Also:
Constant Field Values

RECORDING

public static final int RECORDING
Possible values for player status

See Also:
Constant Field Values

sourceLine

protected javax.sound.sampled.SourceDataLine sourceLine
Audio output line


STARTED

public static final int STARTED
Possible values for status changes

See Also:
Constant Field Values

status

protected int status
The current player status


stopped

protected boolean stopped
Tells if the stop method has been invoked


STOPPED

public static final int STOPPED
Possible values for status changes

See Also:
Constant Field Values

targetFormat

protected javax.sound.sampled.AudioFormat targetFormat
The AudioFormat in which the Audio data must be written to the line (in play situations) or to the provider (in rec situations)


targetLine

protected javax.sound.sampled.TargetDataLine targetLine
Audio input line

Constructor Detail

AudioPlayer

public AudioPlayer()
Constructs a new AudioPlayer using the default ConfigManager and the default Audiomanager


AudioPlayer

public AudioPlayer(ConfigManager configManager)
Constructs a new AudioPlayer using the given ConfigManager and a new AudioManager using this ConfigManager too

Parameters:
configManager - The ConfigManager to be used

AudioPlayer

public AudioPlayer(ConfigManager configManager,
                   AudioManager audioManager)
Constructs a new AudioPlayer using the given ConfigManager and AudioManager

Parameters:
configManager - The ConfigManager to be used
audioManager - The AudioManager to be used
Method Detail

addAudioPlayerListener

public void addAudioPlayerListener(AudioPlayerListener listener)
Register an AudioPlayerListener

Parameters:
listener - The AudioPlayerListener

cont

public void cont()
          throws NotReadyException
Continue playback or recording after pause

Throws:
NotReadyException

createLine

protected javax.sound.sampled.DataLine createLine(javax.sound.sampled.AudioFormat format,
                                                  boolean isTarget)
                                           throws javax.sound.sampled.LineUnavailableException
Get the line from the currently selected Mixer that best supports the specified AudioFormat

Parameters:
format - The wished AudioFormat. Will also return a Line if the Format doesn't match.
isTarget - true if an Input Line (TargetdataLine) is wanted, false for an output Line (SourceDataLine)
Returns:
The best matching DataLine instance
Throws:
javax.sound.sampled.LineUnavailableException - if the requestes ressources are not available

end

protected void end()
Tell the Thread that it should come to its end.


freeRessources

protected void freeRessources()
Free all ressources


getBufferFillLevel

public int getBufferFillLevel()
Gets the fill level of the line“s buffer

Returns:
the number of unprocessed bytes contained in the line“s buffer

getFramePosition

public int getFramePosition()
Get the current position inside audio source considering passed loops and the startPosition provided by the AudioPlayerProvider

Returns:
the current position

getLoop

public boolean getLoop()
Tell if the player is currently in loop mode or not

Returns:
true if it is in loop mode, false otherwise

getProvider

public AudioPlayerProvider getProvider()
Get the currently assigned AudioPlayerProvider

Returns:
The AudioPlayerProvider

getRealBufferSize

public int getRealBufferSize()
Ask for the real buffer size used by the line

Returns:
The buffersize in bytes

getRealFormat

public javax.sound.sampled.AudioFormat getRealFormat()
Get the AudioFormat which the currently active Line is using.

Returns:
The AudioFormat of the currently active Line or null if no Line is active.

getStatus

public int getStatus()
Get the current status

Returns:
The current player status

getStatusName

public static java.lang.String getStatusName(int status)
Get a String description of the given player status

Parameters:
status - The player status
Returns:
The textual description of the given status

getUsableFormat

protected static javax.sound.sampled.AudioFormat getUsableFormat(javax.sound.sampled.DataLine line,
                                                                 javax.sound.sampled.AudioFormat sourceFormat,
                                                                 boolean isTarget)
Tries to get an AudioFormat which is supported by the line and is as near as possible to the specified sourceFormat

Parameters:
line - The Line which has to support the Format
sourceFormat - A hint how the resulting Format should be like if possible
isTarget - Specifies if we are talking about a Target line or not. This is important to find the best matching format.
Returns:
The best matching AudioFormat supported by the Line or null if the Line doesn't support any AudioFormat (which is unlikely to happen, but you never know...)

isFormatComplete

protected static boolean isFormatComplete(javax.sound.sampled.AudioFormat format)
Checks if the given AudioFormat is fully specified and doesn't contain any AudioSystem.NOT_SPECIFIED values

Parameters:
format - The Format to be checked
Returns:
true if the Format is fully specified, false otherwise

notifyListeners

private void notifyListeners(int type)
Notify all registered listeners about a status change

Parameters:
type - The type of status change

notifyListenersLoop

private void notifyListenersLoop(boolean loop)
Notify all registered listeners about a loop change

Parameters:
loop - The new loop state

pause

public void pause()
Pause playback or recording, but stay prepared for immediate continuing


play

public void play()
          throws NotReadyException,
                 javax.sound.sampled.LineUnavailableException
Start playback

Throws:
NotReadyException - if the Player or the provider are not ready for playback or if playback is already active
javax.sound.sampled.LineUnavailableException - if the needed ressources are not available

propertyChange

public void propertyChange(org.eclipse.jface.util.PropertyChangeEvent event)
React to changes of the buffer size

Specified by:
propertyChange in interface org.eclipse.jface.util.IPropertyChangeListener
See Also:
IPropertyChangeListener.propertyChange(org.eclipse.jface.util.PropertyChangeEvent)

rec

public void rec()
         throws NotReadyException,
                javax.sound.sampled.LineUnavailableException
Start recording

Throws:
NotReadyException - if the recorder or the provider is not ready
javax.sound.sampled.LineUnavailableException - if the needed ressources are not available

removeAudioPlayerListener

public void removeAudioPlayerListener(AudioPlayerListener listener)
Remove a registered AudioPlayerListener

Parameters:
listener - The AudioPlayerListener

removeProvider

public void removeProvider()
Remove the AudioPlayerProvider


run

public void run()
Specified by:
run in interface java.lang.Runnable
See Also:
Runnable.run()

setLoop

public void setLoop(boolean loop)
Enable or disable looping

Parameters:
loop - true if looping should be turned on, false otherwise

setPriority

public void setPriority(int p)
Set the priority of the playback/record Thread.

Parameters:
p - The new priority. Values between Thread.MIN_PRIORITY and Thread.MAX_PRIORITY are accepted

setProvider

public void setProvider(AudioPlayerProvider p)
Set the provider, which provides the data for playing and - if supported - processes recorded data

Parameters:
p - The AudioPlayerProvider

stop

public void stop()
Stop recording or playback


switchLoop

public void switchLoop()
Switch the current loop state