如何在C中实现带通滤波器(目的:音调检测)?

时间:2010-11-05 07:27:14

标签: algorithm filter detection pitch

我最近问过this question

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

  

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

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

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

我已经开始了here:但是我可以看到问题:一个可以区分所有可能的音符的FFT会需要大量的样本,而且我也不想这样做因为我的目标是移动设备,所以计算量很大。

所以我试图理解上面的答案,但我不明白如何将带通滤波器的概念应用于代码。

有人可以帮忙吗?

3 个答案:

答案 0 :(得分:3)

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

创建过滤器的最佳方法是使用现有的信号处理库。 Google快速搜索引导我:http://spuc.sourceforge.net/

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

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

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

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

bin/spring stop

如您所见,对于单个频率,该实现相当简单且非常有效。检查链接中有无浮点的不同版本,以及如何使用它。