Fork me on GitHub

随笔 - 997  文章 - 5  评论 - 181  阅读 - 300万 


FIR的作用和价值

  FIR(Finite Impulse Response)滤波器:有限长单位冲激响应滤波器,又称为非递归型滤波器,是数字信号处理系统中最基本的元件,它可以在保证任意幅频特性的同时具有严格的线性相频特性,同时其单位抽样响应是有限长的,因而滤波器是稳定的系统。因此,FIR滤波器在通信、图像处理、模式识别等领域都有着广泛的应用。在音频领域,FIR滤波器是一个无法绕过的滤波器,它可以让你的系统过滤掉特定频段的音频信号。按照功能,可以分为:高通FIR滤波器。低通FIR滤波器,带通FIR滤波器。使用公式解析,如下:

equation 1: y(n)=\sum_{k=0}^{N-1}h(k)x(n-k)

equation 2: y(n)=\sum_{k=n-(N-1)}^{n}h(n-k)x(k)

 

滤波器matab设计

  FIR滤波器使用matlab使用非常的方便,下面我们用一个例子来说明:
首先生成滤波器参数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
    function Hd = fir_256
    %FIR_8 Returns a discrete-time filter object.
     
    % MATLAB Code
    % Generated by MATLAB(R) 9.4 and DSP System Toolbox 9.6.
    % Generated on: 09-Apr-2019 11:22:46
     
    % FIR Window Lowpass filter designed using the FIR1 function.
     
    % All frequency values are in Hz.
    Fs = 16000;  % Sampling Frequency
     
    N    = 256;        % Order
    Fc   = 7200;       % Cutoff Frequency
    flag = 'scale'% Sampling Flag
     
    % Create the window vector for the design algorithm.
    win = hamming(N+1);
     
    % Calculate the coefficients using the FIR1 function.
    b  = fir1(N, Fc/(Fs/2), 'low', win, flag);
    fid = fopen('coef_7k.txt','wt');
 
for inum=1:length(b)
    fprintf(fid,'%.4f,',b(inum));
end
 
fclose(fid);
 
 
    Hd = dfilt.dffir(b);

  

使用滤波器参数处理音频信号:

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[x, fs] = audioread('mic1_data.wav');
t = (0:length(x)-1)/Fs;
figure(1);
plot(t,x);
title("input signal ")
 
Hd=fir_256;
 
d=filter(Hd,x);
figure(2);
plot(t,d);
title("fir process filter ")
 
audiowrite('mic_fir_5.wav', d, fs);

  

滤波器c代码实现

  绝大多数FIR滤波器都需要在芯片中使用,所以,C 语言的滤波器是一个非常有价值的滤波器。这里给出一个C代码的简单例子:

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include <stdio.h>
#include "system.h"
#include "alt_types.h"
#include <time.h>
#include <sys/alt_timestamp.h>
#include <sys/alt_cache.h>
 
float microseconds(int ticks)
{
  return (float) 1000000 * (float) ticks / (float) alt_timestamp_freq();
}
 
void start_measurement()
{
  /* Flush caches */
  alt_dcache_flush_all();
  alt_icache_flush_all();  
  /* Measure */
  alt_timestamp_start();
  time_1 = alt_timestamp();
}
 
void stop_measurement()
{
  time_2 = alt_timestamp();
  ticks = time_2 - time_1;
}
 
float floatFIR(float inVal, float* x, float* coef, int len)
{
  float y = 0.0;
  int i;
  start_measurement();
  for (i = (len-1) ; i > 0 ; i--)
  {
    x[i] = x[i-1];
    y = y + (coef[i] * x[i]);
  }
  x[0] = inVal;
  y = y + (coef[0] * x[0]);
  stop_measurement();
  printf("%5.2f us", (float) microseconds(ticks - timer_overhead));
  printf("(%d ticks)\n", (int) (ticks - timer_overhead));  
  printf("Sum: %f\n", y);
  return y;
}
 
int main(int argc, char** argv)
  /* Calculate Timer Overhead */
  // Average of 10 measurements */
  int i;
  timer_overhead = 0;
  for (i = 0; i < 10; i++) {     
    start_measurement();
    stop_measurement();
    timer_overhead = timer_overhead + time_2 - time_1;
  }
  timer_overhead = timer_overhead / 10;     
  printf("Timer overhead in ticks: %d\n", (int) timer_overhead);
  printf("Timer overhead in ms:    %f\n",
     1000.0 * (float)timer_overhead/(float)alt_timestamp_freq()); 
  float coef[4] = {0.0299, 0.4701, 0.4701, 0.0299};
  float x[4] = {0, 0, 0, 0}; /* or any other initial condition*/
  float y;
  float inVal;
 
  while (scanf("%f", &inVal) > 0)
  {
    y = floatFIR(inVal, x, coef, 4);
  }
  return 0;
}

  

后记

  其实,C代码实现的FIR滤波器有不少优化空间,由于公司保密原因,这里就不给出自己的公司的代码了。有兴趣的朋友可以自己研究一下。

 

参考文档:

 

https://codereview.stackexchange.com/questions/32444/fir-filters-in-c

https://sestevenson.wordpress.com/implementation-of-fir-filtering-in-c-part-1/

https://os.mbed.com/handbook/Matlab-FIR-Filter

posted on   虚生  阅读(990)  评论(0编辑  收藏  举报
编辑推荐:
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
历史上的今天:
2019-12-18 c代码中while循环的一个死机问题引发的思考
2017-12-18 python中stack在实际中的简单应用之平衡符号
2017-12-18 python中两种栈实现方式的性能对比
2017-12-18 python实现stack并测试
点击右上角即可分享
微信分享提示