c语言实现滤波器
我写了很久了,但是新手上路问题巨多,实在不知道怎么解决。用matlab实验后发现滤波的函数没有问题,主要问题出在wav文件data块数据的提取上,具体问题在下面,求大佬拯救。(代码没整理,逻辑混乱,看看就好...)
滤波器设计和使用
一、实验目的和任务:
实验目的:
练习随机数、静态局部变量、滤波器等知识的综合运用;
培养学生综合运用C程序语言进行程序设计的能力;
培养结构化程序设计能力;
实验任务:
实验内容:
完成随机数产生函数:double RandDouble(double Max),即生产0到Max之间的随机数,且返回的随机数带2位小数,如6.28等;
编写一函数,double filter(double x);实现如下功能:输入xi,输出yi,其中xi的定义如5-1所示,即i大于0时,为随机数,小于0时为0,i为整数;xi和yi的关系如5-2所示。
(5-1)
(5-2)
c0,c1,c2,c3,c4的值分别为常数:0.01,0.1, 0.78, 0.1, 0.01,请用宏定义c0到c4的值;rand()为随机数函数,产生随机数整数;
写一主函数,在主函数中调用随机数生成函数,产生序列x,并求出序列y的值,输出x和y的值。
设Cn为某低通滤波器系数,Cn的值见后。改写double filter(double x)函数,实现滤波功能。编写主函数,读取一个被噪声污染的语音文件,并进行滤波处理,把处理后的文件保存下来,并进行试听,观察处理效果。
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define p 101
double *s;
char *temp;
char *temp_2;
unsigned short int *data;
short int *data_11;
double *data_1;
double *data_2;
unsigned short int * data_3;
short int * data_33;
double fir_filt(double x, double *b, double *, int);
typedef struct _tagMsWavPcmHeader44
{
unsigned char ChunkID[4]; // "RIFF"; The "RIFF" the mainchunk;
unsigned long ChunkSize; // FileSize - 8; The size following this data
unsigned char Format[4];
// "WAVE"; The "WAVE" format consists of two subchunks: "fmt " and "data"
unsigned char SubChunk1ID[4]; // "fmt "
unsigned long SubChunk1Size;
// 16 for PCM. This is the size of the rest of the subchunk which follows this data.
unsigned short AudioFormat; // 1 for PCM. Linear quantization
unsigned short NumChannels; // 1->Mono, 2->stereo, etc..
unsigned long SampleRate; // 8000, 11025, 16000, 44100, 48000, etc..
unsigned long ByteRate; // = SampleRate * NumChannels * BitsPerSample/8
unsigned short BlockAlign; // = NumChannels * BitsPerSample / 8
unsigned short BitsPerSample; // 8->8bits, 16->16bits, etc..
unsigned char SubChunk2ID[4]; // "data"
unsigned long SubChun2Size;
// = NumSamples * NumChannels * BitsPerSample / 8. The size of data
} wav_pcm_header44; //44
double randdouble(double Max);
double filter(double * x,int i);
//double c[5]= {0.01,0.1,0.78,0.1,0.01};
double c[101] = {-0.004808919657970,
-0.001547991286813,
-0.001484119075616,
-0.001180626535065,
-0.000638610828712,
0.000104137685310,
0.000976202943056,
0.001875083276187,
0.002678747868229,
0.003258340856584,
0.003497633328625,
0.003310022925111,
0.002656136525684,
0.001555093457088,
0.000095231399231,
-0.001579126147775,
-0.003267487272886,
-0.004745069573984,
-0.005784364014156,
-0.006183187126704,
-0.005799711899067,
-0.004575941863646,
-0.002560489731262,
0.000086215276100,
0.003095941733918,
0.006123608643356,
0.008773450587629,
0.010645725379523,
0.011369883796541,
0.010707969201656,
0.008534221934017,
0.004906086245703,
0.000084923610347,
-0.005500640536805,
-0.011244701868107,
-0.016442739558196,
-0.020332177216741,
-0.022189237562184,
-0.021388750352397,
-0.017496131711919,
-0.010310727721149,
0.000074954684212,
0.013283855664295,
0.028642402846373,
0.045253402410963,
0.062043759242903,
0.077862333668155,
0.091580983706917,
0.102191837897796,
0.108897201849955,
0.111190826178577,
0.108897201849955,
0.102191837897796,
0.091580983706917,
0.077862333668155,
0.062043759242903,
0.045253402410963,
0.028642402846373,
0.013283855664295,
0.000074954684212,
-0.010310727721149,
-0.017496131711919,
-0.021388750352397,
-0.022189237562184,
-0.020332177216741,
-0.016442739558196,
-0.011244701868107,
-0.005500640536805,
0.000084923610347,
0.004906086245703,
0.008534221934017,
0.010707969201656,
0.011369883796541,
0.010645725379523,
0.008773450587629,
0.006123608643356,
0.003095941733918,
0.000086215276100,
-0.002560489731262,
-0.004575941863646,
-0.005799711899067,
-0.006183187126704,
-0.005784364014156,
-0.004745069573984,
-0.003267487272886,
-0.001579126147775,
0.000095231399231,
0.001555093457088,
0.002656136525684,
0.003310022925111,
0.003497633328625,
0.003258340856584,
0.002678747868229,
0.001875083276187,
0.000976202943056,
0.000104137685310,
-0.000638610828712,
-0.001180626535065,
-0.001484119075616,
-0.001547991286813,
-0.004808919657970
};
int main(void)
{
s=(double *)malloc(sizeof(double) * 100);
srand(time(0));
wav_pcm_header44 wav;
FILE * fp,*save;
save=fopen("save.wav","wb");
fp=fopen("test.wav","rb");
if (!fp)
{
printf("can't open audio file\n");
exit(1);
}
fseek(fp,0L,SEEK_END);
int f=ftell(fp);
//printf("%d,\n",f);
rewind(fp);
fread(&wav,sizeof(wav_pcm_header44),1,fp);
fwrite(&wav,sizeof(wav_pcm_header44),1,save);
printf("ChunkID=%c%c%c%c\n",wav.ChunkID[0],wav.ChunkID[1],wav.ChunkID[2],wav.ChunkID[3]);
printf("ChunkSize=%ld\n",wav.ChunkSize);
printf("Format=%c%c%c%c\n",wav.Format[0],wav.Format[1],wav.Format[2],wav.Format[3]);
printf("SubChunk1ID=%c%c%c%c\n",wav.SubChunk1ID[0],wav.SubChunk1ID[1],wav.SubChunk1ID[2],wav.SubChunk1ID[3]);
printf("SubChunk1Size=%ld\n",wav.SubChunk1Size);
printf("AudioFormat=%hd\n",wav.AudioFormat);
printf("NumChannels=%hd\n",wav.NumChannels);
printf("SampleRate=%ld\n",wav.SampleRate);
printf("ByteRate=%ld\n",wav.ByteRate);
printf("BlockAlign=%hd\n",wav.BlockAlign);
printf("BitsPerSample=%hd\n",wav.BitsPerSample);
printf("SubChunk2ID=%c%c%c%c\n",wav.SubChunk2ID[0],wav.SubChunk2ID[1],wav.SubChunk2ID[2],wav.SubChunk2ID[3]);
printf("SubChunk2Size=%ld\n",wav.SubChun2Size);
setvbuf(fp,0,_IOFBF,BUFSIZ);
temp=(char *)malloc(sizeof(char)*f);
temp_2=(char *)malloc(sizeof(char)*f);
data=(unsigned short int *)malloc(sizeof(unsigned short int )*f/2);
data_1=(double *)malloc(sizeof(double) * f/2);
data_2=(double *)malloc(sizeof(double) * f/2);
data_3=(unsigned short int *)malloc(sizeof(unsigned short int )*f/2);
data_11=(short int *)malloc(sizeof(short int )*f/2);
data_33=(short int *)malloc(sizeof(short int )*f/2);
fread(temp,sizeof(char),f,fp);
for(int i=0; i < f/2; i++)
{
data_11[i]=(short int)(temp[2*i]&0xff)*256+(temp[2*i+1]&0xff);
data_1[i]=(double)data_11[i]/32768;
}
for(int i=0 ;i<100;i++)
{
s[i]=data_1[i+1];
}
for(int i=0; i < f/2; i++)
{
data_2[i]=fir_filt(data_1[i],c,s,101);
//printf("%lf,",data_2[i]);
data_33[i]=data_2[i]*32768;
//data_33[i]=data_11[i]+32768;
}
for(int i=0; i < f/2; i++)
{
temp_2[2*i+1]=data_33[i]&0xff;
temp_2[2*i]=(data_33[i]>>8)&0xff;
//printf("%hd,",temp[i]-temp_2[i]);
}
fwrite(temp_2,sizeof(char),f,save);
fclose(fp);
fclose(save);
}
double randdouble(double _max)
{
unsigned long int temp=rand()%(unsigned long int)(_max*100)+1;
return (double)(temp*0.01);
}
double filter(double * x,int i)
{
double ret=0;
for(int n=0; n<=p; n++)
{
if((i-n)>0)
{
ret+=c[n]*x[i-n];
}
}
return ret;
}
double fir_filt(double x, double *b, double *s_, int p_)
{
double y = b[0] * x;
for(int i = 0; i < p_-1; i++)
y += b[i+1] * s_[i];
for(int j = p_-1; j > 0; j--)
s_[j] = s_[j-1];
s_[0] = x;
//printf("%lf,",y-x);
return y;
}