从潜在谐波中确定基频的算法

17

我试图从声源中提取基音频率。也许有人在麦克风中唱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
(Peak[4].power=1009.152954, .freq=4022.363037
(Peak[5].power=995.199585, .freq=4974.120605
(Peak[6].power=987.243713, .freq=8087.792480
(Peak[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个谐波)
  • 我们现在有了一个被认为是彼此谐振的峰值列表

    Harmonic PeakPair: (0,1)=2/3, error: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秒。所以我想音符需要一些时间来稳定下来... - P i
我放置了一个标记,因为在某个时候我想要提取完整的音调,并循环通过该过程,直到没有检测到任何内容。这样我就可以捕捉完整的复音。 - P i
2
你可能想考虑使用自相关或倒谱分析。 - Paul R
这个问题涵盖了相同的内容:https://dev59.com/Em455IYBdhLWcg3wAvbQ 但是由于标题中有“cepstral”,不熟悉该术语的人可能无法识别该问题是否相关。不过,它确实提到了“音高检测”。 - DarenW
你说:“我感觉最强的总是基频或第一谐波。” 我建议你重新考虑这个假设。我知道在语言中通常缺少基频,我听说(请原谅双关语)人类歌唱中经常缺少第二谐波(即基频的两倍)。你有一堆代表性光谱吗?你已经查看过这些光谱来证实你的想法吗? “hotpaw2”的建议进行倒谱分析似乎是获得基频附近的最佳方法,然后您可以尝试从那里进行精细调整。 - mtrw
3个回答

9

Cepstrum(或Cepstral分析)和Harmonic Product Spectrum是两种被广泛研究的算法,用于估计来自谐波序列的激发频率。

如果谐波序列的间隔适当,则Cepstrum(FFT峰值的对数的FFT)可用于估计频率间距的周期,然后可以使用它来估计频率。

Harmonic Product Spectrum基本上通过将频谱通过多个低整数比例抽样并重叠来与第n倍的谱峰进行比较。


2

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接