窗函数法设计滤波器并且matlab/C语言实现

本文介绍滤波器的设计方法与滤波器的实现过程。

基于窗函数的方法是最为简单的设计方法,并且实际性能也还可以,并且有着计算量小的优点,在工程中应用广泛。本文介绍两种:多个矩形窗/三角窗及联/并联的方法设计滤波器。

本文中统一采样率为4Hz,另外采用截止波长lambda代替滤波器设计参数截止频率f,两者的关系为lambda = 1/f。

矩形窗的系统函数可以写成:
W ( z ) = 1 2 M + 1 z M − z − M − 1 1 − z − 1 W(z)=\frac{1}{2 M+1} \frac{z^{M}-z^{-M-1}}{1-z^{-1}} W(z)=2M+111z1zMzM1

W ( Ω ) = 1 N sin ⁡ ( N Ω / 2 ) sin ⁡ ( Ω / 2 ) , N = 2 M + 1 W(\Omega)=\frac{1}{N} \frac{\sin (N \Omega / 2)}{\sin (\Omega / 2)}, \quad N=2 M+1 W(Ω)=N1sin(Ω/2)sin(NΩ/2),N=2M+1

对应三角窗表示为:
W ( z ) = z M − 2 + z − M M 2 ( 1 − z − 1 ) 2 W ( Ω ) = 1 M 2 ( sin ⁡ ( M Ω / 2 ) sin ⁡ ( Ω / 2 ) ) 2 \begin{array}{l} W(z)=\frac{z^{M}-2+z^{-M}}{M^{2}\left(1-z^{-1}\right)^{2}} \\ W(\Omega)=\frac{1}{M^{2}}\left(\frac{\sin (M \Omega / 2)}{\sin (\Omega / 2)}\right)^{2} \end{array} W(z)=M2(1z1)2zM2+zMW(Ω)=M21(sin(Ω/2)sin(MΩ/2))2
下面设计一个两个矩形窗及联的低通滤波器Fir1,两个滤波器的窗长分别是101和81。分析幅频特性的方法参考下面:

lamda = 1:0.1:10000;
pesi  = 1./lamda;           %空间域频率
omega = 2*pi*pesi*0.25;
figure1 = figure('Color',[1 1 1]);
semilogx(lamda, abs(...
  1.*wincau(101,omega).*wincau(81,omega)),'LineWidth',1);hold on;
function Tri = triCau(N,omega)
M1 = (N-1)/2;
for i=1:length(omega)
Tri(i)= ((sin(omega(i)*M1/2)/sin(omega(i)/2))/M1)*((sin(omega(i)*M1/2)/sin(omega(i)/2))/M1);
end
end
function Rec = wincau(N3 , omega)
for i=1:length(omega)
Rec(i) = ((sin(omega(i)*N3/2)/sin(omega(i)/2))/N3);
end
end

20210322170625

当然也可以用这种方法设计高通滤波器:

semilogx(lamda, abs(...
  1-1.*wincau(101,omega).*wincau(81,omega)),'LineWidth',1);hold on;

下面介绍在程序中的实现方法,设计滤波器形式为:3个矩形窗及联为fir1,2个矩形窗及联为fir2,再将fir1与fir2并联,得到一个滤波器形式如下:

20210322171531

在滤波器的实现过程中,需要考虑数组存放的问题,以及并联的滤波器的对齐的问题。实现代码参考如下:

clear all;
x = 0:0.25:1e4;
lambda = 62;
amcol = sin(2*pi/lambda*x);

%% 参数配置
NRec_1 = 201;
NRec_2 = 101;
NRec_3 = 251;
TriM1 = (NRec_1-1)/2;
TriM2 = (NRec_2-1)/2;
TriM3 = (NRec_3-1)/2;
N = 2048;
data1 = zeros(N,1);
data2 = zeros(N,1);
data3 = zeros(N,1);
center_pos1 = 1000;
center_pos2 = center_pos1 - TriM2;
center_pos3 = center_pos2 - TriM3;
RecSum1 = 0;
RecSum2 = 0;
RecSum3 = 0;

%% 并联的滤波器的参数配置
SecN1 = 45;
SecN2 = 89;
SecM1 = (SecN1-1)/2;
SecM2 = (SecN2-1)/2;
Seccenter_pos1 = center_pos3 + SecM2;
Seccenter_pos2 = center_pos3;

Seccenter_pos1 = 1000;
Seccenter_pos2 = Seccenter_pos1 - SecM2;
Secdata1 = zeros(N,1);
Secdata2 = zeros(N,1);
SecRecSum1 = 0;
SecRecSum2 = 0;


%% 
for i = 1:length(amcol)
   %% 第一层
   input_index = center_pos1 + TriM1;
   data1( find_index(input_index)) = amcol(i);
   RecSum1 = RecSum1 + (data1(find_index(center_pos1 + TriM1 )) - data1(find_index( center_pos1 - TriM1 - 1 )))/NRec_1 ;
   
   %% 第二层
   input_index = center_pos2 + TriM2;
   data2( find_index(input_index)) = RecSum1;
   RecSum2 = RecSum2 + (data2(find_index(center_pos2 + TriM2 )) - data2(find_index( center_pos2 - TriM2 - 1 )))/NRec_2;
   
   %% 第三层
   input_index = center_pos3 + TriM3;
   data3( find_index(input_index)) = RecSum2;
   RecSum3 = RecSum3 + (data3(find_index(center_pos3 + TriM3 )) - data3(find_index( center_pos3 - TriM3 - 1 )))/NRec_3;
   
   %% second 第一层
   input_index = Seccenter_pos1 + SecM1;
   Secdata1( find_index(input_index) ) = data1(find_index( center_pos3 + SecM1 + SecM2 ));
   SecRecSum1 = SecRecSum1 + (  Secdata1(find_index(Seccenter_pos1 + SecM1 )) - Secdata1(find_index( Seccenter_pos1 - SecM1 - 1 )) )/SecN1;
   
   %% second 第二层
   input_index = Seccenter_pos2 + SecM2;
   Secdata2( find_index(input_index)) = SecRecSum1;
   SecRecSum2 = SecRecSum2 + ( Secdata2(find_index(Seccenter_pos2 + SecM2 )) - Secdata2(find_index( Seccenter_pos2 - SecM2 - 1 )) )/SecN2;
   %% 计算结果
   yout(i) = data1(center_pos3) - 1.5 * RecSum3 + 0.5 * SecRecSum2;%%center_pos3象征着延时的点数
   
   %% 更新
   center_pos1 = center_pos1+1;
   center_pos2 = center_pos2+1;
   center_pos3 = center_pos3+1;
   center_pos1 = find_index(center_pos1);
   center_pos2 = find_index(center_pos2);
   center_pos3 = find_index(center_pos3);
   
   Seccenter_pos1 = Seccenter_pos1 + 1;
   Seccenter_pos2 = Seccenter_pos2 + 1;
   Seccenter_pos1 = find_index(Seccenter_pos1);
   Seccenter_pos2 = find_index(Seccenter_pos2);
end

%% 下面说明了延时
figure1 = figure('Color',[1 1 1]);plot(yout(TriM1+TriM2+TriM3+1:end));
hold on;plot(amcol);
function out = find_index(in)

%% 用在滤波器的队列中
Num = 2048;%%这个队列不会改变延时的特性
if mod(in,Num) == 0
   out = Num;
else
   out = mod(in,Num);
end
end

模拟58.9m的波长信号输入滤波器,发现与幅度谱表现一致,说明滤波器的正确性。

image-20210322171641166

设计步骤: 1、语音信号的采集 利用Windows下的录音机录制一段自己的话音,或采用其它软件截取一段音乐信号,然后在Matlab软件平台下,利用函数wavread对语音信号进行采样,记住采样频率和采样点数。 2、语音信号的频谱分析 在Matlab中,可以利用函数FFT对信号进行快速傅立叶变换,得到信号的频谱特性,要求学生首先画出语音信号的时域波形,然后对语音信号进行频谱分析。 3、对语音信号分别加入正弦噪声和高斯白噪声,使信噪比为(学号)dB,画出加噪信号的时域波形和频谱图;关于噪声信号,噪声类型分为如下几种:(1)白噪声;(2)单频噪声(正弦干扰);(3)多频噪声(多正弦干扰);(4)其他干扰,如低频、高频、带限噪声,或chirp干扰、充激干扰。 4、设计数字滤波器,并画出其频率响应。 对叠加噪声前后的信号进行频谱分析,确定降噪的滤波器指标;或者根据如下给定的滤波器性能指标: (1) 低通滤波器的性能指标: =1000Hz, =1200Hz, =1dB, =100dB; (2) 高通滤波器的性能指标: =4800Hz, =5000Hz, =100dB, =1dB. (3) 带通滤波器的性能指标: =1200Hz, =3000Hz, =1000Hz, =3200Hz, =100dB, =1dB。 采用窗函数法设计上面要求的3种滤波器,并画出滤波器的频率响应; 5、用滤波器对信号进行滤波 用自己设计滤波器对加噪信号进行滤波,画出滤波后信号的时域波形及频谱,并对滤波前后的信号进行对比,分析信号的变化; 6、回放语音信号,分析滤波前后的语音变化,验证滤波效果
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

擦擦擦大侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值