Reputation: 37
Let's say I've a main GameLoop
Inside this loop I have my Game Updates
I'm handling my Events for Sprite collision testing with each Iteration
If collision is true, play audio file
Here's where the problem occurs
The Audio clip will either play Rapidly, while the game is frozen
or
It will play w/ delay like I want but the entire Game comes to a halt other than the Audio Clip.
I'm just looking for some tips on Threading Basically. As far as i'm aware it'll be the best way to handle this problem and I can't seem to get it running correctly.
Note I would extend Thread on main class but already extends Canvas, needed.
public Main()
{
boolean running = true;
while(running)
{
// check for collision (returns boolean)
// if true proceed to execute Entity.doLogic()
// this then activates the AudioClip class' .playAudioClip(this, path)
// the audio Clip is then played and once it's done it'll return
// returns and instantly goes back to playing again
// meanwhile the loop Freezes up on me.
}
}
And This is the actual Sound.class
public class Sounds
{
public void startSound()
{
String path = "path";
playAudioClip(game, path);
}
public void playAudioClip(String path)
{
try
{
Clip clip = AudioSystem.getClip();
clip.open(AudioSystem.getAudioInputStream(new File(path)));
clip.start();
}
catch(Exception e)
{
System.out.println("Problem loading audio file");
}
try{Thread.sleep(500);}catch(Exception ex){System.out.println("Problem with Sleep");};
}
}
I've tried the below and same situation (Calling it by s.start() and s.run() no difference) using .start() would throw err in thread, will recreate real quick and share)
public class Sounds extends Thread
{
@Override
public void run()
{
String path = "path";
playAudioClip(game, path);
}
public void playAudioClip(String path)
{
try
{
Clip clip = AudioSystem.getClip();
clip.open(AudioSystem.getAudioInputStream(new File(path)));
clip.start();
}
catch(Exception e)
{
System.out.println("Problem loading audio file");
}
try{Thread.sleep(500);}catch(Exception ex){System.out.println("Problem with Sleep");};
}
}
throws to console "java.lang.IllegalThreadStateException" invoking with start() only defining run() inside of this object
Multithreading in the wrong way prime example 243 max threads going at any point there
Upvotes: 0
Views: 452
Reputation: 7910
When the start()
method of a Clip
executes, the sound is played via a daemon thread created just for that purpose. There is no need for you to create a Thread
and no need to include the Thread.sleep()
command. As long as your program is running, the sound will execute. If your program stops while the sound is still playing, because it's on a daemon, the sound will not finish, but will stop along with the program.
My guess is that your code came from an example program who's only task is to play a sound. A better demo example would have shown how to manage a Clip
in the context of a larger program.
Here is a class to try. I've omitted the Exception
handling. I use URL
because that allows one to get resources even if the program has been compiled into a jar. In terms of file structure, the code assumes that the sound files are in a subfolder relative to the location of your Sounds
class.
public class Sounds
{
private Clip clip;
public Sounds(String soundFileName)
{
URL url = this.class.getResource("audio/" + soundFileName);
AudioInputStream ais = AudioSystem.getAudioInputStream(url);
DataLine.Info info = new DataLine.Info(Clip.class, ais.getFormat());
clip = (Clip) AudioSystem.getLine(info);
clip.open(ais);
}
public void playAudioClip()
{
clip.setFramePosition(0);
clip.start();
}
}
The Clip
class was designed for sounds that are held in memory. If you don't want to hold you sound file in memory, you should use SourceDataLine
, as it will launch more quickly and only holds a buffer's worth of data at a time in memory instead of the entire file.
Thus, we make the Clip
an instance variable, and load and open it as part of the instantiation process.
The command clip.setFramePosition(0)
is there so that any time you call the Clip
, it will start playing from the beginning of the file. With this, you can call and play the Clip
at any time. Worst case scenario, if it is in the middle of playing when you call it, the sound will jump back to the beginning and start anew.
Upvotes: 0