用于音高检测的倒谱分析

Posted

技术标签:

【中文标题】用于音高检测的倒谱分析【英文标题】:Cepstral Analysis for pitch detection 【发布时间】:2011-06-02 19:22:33 【问题描述】:

我希望从声音信号中提取音高。

IRC 上的某个人刚刚向我解释了采用双 FFT 是如何实现这一点的。具体来说:

    FFT 取绝对值平方的对数(可通过查找表完成) 再进行一次 FFT 取绝对值

我正在尝试使用 vDSP

我无法理解我之前怎么没有遇到过这种技术。我做了很多狩猎和提问;几个星期的价值。更重要的是,我不明白为什么我没有想到它。

我正在尝试使用 vDSP 库来实现这一点。它看起来好像具有处理所有这些任务的功能。

但是,我想知道最终结果的准确性。

我之前使用过一种技术,该技术可以搜索单个 FFT 的频率区间以获得局部最大值。当它遇到一个时,它会使用一种巧妙的技术(自上次 FFT 以来的相位变化)来更准确地将实际峰值放置在 bin 内。

我担心我在这里介绍的这种技术会丢失这种精度。

我猜想在第二次 FFT 之后可以使用该技术来准确地获得基本面。但看起来信息在第 2 步中丢失了。

由于这可能是一个棘手的过程,有经验的人可以看看我在做什么并检查它的完整性吗?

另外,我听说有一种替代技术涉及在相邻的 bin 上拟合二次方。这是否具有可比性的准确性?如果是这样,我会喜欢它,因为它不涉及记住 bin 阶段。

所以,问题:

这种方法有意义吗?可以改进吗? 我有点担心“log square”组件;似乎有一个 vDSP 函数可以做到这一点:vDSP_vdbcon。但是,没有迹象表明它预先计算了一个日志表——我认为它没有,因为 FFT 函数需要调用一个显式的预先计算函数并将其传递给它。而这个函数没有。 是否存在拾取谐波的危险? 有没有什么巧妙的方法让 vDSP 拉出最大值,先最大?

谁能指点我有关此技术的一些研究或文献?

主要问题:它是否足够准确?精度可以提高吗?一位专家刚刚告诉我,准确性确实不够。到此结束了吗?

圆周率

PS 当我想创建标签时我很生气,但不能。 :|我已经向维护者建议跟踪尝试的标签,但我确定我被忽略了。我们需要 vDSP、加速框架、倒谱分析的标签

【问题讨论】:

如果你标记你的问题 [信号处理] 我想大多数感兴趣的人都会找到它。 phon.ucl.ac.uk/courses/spsci/matlab/lect10.html 一组优秀的问题:)。 【参考方案1】:

您对新的技术感兴趣的现有技术有什么问题?如果这是目标,我认为倒谱不会给你更准确的音高。但是,它会为您提供suppressed fundamentals 的帮助。我想你可以使用倒谱让你靠近,然后回到第一个 FFT(我会保持其原始形式),然后将你的狡猾技术应用于倒谱引导你进入的 bin。

关于二次拟合,Ted Knowlton 在this paper 中提到过,最近在另一个 SO question 中提出,但我从未使用过。

我应该补充一点,至少正如 Knowlton 的参考文献中所述的二次拟合技术取决于在第一个 FFT 上使用矩形窗口。正如Paul R 在您的另一个问题中解释的那样,如果您正在进行音频处理,您应该在第一个 FFT 上使用 Hann 或 Hamming 窗口。所以我猜一个整体的算法可能是这样的:

获取时域缓冲区x,制作窗口副本wSx = FFT(x), Sw = FFT(w) c = Log of square magnitude of Sw Cx = FFT(c) 使用Cx 估计基波(可能还有谐波) 使用Sw 对基波(或高次谐波)bin 进行巧妙的相位技巧 和/或使用 Sx 围绕基波(或高次谐波)进行二次 bin 拟合

(or higher harmonic) 注释适用于您确实有抑制基本面的情况。

我在您的另一个问题中提到了这一点,但是是什么让您认为日志需要查找表?为什么不直接调用 log 函数呢?我想两个 FFT 所花费的时间 (O(n*logn)) 会使您可以执行的任何其他处理相形见绌。

【讨论】:

在第 3 步之后,即“c = Sw 平方幅度的对数”,结果数组是初始数组长度的一半。真的吗?在这种情况下,Cx 也是原始数组长度的一半,那么 Cx 中的 bin 频率如何确定?如果我问的问题很明显,请原谅。【参考方案2】:

倒谱分析是同态处理的一种形式,在 Oppenheim & Schafer 的“离散时间信号处理”一书中进行了解释。它曾经被认为对于从形成包络中分离激励器频率很有用(也许仍然是,不知道)。当给定一个相当长的固定数据窗口时,它似乎工作得更好。

但倒谱分析并不意味着频率估计的准确性。这实际上是一种有损的分析形式。但它可能有助于从一系列谐波中找到基频,其中基频频谱分量可能相对较弱甚至丢失。

相位声码器分析(不那么狡猾,因为该技术可能已经存在了半个世纪)在给定峰值的频率估计方面更好,假设您选择了正确的峰值(不一定是最强的峰值),峰值频谱在两个 fft 帧中是固定的,并且基本没有完全从频谱中丢失。

如果您的窗口函数的变换类似于抛物线,则二次或抛物线插值可能非常适合。 Sinc 插值适用于矩形窗口。

【讨论】:

【参考方案3】:

好,我们来一一道来:

我希望从声音信号中提取音高。

虽然我不是专家并且接受过最少的正式培训,但我想我知道这个问题的最佳答案。在过去的几年中,我进行了大量的搜索、阅读和实验。我的共识是,就准确性、复杂性、噪声鲁棒性和速度之间的权衡而言,自相关方法到目前为止是最好的音高检测器。除非您有一些非常具体的情况,否则我几乎总是建议使用自相关。稍后再详细介绍,让我回答您的其他问题。

你描述的是“倒谱分析”,这是一种主要用于从speech中提取音高的方法。倒谱分析完全依赖于信号泛音的丰富度强度。例如,如果你要通过倒谱分析传递一个纯正弦波,你会得到可怕的结果。然而,对于复杂信号的语音,存在大量泛音。 (顺便说一下,泛音是信号的元素,它以基本频率的 倍数 振荡,即我们感知的音高)。倒谱分析在检测具有缺少基频的语音方面具有鲁棒性。也就是说,假设您绘制了函数sin(4x)+sin(6x)+sin(8x)+sin(10x)。如果你看一下,很明显它与函数 sin(2x) 具有相同的频率。但是,如果您对该函数应用傅立叶分析,则对应于 sin(2x) 的 bin 将具有 量级。因此,该信号被认为具有“缺失的基频”,因为它不包含我们认为的频率的正弦曲线。因此,简单地选择傅立叶变换上的最大峰值对这个信号不起作用。

我以前使用过一种技术,它可以搜索 局部最大值的单个 FFT。当它遇到一个时,它使用一个 狡猾的技术(自上次 FFT 以来的相位变化)到更多 准确地将实际峰值放置在 bin 内。

您所描述的是相位声码器技术,可以更准确地测量给定部分的频率。但是,如果您使用的信号缺少基频分量或基频分量较弱,那么挑选最大 bin 的基本技术会给您带来麻烦。

我担心我在这里介绍的这种技术会丢失这种精度。

首先,请记住相位声码器技术只会更准确地测量单个分音的频率。它忽略了较高部分中包含的关于基频的信息。其次,给定一个不错的 FFT 大小,您可以使用峰值插值获得非常好的精度。这里的其他人已将您指向抛物线插值。我也建议这样做。

如果您以 44100 Hz 的间距对 4098 个样本数据块的 FFT 进行抛物线插值,间距约为 440 Hz,这意味着它将位于第 40 个 (430.66 Hz) 和第 41 个 (441.430664064) 个 bin 之间。假设this paper 在一般情况下大致正确,它表示抛物线插值将分辨率提高了一个数量级以上。这使得分辨率至少为 1 Hz,这是人类听觉的阈值。事实上,如果您使用理想的高斯窗,抛物线插值在峰值处精确(没错,精确。但是请记住,您永远不能使用真正的高斯窗,因为它在两个方向。)如果您仍然担心获得更高的准确性,您可以随时填充 FFT。这意味着在转换之前将零添加到 FFT 的末尾。结果表明,这相当于“sinc 插值”,是频率受限信号的理想插值函数。

我猜想在第二次 FFT 之后可以使用该技术来准确地获得基本面。但看起来信息在第 2 步中丢失了。

没错。相位声码器技术依赖于连续帧连接并具有特定相位关系的事实。但是,连续帧的 FFT 的对数幅度在相位方面显示相同的关系,因此在第二个 FFT 中使用这种变换是没有用的。

这种方法有意义吗?可以改进吗?

是的,是的,我将在最后详细说明我对自相关的改进。

我有点担心 对数平方分量;似乎有一个 vDSP 函数可以做到这一点:vDSP_vdbcon 然而,没有迹象表明它预先计算了一个日志表——我认为它没有,因为 FFT 函数需要调用并传递一个显式的预先计算函数进去。而这个函数没有。

我不知道 vDSP 库的细节,抱歉。

是否存在拾取谐波的危险?

在您原来的相位声码器峰值拾取技术中?是的。用倒谱法?不,不是真的,重点是它考虑了所有的谐波来获得它的频率估计。例如,假设我们的频率是 1。我们的泛音是 2,3,4,5,6,7,8,9 等 我们必须去掉所有的奇次谐波,即留下 2,4,6, 8 等,在基频开始与其泛音之一混淆之前将其移除。

有没有什么巧妙的方法让 vDSP 拉出最大值,先最大?

不知道 vDSP,但在一般情况下,您通常只需遍历所有这些并跟踪最大的。

谁能告诉我有关这项技术的一些研究或文献?

我在评论中给你的链接 P. 看起来不错。

此外,this 网站以理论和实践的方式对 DSP 主题提供了令人难以置信的深入和广泛的解释,包括各种音高提取、操作等。 (this 是指向网站索引的更通用链接)。我总是发现自己回到了它。有时如果你跳到它的中间可能会有点不知所措,但你总是可以按照每个解释回到基本的构建块。

现在是自相关。基本上,该技术是这样的:您获取(窗口)信号并对其进行不同数量的时间延迟。找到与您的原始信号最匹配的数量。那是基本时期。它有很多理论意义。您正在寻找信号的重复部分。

在实践中,与所有这些时间延迟的信号副本进行相关是很慢的。它通常以这种方式实现(在数学上是等效的):

对其进行零填充以使其原始长度加倍。进行 FFT。然后用它们的平方幅度替换所有系数,除了你设置为 0 的第一个系数。现在进行 IFFT。将每个元素除以第一个元素。这为您提供了自相关。从数学上讲,您正在使用循环卷积定理(查找),并使用零填充将线性卷积问题转换为循环卷积问题,这可以有效地解决。

但是,选择峰值时要小心。对于非常小的延迟,信号会很好地匹配自身,因为它是连续的。 (我的意思是,如果你将它延迟为零,它与自身完全相关)相反,选择第一个过零之后 的最大峰值。您可以像使用其他技术一样对自相关函数进行抛物线插值以获得更准确的值。

这本身将为您提供非常好的所有标准音高检测但是,您有时可能会遇到音高减半和音高加倍的问题。基本上问题在于,如果一个信号每 1 秒重复一次,那么它也每 2 秒重复一次。同样,如果它具有非常强的泛音,您可能会得到音调减半。因此,最大的峰可能并不总是您想要的。这个问题的一个解决方案是 Phillip McLeod 的 MPM 算法。思路是这样的:

您不想选择最大的峰,而是要选择足够大的第一个峰。您如何确定一个峰值是否足够大以供考虑?如果它至少与 A* 一样高,则为最大峰值,其中 A 是某个常数。 Phillip 建议我认为 A 的值在 0.9 左右。实际上,他编写的程序 Tartini 允许您实时比较几种不同的音高检测算法。我强烈建议 downloading 并尝试一下(它实现了倒谱、直接自相关和 MPM):(如果您在构建时遇到问题,请尝试使用说明 here。

我应该注意的最后一件事是关于窗口化。一般来说,任何平滑的窗口都可以。汉宁窗,汉明窗等希望你应该知道如何开窗。如果您想要更准确的时间测量,我还建议您使用重叠窗口。

顺便说一句,自相关的一个很酷的特性是,如果频率通过您正在测量的窗口部分呈线性变化,它将在窗口的中心处为您提供正确的频率。

还有一件事:我所描述的称为有偏自相关函数。这是因为对于更高的时滞,原始信号和时滞版本之间的重叠变得越来越少。例如,如果您查看已延迟 N-1 个样本的大小为 N 的窗口,您会看到只有一个样本重叠。所以这个延迟的相关性显然会非常接近于零。您可以通过将自相关函数的每个值除以样本重叠数得到它来补偿这一点。这称为无偏自相关。但是,一般而言,这样做会得到更差的结果,因为自相关的较高延迟值非常嘈杂,因为它们仅基于少数样本,因此减少它们的权重是有意义的。

如果您想了解更多信息,一如既往,谷歌是您的朋友。好的搜索词:自相关、基音检测、基音跟踪、基音提取、基音估计、倒谱等。

【讨论】:

这个答案对我帮助很大!很详细! +1。谢谢! 非常感谢杰里米。对问题和所有答案+1。我希望有一个+2。真的谢谢。 优秀的答案,感谢 Pi 的问题和 Jeremy 的出色回答。感谢分享这个。它的深度特别惊人,我相信你已经收集了很多年了。 为什么我们在通过 FFT 计算自相关时将第一个元素设置为零?【参考方案4】:

这是对用于音高确定的倒谱的简要分析。

首先让我们检查一个合成信号。

下图显示了合成稳态 E2 音符的倒谱,该音符使用典型的近直流分量、82.4 Hz 的基波和 82.4 Hz 整数倍的 8 个谐波合成。合成正弦曲线被编程为生成 4096 个样本。

在 12.36 观察显着的非直流峰值。倒谱宽度为 1024(第二个 FFT 的输出),因此峰值对应于 1024/12.36 = 82.8 Hz,非常接近真正的基频 82.4 Hz。

现在让我们检查一个真实的声学信号。

下图显示了真实原声吉他 E2 音符的倒谱。信号在第一次 FFT 之前没有加窗。观察 542.9 处显着的非 DC 峰值。倒谱宽度为 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

【讨论】:

【参考方案5】:

此答案旨在与 Jeremy Salwen 的帖子一起阅读,并回答有关文献的问题。

首先,重要的是要考虑什么是信号的周期性。对于给定的分析窗口,信号是否更接近全周期信号。

有关术语和数学的详细说明,请参阅此处https://en.wikipedia.org/wiki/Almost_periodic_function#Quasiperiodic_signals_in_audio_and_music_synthesis

简短的回答是,如果对于给定的分析窗口,信号是完全周期性的,或者如果信号是准周期性的并且分析窗口足够小以实现周期性,那么自相关 完成任务就足够了。 满足这些条件的信号示例如下:

纯正弦音色 具有长延音和稳定音高(无颤音)的弦乐器,在延音部分尤其如此,但在瞬态方面则不然。 吹得足够长的风管乐器。

不满足这些条件的信号示例如下:

打击乐声音 弦乐器或气管乐器的每个音符只保持很短的时间,或在很短的时间内改变 复杂的音乐,或基本上以不同音高演奏的多种乐器的组合。

对于使用自相关的音高检测,有一个关于如何在 Praat 中实现的教程:

http://www.pinguinorodriguez.cl/blog/pitch-in-praat/ 在普拉特球场 Praat 的音高检测算法的简要说明。这描述了名为“ac”的算法。 www.fon.hum.uva.nl/paul/praat.html 对采样声音的基频和谐波噪声比进行准确的短期分析。保罗·博尔斯马。 IFA 诉讼 17:97-110。

该论文详细描述了使用无偏自相关(Jeremy Salwen 使用的术语)进行音高检测,还表明它在音高检测方面优于有偏自相关。虽然它注意到自相关结果仅在窗口大小的一半内显着,但您不需要计算后半部分。

通过使用锥形窗口对信号进行窗口化,然后进行自相关来完成有偏的自相关。这减少了对音高检测有害的低频调制(缓慢时间尺度上的幅度变化)的影响,因为否则具有较大幅度的部分将给出较大的自相关系数,这将是首选。

Boersma 论文中使用的算法可以用 5 个步骤来描述:

    从要加窗的信号中移除 DC (x - x_avg) 使用锥度函数对信号进行窗口化(他认为使用 Hann 窗口或更好的 Gaussian 窗口) 自相关信号 将自相关函数除以所用窗口的自相关。 峰值拾取(类似于以前的算法)

需要注意的是,窗口的两端都将趋于零,并且窗口的自相关也将趋于零。这就是为什么无偏自相关的后半部分是无用的,它是在窗口末端附近被零除。

接下来是尹: - De Cheveigné、Alain 和 Hideki Kawahara。 “YIN,语音和音乐的基频估计器。”美国声学学会杂志 111.4 (2002): 1917-1930。

据我了解,YIN 论文还提供证据表明使用锥形窗口会对音高检测精度产生不利影响。有趣的是,它更喜欢不使用任何锥形窗口函数(它说明锥形窗口不会对结果带来任何改进,反而会使结果复杂化。)

最后是 Philip McLeod 的 SNAC 和 WSNAC(已由 Jeremy Salwen 链接):

Philip McLeod,用于音乐分析的快速、准确的音高检测工具,博士论文,奥塔哥大学计算机科学系,2008 年。 麦克劳德。 P,威维尔。 G,“寻找音高的更聪明的方法”,Proc。国际计算机音乐会议,西班牙巴塞罗那,2005 年 9 月 5 日至 9 日,第 138-141 页。 麦克劳德。 P,威维尔。 G,“音乐音高的可视化”,PROC。 Computer Graphics International,日本东京,2003 年 7 月 9 日至 11 日,第 300-303 页。

可以在 Miracle.otago.ac.nz/tartini/papers.html 上找到它们

我没有深入了解它,但有人提到它是一种减少有偏自相关锥形窗口的不利影响的方法,与 Boersma 使用的方法不同。 (请注意,我没有遇到任何关于 MPM 的事情,所以我不能说什么)

最后一个建议是,如果您正在制作乐器调谐器,与自相关相比,更简单且效果更好的方法是使用具有预定频率的纯正弦信号的互相关。

杰里米·萨尔文:

也就是说,假设您绘制了函数 sin(4x)+sin(6x)+sin(8x)+sin(10x)。如果你看一下,很明显它与函数 sin(2x) 具有相同的频率。但是,如果您对该函数应用傅立叶分析,则对应于 sin(2x) 的 bin 的量级为零。因此,该信号被认为具有“缺失的基频”,因为它不包含我们认为的频率的正弦曲线。

我想说,虽然给定的信号在 \omega=2 处是周期性的,但它与函数 sin(2x) 的频率不同。正如傅立叶分析将表明分量 sin(2x) 的大小为零。 这与信号的音高、频率和基频之间存在关系有关,但它们不同且不可互换。重要的是要记住,音高是一种主观测量,它取决于感知它的人。 它看起来好像与 sin(2x) 具有相同的频率,这就是我们在视觉上感知它的方式。 同样的效果也同样发生在音高和音频感知上。立即想到的例子是 Beats,即当有两个频率接近但不同的正弦曲线时听到的感知音高。

【讨论】:

以上是关于用于音高检测的倒谱分析的主要内容,如果未能解决你的问题,请参考以下文章

用于查找歌曲音高的音频分析器

如何检测录制的声音样本的音高

频域分析的目的是啥

音频处理梅尔频率倒谱系数(MFCC)

梅尔频率倒谱系数如何工作?

语音处理基于matlab GUI录音与音频时域+频域+倒谱+功率谱分析含Matlab源码 070期