【问题标题】:How do I implement a bandpass filter in C (Purpose: pitch detection)?如何在 C 中实现带通滤波器(目的:音高检测)?
【发布时间】:2011-05-05 11:38:27
【问题描述】:

我最近问this question

我正在寻找一种算法来检测音高。其中一个答案建议我使用初始 FFT 来获得基本频率响应,找出哪些频率被发声,然后在每个感兴趣的区域使用带通滤波器:

稍微高级的算法可以做这样的事情:

  1. 粗略检测音高频率(可以使用 DFT 完成)。
  2. 带通信号过滤隔离音调频率。
  3. 计算过滤信号中两个峰值之间的样本数。

现在我可以做第一步了(我正在为 iOS 编码,Apple 有一个框架(加速框架)用于执行 FFT 等。

我已经开始here:但我可以看到问题:一个可以区分所有可能的音符的 FFT 需要大量样本,我不想执行太多不必要的操作计算,因为我的目标是移动设备。

所以我试图弄清楚上面的这个答案,但我不明白如何将带通滤波器的概念应用到代码中。

谁能帮忙?

【问题讨论】:

  • 您已经在 SO 上提出了很多关于音高检测的问题,但您似乎仍然不太了解 (a) pitch频率或(b)需要选择适合您尝试分析的声音类型(例如语音、音乐等)的音高检测算法。我建议您在尝试实现某些东西之前多阅读一些基础知识,否则您很可能会在错误的路线上花费大量不必要的精力。
  • 这就是我问这么多问题的原因——我试图在开始做某事之前弄清楚什么是实用的,什么不是。我正在慢慢了解这个问题。
  • @Ohmu:您可能想返回并重新阅读之前的一些答案,以及提供的链接。我感觉你是在没有先掌握基础知识的情况下尝试跳入实现。祝你好运。
  • @Paul R:据我了解,声音由基频及其谐波组成。我已经完成了傅里叶变换、DFT、FFT 的数学运算,并遇到了实际限制;检测唱歌的音调是否略微偏离但实际音符需要较低的基频,这需要较大的采样窗口,这需要大量的 CPU 或大幅降低麦克风采样率。因此,我正在考虑执行基本的 FFT 以获得频域中感兴趣的一般区域,并以某种方式改进结果。
  • @Paul R:因此我对答案的兴趣给了我建议我在这个阶段使用带通滤波器。但是,我无法确定这是否是一个实用的建议。我还研究了其他建议;自相关实际上与将源信号乘以所需频率的正弦波并在整数个波长上积分相同,这可能有效,但需要一些工作才能从输出中破译稍微偏离的频率。我真的还在尝试从各个角度刺激它。

标签: c algorithm filter detection pitch


【解决方案1】:

由于您只想检测单个频率,因此执行 DFT 然后只使用其中一个值将是一种过度杀伤力。

您可以实现Goertzel algorithm。就像this C implementation 用于通过电话线检测 DTMF 音,来自 FreePBX 源代码:

float goertzel(short x[], int nmax, float coeff) {
    float s, power;
    float sprev, sprev2;
    int   n;

    sprev = 0;
    sprev2 = 0;
    for(n=0; n<nmax; n++) {
        s = x[n] + coeff * sprev - sprev2;
        sprev2 = sprev;
        sprev = s;
    }

    power = sprev2*sprev2 + sprev*sprev - coeff*sprev*sprev2;

    return power;
}

如您所见,该实现非常简单,并且对于单频非常有效。查看链接以了解带和不带浮点的不同版本,以及如何使用它。

【讨论】:

    【解决方案2】:

    在维基百科中,检查低通滤波器和高通,然后加入它们以制作带通滤波器。维基百科有这两个过滤器的代码实现。

    http://en.wikipedia.org/wiki/Low-pass_filter http://en.wikipedia.org/wiki/High-pass_filter

    【讨论】:

    • 我目前正忙于神经网络,并且使用带通滤波器或 FFT 的重要性超过了。这就是我遇到你的问题的方式:)
    【解决方案3】:

    过滤器设计相当复杂。有很多技巧。首先,您必须决定要创建哪种过滤器。有限脉冲响应 (FIR)?无限脉冲响应 (IIR)?然后,您选择一种算法来设计该类型的过滤器。 Remez 算法常用于 FIR 滤波器设计。去这里看看我所指的复杂性:http://en.wikipedia.org/wiki/Remez_algorithm

    创建滤波器的最佳方法是使用现有的信号处理库。一个快速的谷歌搜索把我带到了这里:http://spuc.sourceforge.net/

    鉴于您的应用程序是什么,您可能想了解匹配过滤器。我不确定它们在这里是否相关,但它们可能是相关的。 http://en.wikipedia.org/wiki/Matched_filter

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-08
      • 2012-12-02
      • 2016-03-23
      • 2017-05-09
      • 2017-09-02
      • 2018-11-03
      相关资源
      最近更新 更多