/**
* Copyright (c) 2003-2009, Xith3D Project Group all rights reserved.
*
* Portions based on the Java3D interface, Copyright by Sun Microsystems.
* Many thanks to the developers of Java3D and Sun Microsystems for their
* innovation and design.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the 'Xith3D Project Group' nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) A
* RISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE
*/
package org.xith3d.sound.drivers.javasound;
import java.util.ArrayList;
import java.util.List;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.Mixer;
import org.openmali.vecmath2.Point3f;
import org.openmali.vecmath2.Tuple3f;
import org.xith3d.sound.SoundBuffer;
import org.xith3d.sound.SoundContainer;
import org.xith3d.sound.SoundDriver;
import org.xith3d.sound.SoundSource;
import org.xith3d.sound.SoundState;
/**
* JavaSound implementation of the SoundSource.
*
* @author David Yazel
*/
public class SoundSourceImpl implements SoundSource
{
private List< SoundBuffer > queue = new ArrayList< SoundBuffer >();
private Clip clip;
private SoundDriver driver;
private SoundState state;
private Point3f position = new Point3f();
private int loopCount = 0;
public SoundSourceImpl( SoundDriver driver )
{
this.driver = driver;
state = SoundState.INITIAL;
}
public Mixer getMixer()
{
// TODO (yvg): Select compatible non-buggy Mixer (if we found one)
Mixer.Info[] mixers = AudioSystem.getMixerInfo();
for ( int i = 0; i < mixers.length; i++ )
{
if ( mixers[ i ].getName().equals( "Java Sound Audio Engine" ) )
{
return ( AudioSystem.getMixer( mixers[ i ] ) );
}
}
return ( null );
}
public void setBuffer( SoundBuffer buffer )
{
try
{
SoundBufferImpl sb = (SoundBufferImpl)buffer;
Mixer mix = getMixer();
// Use selected (compatible) Mixer, or fall back to default system Mixer
// if no compatible one found
if ( mix != null )
clip = (Clip)mix.getLine( ( (SoundBufferImpl)buffer ).getInfo() );
else
clip = (Clip)AudioSystem.getLine( ( (SoundBufferImpl)buffer ).getInfo() );
clip.open( sb.af, sb.data, 0, sb.size );
}
catch ( LineUnavailableException e )
{
e.printStackTrace(); // To change body of catch statement use
// Options | File Templates.
throw new Error( e );
}
}
public void close()
{
if ( clip != null )
{
clip.close();
clip = null;
}
state = SoundState.INITIAL;
}
public void queueBuffer( SoundBuffer buffer )
{
queue.add( buffer );
}
public void setContainer( SoundContainer container )
{
SoundBuffer sb = container.getData( driver );
if ( sb != null )
{
setBuffer( sb );
}
}
public void play()
{
if ( clip == null )
{
if ( queue.size() > 0 )
{
SoundBufferImpl sb = (SoundBufferImpl)queue.remove( 0 );
setBuffer( sb );
}
else
return;
}
// Clip.loop() also starts clip playback
// clip.start();
clip.loop( loopCount );
state = SoundState.PLAYING;
}
public void pause()
{
if ( clip != null )
clip.stop();
state = SoundState.PAUSED;
}
public void rewind()
{
if ( clip != null )
clip.setFramePosition( 0 );
}
public void stop()
{
if ( clip != null )
clip.stop();
state = SoundState.STOPPED;
}
public boolean isPlaying()
{
return ( getState() == SoundState.PLAYING );
}
public void setPosition( float posX, float posY, float posZ )
{
this.position.set( posX, posY, posZ );
}
public void setPosition( Tuple3f position )
{
this.position.set( position );
}
public void setVelocity( float veloX, float veloY, float veloZ )
{
}
public void setVelocity( Tuple3f velocity )
{
}
public void setDirection( float dirX, float dirY, float dirZ )
{
}
public void setDirection( Tuple3f direction )
{
}
public SoundState getState()
{
return ( state );
}
public void setVolume( float gain )
{
}
public void setReferenceDistance( float refDistance )
{
}
public void setRolloffFactor( float factor )
{
}
public void setRelative( boolean relative )
{
}
public void setLoop( boolean loop )
{
if ( clip != null )
{
loopCount = ( loop ? Clip.LOOP_CONTINUOUSLY : 0 );
// Defer setting of clip loop because of loop also starts playback
// in JavaSound
if ( isPlaying() )
clip.loop( loopCount );
}
}
public void setMaxVolume( float maxVolume )
{
}
public void setMinVolume( float minVolume )
{
}
public void setMaxDistance( float maxDistance )
{
}
public void setMaxTime( long ms )
{
}
public SoundDriver getSoundDriver()
{
return ( driver );
}
}