我正在寻找从声音信号中提取音高。
IRC上的某个人刚刚向我解释了如何采用双FFT实现这一目标。具体做法是:
我正在尝试使用vDSP
我无法理解我之前没有遇到过这种技术。我做了很多狩猎和提问;几周值得。更重要的是,我无法理解为什么我没有想到它。
我正在尝试使用vDSP库实现此目的。它看起来好像有处理所有这些任务的功能。
但是,我想知道最终结果的准确性。
我之前使用的技术是将单个FFT的频率区域搜索到局部最大值。当它遇到一个时,它使用一种狡猾的技术(自上次FFT以来的相位变化)来更准确地将实际峰值放置在箱内。
我担心这种精确度会因为我在这里提出的技术而失去。
我想这种技术可以在第二次FFT之后使用,以准确地得到基波。但有点看起来信息在第2步中丢失了。
由于这是一个潜在的棘手过程,有经验的人是否可以只看看我在做什么并检查它的理智?
另外,我听说有一种替代技术涉及在相邻的箱子上安装二次方。这是否具有可比性?如果是这样,我会赞成它,因为它不涉及记住bin阶段。
所以,问题:
有人能指出我对这项技术的一些研究或文献吗?
主要问题:它是否足够准确?可以提高准确度吗?我刚刚被一位专家告知我的准确性是不充分的。这是行的结尾吗?
裨
PS当我想创建标签时,我很生气,但不能。 :|我已向维护人员建议SO跟踪尝试的标签,但我确信我被忽略了。我们需要vDSP标签,加速框架,倒谱分析
答案 0 :(得分:77)
答案 1 :(得分:8)
这是用于音高确定的倒谱的简要分析。
首先让我们检查合成信号。
下图显示了合成稳态E2音符的倒谱,使用典型的近直流分量,82.4 Hz的基波和82.4 Hz的整数倍的8次谐波合成。对合成正弦曲线进行编程以生成4096个样本。
观察12.36处突出的非DC峰值。倒谱宽度为1024(第二个FFT的输出),因此峰值对应于1024 / 12.36 = 82.8 Hz,非常接近真正的基频82.4 Hz。
现在让我们来看一个真实的声学信号。
下图显示了真正的原声吉他E2音符的倒谱。在第一次FFT之前,信号没有加窗。观察突出的非DC峰值542.9。倒谱宽度为32768(第二个FFT的输出),因此峰值对应于32768 / 542.9 = 60.4 Hz,这与真正的基频相差82.4 Hz。
下图显示了相同真实原声吉他的E2音符的倒谱,但这次信号在第一次FFT之前被Hann窗口化。观察268.46处突出的非DC峰值。倒谱宽度为32768(第二个FFT的输出),因此峰值对应于32768 / 268.46 = 122.1 Hz,甚至比真正的基频82.4 Hz还要远。
用于此分析的原声吉他的E2音符在工作室条件下使用高质量麦克风以44.1 KHz采样,它基本上包含零背景噪音,没有其他乐器或声音,也没有后期处理。
这说明了使用倒谱分析在真实声学信号中进行音高确定的重大挑战。
参考文献:
真实的音频信号数据,合成信号生成,绘图,FFT和倒谱分析在这里完成:Musical instrument cepstrum
答案 2 :(得分:5)
您对现有技术有什么不妥?如果这是目标,我认为倒谱不会给你更准确的音调。但是,它会帮助您suppressed fundamentals。我想你可以使用倒谱来让你靠近,然后回到第一个FFT(我将保持其原始形式),然后将你的狡猾技术应用到倒谱引导你的垃圾箱。
关于二次拟合,Ted Knowlton在this paper中提到了它,最近出现在另一个SO问题中,但我从未使用它。
我应该补充一点,二次拟合技术,至少在Knowlton参考文献中所概述的,取决于在第一个FFT上使用矩形窗口。正如Paul R在另一个问题中解释的那样,如果您正在进行音频处理,则应在第一个FFT上使用Hann或Hamming窗口。所以我想整体算法看起来像:
x
,制作窗口副本w
。Sx = FFT(x)
,Sw = FFT(w)
c = Log of square magnitude of Sw
Cx = FFT(c)
Cx
Sw
对基本(或更高谐波)的垃圾箱进行狡猾的阶段技巧Sx
围绕基本(或更高次谐波)进行二次陷阱拟合 (or higher harmonic)
注释适用于您确实已经抑制基本面的情况。
我在你的另一个问题中提到了这一点,但是是什么让你认为日志需要查找表?为什么不直接调用日志功能?我想两个FFT(O(n * logn))所花费的时间相形见绌。
答案 3 :(得分:4)
但倒谱分析并不意味着频率估计的准确性。它实际上是一种有损的分析形式。但它可能有助于从一系列谐波中找到基频,其中基频频谱分量可能相对较弱甚至缺失。
相位声码器分析(不是那么狡猾,因为该技术已存在了大约半个世纪)在给定峰值的频率估计方面更好,假设您选择了正确的峰值(不一定是最强的峰值),峰值频谱在两个fft帧上都是静止的,并且光谱中的基波并没有完全消失。
如果窗函数的变换类似于抛物线,则二次或抛物线插值可能是一个不错的选择。对于矩形窗口,Sinc插值效果更好。