自相关返回麦克风输入的随机结果(使用高通滤波器)

发布于 2024-08-03 06:42:47 字数 855 浏览 10 评论 0原文

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

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

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

(已修复)

谢谢,

尼尔。

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

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

Sorry to ask a similar question to the one i asked before (FFT Problem (Returns random results)), but i've looked up pitch detection and autocorrelation and have found some code for pitch detection using autocorrelation.

Im trying to do pitch detection of a users singing. Problem is, it keeps returning random results. I've got some code from http://code.google.com/p/yaalp/ which i've converted to C++ and modified (below). My sample rate is 2048, and data size is 1024. I'm detecting pitch of both a sine wave and mic input. The frequency of the sine wave is 726.0, and its detecting it to be 722.950820 (which im ok with), but its detecting the pitch of the mic as a random number from around 100 to around 1050.

I'm now using a High pass filter to remove the DC offset, but it's not working. Am i doing it right, and if so, what else can i do to fix it? Any help would be greatly appreciated!

(Fixed)

Thanks,

Niall.

Edit: Changed the code to implement a high pass filter with a cutoff of 30hz (from What Are High-Pass and Low-Pass Filters?, can anyone tell me how to convert the low-pass filter using convolution to a high-pass one?) but it's still returning random results. Plugging it into a VST host and using VST plugins to compare spectrums isn't an option to me unfortunately.

Edit: Fixed, thanks for everyones help, but I never got it to work, now using new code.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

送你一个梦 2024-08-10 06:42:48

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

I am no sound expert, but if you are sampling with 44100 (I guess samples per second) and use 1024 datapoints. You are working with about 1/40th of a second worth of data. I doesn't surprise me that the current pitch varies a lot, depending on which piece you pick. If you want to find the average or main pitch of a voice, I'd expect to need about 1second worth of data.

享受孤独 2024-08-10 06:42:48

在 44.1 kHz 采样频率下,1024 个样本仅相当于 23 ms 多一点的数据。难道这可能只是因为数据不足以计算人类歌手的音调吗?

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

At 44.1 kHz sampling frequency, 1024 samples is only a little bit over 23 ms worth of data. Isn't it possible that this is simply insufficient data in order to compute the pitch of a human singer?

I mean, the sound I can make that lasts for 23 ms is probably not something I have a lot of pitch-control over; I would expect this kind of measurement to be done over slighly longer periods of time.

请帮我爱他 2024-08-10 06:42:48

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

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

编辑:

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

The problem is in your findBestCandidates() function:

Inside this function you access the 'inputs' array from 0 up to 'length - 1'.
When you call this function inside detectPitchCalculation() function 'inputs' is 'results' and 'length' is 'nHiPeriodInSamples'.
But 'results' is only allocated and filled up to 'nHiPeriodInSamples - nLowPeriodInSamples - 1'.
So if 'nLowPeriodInSamples' is greater 0 you access unallocated and random memory inside the findBestCandidates() function!

EDIT:

Another bug is that you fill each 'nResolution' entry of the 'results' array in detectPitchCalculation() function but access each entry in the findBestCandidates() function (via the 'inputs' argument). But since you call detectPitchCalculation() with a 'nResolution=1' this does not explain your specific problem...so I will look a little bit more. But it would definitely a problem if you call it with higher resolutions.

尴尬癌患者 2024-08-10 06:42:48

我在你的代码中没有看到问题,但我不擅长 C。但我会尝试以下方法来找到问题:

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

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

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

I don't see the problem in you code, but I'm no good in C. But I'd try the following to find the problem:

  • run with data where the result in known, e.g. with sin(x) as input
  • run it with small data size (e.g. 2)

Compare the results with known correct ones. You should be able to find those on the internet, or do them by hand.

If random means: same input, different output, you most probably have some bug in the initialisation of variables. Use a debugger and known input to check, that all variables, especially all elements of arrays are properly initialized.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文