我正在尝试从声源中提取基频。也许有人在对着麦克风唱 A3,所以我想检测 ~ 110Hz
我的方法是:
- FFT 1024 浮点数
- 使用每个 bin 的相位来准确确定其精确频率
- 确定峰值(通常为 50 左右)
- 以最响亮的顺序排列它们
(Peak[0].power=1063.343750, .freq=2032.715088
(Peak[1].power=1047.764893, .freq=3070.605225
(Peak[2].power=1014.986877, .freq=5925.878418
(Peak[3].power= 1011.707825,.freq=6963.769043
(峰值[4].power=1009.152954,.freq=4022.363037
(峰值[5].power=995.199585,.freq=4974.120605
(
峰值[6].power=987.248713,24.freq=887.79 )
[7].power=533.514832,.freq=908.691833
- (MARKER1)从最响亮的开始,并将其与所有剩余的峰值相匹配,所以如果我有 N 个峰值,我将在这一点上有 N-1 个峰值对
- 检查每个峰值对的谐波;即它与某个分数 a/b 有多接近,即我们能否找到 b<20 的 a/b 使得 |peakA.freq/peakB.freq - a/b| < 0.01(这将匹配高达 20 次的谐波)
我们现在有一个精确的峰值列表,这些峰值被认为是彼此谐波
谐波峰值对:(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 等...虽然有些可能会丢失。
实际上,我有一种感觉,它总是要么是基频要么是具有最大强度的一次谐波。但我不知道我是否可以依靠这个......
这么多因素,它让我头晕目眩。对于这样一个乱七八糟的问题,我提前道歉。希望我能在死后整理一下。