package paulscode.sound;
import java.net.URL;
import java.util.LinkedList;
import java.util.ListIterator;
import javax.sound.sampled.AudioFormat;
/**
* The Source class is used to store information about a source.
* Source objects are stored in a map in the Library class. The
* information they contain is used to create library-specific sources.
* This is the template class which is extended for each specific library.
* This class is also used by the "No Sound" library to represent a mute
* source.
*<br><br>
*<b><i> SoundSystem License:</b></i><br><b><br>
* You are free to use this library for any purpose, commercial or otherwise.
* You may modify this library or source code, and distribute it any way you
* like, provided the following conditions are met:
*<br>
* 1) You may not falsely claim to be the author of this library or any
* unmodified portion of it.
*<br>
* 2) You may not copyright this library or a modified version of it and then
* sue me for copyright infringement.
*<br>
* 3) If you modify the source code, you must clearly document the changes
* made before redistributing the modified source code, so other users know
* it is not the original code.
*<br>
* 4) You are not required to give me credit for this library in any derived
* work, but if you do, you must also mention my website:
* http://www.paulscode.com
*<br>
* 5) I the author will not be responsible for any damages (physical,
* financial, or otherwise) caused by the use if this library or any part
* of it.
*<br>
* 6) I the author do not guarantee, warrant, or make any representations,
* either expressed or implied, regarding the use of this library or any
* part of it.
* <br><br>
* Author: Paul Lamb
* <br>
* http://www.paulscode.com
* </b>
*/
public class Source
{
/**
* The library class associated with this type of channel.
*/
protected Class libraryType = Library.class;
/**
* Used to return a current value from one of the synchronized
* boolean-interface methods.
*/
private static final boolean GET = false;
/**
* Used to set the value in one of the synchronized boolean-interface methods.
*/
private static final boolean SET = true;
/**
* Used when a parameter for one of the synchronized boolean-interface methods
* is not aplicable.
*/
private static final boolean XXX = false;
/**
* Processes status messages, warnings, and error messages.
*/
private SoundSystemLogger logger;
/**
* True if this source is being directly fed with raw audio data.
*/
public boolean rawDataStream = false;
/**
* Format the raw data will be in if this is a Raw Data Stream source.
*/
public AudioFormat rawDataFormat = null;
/**
* Determines whether a source should be removed after it finishes playing.
*/
public boolean temporary = false;
/**
* Determines whether or not this is a priority source. Priority sources will
* not be overwritten by other sources when there are no available channels.
*/
public boolean priority = false;
/**
* Whether or not this source should be streamed.
*/
public boolean toStream = false;
/**
* Whether this source should loop or only play once.
*/
public boolean toLoop = false;
/**
* Whether this source needs to be played (for example if it was playing and
* looping when it got culled).
*/
public boolean toPlay = false;
/**
* Unique name for this source. More than one source can not have the same
* sourcename.
*/
public String sourcename = "";
/**
* The audio file which this source should play.
*/
public FilenameURL filenameURL = null;
/**
* This source's position in 3D space.
*/
public Vector3D position;
/**
* Attenuation model to use for this source.
*/
public int attModel = 0;
/**
* Either fade distance or rolloff factor, depending on the value of attModel.
*/
public float distOrRoll = 0.0f;
/**
* Source's velocity in world-space, for use in Doppler effect.
*/
public Vector3D velocity;
/**
* This source's volume (a float between 0.0 - 1.0). This value is used
* internally for attenuation, and should not be used to manually change a
* source's volume.
*/
public float gain = 1.0f;
/**
* This value should be used to manually increase or decrease source volume.
*/
public float sourceVolume = 1.0f;
/**
* This value represents the source's pitch (float value between 0.5f - 2.0f).
*/
protected float pitch = 1.0f;
/**
* This source's distance from the listener.
*/
public float distanceFromListener = 0.0f;
/**
* Channel to play this source on.
*/
public Channel channel = null;
/**
* Holds the data used by normal sources.
*/
public SoundBuffer soundBuffer = null;
/**
* False when this source gets culled.
*/
private boolean active = true;
/**
* Whether or not this source has been stopped.
*/
private boolean stopped = true;
/**
* Whether or not this source has been paused.
*/
private boolean paused = false;
/**
* Codec used to read data for streaming sources.
*/
protected ICodec codec = null;
/**
* The list of files to stream when the current stream finishes.
*/
protected LinkedList<FilenameURL> soundSequenceQueue = null;
/**
* Ensures that only one thread accesses the soundSequenceQueue at a time.
*/
protected final Object soundSequenceLock = new Object();
/**
* Used by streaming sources to indicate whether or not the initial
* stream-buffers still need to be queued.
*/
public boolean preLoad = false;
/**
* Specifies the gain factor used for the fade-out effect, or -1 when
* source is not currently fading out.
*/
protected float fadeOutGain = -1.0f;
/**
* Specifies the gain factor used for the fade-in effect, or 1 when
* source is not currently fading in.
*/
protected float fadeInGain = 1.0f;
/**
* Specifies the number of miliseconds it should take to fade out.
*/
protected long fadeOutMilis = 0;
/**
* Specifies the number of miliseconds it should take to fade in.
*/
protected long fadeInMilis = 0;
/**
* System time in miliseconds when the last fade in/out volume check occurred.
*/
protected long lastFadeCheck = 0;
/**
* Constructor: Creates a new source using the specified parameters.
* @param priority Setting this to true will prevent other sounds from overriding this one.
* @param toStream Setting this to true will create a streaming source.
* @param toLoop Should this source loop, or play only once.
* @param sourcename A unique identifier for this source. Two sources may not use the same sourcename.
* @param filenameURL The filename/URL of the sound file to play at this source.
* @param soundBuffer Buffer containing audio data, or null if not loaded yet.
* @param x X position for this source.
* @param y Y position for this source.
* @param z Z position for this source.
* @param attModel Attenuation model to use.
* @param distOrRoll Either the fading distance or rolloff factor, depending on the value of 'att'.
* @param temporary Whether or not to remove this source after it finishes playing.
*/
public Source( boolean priority, boolean toStream, boolean toLoop,
String sourcename, FilenameURL filenameURL,
SoundBuffer soundBuffer, float x, float y, float z,
int attModel, float distOrRoll, boolean temporary )
{
// grab a handle to the message logger:
logger = SoundSystemConfig.getLogger();
this.priority = priority;
this.toStream = toStream;
this.toLoop = toLoop;
this.sourcename = sourcename;
this.filenameURL = filenameURL;
this.soundBuffer = soundBuffer;
position = new Vector3D( x, y, z );
this.attModel = attModel;
this.distOrRoll = distOrRoll;
this.velocity = new Vector3D( 0, 0, 0 );
this.temporary = temporary;
if( toStream && filenameURL != null )
codec = SoundSystemConfig.getCodec( filenameURL.getFilename() );
}
/**
* Constructor: Creates a new source matching the specified one.
* @param old Source to copy information from.
* @param soundBuffer Buffer containing audio data, or null if not loaded yet.
*/
public Source( Source old, SoundBuffer soundBuffer )
{
// grab a handle to the message logger:
logger = SoundSystemConfig.getLogger();
priority = old.priority;
toStream = old.toStream;
toLoop = old.toLoop;
sourcename = old.sourcename;
filenameURL = old.filenameURL;
position = old.position.clone();
attModel = old.attModel;
distOrRoll = old.distOrRoll;
velocity = old.velocity.clone();
temporary = old.temporary;
sourceVolume = old.sourceVolume;
rawDataStream = old.rawDataStream;
rawDataFormat = old.rawDataFormat;
this.soundBuffer = soundBuffer;
if( toStream && filenameURL != null )
codec = SoundSystemConfig.getCodec( filenameURL.getFilename() );
}
/**
* Constructor: Creates a new streaming source that will be directly fed with
* raw audio data.
* @param audioFormat Format that the data will be in.
* @param priority Setting this to true will prevent other sounds from overriding this one.
* @param sourcename A unique identifier for this source. Two sources may not use the same sourcename.
* @param x X position for this source.
* @param y Y position for this source.
* @param z Z position for this source.
* @param attModel Attenuation model to use.
* @param distOrRoll Either the fading distance or rolloff factor, depending on the value of 'att'.
*/
public Source( AudioFormat audioFormat, boolean priority, String sourcename,
float x, float y, float z, int attModel, float distOrRoll )
{
// grab a handle to the message logger:
logger = SoundSystemConfig.getLogger();
this.priority = priority;
this.toStream = true;
this.toLoop = false;
this.sourcename = sourcename;
this.filenameURL = null;
this.soundBuffer = null;
position = new Vector3D( x, y, z );
this.attModel = attModel;
this.distOrRoll = distOrRoll;
this.velocity = new Vector3D( 0, 0, 0 );
this.temporary = false;
rawDataStream = true;
rawDataFormat = audioFormat;
}
/* Override methods */
/**
* Shuts the source down and removes references to all instantiated objects.
*/
public void cleanup()
{
if( codec != null )
codec.cleanup();
synchronized( soundSequenceLock )
{
if( soundSequenceQueue != null )
soundSequenceQueue.clear();
soundSequenceQueue = null;
}
sourcename = null;
filenameURL = null;
position = null;
soundBuffer = null;
codec = null;
}
/**
* If this is a streaming source, queues up the next sound to play when
* the previous stream ends. This method has no effect on non-streaming
* sources.
* @param filenameURL The filename/URL of the sound file to stream next.
*/
public void queueSound( FilenameURL filenameURL )
{
if( !toStream )
{
errorMessage( "Method 'queueSound' may only be used for " +
"streaming and MIDI sources." );
return;
}
if( filenameURL == null )
{
errorMessage( "File not specified in method 'queueSound'" );
return;
}
synchronized( soundSequenceLock )
{
if( soundSequenceQueue == null )
soundSequenceQueue = new LinkedList<FilenameURL>();
soundSequenceQueue.add( filenameURL );
}
}
/**
* Removes the first occurrence of the specified filename from the list of
* sounds to play when the previous stream ends. This method has no effect
* on non-streaming sources.
* @param filename Filename/identifier of a sound file to remove from the queue.
*/
public void dequeueSound( String filename )
{
if( !toStream )
{
errorMessage( "Method 'dequeueSound' may only be used for " +
"streaming and MIDI sources." );
return;
}
if( filename == null || filename.equals( "" ) )
{
errorMessage( "Filename not specified in method 'dequeueSound'" );
return;
}
synchronized( soundSequenceLock )
{
if( soundSequenceQueue != null )
{
ListIterator<FilenameURL> i = soundSequenceQueue.listIterator();
while( i.hasNext() )
{
if( i.next().getFilename().equals( filename ) )
{
i.remove();
break;
}
}
}
}
}
/**
* Fades out the volume of whatever this source is currently playing, then
* begins playing the specified filename at the source's previously assigned
* volume level. If the filename parameter is null or empty, the source will
* simply fade out and stop. The miliseconds parameter must be non-negative or
* zero. This method will remove anything that is currently in the list of
* queued sounds that would have played next when the current sound finished
* playing. This method has no effect on non-streaming sources.
* @param filenameURL Filename/URL of the sound file to play next, or null for none.
* @param milis Number of miliseconds the fadeout should take.
*/
public void fadeOut( FilenameURL filenameURL, long milis )
{
if( !toStream )
{
errorMessage( "Method 'fadeOut' may only be used for " +
"streaming and MIDI sources." );
return;
}
if( milis < 0 )
{
errorMessage( "Miliseconds may not be negative in method " +
"'fadeOut'." );
return;
}
fadeOutMilis = milis;
fadeInMilis = 0;
fadeOutGain = 1.0f;
lastFadeCheck = System.currentTimeMillis();
synchronized( soundSequenceLock )
{
if( soundSequenceQueue != null )
soundSequenceQueue.clear();
if( filenameURL != null )
{
if( soundSequenceQueue == null )
soundSequenceQueue = new LinkedList<FilenameURL>();
soundSequenceQueue.add( filenameURL );
}
}
}
/**
* Fades out the volume of whatever this source is currently playing, then
* fades the volume back in playing the specified file. Final volume after
* fade-in completes will be equal to the source's previously assigned volume
* level. The filenameURL parameter may not be null or empty. The miliseconds
* parameters must be non-negative or zero. This method will remove anything
* that is currently in the list of queued sounds that would have played next
* when the current sound finished playing. This method has no effect on
* non-streaming sources.
* @param filenameURL Filename/URL of the sound file to play next, or null for none.
* @param milisOut Number of miliseconds the fadeout should take.
* @param milisIn Number of miliseconds the fadein should take.
*/
public void fadeOutIn( FilenameURL filenameURL, long milisOut, long milisIn )
{
if( !toStream )
{
errorMessage( "Method 'fadeOutIn' may only be used for " +
"streaming and MIDI sources." );
return;
}
if( filenameURL == null )
{
errorMessage( "Filename/URL not specified in method 'fadeOutIn'." );
return;
}
if( milisOut < 0 || milisIn < 0 )
{
errorMessage( "Miliseconds may not be negative in method " +
"'fadeOutIn'." );
return;
}
fadeOutMilis = milisOut;
fadeInMilis = milisIn;
fadeOutGain = 1.0f;
lastFadeCheck = System.currentTimeMillis();
synchronized( soundSequenceLock )
{
if( soundSequenceQueue == null )
soundSequenceQueue = new LinkedList<FilenameURL>();
soundSequenceQueue.clear();
soundSequenceQueue.add( filenameURL );
}
}
/**
* Resets this source's volume if it is fading out or in. Returns true if this
* source is currently in the process of fading out. When fade-out completes,
* this method transitions the source to the next sound in the sound sequence
* queue if there is one. This method has no effect on non-streaming sources.
* @return True if this source is in the process of fading out.
*/
public boolean checkFadeOut()
{
if( !toStream )
return false;
if( fadeOutGain == -1.0f && fadeInGain == 1.0f )
return false;
long currentTime = System.currentTimeMillis();
long milisPast = currentTime - lastFadeCheck;
lastFadeCheck = currentTime;
if( fadeOutGain >= 0.0f )
{
if( fadeOutMilis == 0 )
{
fadeOutGain = -1.0f;
fadeInGain = 0.0f;
if( !incrementSoundSequence() )
{
stop();
}
positionChanged();
preLoad = true;
return false;
}
else
{
float fadeOutReduction = ((float)milisPast) / ((float)fadeOutMilis);
fadeOutGain -= fadeOutReduction;
if( fadeOutGain <= 0.0f )
{
fadeOutGain = -1.0f;
fadeInGain = 0.0f;
if( !incrementSoundSequence() )
stop();
positionChanged();
preLoad = true;
return false;
}
}
positionChanged();
return true;
}
if( fadeInGain < 1.0f )
{
fadeOutGain = -1.0f;
if( fadeInMilis == 0 )
{
fadeOutGain = -1.0f;
fadeInGain = 1.0f;
}
else
{
float fadeInIncrease = ((float)milisPast) / ((float)fadeInMilis);
fadeInGain += fadeInIncrease;
if( fadeInGain >= 1.0f )
{
fadeOutGain = -1.0f;
fadeInGain = 1.0f;
}
}
positionChanged();
return true;
}
return false;
}
/**
* Removes the next filename/URL from the sound sequence queue and assigns it to
* this source. This method has no effect on non-streaming sources. This
* method is used internally by SoundSystem, and it is unlikely that the user
* will ever need to use it.
* @return True if there was something in the queue.
*/
public boolean incrementSoundSequence()
{
if( !toStream )
{
errorMessage( "Method 'incrementSoundSequence' may only be used " +
"for streaming and MIDI sources." );
return false;
}
synchronized( soundSequenceLock )
{
if( soundSequenceQueue != null && soundSequenceQueue.size() > 0 )
{
filenameURL = soundSequenceQueue.remove( 0 );
if( codec != null )
codec.cleanup();
codec = SoundSystemConfig.getCodec( filenameURL.getFilename() );
return true;
}
}
return false;
}
/**
* Returns the size of the sound sequence queue (if this is a streaming source).
* @return Number of sounds left in the queue, or zero if none.
*/
public int getSoundSequenceQueueSize()
{
if( soundSequenceQueue == null )
return 0;
return soundSequenceQueue.size();
}
/**
* Sets whether or not this source should be removed when it finishes playing.
* @param tmp True or false.
*/
public void setTemporary( boolean tmp )
{
temporary = tmp;
}
/**
* Called every time the listener's position or orientation changes.
*/
public void listenerMoved()
{}
/**
* Moves the source to the specified position.
* @param x X coordinate to move to.
* @param y Y coordinate to move to.
* @param z Z coordinate to move to.
*/
public void setPosition( float x, float y, float z )
{
position.x = x;
position.y = y;
position.z = z;
}
/**
* Called every time the source changes position.
*/
public void positionChanged()
{}
/**
* Sets whether or not this source is a priority source. A priority source
* will not be overritten by another source if there are no channels available
* to play on.
* @param pri True or false.
*/
public void setPriority( boolean pri )
{
priority = pri;
}
/**
* Sets whether this source should loop or only play once.
* @param lp True or false.
*/
public void setLooping( boolean lp )
{
toLoop = lp;
}
/**
* Sets this source's attenuation model.
* @param model Attenuation model to use.
*/
public void setAttenuation( int model )
{
attModel = model;
}
/**
* Sets this source's fade distance or rolloff factor, depending on the
* attenuation model.
* @param dr New value for fade distance or rolloff factor.
*/
public void setDistOrRoll( float dr)
{
distOrRoll = dr;
}
/**
* Sets this source's velocity, for use in Doppler effect.
* @param x Velocity along world x-axis.
* @param y Velocity along world y-axis.
* @param z Velocity along world z-axis.
*/
public void setVelocity( float x, float y, float z )
{
this.velocity.x = x;
this.velocity.y = y;
this.velocity.z = z;
}
/**
* Returns the source's distance from the listener.
* @return How far away the source is.
*/
public float getDistanceFromListener()
{
return distanceFromListener;
}
/**
* Manually sets the specified source's pitch.
* @param value A float value ( 0.5f - 2.0f ).
*/
public void setPitch( float value )
{
float newPitch = value;
if( newPitch < 0.5f )
newPitch = 0.5f;
else if( newPitch > 2.0f )
newPitch = 2.0f;
pitch = newPitch;
}
/**
* Returns the pitch of the specified source.
* @return Float value representing the source pitch (0.5f - 2.0f).
*/
public float getPitch()
{
return pitch;
}
/**
* Indicates whether or not this source's associated library requires some
* codecs to reverse-order the audio data they generate.
* @return True if audio data should be reverse-ordered.
*/
public boolean reverseByteOrder()
{
return SoundSystemConfig.reverseByteOrder( libraryType );
}
/**
* Changes the sources peripheral information to match the supplied parameters.
* @param priority Setting this to true will prevent other sounds from overriding this one.
* @param toStream Setting this to true will create a streaming source.
* @param toLoop Should this source loop, or play only once.
* @param sourcename A unique identifier for this source. Two sources may not use the same sourcename.
* @param filenameURL Filename/URL of the sound file to play at this source.
* @param x X position for this source.
* @param y Y position for this source.
* @param z Z position for this source.
* @param attModel Attenuation model to use.
* @param distOrRoll Either the fading distance or rolloff factor, depending on the value of 'att'.
* @param temporary Whether or not to remove this source after it finishes playing.
*/
public void changeSource( boolean priority, boolean toStream,
boolean toLoop, String sourcename,
FilenameURL filenameURL, SoundBuffer soundBuffer,
float x, float y, float z, int attModel,
float distOrRoll, boolean temporary )
{
this.priority = priority;
this.toStream = toStream;
this.toLoop = toLoop;
this.sourcename = sourcename;
this.filenameURL = filenameURL;
this.soundBuffer = soundBuffer;
position.x = x;
position.y = y;
position.z = z;
this.attModel = attModel;
this.distOrRoll = distOrRoll;
this.temporary = temporary;
}
/**
* Feeds raw data to the specified channel.
* @param buffer Byte buffer containing raw audio data to stream.
* @param c Channel to stream on.
* @return Number of prior buffers that have been processed, or -1 if unable to queue the buffer (if the source was culled, for example).
*/
public int feedRawAudioData( Channel c, byte[] buffer )
{
if( !active( GET, XXX) )
{
toPlay = true;
return -1;
}
if( channel != c )
{
channel = c;
channel.close();
channel.setAudioFormat( rawDataFormat );
positionChanged();
}
// change the state of this source to not stopped and not paused:
stopped( SET, false );
paused( SET, false );
return channel.feedRawAudioData( buffer );
}
/**
* Plays the source on the specified channel.
* @param c Channel to play on.
*/
public void play( Channel c )
{
if( !active( GET, XXX) )
{
if( toLoop )
toPlay = true;
return;
}
if( channel != c )
{
channel = c;
channel.close();
}
// change the state of this source to not stopped and not paused:
stopped( SET, false );
paused( SET, false );
}
/* END Override methods */
/**
* Streams the source on its current channel
* @return False when stream has finished playing.
*/
public boolean stream()
{
if( channel == null )
return false;
if( preLoad )
{
if( rawDataStream )
preLoad = false;
else
return preLoad();
}
if( rawDataStream )
{
if( stopped() || paused() )
return true;
if( channel.buffersProcessed() > 0 )
channel.processBuffer();
}
else
{
if( codec == null )
return false;
if( stopped() )
return false;
if( paused() )
return true;
int processed = channel.buffersProcessed();
SoundBuffer buffer = null;
for( int i = 0; i < processed; i++ )
{
buffer = codec.read();
if( buffer != null )
{
if( buffer.audioData != null )
channel.queueBuffer( buffer.audioData );
buffer.cleanup();
buffer = null;
}
if( codec.endOfStream() )
return false;
}
}
return true;
}
/**
* Queues up the initial stream-buffers for the stream.
* @return False if the end of the stream was reached.
*/
public boolean preLoad()
{
if( channel == null )
return false;
if( codec == null )
return false;
URL url = filenameURL.getURL();
codec.initialize( url );
SoundBuffer buffer = null;
for( int i = 0; i < SoundSystemConfig.getNumberStreamingBuffers(); i++ )
{
buffer = codec.read();
if( buffer != null )
{
if( soundBuffer.audioData != null )
channel.queueBuffer( soundBuffer.audioData );
buffer.cleanup();
buffer = null;
}
}
return true;
}
/**
* Pauses the source.
*/
public void pause()
{
toPlay = false;
paused( SET, true );
if( channel != null )
channel.pause();
else
errorMessage( "Channel null in method 'pause'" );
}
/**
* Stops the source.
*/
public void stop()
{
toPlay = false;
stopped( SET, true );
paused( SET, false );
if( channel != null )
channel.stop();
else
errorMessage( "Channel null in method 'stop'" );
}
/**
* Rewinds the source. If the source was paused, then it is stopped.
*/
public void rewind()
{
if( paused( GET, XXX ) )
{
stop();
}
if( channel != null )
{
boolean rePlay = playing();
channel.rewind();
if( toStream && rePlay )
{
stop();
play( channel );
}
}
else
errorMessage( "Channel null in method 'rewind'" );
}
/**
* Dequeues any previously queued data.
*/
public void flush()
{
if( channel != null )
channel.flush();
else
errorMessage( "Channel null in method 'flush'" );
}
/**
* Stops and flushes the source, and prevents it from being played again until
* the activate() is called.
*/
public void cull()
{
if( !active( GET, XXX ) )
return;
if( playing() && toLoop )
toPlay = true;
if( rawDataStream )
toPlay = true;
active( SET, false );
if( channel != null )
channel.close();
channel = null;
}
/**
* Allows a previously culled source to be played again.
*/
public void activate()
{
active( SET, true );
}
/**
* Returns false if the source has been culled.
* @return True or False
*/
public boolean active()
{
return active( GET, XXX );
}
/**
* Returns true if the source is playing.
* @return True or False
*/
public boolean playing()
{
if( channel == null || channel.attachedSource != this )
return false;
else if( paused() || stopped() )
return false;
else
return channel.playing();
}
/**
* Returns true if the source has been stopped.
* @return True or False
*/
public boolean stopped()
{
return stopped( GET, XXX );
}
/**
* Returns true if the source has been paused.
* @return True or False
*/
public boolean paused()
{
return paused( GET, XXX );
}
/**
* Returns the number of miliseconds since the source began playing.
* @return miliseconds, or -1 if not playing or unable to calculate
*/
public float millisecondsPlayed()
{
if( channel == null )
return( -1 );
else
return channel.millisecondsPlayed();
}
/**
* Sets or returns whether or not the source has been culled.
* @return True or False
*/
private synchronized boolean active( boolean action, boolean value )
{
if( action == SET )
active = value;
return active;
}
/**
* Sets or returns whether or not the source has been stopped.
* @return True or False
*/
private synchronized boolean stopped( boolean action, boolean value )
{
if( action == SET )
stopped = value;
return stopped;
}
/**
* Sets or returns whether or not the source has been paused.
* @return True or False
*/
private synchronized boolean paused( boolean action, boolean value )
{
if( action == SET )
paused = value;
return paused;
}
/**
* Returns the name of the class.
* @return SoundLibraryXXXX.
*/
public String getClassName()
{
String libTitle = SoundSystemConfig.getLibraryTitle( libraryType );
if( libTitle.equals( "No Sound" ) )
return "Source";
else
return "Source" + libTitle;
}
/**
* Prints a message.
* @param message Message to print.
*/
protected void message( String message )
{
logger.message( message, 0 );
}
/**
* Prints an important message.
* @param message Message to print.
*/
protected void importantMessage( String message )
{
logger.importantMessage( message, 0 );
}
/**
* Prints the specified message if error is true.
* @param error True or False.
* @param message Message to print if error is true.
* @return True if error is true.
*/
protected boolean errorCheck( boolean error, String message )
{
return logger.errorCheck( error, getClassName(), message, 0 );
}
/**
* Prints an error message.
* @param message Message to print.
*/
protected void errorMessage( String message )
{
logger.errorMessage( getClassName(), message, 0 );
}
/**
* Prints an exception's error message followed by the stack trace.
* @param e Exception containing the information to print.
*/
protected void printStackTrace( Exception e )
{
logger.printStackTrace( e, 1 );
}
}