缓存声音并创建它的实例

Cache a sound and create instaces of it

我目前正在编写游戏,现在我也想添加声音。我目前的方法工作正常,但我对此并不满意。

new Sound(new Resource().readAndGetStream("small_click.wav")).play();

这行代码在执行时读取文件 small_click.wav。但是我觉得一直在需要的时候去读取资源文件效率不是很高。 所以我现在想做的是将声音缓存在变量或其他东西中,而不必再次从文件中加载声音。但我也想从声音中创建一个新对象,这样我就可以多次播放它并且它在扬声器中 重叠

我找不到执行此操作的方法。我已经尝试使用线程但是..这段代码没有任何线程。

如果你想知道,这里是Sound的代码class:

public Sound(InputStream audioSrc) {
    try {
        InputStream bufferedIn = new BufferedInputStream(audioSrc);
        AudioInputStream audioStream = AudioSystem.getAudioInputStream(bufferedIn);
        clip = AudioSystem.getClip();
        clip.open(audioStream);
    } catch {
        ...exception handling...
    }

}

public void play() {
    clip.setFramePosition(0);
    clip.start();
}

如果您想知道 "new Resource().readAndGetStream()" 的作用: 它基本上加载一个资源和 returns 该资源的 InputStream getResourceAsStream().

使用您拥有的声音 class,您可以轻松创建 "cache"。例如,创建一个 Sound[] soundCache 类型的数组并执行您在示例中给出的代码行的第一部分。

soundCache[0] = new Sound(new Resource().readAndGetStream("small_click.wav"));

你甚至可以考虑让常数对应于每个声音。

final int SMALL_CLICK = 0;

然后,当需要播放声音时,执行播放函数。

soundCache[SMALL_CLICK].play();

从这里到同时播放给定的声音要复杂得多。如果继续以 Clip 作为基础,我不知道有什么方法可以重叠播放相同的声音资源,除非制作和管理尽可能多的 Clip 副本允许立即听到。

面对这个编码挑战,我最终编写了自己的库,AudioCue。它在 Github 上可用,并且具有非常宽松的许可证。

基本概念是将音频数据存储在一个带符号的 PCM 浮点数组中,并通过多个 "cursors" 来管理并发播放,这些 "cursors" 可以独立地遍历 PCM 数据并将其提供给 SourceDataLine.

这些游标可以实时管理。您可以更改它们在数据中传播的速率并缩放数据的体积级别,从而允许频率和体积变化。

我尽最大努力使 API 与 Clip 相似,以便熟悉 Java 的编码人员易于使用 class ]的Clip.

随时检查 ideas/examples 的代码或在您的项目中使用此库。