Java频率分析性能

3
我正在开发一个应用程序,对音频进行采样并需要实时处理(FFT和谐产品谱)这些数据。
我需要使用44100Hz的采样率,并需要0.5Hz的频率分辨率,这意味着在FFT之前需要88200个采样。由于是两倍的采样率,因此这需要约2秒钟来捕获;但是,在第一次采样后,通过使用循环缓冲区进行采样,并从那时起仅读取一半的采样数,我确实改善了很多。
不幸的是,性能仍然相当低,并且存在相当大的延迟。这是一个大问题,因为应用程序需要及时响应输入。
有没有人可以提供任何建议,以改善此性能?我认为主要问题在于需要大量的采样,如果有办法减少读取的音频量同时保持相同的准确度,那就太好了。也许线程会在这里有所帮助?
编辑:
如有助于了解,我正在尝试从电吉他输入进行实时F0估计,以及进行和弦匹配的多个F0估计。我有一些有效且准确的方法可以实现这一点,但这是一个大学项目,我没有足够的时间去研究除FFT以外的其他方法。实际上,我只是希望能够加快采样过程的速度。

有没有可能提高并发级别?例如,将文件分成更小的块(首先是2个块),并在不同的线程下运行这些样本?如果您没有硬件依赖关系(受CPU驱动而非声卡驱动),我认为这种分而治之的方法可能会有所帮助。 - questzen
2个回答

1

由于您需要最初捕获2秒的音频,这将对延迟设置下限。即使您有50%的重叠,您仍将具有最小1秒的延迟。FFT和其他处理只会增加这个延迟,但希望不会增加太多(否则请使用更快的FFT库)。您唯一能够减少此延迟的方法是牺牲频率分辨率。


这正是我担心的。我认为有些人尝试使用零的插值与FFT输入来增加分辨率,但仍然使用更少的样本。我可能会尝试一下,看看它的效果如何,但我认为这并不是一个解决方案。 - nihilo90
1
用零填充并不能提供更多的“准确性”,它只是插值你的频域数据,以便获得更多的表面分辨率,但这只是表面的 - 它不会分离峰值,如果它们太接近而无法根据采样率进行分辨,即你不能从无处获取信息。如果您给出您正在尝试做什么的高级别想法,那可能会有其他方法可以帮助您。 - Paul R
我已经编辑了我的项目的更多信息。对于零填充,如果我只对某个频率范围感兴趣,这会有影响吗?此外,对于这些插值点周围的桶进行平均处理是否值得考虑? - nihilo90
1
好的 - 我以为这可能是另一个音高估计问题。;-) 你可能想看看关于这个主题的一些其他问题和答案,因为在过去的几年里已经广泛涵盖了这个主题 - 似乎有很多人为iOS等编写吉他调音器和类似应用程序。基于FFT的方法可能不是理想的选择,但如果你时间有限,那么你可能只能尽力而为。 - Paul R
我知道还有其他选项,但老实说,FFT方法是我唯一真正能理解的方法。我发现在线上关于这些事情的解释并不是很好(至少对于没有高级数学背景的人来说)。不过还是谢谢你的帮助 :) - nihilo90

1

使用FFT方法会产生时间和频率的权衡。如果你想要更低的延迟,就需要使用较少的数据,而这样做会导致使用FFT(无论是缩短还是零填充)时频率估计的准确性降低。

零填充只会给你一个高质量的插值结果。但是相比只使用较短FFT的峰值频率所在的频率段,这样做可能会提供更好的峰值频率估计。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接