我试图从声源中提取基音频率。也许有人在麦克风中唱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等...尽管可能会缺失某些值。
实际上,我有一种感觉,无论是基频还是第一个谐波,它们都具有最大的强度。但我不知道是否可以依此进行可靠性判断...
有太多的因素,这让我感到头昏眼花。我提前为这个混乱的问题道歉。希望我以后可以把它整理好。