題目:
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...