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

P i*_*P i 16 algorithm estimation signal-processing pitch

我试图从声源中提取基频.也许有人在麦克风上唱A3,所以我想要检测~110Hz

我的方法是:

  • FFT 1024浮点数
  • 使用每个箱的相位来准确地确定其精确的频率
  • 确定峰值(通常为50左右)
  • 先用最大的声音命令它们

(峰值[0] .power = 1063.343750,.freq = 2032.715088
(峰值[1] .power = 1047.764893,.freq = 3070.605225
(峰值[2] .power = 1014.986877,.fr​​eq = 5925.878418
(峰值[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,误差: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
    Harmonic PeakPair:(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等......虽然有些人可能会失踪.

实际上,我有一种感觉,它总是要么是基础的,要么是具有最大力量的一次谐波.但我不知道我是否可以依靠这个......

这么多因素,它让我的头脑游泳.我提前为这样一个混乱的问题道歉.希望我可以在死后收拾它.

hot*_*aw2 9

Cepstum(或倒谱分析)和谐波产品谱是两种经过充分研究的算法,可以估算泛音系列的激励频率.

如果泛音序列被适当地隔开,则倒谱(FFT峰的对数的FFT)可用于估计频率间隔的周期,然后可用于估计频率.

谐波产品谱基本上通过用多个低整数比率抽取光谱并将它们重叠来比较光谱峰值与它们自身的第n个多个拷贝.


P i*_*P i 1

我重新表述了这个问题,并在这里提供了答案:如何接受一组数字,例如 {301,102,99,202,198,103} 并扔掉 ~100?

我研究了几种方法,这比我发现的其他方法要简洁得多。我已经测试过了,效果很好。