P i*_*P i 30 signal-processing fft detection pitch vdsp
我正在寻找从声音信号中提取音高.
IRC上的某个人刚刚向我解释了如何采用双FFT实现这一目标.特别:
我正在尝试使用vDSP
我无法理解我之前没有遇到过这种技术.我做了很多狩猎和提问; 几周值得.更重要的是,我无法理解为什么我没有想到它.
我试图用vDSP库实现这一目标.它看起来好像有处理所有这些任务的功能.
但是,我想知道最终结果的准确性.
我之前使用的技术是将单个FFT的频率区域扫描为局部最大值.当它遇到一个时,它使用一种狡猾的技术(自上次FFT以来的相位变化)来更准确地将实际峰值放置在箱内.
我担心这种精确度会因为我在这里介绍的技术而丢失.
我想这种技术可以在第二次FFT之后使用,以准确地得到基波.但有点看起来信息在第2步中丢失了.
由于这是一个潜在的棘手过程,有经验的人可以只看一下我正在做的事情并检查它的理智吗?
此外,我听说有一种替代技术涉及在相邻的箱子上安装二次方.这是否具有可比性?如果是这样,我会赞成它,因为它不涉及记住bin阶段.
所以,问题:
有人能指出我对这种技术的一些研究或文献吗?
主要问题:它足够准确吗?可以提高准确度吗?一位专家刚刚告诉我,准确性是不充分的.这是行的结束吗?
皮
PS当我想创建标签时,我很生气,但不能.:| 我已向维护人员建议SO跟踪尝试的标签,但我确信我被忽略了.我们需要vDSP标签,加速框架,倒谱分析
Jer*_*wen 77
好的,让我们逐一介绍:
我正在寻找从声音信号中提取音高.
虽然我不是专家,并且接受过最少的正规培训,但我认为我知道这个问题的最佳答案.在过去的几年里,我做了大量的搜索,阅读和实验.我的共识是,就准确性,复杂性,噪声稳健性和速度之间的权衡而言,自相关方法是迄今为止最好的音调检测器.除非你有一些非常具体的情况,否则我几乎总是建议使用自相关.更多相关内容,让我回答您的其他问题.
你所描述的是"倒谱分析",这是一种主要用于从语音中提取音高的方法.倒谱分析完全依赖于信号泛音的丰富性和强度.例如,如果您通过倒谱分析传递纯正弦波,您将得到可怕的结果.然而,对于作为复杂信号的语音,存在大量泛音.顺便说一句,泛音是信号的元素,它们以基频的倍数振荡,即我们感知的音高.倒谱分析在检测具有缺失基频的语音时可以是稳健的.也就是说,假设您绘制了函数sin(4x)+ sin(6x)+ sin(8x)+ sin(10x).如果你看一下,很明显它与函数sin(2x)具有相同的频率.但是,如果对此函数应用傅里叶分析,则对应于sin(2x)的bin将具有零幅度.因此,该信号被认为具有"缺失的基频",因为它不包含我们认为它的频率的正弦波.因此,简单地选择傅里叶变换上的最大峰值将不会对此信号起作用.
我之前使用的技术是将单个FFT的频率区域扫描为局部最大值.当它遇到一个时,它使用一种狡猾的技术(自上次FFT以来的相位变化)来更准确地将实际峰值放置在箱内.
你所描述的是相位声码器技术,以更准确地测量给定部分的频率.但是,如果使用基频频率成分缺失或较弱的信号,挑选最大容器的基本技术会导致问题.
我担心这种精确度会因为我在这里介绍的技术而丢失.
首先,请记住,相位声码器技术只能更准确地测量单个部分的频率.它忽略了关于基频的较高部分中包含的信息.其次,考虑到适当的FFT大小,您可以使用峰值插值获得非常好的精度.这里有人向你指出了抛物线插值.我也建议这样做.
如果您以44100 Hz抛物线插值4098样本数据块的FFT,其间距约为440 hz,这意味着它将介于第40(430.66 Hz)和第41(441.430664064)个bin之间.假设这篇论文在一般情况下近似正确,它表示抛物线插值会使分辨率提高一个数量级以上.这使得分辨率至少为1Hz,这是人类听觉的阈值.事实上,如果你使用理想的高斯窗口,抛物线插值在峰值处是精确的(那是正确的,确切的.但是,请记住,你永远不能使用真正的高斯窗口,因为它在两个方向上永远延伸.)如果你是仍然担心获得更高的精度,你可以随时填充FFT.这意味着在变换之前将零添加到FFT的末尾.可以看出,这相当于"sinc插值",它是频率受限信号的理想插值函数.
我想这种技术可以在第二次FFT之后使用,以准确地得到基波.但有点看起来信息在第2步中丢失了.
那是正确的.相位声码器技术依赖于连续帧连接并具有特定相位关系的事实.然而,连续帧的FFT的对数幅度在相位方面不显示相同的关系,因此将该变换用于第二FFT将是无用的.
- 这种方法有意义吗?可以改进吗?
是的,是的,我将在最后详细阐述我对自相关的改进.
- 我有点担心和log square组件; 似乎有一个vDSP函数可以做到这一点:vDSP_vdbcon但是,没有迹象表明它预先计算了一个日志表 - 我认为它没有,因为FFT函数需要一个显式的预计算函数来调用和传递进去.而这个功能没有.
对不起,我不知道vDSP库的具体细节.
- 是否存在拾取谐波的危险?
在您的原始相位 - 声码器峰值拾取技术?是.用cepstral方法?不,不是真的,重点是它考虑所有谐波来获得其频率估计.例如,我们的频率是1.我们的泛音是2,3,4,5,6,7,8,9等我们必须取出所有的奇次谐波,即离开2,4,6, 8等,并在它开始与其中一个泛音混淆之前消除基频.
- 是否有任何狡猾的方式使vDSP拉出最大值,最大的第一?
不知道vDSP,但在一般情况下,你通常只是迭代所有这些并跟踪最大的.
- 有人能指出我对这种技术的一些研究或文献吗?
我在评论中给你的链接看起来很好.
此外,该网站以理论和实践的方式提供了对DSP主题的令人难以置信的深入和奇妙的广泛解释,包括各种音调提取,操作等.(这是指向网站上索引的更一般链接).我总是发现自己回到了它.如果你跳到它的中间,有时它可能有点压倒性,但你总是可以按照每个解释回到基本的构建块.
现在为自相关.基本上技术是这样的:你把你的(窗口)信号和时间延迟不同的量.找到与原始信号最匹配的数量.那是基本时期.它具有很多理论意义.您正在寻找信号的重复部分.
在实践中,与所有这些时间相关的信号的延迟副本是缓慢的.它通常以这种方式实现(在数学上等效):
将其填零以使其原始长度加倍.进行FFT.然后用它们的平方幅度替换所有系数,除了第一个,你设置为0.现在采用IFFT.将每个元素除以第一个元素.这给你自相关.在数学上,你正在使用循环卷积定理(查找它),并使用零填充将线性卷积问题转换为循环卷积问题,这可以有效地解决.
但是,要小心选择峰值.对于非常小的延迟,信号将非常好地匹配,因为它是连续的.(我的意思是,如果你将它延迟为零,它与自身完全相关)相反,选择第一个过零点后的最大峰值.您可以抛物线插值自相关函数,就像使用其他技术一样,以获得更准确的值.
这本身就可以通过所有标准为您提供非常好的音高检测.但是,您有时会遇到音高减半和音高加倍的问题.基本上,问题是,如果一个信号是重复的每1秒,它也是每重复两个秒.同样,如果它具有非常强烈的泛音,你可能会使音高减半.所以最大的峰值可能并不总是你想要的.该问题的解决方案是Phillip McLeod的MPM算法.这个想法是这样的:
而不是选择最大的峰值,你想要选择足够大的第一个峰值来考虑.您如何确定峰值是否足够大以至于被考虑?如果它至少与最大峰值A*一样高,其中A是一些常数.菲利普建议我认为A的值约为0.9.实际上,他编写的程序Tartini允许您实时比较几种不同的音高检测算法.我强烈建议下载并试用它(它实现Cepstrum,直接自相关和MPM):(如果你在构建时遇到问题,请尝试这里的说明.
我应该注意的最后一件事是关于窗口问题.通常,任何平滑的窗口都可以.汉宁窗口,汉明窗口等.希望你应该知道如何窗口.如果你想要更精确的时间测量,我还建议做重叠窗口.
顺便说一句,自相关的一个很酷的特性是,如果频率通过你正在测量的窗口部分线性变化,它将在窗口的中心给你正确的频率.
还有一件事:我所描述的被称为偏置自相关函数.这是因为对于更高的时间滞后,原始信号和时间滞后版本之间的重叠变得越来越少.例如,如果您查看大小为N且已延迟N-1个样本的窗口,您会看到只有一个样本重叠.因此,此延迟的相关性显然将非常接近零.你可以通过将自相关函数的每个值乘以重叠的样本数来得到它来弥补这一点.这被称为无偏自相关.但是,一般情况下,你会得到更糟糕的结果,因为自相关的较高延迟值非常嘈杂,因为它们仅基于少量样本,所以更少权衡它们是有意义的.
如果您正在寻找更多信息,谷歌一如既往,是您的朋友.良好的搜索条件:自相关,音高检测,音高跟踪,音高提取,音高估计,倒谱等.
这是用于音高确定的倒谱的简要分析.
首先让我们检查一下合成信号.
下图显示了合成稳态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和倒谱分析在这里完成:乐器倒谱
你对现有技术感兴趣的是什么?如果这是目标,我认为倒谱不会给你更准确的音调.但是,它会帮助你克服基本面.我想你可以使用倒谱来让你靠近,然后回到第一个FFT(我将保持其原始形式),然后将你的狡猾技术应用到倒谱引导你的垃圾箱.
至于二次拟合,Ted Knowlton 在本文中提到了它,最近出现在另一个SO问题中,但我从未使用它.
我应该补充一点,二次拟合技术,至少在Knowlton的参考文献中所概述的,取决于在第一个FFT上使用矩形窗口.正如Paul R在另一个问题中解释的那样,如果你正在进行音频处理,你应该在第一个FFT上使用Hann或Hamming窗口.所以我猜一个整体算法看起来像:
x,制作一个窗口副本w.Sx = FFT(x), Sw = FFT(w)c = Log of square magnitude of SwCx = FFT(c)CxSw对基本(或高次谐波)箱进行狡诈阶段处理Sx围绕基波(或高次谐波)进行二次陷阱拟合(or higher harmonic)如果您确实已经抑制了基本面,则该注释适用.
我在你的另一个问题中提到了这一点,但是是什么让你认为日志需要查找表?为什么不直接调用日志功能?我想两个FFT(O(n*logn))所花费的时间相比你可以做的任何其他处理相形见绌.