我一直在环顾四周,发现了一些与我的问题相似的问题,但我对答案从来都不满意。我或多或少是一个Java n00b,虽然我对C++有一定的精通,我认为自己是一个中级到高级的程序员。我想用Java编写一个程序,它的功能类似于调谐器--我想要做的是记录一台仪器大约3秒钟的音高,并测量平均偏差。(这是给乐队的。)
我在想的是,我会有大量的数字,数组中的每个条目都是一个频率上的数字。我想要能够循环通过数组,并计算平均赫兹显示在屏幕或其他什么。因此,我想做的是有某种方式的“轮询”(因为没有一个更好的词)麦克风,看看什么频率被输入了正确的那一刻。
有没有一种简单的方式来接受来自麦克风的赫兹音频输入?这将在Java中,在Windows平台下进行。
发布于 2012-02-22 06:36:23
你需要做一些频谱分析。取一小块音频数据,大概256个样本,然后计算出每一段数据的快速傅里叶变换(FFT)。然而,傅里叶变换本身是不够的,因为在短样本中分割声音的过程会带来一些失真。这种失真将主要发生在更高的频率上。对于基音检测,你可以简单地用低通滤波器过滤掉这个失真。或者,你可以窗口你的声音样本,通常使用汉宁或布莱克曼窗口函数(基本上是不同的正弦斜率)。为了提高时间分辨率,您还应该重叠您所采集的单个样本。最后,你应该把你的个人光谱平均超过你想要分析的时间。
所有这些都会给你一个叫做功率谱密度函数的东西。这种导出它的方法称为Welch方法。因此,如果您幸运的话,Java声音将包括一个计算其中之一的方法。在许多信号处理环境中,这将被称为“突出”或“私营部门司”。
当然,频谱将使用对数频率(更多的频率点向高频率),振幅很可能是非规范化和线性的,而不是简单的dB值。此外,你还必须找到一个很好的方法来找出你的实际音高频率在所有的谐波噪声等。
我想说的是:要么你的库有一个简单的函数来做你想做的事情,要么这个东西太复杂了,没有一个简单的答案。抱歉的。
发布于 2012-02-22 07:48:28
我建议你阅读一些关于数字信号处理的教程或教科书。你想做的事情其实是相当复杂的。使它变得复杂的一些事情是:
所有这些并不是为了阻止你去做这个项目,我只是想列出你在做这个项目时可能面临的一些问题。我做过一个类似的项目,并遇到了这些问题。
https://softwareengineering.stackexchange.com/questions/136215
复制