开发者

Java Sound API Initialization

I use the following code to play back sound in my game.

import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import ja开发者_JS百科va.io.IOException;

public class AudioController {

    public static void playback(String fileName) 
        throws LineUnavailableException, UnsupportedAudioFileException, IOException {
        AudioInputStream ais = AudioSystem.getAudioInputStream(AudioController.class.getClassLoader().getResourceAsStream("sounds/"+fileName));

        AudioFormat format = ais.getFormat();
        DataLine.Info info = new DataLine.Info(Clip.class, format);
        Clip clip = (Clip) AudioSystem.getLine(info);

        clip.open(ais);
        clip.start();
    }
}

The problem is: if a sound is played back for the very first time, the application hangs for a short time, as some sort of initialization work would be done. Every sound played after that does not show this behavior. How to prevent that?


I've run into this issue too, and my experience is that it doesn't have to do with the size of your clip, but rather the fact that lots of classes get loaded the first time you try to start a clip due to the overhead of many JavaSound classes being loaded.

If you add the the argument -verbose:class to java you may see this issue too.

What works for me is to have a silent.wav file that doesn't have any audio. I play it up front before the main sound starts and it gets everything primed.


First of all, Java's sound library is rather weak compared to something like Java Media Framework, which you might look into, but if this is a simple game with minimal sound effects, Java's sound library should be enough. You may want to give more details on what type of sound files you want to play (format, length, etc) so we can better address your problem.

If you want to play short clips of sound (less than a second) you should initialize the Clip at the start, and play it whenever you need it:

//initialize this at the beginning of your program
AudioInputStream soundStream = AudioSystem.getAudioInputStream(new File("sound.wav"));

Clip soundEffect = AudioSystem.getClip();
soundEffect.open(soundStream);

...

//later, play the sound
soundEffect.start();

The issue with this is that Clip has a very limited buffer, and you won't be able to play anything remotely long (>1 second on average, in my experience).

If you want to play background music, or something longer, and want to avoid managing byte streams yourself, you'll have to look at outside libraries. There exists a BigClip class that I can't seem to find a download link for, but you can have a look:

http://pscode.org/javadoc/org/pscode/xui/sound/bigclip/BigClip.html

When I've had to play longer sound I use my own modified version of the PCMFilePlayer class found here (I add some extra methods to make it work more like a BigClip):

http://codeidol.com/java/swing/Audio/Play-Non-Trivial-Audio/

In either case, I load up as much sound as is reasonable at the very beginning of the program, and play has needed, but in all cases this has been with a very limited number of sounds. If you're playing huge amounts of sound/music or worry about memory usage, you may want to look into libraries like JMF, which are much more powerful.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜