Java频率分析性能
Posted
技术标签:
【中文标题】Java频率分析性能【英文标题】:Java frequency analysis performance 【发布时间】:2012-03-27 12:21:34 【问题描述】:我正在开发一个对音频进行采样的应用程序,并且需要对此数据进行实时处理(FFT 和谐波乘积频谱)。
我需要使用 44100Hz 的采样率和 0.5Hz 的频率分辨率,这意味着我需要 88200 个样本 pre-FFT。这需要大约 2 秒来捕获,因为它是采样率的两倍;但是,在第一个样本之后,我通过使用循环缓冲区进行采样确实显着改善了事情,并且从那时起只读取了一半的样本。
不幸的是,性能仍然很低,并且有相当多的延迟。这是一个大问题,因为应用程序需要及时响应输入。
有没有人对我如何提高它的性能有任何建议?我认为主要问题在于对大样本的要求,如果有某种方法可以减少读取的音频量,同时仍保持相同的准确性,那就太好了。线程在这里可能会有所帮助吗?
编辑
如果有帮助,我正在尝试根据电吉他输入进行实时 F0 估计,以及用于和弦匹配的多个 F0 估计。我有这样做的方法,并且非常准确,但它是针对一个 uni 项目的,我真的没有足够的时间来研究 FFT 以外的其他方法。真的,我只是希望有某种方法可以加快采样过程。
【问题讨论】:
是否可以提高并发水平?例如将文件拆分成更小的块(开始 2 个块)并在不同的线程下运行样本?如果您不依赖硬件(CPU 驱动而不是声卡驱动),我认为这种分而治之的方法可能会有所帮助。 【参考方案1】:由于您最初需要捕获 2 秒的音频,因此这将为延迟设置一个下限。即使有 50% 的重叠,您仍然会有 1 秒的最小延迟。 FFT 和其他处理只会增加这一点,但希望不会显着增加(否则使用更快的 FFT 库)。减少这种延迟的唯一方法是牺牲频率分辨率。
【讨论】:
这就是我所担心的。我认为有些人已经尝试在 FFT 输入中使用某种零插值来提高分辨率,但仍然使用更少的样本。我可能会尝试一下,看看它是如何工作的,但我认为仅凭这一点并不能解决问题。 用零填充不会再提供 准确度,它只是对频域数据进行插值,以便获得更明显的分辨率,但这实际上只是装饰性的 - 它不会根据您的采样率将靠得太近而无法解析的峰值分开,即您无法从任何地方获取信息。如果您对您正在尝试做的事情给出一个高层次的想法,这可能会有所帮助,因为可能还有其他方法。 我已经用我的项目的更多信息编辑了这个问题。就零填充而言,如果我只对某个频率范围感兴趣,会有什么不同吗?此外,是否需要考虑对这些插值点的周围 bin 进行平均? 好的——我想这可能是另一个音高估计问题。 ;-) 你可能想看看关于这个主题的其他一些问题和答案,因为在过去的几年里它已经被广泛地覆盖了——似乎有很多人在写吉他调音器和类似的应用程序对于 ios 等。基于 FFT 的方法可能并不理想,但如果您有时间限制,那么您可能只需要充分利用它。 我知道还有其他选择,但老实说,FFT 方法是我唯一能真正理解的方法。我发现网上对这些东西的解释不是很好(至少对于没有高等数学背景的人来说不是)。不过感谢您的帮助:)【参考方案2】:使用 FFT 方法可以在时间和频率之间进行权衡。如果您想要更低的延迟,您将不得不使用更少的数据,而 FFT(更短或零填充)将使您的频率估计不太准确。
零填充只会为您提供高质量的插值。但这可能比仅使用较短 FFT 的峰值 bin 中心提供更好的峰值频率估计。
【讨论】:
以上是关于Java频率分析性能的主要内容,如果未能解决你的问题,请参考以下文章
频率分析 - Novocaine 和麦克风播放:如何禁用扬声器输出?