根据频率响应计算FIR系数

时间:2011-10-06 18:02:07

标签: c# c++ signal-processing fft

我有一个幅度频率响应点列表。幅度以分贝给出。

任务是将此AFR列表导出到某些硬件DSP设备的一组系数。我知道这个设备的文件格式。该器件的规格表明它需要12288个系数,DSP有2个FIR滤波器模块(每个6144个抽头)。这个想法是在加载这些系数之后,该设备应该作为均衡器工作,根据初始的放大频率点列表转换信号。

我发现FIR滤波器的系数可以通过对所需频率响应进行逆傅里叶变换并使用一些窗函数(最好不是矩形)来计算。

问题在于我不擅长信号处理,我对FIR并不太了解,我使用FFT来获取音频数据的频率响应,但我仍然对FFT和相关的东西有一个非常模糊的想法的工作原理。

点的计算应该用C#或C ++完成(我擅长创建C ++ / CLI包装器),所以我可以将它集成到现有的应用程序中。 导出过程不是时间关键,因此我可以使用简单和慢速的算法,但无论如何,它不应该在中档计算机上花费超过一分钟。

是否有任何免费的库或代码可以从幅频响应数据中获取FIR系数?

最好的解决方案就像是一个“黑匣子”,所以我可以只提供AFR点列表并输出12288个系数,但我还要感谢多个库/代码片段,只要它可以放到很容易。

其他信息:

  • 将通过此FIR传输的音频的采样频率为44100 Hz

  • 信号的整体特性可以宽松地定义为“音乐”,FIR将用于均衡高质量音频,因此任何错误和信号失真都是可以接受的,如果它们不能被训练有素的耳朵听到高端音频系统

  • 理论上,初始AFR点的相邻幅度之间的差异可能在[0 dB ... 80 dB]范围内,但在实际测试中它们通常在[0 dB ... 2 dB]范围内

  • AFR点与它们之间的距离越来越远,第一点是 20.17246114 20.68984457 和最后两个 21632.14039 21754.41533

使用以下公式计算得分:

       float x;
       for(int i = 0; i<bandPoints; i++){
               x = (((float)i + 1) / ((float)(bandPoints + 2)));
               bandsHz[i] = ((x*x)*(22000-20))+20; // 20...22000
       }

1 个答案:

答案 0 :(得分:5)

寻找良好FIR系数的标准方法是使用“Remez交换”算法。我找到了一些代码的链接(我自己没有尝试过),你可能会发现它很有用:http://www.janovetz.com/jake/remez/remez-19980711.zip。另一个要搜索的关键词是“Parks-McClellan”。

算法的输入是幅度与频率的描述以及一组权重因子与频率的关系,描述了满足该频率的幅度要求的相对重要性。然后,算法在mini-max意义上找到最佳滤波器(最小化最大误差)。