这是我从别的地方弄的一个程序,看不懂啊!不过已经调试成功,希望高手能帮我加上注释!还有我的设计题!帮我把程序改一下!感激涕零!目前我刚注册这个工控网,还没有积分,望见谅!!!
在许多的数据采集中,不可避免地会产生一些干扰,我们从一个声音信号中截取一段信号,它的频谱如图(1)所示。为这一段声音信号加干扰,干扰信号的频谱如图(2)所示,两者叠加后的频谱如图(3)所示。
试用双线性变换法设计一个IIR数字滤波器,滤去干扰的信号,保留输入的声音信号,并分析干扰对原信号的影响,以及滤波后的信号质量.
解:由上面(图1,2,3)三个频谱图可知,本题要求设计一低通IIR滤波器,所设计的数字滤波器为Butterworth型,其设计参数为:频率在0.5π处的最小衰减为3dB,在0.75π处的幅度衰减至少为15dB。通带和阻带都是频率的单调下降函数。
ωp=0.5π, ωs=0.75π, p =3dB, s=15dB
(1) 将数字滤波器的设计要求转换为模拟滤波器的设计要求,根据式
Ωp= tan( ),Ωs= tan( ), p=1, s=tan(ωs/2)/tan(ωp/2),
并令T=1,可得
Ωp=2tan(0.5π/2)=2.000,Ωs=2tan(0.75π/2)=4.828, p=3dB, s=15dB
(2) 设计模拟低通滤波器的传递函数
按照Butterworth低通滤波器的设计方法进行设计,有公式
= —1,n=lg /lg(Ωs/Ωp)可得
= = =1
n = =2.1996
选取n=2,根据归一化Butterworth低通滤波器传递函数的通式和多项式系数表可得
对于实际低通滤波器,将上式中的s换为s/Ωp=s/2,即可得
=
(3)将模拟滤波器转换为数字滤波器
根据式 =
得H(z)= =
-双线性变换法设计IIR数字滤波器的C语言实现
IIRD_DF.c
Infinite Impulse Response Digital Filter Design By Double Converting
***********************************************************/
/*#include <windows.h>*/
#include <math.h>
#include <dos.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <graphics.h>
/*COMPLEX STRUCTURE*/
typedef struct{
double real,image;
}COMPLEX;
struct rptr{
double *a;
double *b;
};
#define PI (double)(4.0*atan(1.0))
#define FNSSH(x) log(x+sqrt(x*x+1))
#define FNCCH(x) log(x+sqrt(x*x-1))
#define FNSH1(x) (exp(x)-exp(-x))/2
#define FNCH1(x) (exp(x)+exp(-x))/2
/***********************************************************************************************/
double *bcg(double ap,double as,double wp,double ws,int *n,double *h,int *type);
struct rptr *bsf(double *c,int ni,double *f1,double *f2,int nf,struct rptr *ptr,int *no);
double *pnpe(double *a,int m,int n,double *b,int *mn);
double *ypmp(double *a,int m,double *b,int n,double *c,int *mn);
void lowpass_input(double *wp,double *ws,double *ap,double *ar,double *f1,double *f2,int *nf);
void highpass_input(double *wp,double *ws,double *ap,double *ar,double *f1,double *f2,int *nf);
void bandpass_input(double *wp,double *ws,double *ap,double *ar,double *f1,double *f2,int *nf);
void draw_image(double *x,int m,char *title1,char *title2,char *xdis1,char *xdis2,int dis_type);
/***********************************************************************************************/
ttextxy(start_x+10,scy-end_y+4,dis);
outtextxy(start_x-10,scy-end_y+24,xdis1);
outtextxy(scx-2-strlen(xdis2)*8,scy-end_y+24,xdis2);
}
strcpy(dis,"Press any key to continue...");
setcolor(LIGHTRED);
outtextxy((scx-28*8)>>1,scy-16,dis);
settextstyle(DEFAULT_FONT,HORIZ_DIR,2);
tlen=strlen(title1);
if((tlen<<4)<scx){
setcolor(LIGHTGREEN);
outtextxy((start_x+scx-end_x-(tlen<<4))>>1,start_y-40,title1);
}
settextstyle(DEFAULT_FONT,VERT_DIR,1);
tlen=strlen(title2);
if((tlen<<4)<scy){
setcolor(LIGHTGREEN);
outtextxy(start_x-20,(scy-end_y-(tlen<<3))>>1,title2);
}
/* draw the amplititude image */
setcolor(WHITE)