Java 声音 API 初始化

发布于 2024-10-21 21:20:23 字数 996 浏览 1 评论 0原文

我使用以下代码在游戏中播放声音。

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 java.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();
    }
}

问题是:如果第一次播放声音,应用程序会挂起一小段时间,因为需要完成某种初始化工作。此后播放的每个声音都不会表现出这种行为。如何预防呢?

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 java.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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

尝蛊 2024-10-28 21:20:23

我也遇到过这个问题,我的经验是,这与剪辑的大小无关,而是与您第一次尝试启动剪辑时加载许多类有关,因为加载许多 JavaSound 类的开销。

如果将参数 -verbose:class 添加到 java,您也可能会看到此问题。

对我有用的是有一个没有任何音频的silent.wav 文件。我在主声音开始之前预先播放它,它让一切都准备好了。

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.

浅唱々樱花落 2024-10-28 21:20:23

首先,与 Java Media Framework 之类的东西相比,Java 的声音库相当弱,您可能会研究一下,但如果这是一个具有最小音效的简单游戏,Java 的声音库应该足够了。您可能需要提供有关您想要播放的声音文件类型(格式、长度等)的更多详细信息,以便我们更好地解决您的问题。

如果您想播放简短的声音片段(少于一秒),您应该在开始时初始化 Clip,并在需要时播放它:

//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();

这样做的问题是 Clip 的缓冲区非常有限,您不会能够远程长时间播放任何内容(根据我的经验,平均>1秒)。

如果您想播放背景音乐或更长时间,并且希望避免自己管理字节流,则必须查看外部库。有一个 BigClip 类,我似乎找不到下载链接,但您可以看看:

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

当我必须播放更长的声音时,我使用自己的此处找到的 PCMFilePlayer 类的修改版本(我添加了一些额外的方法以使其更像 BigClip):

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

在任何一种情况下,我都会加载尽可能多的合理声音节目开始时,需要播放,但在所有情况下,声音的数量都非常有限。如果您正在播放大量声音/音乐或担心内存使用情况,您可能需要查看 JMF 等库,它们功能更强大。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文