【发布时间】:2011-06-10 15:19:30
【问题描述】:
我正在尝试从声源中提取基频。也许有人在对着麦克风唱 A3,所以我想检测 ~ 110Hz
我的做法是:
- FFT 1024 浮点数
- 使用每个 bin 的相位来准确确定其精确频率
- 确定峰值(通常为 50 个左右)
- 按最响的顺序排列
(峰值[0].power=1063.343750, .freq=2032.715088
(峰值[1].power=1047.764893,.freq=3070.605225
(峰值[2].power=1014.986877,.freq=5925.878418
(峰值[3].power=1011.707825,.freq=6963.769043
(峰值[4].power=1009.152954,.freq=4022.363037
(峰值[5].power=995.199585,.freq=4974.120605
(峰值[6].power=987.243713, .freq=8087.792480
(峰值[7].power=533.514832, .freq=908.691833
- (MARKER1) 从最响亮的开始,并将其与所有剩余的峰值匹配,所以如果我有 N 个峰值,我将在这一点上有 N-1 个峰值对
- 检查每个峰对的谐波;即它与某个分数 a/b 有多接近,即我们能否找到 b
-
我们现在有了一个精确的峰值列表,这些峰值被认为是相互谐波
谐波峰值对:(0,1)=2/3,错误:0.00468 => f0 @ 1019.946289
谐波峰值对:(0,2)=1/3,误差:0.00969 => f0 @ 2004.003906
谐波峰值对:(0,3)=2/7,误差:0.00618 => f0 @ 1005.590820
谐波峰值对:(0,4)=1/2,误差:0.00535 => f0 @ 2021.948242
谐波峰值对:(0,5)=2/5,误差:0.00866 => f0 @ 1005.590820
谐波峰值对:(0,6)=1/4,误差:0.00133 => f0 @ 2027.331543
谐波峰值对:(0,7)=9/4,误差:0.01303 => f0 @ 226.515106
我的问题是:我如何设计一种算法,将上述基本频率正确识别为 ~1000Hz?
绝对不能保证在 ~1000 处的值会比在 ~2000 或 ~3000 处更高的集中度等。甚至不能保证在 ~1000 处会有任何条目。我们可以有 ~5000 x 一个条目,~4000 x 三个条目,~3000 x 2 条目,以及一些浮动的虚假值,比如上面列表中的 226。
我想我可以再次重复该过程,剔除与列表其余部分不“和谐”的建议基本面。这至少会摆脱虚假的价值......
可能我什至没有问对正确的问题。也许这整个方法很糟糕。但我认为选择最强的峰值并提取一组与该峰值相关的谐波是有意义的。
理论上应该产生一个比率的负载,比如如果原始最强峰值是三次谐波,那么这组峰值应该包含 3/1 3/2 3/3 3/4 3/5 3/6 3 /7 等等……虽然有些可能会丢失。
实际上,我有一种感觉,它总是要么是基频,要么是具有最大强度的一次谐波。但不知道能不能靠这个……
这么多因素,让我头晕目眩。对于这样一个乱七八糟的问题,我提前道歉。希望我能在死后把它整理一下。
【问题讨论】:
-
由于某种原因,检测吉他音色比检测歌曲音色要困难得多。虽然这可能是因为我陷印了笔记的前几帧; 32 x 256 字节 = 8k,这大约是前 1/5 秒。所以我猜这个笔记需要一些时间来稳定......
-
我已经放置了一个标记,因为在某些时候我想拉出一个完整的音调,并为每个音调再次循环该过程,直到没有检测到任何东西。这样我就可以捕捉到完整的复音。
-
您可能需要考虑使用自相关或倒谱分析。
-
这个问题涵盖了同样的问题:stackoverflow.com/q/4583950/10468 但是标题中有“倒谱”,不熟悉该术语的人可能不会认为这个问题是相关的。不过,它确实说“音高检测”。
-
您说“我有一种感觉,它总是要么是基频要么是具有最大强度的一次谐波”。我会重新考虑这个假设。我知道语音中经常缺少基本音,而且我听说(请原谅双关语)人类歌唱中经常缺少二次谐波(即两倍的基本音)。你是否有一堆你看过的有代表性的光谱让你有不同的想法?
hotpaw2对倒谱分析的建议似乎是在基本原理的一两个 bin 内获得的最佳方法,然后您可以尝试从那里进行改进。
标签: algorithm signal-processing estimation pitch