从频率响应计算FIR系数

Calculating FIR coefficients from frequency response

本文关键字:FIR 系数 计算 响应 频率      更新时间:2023-10-16

我有一个振幅频率响应点列表。振幅以分贝表示。

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

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

问题是我不擅长信号处理,我不太了解第一,我用FFT从音频数据中获得频率响应,但我仍然对FFT和相关的东西是如何工作的有一个相当模糊的想法。

计算点应该在c#或c++中完成(我擅长创建c++/CLI包装器),这样我就可以将其集成到已经存在的应用程序中。导出过程不是时间关键,所以我可以使用简单而缓慢的算法,但无论如何,在中档计算机上它应该不超过一分钟。

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

最好的解决方案是类似于"黑盒"的东西,所以我可以只提供AFR点列表并得到12288个系数,但我也会感激多个库/代码片段,如果只有它可以很容易地放在一起。

额外的信息:

  • 将通过该FIR的音频的采样频率为44100 Hz

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

  • 初始AFR点相邻振幅之间的差理论上可以在[0 dB ..]80分贝],但在实际测试中,它们通常在[0分贝…2 dB)

  • AFR点之间的距离越远,越靠前20.1724611420.68984457最后两个21632.1403921754.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
       }

找到好的FIR系数的标准方法是使用"Remez交换"算法。我找到了一些代码的链接(我自己没有尝试过),您可能会觉得有用:http://www.janovetz.com/jake/remez/remez-19980711.zip。另一个搜索关键词是"帕克斯-麦克莱伦"。

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