Java - 一次多次播放相同的声音

时间:2015-03-05 22:19:32

标签: audio

我正在开发一款游戏,并且我有一些问题会多次播放相同的声音,就像你激活一个已播放的声音一样,它不能取消第一个声音。我在Stackoverflow上找到的解决方案是将其读入一个字节数组,我按以下方式执行:

public SoundObject(AudioInputStream audioIn) {

    try {
        af = audioIn.getFormat();
        size = (int) (af.getFrameSize() * audioIn.getFrameLength());
        audio = new byte[size];
        info = new DataLine.Info(Clip.class, af, size);
        audioIn.read(audio, 0, size);

    } catch (IOException e) {
        e.printStackTrace();
    }
}

public void playSound() {
    try {
        Clip localSound = (Clip) AudioSystem.getLine(info);
        localSound.open(af, audio, 0, size);
        localSound.start();
    } catch (LineUnavailableException e) {
        e.printStackTrace();
    }

}

直到现在我才尝试将它导出到一个jar文件中,因为某种原因,jar文件出现了一个字节数组的问题,导致声音在几毫秒后切断,我设法找到一个在有人提出以下解决方案的同一问题上发帖:

    public SoundObject(String filePath) {
    try {
        AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(Loader.class.getResource(filePath));
        clip = AudioSystem.getClip();
        clip.open(audioInputStream);
    } catch (IOException e) {
        e.printStackTrace();
    } catch (LineUnavailableException e) {
        e.printStackTrace();
    } catch (UnsupportedAudioFileException e) {
        e.printStackTrace();
    }
}

// Play the sound in a separate thread.
public void playSound() {
    Runnable soundPlayer = new Runnable() {

        @Override
        public void run() {
            try {
                clip.setMicrosecondPosition(0);
                clip.start();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    };
    new Thread(soundPlayer).start();
}

使用第二种方法适用于jar文件,但问题是声音不像以前那样好玩,我有一个拍摄功能,如果拍得很快,这个方法并不总是选择当我按空间拍摄时,有时无法发出声音。因此,对于这两种解决方案,我必须选择具有不可靠的声音而不能始终播放,或者我无法将其导出到可运行的JAR。

有没有人有这类问题的经验?

编辑:这是一个剪辑,向您展示2个罐子的工作原理:https://www.youtube.com/watch?v=wZPOIhHZSJM&

1 个答案:

答案 0 :(得分:0)

我建议尝试使用TinySound库。它是免费代码,可在github上找到。此代码提供了一个最小的混音器,并且可以同时播放剪辑。

我很难搞清楚代码可能出现的问题。我还制作了一个我在游戏中使用的调音台,它支持剪辑的并发播放。我将声音存储在介于-1到1之间的浮点数。每个播放实例从预先制作的池(它限制并发播放的数量)中获取一个光标,该光标跟踪浮点数组中的位置,并在同时进行查询和递增循环,其中各种声音被加在一起(简单添加)并转换为通过SourceDataLine输出的字节。如果你决定走这条路,这就是基本计划。

通过创建一个线程池,让你的声音尽可能接近准备在被叫时播放,你可以在第二次设置中获得更高的效率。使用混音器,您只需要一个音频线程。

第一个例子中是否有任何错误?从给出的代码中,我没有看到为什么声音因使用jar而被切断。切断它们的东西,比如另一个声音,还是调用线程的结尾?