【问题标题】:How to use cepstral?如何使用倒谱?
【发布时间】:2011-06-22 23:00:06
【问题描述】:

最近我问了这个问题:How to get the fundamental frequency from FFT?(其实不需要看)

我现在的疑惑吧:倒谱算法怎么用?

我只是不知道如何使用它,因为我知道的唯一语言是 ActionScript 3,因此我很少参考 C、Java 等中的本机函数,以及我应该如何实现他们在 AS 上。大多数文章都是关于这些语言的 =/ (虽然,欢迎使用除 AS 以外的其他语言的答案,请解释一下脚本的工作原理)

我找到的关于倒谱的文章以查找 FFT 结果的基频告诉我应该这样做:

signal → FT → abs() → square → log → FT → abs() → square → power cepstrum

数学上: |F{log(|F{f(t)}|²)}|²

重要信息:

  • 我正在 Flash 中开发一个 GUITAR TUNER
  • 这是我第一次处理高级声音
  • 我正在使用 FFT 从到达用户麦克风的信号中提取频率区间,但我无法从中获取基频

我不知道:

  • 如何在 ARRAY 中应用正方形(我的意思是,我的 FFT 给我的数据是一个数组。我应该将它自己相乘吗?当我尝试 fftResults * fftResults 时,ActionScript 的调试会引发错误)
  • 如何应用“日志”。即使我只有一个号码,我也不知道如何申请。
  • 复倒谱和功率倒谱有什么区别。另外,我应该使用它们中的哪一个?我正在尝试开发吉他调音器。

谢谢!

【问题讨论】:

    标签: arrays actionscript fft frequency frequency-analysis


    【解决方案1】:

    自相关是最简单、最合乎逻辑的方法,也是最好的起点。

    要使其发挥作用,从一个简单的自相关开始,然后在必要时按照 YIN 提供的大纲对其进行改进。 (YIN 基于与细化的自相关。但您是否需要这些细化取决于您的具体情况。)通过这种方式,您可以边做边学,而不是试图一次性理解整个事情。

    虽然 FFT 方法也可以工作,但它们有点令人困惑。问题是您真正追求的是时期,而 FFT 并不能很好地代表这一点。缺少的基波就是一个很好的例子,如果你有 2Hz 和 3Hz,基波是 1Hz,但在 FFT 中没有,而 1Hz 在基于时间的表示(例如自相关)中是显而易见的。除此之外,泛音不一定是谐波和噪音等......所有这些问题通常最好从直接解决问题的方法开始。

    【讨论】:

    • 你知道一些自相关代码给我看吗?此外,自相关是否在某些时候基于 FFT?
    • 自相关是很容易实现的,不过具体做什么取决于你有什么工具,我不知道actionscript。大多数对数组进行数学运算的库都有一个“相关”函数,然后只是将数据与自身相关联。如果您没有这种类型的东西,这里有一个 C++ 示例 (koders.com/cpp/…)。但是编写自己的很容易,只需将对象与自身的移位版本相乘即可。
    • 对于您问题的第二部分:使用 FFT 计算自相关有时会更快,但现在,将其视为纯粹的计算技巧。无论是使用 FFT 还是不使用 FFT,都可以做到这一点。
    【解决方案2】:

    请注意,FFT 的输出是一个复数值数组,即每个 bin = re + j*im。我认为您可以结合 abs 和 square 运算并为每个 bin 计算 re*re + im*im。这为每个 bin 提供了一个正值,显然您可以很容易地计算每个 bin 的 log 值。然后,您需要对该对数平方数据进行第二次 FFT,并再次使用第二次 FFT 的输出,您将为每个 bin 计算 re*re + im*im。然后,您将拥有一组正值,这些正值将具有一个或多个峰值,代表您输入的一个或多个基频。

    【讨论】:

    • 我得到的数组示例:[0.123123,0.4809,0.0498356,0.000231,82.31240987,0.1230987 ..... ................... 值 1020,值 1021,值 1022,值 1023,值 1024]。这些值只是数字。它们并不复杂,不是吗?
    • @Lucas:这取决于您使用的特定 FFT 以及输入和输出数据的组织方式。有些会使用复杂的数据类型,有些会交错实部和虚部,有些会在数组的前半部分包含所有实部,在后半部分包含虚部(实际上是两个数组) - 你需要阅读和了解您选择的 FFT 的文档。
    • @PaulR:对 N 个样本进行 FFT 得到 N 个值,对应于 N/2 个复数(bins)。但是,在计算平方幅度之后,我只剩下 N/2 个值,在 FFT 上再次只给出 N/4 个复数。真的吗?我们如何计算第二个 FFT 之后的 bin 频率?你能纠正/帮助我吗?
    • @Ravi:不,N 个样本为您提供了 N 个复杂的 FFT 箱。但是,如果您的输入信号是纯实数,则复数 FFT 输出箱中的 N/2 是冗余的,因为它们与其他 N/2 箱具有共轭对称性,因此可以忽略。但它们仍然有效,并且是逆 FFT 运算所必需的。
    • 非常感谢保罗。由于复数的后半部分是复共轭,将第一个 N/2 值的对数幅度值复制到其他 N/2 值并将它们用于第二次 FFT(倒谱分析)应该没问题吧?我问这个是因为我使用的 FFT 库会自动忽略值的共轭部分。
    【解决方案3】:

    有很多方法可以找到基频 (F0)。

    对于 Java 等语言,有许多库已经实现了这些类型的算法(您可以研究它们的源代码)。

    • MFCC(基于倒谱)在Comirva(开源)中实现。
    • Audacity(测试版!)(开源)提供倒谱、自相关、增强自相关,
    • 基于自相关的Yin (example)
    • 在 FFT 之后查找最大信号值

    所有这些算法可能对您很有帮助。然而,获得 F0(以 Hz 为单位的一个值)的最简单方法是使用 Yin。

    【讨论】:

    • 这些方法是否足以制作吉他调音器?我的意思是...我需要一个非常高的精度!
    • 这取决于很多因素 - 麦克风质量、噪音等 有时可能还需要一些去噪算法。您可以运行该 Yin 示例 - 它是从麦克风捕获声音并显示 f0 的应用程序 - 使用普通(硬件?)调谐器进行测试和验证。
    • 我读了一半:recherche.ircam.fr/equipes/pcm/cheveign/ps/… 它看起来像是某种文档,但它正在煎熬我的大脑。我不想惹恼你,但你能告诉我应该如何实现这些方程式吗?在信号中,在 fft 结果中,以及如何?非常感谢您的帮助!
    • 1.测试该示例应用程序是否可以使用吉他 2. 如果工作研究(理解)该应用程序代码(Yin 类)并尝试将其重写为动作脚本。这样做你也会学习一点 java ;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-10
    • 2012-02-28
    • 1970-01-01
    • 2010-12-09
    • 1970-01-01
    相关资源
    最近更新 更多