FIR濾波器的設計和實現



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使用非常的方便,下面我們用一個例子來說明:
首先生成濾波器參數:

    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);

  

使用濾波器參數處理音頻信號:

 

[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代碼的簡單例子:

 

#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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM