Sound Application
Hi,
I am using the following class (that I found on these forums) to play long songs in my application.
import java.io.*;
import javax.sound.sampled.*;
import javax.sound.sampled.DataLine.*;
publicclass SoundPlayerimplements LineListener
{
privatefloat bufTime;
private File soundFile;
private SourceDataLine line;
private AudioInputStream stream;
private AudioFormat format;
private Info info;
privateboolean opened;
privateint frameSize;
privatelong frames;
privateint bufFrames;
privateint bufsize;
privateboolean running;
privateboolean shutdown;
privatelong firstFrame, lastFrame;
privatefloat frameRate;
privatelong currentFrame;
privatefloat currentTime;
private Thread playThread;
// constructor, take a path to an audio file
public SoundPlayer(String path)
{
this(path, 2);// use 2 second buffer
}
// or a path and a buffer size
public SoundPlayer(String path,float bt)
{
this(new File(path),bt);
}
public SoundPlayer(File sf)
{
this(sf, 2);// use 2 second buffer
}
public SoundPlayer(File sf,float bt)
{
bufTime = bt;// seconds per buffer
soundFile = sf;
openSound();
}
privatevoid openSound()
{
System.out.println("Opening file"+soundFile.getName());
try
{
firstFrame = 0;
currentFrame = 0;
shutdown =false;
running =false;
stream=AudioSystem.getAudioInputStream(soundFile);
format=stream.getFormat();
if(format.getEncoding() != AudioFormat.Encoding.PCM_SIGNED)
{
System.out.println("Converting Audio stream format");
stream = AudioSystem.getAudioInputStream(AudioFormat.Encoding.PCM_SIGNED,stream);
format = stream.getFormat();
}
frameSize = format.getFrameSize();
frames = stream.getFrameLength();
lastFrame = frames;
frameRate = format.getFrameRate();
bufFrames = (int)(frameRate*bufTime);
bufsize = frameSize * bufFrames;
System.out.println("frameRate="+frameRate);
System.out.println("frames="+frames+" frameSize="+frameSize+" bufFrames="+bufFrames+" bufsize="+bufsize);
info=new Info(SourceDataLine.class,format,bufsize);
line = (SourceDataLine)AudioSystem.getLine(info);
line.addLineListener(this);
line.open(format,bufsize);
opened =true;
}
catch(Exception e)
{
e.printStackTrace();
}
}
publicvoid stop()
{
System.out.println ("Stopping");
if(running)
{
running =false;
shutdown =true;
if(playThread !=null)
{
playThread.interrupt();
try{playThread.join();}
catch(Exception e){e.printStackTrace();}
}
}
if (opened) close();
}
privatevoid close()
{
System.out.println("close line");
line.close();
try{stream.close();}catch(Exception e){}
line.removeLineListener(this);
opened =false;
}
// set the start and stop time
publicvoid setTimes(float t0,float tz)
{
currentTime = t0;
firstFrame = (long)(frameRate*t0);
if(tz > 0)
lastFrame = (long)(frameRate*tz);
else lastFrame = frames;
if(lastFrame > frames)lastFrame = frames;
if(firstFrame > lastFrame)firstFrame = lastFrame;
}
publicvoid playAsync(float start,float end)
{
setTimes(start,end);
playAsync();
}
// play the sound asynchronously */
publicvoid playAsync()
{
System.out.println("Play async");
if(!opened)openSound();
if(opened && !running)
{
playThread =new Thread(new Runnable(){publicvoid run(){play();}});
playThread.start();
}
}
publicvoid play(float start,float end)
{
setTimes(start,end);
play();
}
// play the sound in the calling thread
publicvoid play()
{
if(!opened)openSound();
if(opened && !running)
{
running =true;
int writeSize = frameSize*bufFrames/2;// amount we write at a time
byte buf[] =newbyte[writeSize];// our io buffer
int len;
long framesRemaining = lastFrame-firstFrame;
int framesRead;
currentFrame=firstFrame;
System.out.println("playing file, firstFrame="+firstFrame+" lastFrame="+lastFrame);
try
{
line.start();
if(firstFrame > 0)
{
long sa = firstFrame * frameSize;
System.out.println("Skipping "+firstFrame+" frames="+sa+" bytes");
while(sa > 0)sa -= stream.skip(sa);
}
while (running && framesRemaining > 0)
{
len = stream.read(buf,0,writeSize);// read our block
if(len > 0)
{
framesRead = len/frameSize;
framesRemaining -= framesRead;
currentTime = currentFrame/frameRate;
if(currentTime < 0)throw(new Exception("time too low"));
System.out.println("time="+currentTime+" writing "+len+" bytes");
line.write(buf,0,len);
currentFrame+=framesRead;
}
else framesRemaining = 0;
}
if(running)
{
line.drain();// let it play out
while(line.isActive() && running)
{
System.out.println("line active");
Thread.sleep(100);
}
shutdown =true;
}
running =false;
}
catch(Exception e)
{
e.printStackTrace();
shutdown =true;
running =false;
}
if(shutdown)
{
close();
}
}
}
// return current time relative to start of sound
publicfloat getTime()
{
return ((float)line.getMicrosecondPosition())/1000000;
}
// return total time
publicfloat getLength()
{
return (float)frames / frameRate;
}
// stop the sound playback, return time in seconds
publicfloat pause()
{
running =false;
line.stop();
return getTime();
}
publicvoid update(LineEvent le)
{
System.out.println("Line event"+le.toString());
}
// play a short simple PCM encoded clip
publicstaticvoid playShortClip(String fnm)
{
java.applet.AudioClip clip=null;
try
{
java.io.File file =new java.io.File(fnm);// get a file for the name provided
if(file.exists())// only try to use a real file
{
clip = java.applet.Applet.newAudioClip(file.toURL());// get the audio clip
}
else
System.out.println("file="+fnm+" not found");
}
catch(Exception e)
{
System.out.println("Error building audio clip from file="+fnm);
e.printStackTrace();
}
if(clip !=null)// we may not actually have a clip
{
final java.applet.AudioClip rclip = clip;
new Thread
(new Runnable()
{
publicvoid run()
{
rclip.play();
}
}
).start();
}
}
publicboolean isOpened()
{
return opened;
}
publicboolean isRunning()
{
return running;
}
}
However, when the song is playing, everything stops. Does anyone have any suggestions on how to fix this? Thanks ahead of time.

