2

很抱歉问了一个与我之前问过的问题类似的问题(FFT 问题(返回随机结果)),但我已经查找了音高检测和自相关,并找到了一些使用自相关进行音高检测的代码。

我正在尝试对用户唱歌进行音高检测。问题是,它不断返回随机结果。我从http://code.google.com/p/yaalp/获得了一些代码,我已将其转换为 C++ 并进行了修改(如下)。我的采样率为 2048,数据大小为 1024。我正在检测正弦波和麦克风输入的音高。正弦波的频率是 726.0,它检测到它是 722.950820(我可以接受),但它检测到麦克风的音高是从大约 100 到大约 1050 的随机数。

我现在正在使用高通滤波器来消除直流偏移,但它不起作用。我做对了吗,如果是这样,我还能做些什么来解决它?任何帮助将不胜感激!

(固定的)

谢谢,

尼尔。

编辑:更改代码以实现截止频率为 30hz 的高通滤波器(来自What Are High-Pass and Low-Pass Filters?,谁能告诉我如何使用卷积将低通滤波器转换为高通滤波器?) 但它仍然返回随机结果。不幸的是,将它插入 VST 主机并使用 VST 插件来比较频谱对我来说不是一个选择。

编辑:已修复,感谢大家的帮助,但我从来没有让它工作,现在使用新代码。

4

4 回答 4

2

我不是声音专家,但如果您使用 44100 采样(我猜是每秒采样)并使用 1024 个数据点。您正在处理大约 1/40 秒的数据。我并不感到惊讶,当前的音高变化很大,这取决于你选择哪一个。如果你想找到一个声音的平均或主要音高,我预计需要大约 1 秒的数据。

于 2009-08-30T13:51:24.493 回答
1

在 44.1 kHz 采样频率下,1024 个样本仅略高于 23 ms 的数据。难道这只是不足以计算人类歌手的音高的数据吗?

我的意思是,我能发出的持续 23 毫秒的声音可能不是我有很多音高控制的东西。我希望这种测量会在更长的时间内完成。

于 2009-08-30T13:55:34.443 回答
1

问题出在您的 findBestCandidates() 函数中:

在此函数中,您可以访问从 0 到 'length - 1' 的 'inputs' 数组。当您在 detectPitchCalculation() 函数中调用此函数时,“输入”为“结果”,“长度”为“nHiPeriodInSamples”。但是“结果”仅分配并填充到“nHiPeriodInSamples - nLowPeriodInSamples - 1”。因此,如果 'nLowPeriodInSamples' 大于 0,您将访问 findBestCandidates() 函数内的未分配和随机内存!

编辑:

另一个错误是您在 detectPitchCalculation() 函数中填充了“结果”数组的每个“nResolution”条目,但访问了 findBestCandidates() 函数中的每个条目(通过“输入”参数)。但是由于您使用“nResolution = 1”调用detectPitchCalculation(),这并不能解释您的具体问题......所以我会多看一点。但是如果你用更高的分辨率调用它肯定会出现问题。

于 2009-08-30T08:15:35.563 回答
0

我在您的代码中看不到问题,但我在 C 语言中并不擅长。但我会尝试以下方法来查找问题:

  • 使用结果已知的数据运行,例如使用 sin(x) 作为输入
  • 以小数据量运行它(例如 2)

将结果与已知的正确结果进行比较。你应该能够在互联网上找到这些,或者手工完成。

如果随机意味着:相同的输入,不同的输出,您很可能在变量的初始化中有一些错误。使用调试器和已知输入来检查所有变量,尤其是数组的所有元素是否已正确初始化。

于 2009-08-30T07:59:02.943 回答