IIR數字濾波器實現

2021-05-23 18:26:51 字數 3341 閱讀 7926

題目:

16k取樣率音訊資料下取樣到

8k取樣率

求解方案分析:直接每隔乙個取乙個取樣值,這樣就可以得到

8k取樣率的資料。但是這樣明顯會有問題。按照取樣率變換理論,首先應該通過乙個低通濾波器,濾掉

[pi/2, pi]

這個區間上的頻率,以防止下取樣造成的頻率混疊。這個低通濾波器在很多書上都用

fir濾波去實現,並且可以用

fir濾波的多相結構去實現。這樣濾波和下取樣過程可以互換位置。即先下取樣再進行多相

fir濾波。

在嵌入式裝置上

fir濾波會占用較長的時間,為此,我們可以採用

iir濾波器來做。濾波器的設計採用

matlab

的fdatool

採用最小

p階範數設計

iir濾波器的幅頻特性較好。濾波器階數設定為

6階,需要濾除4k到

8k的頻率段,才能保證無混疊失真。實際由於濾波器的特性沒法做到理想的狀態,選擇濾波器截止頻率為

3800hz

,3600

到3800

為過渡頻寬。其它選項採用預設設定。設計的濾波器幅度響應如下圖:

生成的濾波器係數檔案如下:/*

* filter coefficients (c source) generated by the filter design and analysis tool *

* generated by matlab(r) 7.6 and the signal processing toolbox 6.9. *

* generated on: 03-dec-2010 10:41:03 *

*/

/* * discrete-time iir filter (real)

* -------------------------------

* filter structure: direct-form ii, second-order sections

* number of sections: 3

* stable: yes

* linear phase: no */

/* general type conversion for matlab generated c-code*/

#include

"tmwtypes.h"

/*

* expected path to tmwtypes.h

* d:/matlab/r2008a/extern/include/tmwtypes.h */

#define

mwspt_nsec 7

const

intnl[mwspt_nsec] = ;

const

real64_t

num[mwspt_nsec][3] = , ,

, ,, ,

}; const

intdl[mwspt_nsec] = ;

const

real64_t

den[mwspt_nsec][3] = , ,

, ,, ,

}; 上述係數是3個2階節iir結構的級聯。可以轉換為我們熟悉的b/a的形式如下:

double

a[3][3] = , ,

};double

b[3][3] = , ,

, };

注意上面係數檔案中還有乙個增益:

double

gain = 0.09065504059673;

這個增益最好在第一級實現以後加入運算。這樣可以減小誤差,保證資料 動態範圍不被溢位。尤其是在定點計算的時候尤為如此。

乙個2階節結構是下面這樣乙個表示式:

實現上面這個表示式需要

4個過去的歷史值,把它定義在結構體

typedef

struct

tag_ iir_state_2order

iir_state_2order;

呼叫下面函式之前需要把上述結構體所有值初始化為零。濾波按一幀一幀資料進行。

#define

one_frame_sample_size

1024

void

cy_signal_filter_by_iir(signed

short* pcmin, iir_state_2order* filter_state, float

a, float

b, signed

short* pcmout)

if(tmp

<= -32768)

pcmout[i] = (signed

short)tmp;

filter_state->y2 = filter_state->y1;

filter_state->y1 = tmp; }

}有乙個簡單的技巧可以把上面的計算簡化,使得歷史狀態數由4減少為2。定義下面的表示式:

結構體定義如下:

typedef

struct

tag_ iir_state_2order

iir_state_2order;

void

cy_signal_filter_by_iir(signed

short* pcmin, iir_state_2order* filter_state, float

a, float

b, signed

short* pcmout)

if(tmp_fl

<= -32768)

pcmout[i] = (signed

short)tmp_fl; }

} 有個上面的基礎,我們來實現上面設計的6階

iir濾波器。 6

階節分解為3個

2階節級聯實現。每個

2階節需要

2個歷史狀態,總共需要

6個歷史狀態。結構體定義如下:

typedef

struct

tag_iir_state_3order

iir_state_6order;

**中陣列a,b,還有gain的定義見第一部分。

void

cy_signal_filter_by_6th_iir(signed

short* pcmin, iir_state_6order* filter_state, int

sample_size)

if (x3

<= -32768)

pcmin[i] = (signed

short)x3;

} }

最後看下濾波的效果:

濾波之後的頻譜:

濾波效果不錯,下面可以進行下取樣了。

IIR數字濾波器設計

1 iir數字濾波器的差分方程和系統函式 iir數字濾波器是一類遞迴型的線性時不變因果系統,其差分方程可以寫為 y n i 0maix n i i 1nbiy n i y n i 0maix n i i 1nbiy n i 進行z變換,可得 y z i 0maiz ix z i 1nbiz iy z...

數字濾波器 FIR和IIR

傳統的線性數字濾波器一般有兩種型別,有限衝激響應 fir 濾波器和無限衝激響應 iir 濾波器。fir數字濾波器只用當前和過去的輸入樣點值來得到當前的輸出樣點值,過去的輸出樣點值乙個也未用到。給定乙個有限持續時間的非0輸入值,fir濾波器給出乙個有限持續時間的非0輸出值。給定乙個全為0的輸入,fir...

基於Python的IIR數字濾波器

import numpy as np from scipy.fftpack import fft from scipy import signal import matplotlib.pyplot as plt from matplotlib.pylab import mpl mpl.rcparam...