Reputation: 23
I have a game where sound effects are played using this method:
AudioInputStream inputStream = AudioSystem.getAudioInputStream(
TheGame.class.getResource(url));
Clip clip = AudioSystem.getClip();
clip.open(inputStream);
clip.start();
However, not closing the clips obviously builds up memory, and the fixes I've tried cause the game to freeze up occasionally. I tried :
I'm not sure why closing clips seems to take so much time that it freezes up the entire game, is there a more time-efficient way?
Here is the code for the LineListener's update method I'm using:
@Override
public void update(LineEvent event) {
if (event.getType() == LineEvent.Type.STOP){
Clip c = (Clip) event.getSource();
c.close();
c.removeLineListener(this);
}
}
Upvotes: 2
Views: 183
Reputation: 44191
As per my comment above, you should reuse the existing Clip
object.
Map<String, Clip> clips = new HashMap<String, Clip>();
public synchronized void play(String url) {
Clip clip = clips.get(url);
if(clip == null) {
AudioInputStream inputStream = AudioSystem.getAudioInputStream(
TheGame.class.getResource(url));
Clip clip = AudioSystem.getClip();
clip.open(inputStream);
clips.put(url, clip);
}
if(clip.isRunning())
clip.stop();
clip.setFramePosition(0);
clip.start();
}
You will need to get a bit more creative if you need to overlap the same sound with itself. Note that I have placed this in a synchronized
method to protect the Map
from concurrent modification if you should happen to be calling this from multiple threads.
Upvotes: 3