很抱歉向我之前询问的问题(FFT Problem (Returns random results))提出类似的问题,但我已经查找了音高检测和自相关,并找到了一些使用自相关进行音高检测的代码。
我试图对用户唱歌进行音高检测。问题是,它不断返回随机结果。我从http://code.google.com/p/yaalp/获得了一些代码,我将其转换为C ++并进行了修改(如下)。我的采样率是2048,数据大小是1024.我正在检测正弦波和麦克风输入的音高。正弦波的频率为726.0,它的检测频率为722.950820(即可),但它检测到麦克风的音高为100到1050左右的随机数。
我现在正在使用高通滤波器来消除DC偏移,但它不起作用。我做得对吗,如果是这样,我还能做些什么来解决它?任何帮助将不胜感激!
(固定)
谢谢,
尼尔。
编辑:更改代码以实现截止值为30hz的高通滤波器(来自What Are High-Pass and Low-Pass Filters?,有人能告诉我如何使用卷积将低通滤波器转换为高通滤波器吗?)但是它仍在返回随机结果。不幸的是,将它插入VST主机并使用VST插件来比较频谱不是我的选择。
编辑:修复,感谢大家的帮助,但我从来没有让它工作,现在使用新代码。
答案 0 :(得分:2)
我不是专家,但如果您使用44100(我猜每秒采样)并使用1024个数据点进行采样。您正在处理大约1/40秒的数据。我并不让我感到惊讶的是,目前的音调变化很大,这取决于你选择哪一首。如果你想找到一个声音的平均或主音高,我希望需要大约1秒的数据。
答案 1 :(得分:1)
问题出在你的findBestCandidates()函数中:
在此函数中,您可以访问'inputs'数组,从0到'length - 1'。 当你在detectPitchCalculation()函数中调用这个函数时,'inputs'是'results'而'length'是'nHiPeriodInSamples'。 但'结果'仅被分配并填充到'nHiPeriodInSamples - nLowPeriodInSamples - 1'。 因此,如果'nLowPeriodInSamples'大于0,则可以访问findBestCandidates()函数中的未分配和随机内存!
修改
另一个错误是你在detectPitchCalculation()函数中填充'results'数组的每个'nResolution'条目,但是访问findBestCandidates()函数中的每个条目(通过'inputs'参数)。但是,因为你用'nResolution = 1'调用detectPitchCalculation(),这并不能解释你的具体问题...所以我会多看一点。但如果你用更高的分辨率调用它肯定会有问题。
答案 2 :(得分:1)
采样频率为44.1 kHz时,1024个样本仅略高于23 ms的数据量。为了计算一个人类歌手的音调,这不是可能只是数据不足吗?
我的意思是,我可以制作持续23毫秒的声音可能不是我有很多音高控制的东西;我希望这种测量可以在很长一段时间内完成。
答案 3 :(得分:0)
我没有在你的代码中看到问题,但我对C不好。但我会尝试以下方法来找到问题:
将结果与已知正确结果进行比较。您应该能够在互联网上找到这些,或者手工完成。
如果随机意味着:相同的输入,不同的输出,你很可能在变量的初始化中有一些错误。使用调试器和已知输入来检查所有变量,尤其是数组的所有元素是否都已正确初始化。