0

我正在用Java制作游戏。我希望有大约 100 个不同的样本,并且在任何给定时间,都可以播放 10 个样本。但是,对于这 10 个样本中的每一个,我都希望能够操纵它们的音量和平移。

截至目前,我要求如下一行:new DataLine.Info(Clip.class, format);

我没有指定此行所需的控件,但似乎 Clips 始终具有MASTER_GAINBALANCE控件。

  1. 这个对吗?
  2. 我可以创建一个包含 100 个剪辑的数组并预加载所有样本吗?我不太明白Java的线路是否与物理混合器中的物理线路相对应,或者它们是否被虚拟化。
  3. 如果我是有限的,那么我如何交换样本进出线?有没有办法让我所有的 100 个样本都被预加载?或者,仅当您已经指定了一条线时,预加载是否有帮助?
  4. 同样,如果我是有限的,这是错误的方法吗?我是否应该:使用不同的编程语言,和/或 b. 手动组合音频流并将它们全部放在同一条线上。

哇,这是很多问题。我没有在文档中找到答案,我真的希望你们能提供帮助。请将您的答案编号为 1 到 4。非常感谢!

4

1 回答 1

2

1) 我认为假设总会有 BALANCE 甚至 MASTER_GAIN 是不安全的。也许有。我对音频 Java 控件的体验既令人烦恼又短暂。我很快决定编写自己的混音器,并且已经这样做了。我愿意分享这段代码。它包括处理音量和平移的基本规定。

即使它们可以工作,Java 控件的粒度也会受到所使用的缓冲区大小的限制,如果您尝试淡入淡出,这会严重限制您在不产生点击的情况下淡入或淡出的速度。不过,设置和保存单个卷没有问题。

另一个 java 库(基本但已在 java-gaming.org 上经过几位游戏程序员的审查)是“TinySound”,可通过 github 获得。我已经看过了,但我自己没有使用过。它还将所有声音混合到单个输出 SourceDataLine。我不记得如何处理音量或平移。他包括了 ogg/vorbis 文件的规定。

2) 当您提到“示例”时,我不确定您是如何设想使用 Clips 工作的。是的,您可以预加载包含 100 个剪辑的数组。您将直接在其自己的线程上播放这些剪辑中的一个或另一个(假设使用原始 Java 而不是音频混合库),然后将它们重置回第 0 帧,然后再次播放它们。但是你一次只能有一个线程播放给定的剪辑:它们不适应并发播放。(您可以通过停止给定的播放并将位置移回第 0 帧然后重播来“重新触发”。)

Clips 有多长?其中100个可能是很多内存。如果每个都是一秒长,则 100 秒 * 44100 帧/秒 * 4 字节/帧 = 17,640,000 字节(几乎 18MB 专门用于声音的 RAM!)。

我想,如果您知道一次只需要几个,并且您可以预测需要哪些,您可以预先加载并重复使用它们。但不要落入认为剪辑是在播放时加载的陷阱。如果您这样做,则应改用 SourceDataLines。它们可以更快地开始播放,因为它们不必等到整个外部文件都被放入内存(就像剪辑一样)。如果您打算将剪辑重置为第 0 帧并重播(或循环播放),我建议您仅使用剪辑!

3)一旦作为剪辑加载,它基本上就可以开始了,真的没有额外的阶段。在外部文件和内存中的剪辑之间确实没有任何中间阶段,我认为这可能会有所帮助。

啊,另一个想法:您可能想要创建一个线程池(=最大并发声音数)并管理它。我不知道扩展在什么时候证明了额外的管理是合理的。

4) 可以在许多上下文中运行并发 SourceDataLines,这消除了将整个文件保存在 RAM 中的需要。在这种情况下,我认为唯一可以预加载的是文件位置的字符串。我可能是错的,您也可以预加载文件,但也许不是。绝对不能重用 AudioInputLine!从好的方面来说,与未加载剪辑相比,SDL 的启动速度非常快。

然而!有些系统(例如,某些 Linux 操作系统)将您限制为单个输出,可能是 Clip 或 SourceDataLine。当我决定建造自己的混音器时,这对我来说是关键。

我认为如果一次只播放 8 或 10 个音调,只要图形不是太雄心勃勃(不包括上面提到的 Linux OS 情况),你可能会没事。你必须测试它。

我不知道您正在考虑使用哪些替代语言。C 的某种风味是我所知道的唯一替代方案。我所知道的大多数其他东西,除了 Java,都不够低级或不够快,无法处理这么多的音频处理。但我只是经验不足,没有良好的工程背景,而是自学成才。

于 2013-05-18T01:40:08.787 回答