#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define WL 256 // 窗长
#define P 10 // 预测系数
#undef pi
#define pi 3.1415926535897932384626434
#define PI 3.1415926
#define winsize 256
#define tempsize winsize/2
#define buffsize winsize*10
typedef struct{
double real;
double img;
}complex;
unsigned int f=0;
unsigned int c=0;
complex noise[winsize];
double buff_r[buffsize];
double buff_w[buffsize];
double temp[tempsize];
complex x[winsize];
complex y[winsize];
int hr=0;
complex W[winsize];
complex W1[winsize];
double x_abs[winsize];
double y_abs[winsize];
double noise_abs[winsize];
void fft(complex *x,int size_x,complex *W); /*快速傅里叶变换*/
void ifft(complex *x,int size_x,complex *W1);
double angle(complex a); //
void add(complex ,complex ,complex *); /*复数加法*/
void mul(complex ,complex ,complex *); /*复数乘法*/
void sub(complex ,complex ,complex *); /*复数减法*/
void change(complex *x,int size_x); /*数组转置*/
double abs1(complex a);
void hamming(complex hw[]);
/*int ReadWaveFile( char *fn,int *fs,short **dat );
int ReadWaveFile(
char *fn, // I: 文件名
int *fs, // O: 文件大小
short **dat // O: 语音数据
)
{
FILE *fp;
int dsize;
if ((fp = fopen(fn, "rb+")) == NULL) {
fprintf(stderr, "%s: No such file \n", fn); return(-1);
} c语言二维数组转置
fseek(fp, 0L, SEEK_END);
dsize = ftell(fp)/2;
fseek(fp, 0L, SEEK_SET);
if ((*dat = (short *)malloc(sizeof(short)*dsize)) == NULL) {
fprintf(stderr, "Memory Error \n"); return(-1);
}
if (fread(*dat, sizeof(short), dsize, fp) != (unsigned int)dsize) {
free(*dat);
return(-1);
}
fclose(fp);
*fs = dsize;
return(0);
}*/
void hamming(complex hw[])
{
double x;
int i;
for(i=0;i<WL;i++)
{
double cos(x);
x=2*pi*i/(WL-1);
hw[i].real=hw[i].real*(0.54-0.46*cos(x));//*32768;
}
}
void fft(complex *x,int size_x,complex *W){
int i=0,j=0,k=0,l=0,jk=0;
complex up,down,product;
change(x,size_x);
for(i=0;i<log(size_x)/log(2);i++){ /*一级蝶形运算*/
l=1<<i;
for(j=0;j<size_x;j+= 2*l ){ /*一组蝶形运算*/
for(k=0;k<l;k++){ /*一个蝶形运算*/
jk=j+k;
mul(x[jk+l],W[size_x*k/2/l],&product);
up.img=x[jk].img+product.img;
down.img=x[jk].img-product.img;
x[jk]=up;
x[jk+l]=down;
}
}
}
}
/*变址计算,将x(n)码位倒置*/
void change(complex *x,int size_x){
complex temp;
unsigned short i=0,j=0,k=0;
double t;
for(i=0;i<size_x;i++){
k=i;j=0;
t=(log(size_x)/log(2));
while( (t--)>0 ){
j=j<<1;
j|=(k & 1);
k=k>>1;
}
if(j>i){
temp=x[i];
x[i]=x[j];
x[j]=temp;
}
}
}
void ifft(comple
x *x,int size_x,complex *W1)
{
int i=0,j=0,k=0,l=0,jk=0;
complex up,down,product;
change(x,size_x);
for(i=0;i< log(size_x)/log(2) ;i++) /*一级蝶形运算*/
{
l=1<<i;
for(j=0;j<size_x;j+= 2*l ) /*一组蝶形运算*/
{
for(k=0;k<l;k++){ /*一个蝶形运算*/
jk=j+k;
mul(x[jk+l],W1[size_x*k/2/l],&product);
up.img=x[jk].img+product.img;
down.img=x[jk].img-product.img;
x[jk]=up;
x[jk+l]=down;
}
}
}
for(i=0;i<size_x;i++)
{
x[i].img=x[i].img/size_x;
x[i].real=x[i].real/size_x;
}
}
double angle(complex a)
{
double m;
m=tan(a.img/(a.real+0.00001));
return m;
}
void add(complex a,complex b,complex *c){
c->al;
c->img=a.img+b.img;
}
void mul(complex a,complex b,complex *c){
c->al - a.img*b.img;
c->al*b.img + a.al;
}
void sub(complex a,complex b,complex *c){
c->al;
c->img=a.img-b.img;
}
double abs1(complex a){
double t;
t = (a.real)*(a.real)+(a.img)*(a.img);
return (double) sqrt(t);
}
/**************************主程序*****************************/
void main(void)
{
double wavin[7680], wavout[7680];
complex S[60][256],voice[256];
complex noise1[256];
double noise_foward15frame[15][256];
double am_noise[256];
int fs=8000;
double sum[15][256],voice_timedomain[60][256];
double phase[256];
double am_signal[256];
double am_voice[256];
int frame_len=256,step_len=128,n_frame=15,wav_length=7680,i,j,size_x=256,nifrm,ifrm;
int kk=0,n=1;
for(i=0;i<wav_length;i++)
{
wavin[i]=i;
}
switch (fs)
{
case 8000:
frame_len=256;step_len=128;break;
case 10000:
frame_len=400;step_len=200;break;
case 12000:
frame_len=480;step_len=240;break;
case 16000:
frame_len=640;step_len=320;break;
case 44100:
frame_len=1800;step_len=900;break;
default:
frame_len=1800;step_len=900;break;
}
n_frame=(wav_length-frame_len)/step_len+1;
for(i=0;i<n_frame;i++) //分帧
{
int n1,n2;
n1=i*step_len;
n2=i*step_len+frame_len;
for(j=n1;j<=n2;j++)
{
S[i][j-n1].real=wavin[j];
S[i][j-n1].img=0.0;
}
}
for(i=0;i<winsize;i++) //初始化W数组
{
W[i].real=cos(2*PI/size_x*i);
W[i].img=-1*sin(2*PI/size_x*i);
}
for(i=0;i<winsize;i++) //初始化W数组
{
W1[i].real=cos(2*PI/size_x*i);
W1[i].img=sin(2*PI/size_x*i);
}
for(nifrm=0;nifrm<15;nifrm++)
{
hamming(S[nifrm]);
for(i=0;i<frame_len;i++)
{
noise1[i].real=S[nifrm][i].real;
noise1[i].img=0.0;
}
fft(noise1,256,W);
for( i=0;i<frame_len
;i++)
{
noise_foward15frame[nifrm][i]=abs1(noise1[i]); //noise_foward15frame保存前15帧的噪音短时傅立叶变换幅度结果
}
}
for(j=0;j<frame_len;j++)
{
double w=0.0;
for(i=0;i<15;i++)
{
w=w+noise_foward15frame[i][j];
}
am_noise[j]=w/15;
}
for(ifrm=0;ifrm<n_frame;ifrm++)
{
hamming(S[ifrm]);
for( i=0;i<frame_len;i++)
{
sum[ifrm][i]=S[ifrm][i].real; //sum_timedomain保存整个语音信号的时域和的结果
}
fft(S[ifrm],256,W); //快速傅里叶变换参数
for(i=0;i<frame_len;i++)
{
phase[i]=angle(S[ifrm][i]); ; //保存这帧语音信号的傅立叶变换的结果的相位
}
for(i=0;i<frame_len;i++)
{
am_signal[i]=abs1(S[ifrm][i]); // 保存这帧语音信号的傅立叶变换的结果的幅度
}
for( i=0;i<frame_len;i++)
{
am_voice[i]=am_signal[i];//-am_noise[i]; //谱减 %用信号的幅度减去噪声的幅度得到纯净语音的幅度
}
for (i=0;i<frame_len;i++)
{
if(am_voice[i]<0)
am_voice[i]=0.0;
}
for(i=0;i<frame_len;i++)
{
voice[i].real=am_voice[i]; //组合相位与幅度得到去噪后的纯净语音信号
voice[i].img=phase[i]*voice[i].real;
}
ifft(voice,frame_len,W1);
for(i=0;i<frame_len;i++)
{
voice_timedomain[ifrm][i]=voice[i].real; // 求这帧纯净语音信号的傅立叶反变换的实部
}
}
//%求出纯净语音信号的真实幅度
for(i=0;i<wav_length;i++)
{
wavout[i]=0.0;
}
for(i=0;i<n_frame;i++)
{
int m1,m2,m3;
m3=0;
m1=i*step_len;
m2=i*step_len+frame_len;
for(j=m1;j<=m2;j++)
{
m3=j-m1;
wavout[j]=wavout[j]+voice_timedomain[i][m3];
}
}
for(i=0;i<wav_length;i++)
{
printf("%f/n",wavout[i]);
}
}
/***************************结束******************************/
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论