3

在花了相当多的时间尝试围绕现有的 javax.sound.sampled 库设计我的方式以进行简单(但相对时间准确)的音频捕获/渲染之后,我得出的结论是我真的需要获得原生音频API。我发现的问题是我需要能够以 20 或 50 毫秒的增量获取声音的帧位置(我通过写入 SourceDataLine 来渲染),精确到 1 或 2 毫秒。换句话说,我想将一些图形事件同步到正在播放的音频,视频帧速率为 20 到 50 fps,抖动不超过 1 或 2 毫秒。JavaSound 的实现似乎离硬件太远了(为平台独立性付出的代价?)。经过对 SDL/TDL 缓冲区大小、音频格式、SDL 大小的大量“修补”。

[进一步澄清:我可以让图形渲染基于系统时钟以固定速率运行,这对于我的需要来说足够准确。但是,如果要与音轨同步,则在典型的音轨(例如 5 分钟长)接近尾声时,即使很小的时间差异也会累积到音频和图形之间的明显时间差异。我想每秒钟(或 2 或 5 次)检查一次同步,但是报告的音频帧位置的“抖动”会导致更正,然后会很明显。]

我一直在研究哪些库可能已经可用。似乎许多现有的软件包都是为了支持游戏开发社区。但是,我不需要 3D 音频、效果的硬件加速、合成、处理——只是一种以一致的延迟读取正在听到的内容的帧位置的方法。如果延迟高达 100 毫秒,但保持一致,我可以围绕它进行设计。

对于提供这种功能的 Java 库,我将不胜感激。我认为它将是本机音频 API 的 JNI 包装器。我现在只需要支持Windows7。我见过 OpenAL(似乎是 Creative 支持音频硬件加速的“开放”方式,因为现在在 Vista 中不再支持 - 面向游戏并且超出了我的需要),JSyn(专注于合成,MIDI,而不是简单的采样接口)和 JAsioHost(迄今为止最有希望)。

如果有办法绕过我在 JavaSound API 中注意到的限制,那也很好,但经过一周的努力,我几乎放弃了。

谢谢。

4

2 回答 2

1

我还没有尝试过其中任何一个,但可能值得研究:

于 2017-04-01T02:44:33.247 回答
0

我想没有这样的库......但你想要完成的任务实际上并不难:

您需要将您的应用程序与音频帧同步......这意味着音频是时间的主要权威。您可以创建一个新的计时器,该计时器将定期发布声音块进行播放,并发出正在播放块 xy 的事件。

您需要以与实时相同的速率提供块......这意味着在一秒钟内发布一秒钟的样本。

播放本身可以通过 Windows 中的 WaveOut 函数来完成(链接在这里,您可以搜索教程)。您可以使用 JNI 从 Java 访问这些函数。WaveOut 以 Wav 格式播放声音,这意味着您可以使用简单的 LPC 调制打开设备并发布原始样本。

整个事情不会完全同步,但延迟不会很大。注意waveOutWrite 的缓冲区下溢,您需要在最后一个块完成播放之前提供新块,否则声音会失真。

于 2012-05-03T00:41:45.860 回答