📄 filterdlg.cpp
字号:
}
//递推计算
double R=log10(l)/log10(2)+0.1;
for(m=1;m<=R;m++)
{le=(UINT)pow(2,m);
lei=le/2;
u.set(1,0);
tmp=pi/lei;
w.set(cos(tmp),sin(tmp));
for(j=0;j<lei;j++)
{for(i=j;i<n;i+=le)
{ip=i+lei;
t=a[ip]*u;
a[ip]=a[i]-t;
a[i]=a[i]+t;
}
u=u*w;
}
}
for(m=1;m<l;m++)
a[m]=a[m]/l;
return;
}
void CFilterDlg::wlowpass(double *wfil, UINT length, double w)
{
double tao=(length-1)/2;
UINT i;
for(i=0;i<length;i++)
{
if(i!=tao)
wfil[i]=sin(w*(i-tao))/pi/(i-tao);
else
wfil[i]=w/pi;
}
return;
}
void CFilterDlg::whighpass(double *wfil, UINT length, double w)
{
double tao=(length-1)/2;
UINT i;
for(i=0;i<length;i++)
{
if(i!=tao)
wfil[i]=(sin(pi*(i-tao))-sin(w*(i-tao)))/pi/(i-tao);
else
wfil[i]=1-w/pi;
}
return;
}
void CFilterDlg::wbandpass(double *wfil, UINT length, double w1, double w2)
{
double tao=(length-1)/2;
UINT i;
for(i=0;i<length;i++)
{
if(i!=tao)
wfil[i]=(sin(w2*(i-tao))-sin(w1*(i-tao)))/pi/(i-tao);
else
wfil[i]=(w2-w1)/pi;
}
return;
}
void CFilterDlg::wbandstop(double *wfil, UINT length, double w1, double w2)
{
double tao=(length-1)/2;
UINT i;
for(i=0;i<length;i++)
{
if(i!=tao)
wfil[i]=(sin(pi*(i-tao))+sin(w1*(i-tao))-sin(w2*(i-tao)))/pi/(i-tao);
else
wfil[i]=1-(w2-w1)/pi;
}
return;
}
void CFilterDlg::wwindow(double *wwin, UINT length, int kind)
{
UINT i;
switch(kind)
{
case 0: //'矩形窗'
for(i=0;i<length;i++)
wwin[i]=1;
break;
case 1: //'三角形窗'
for(i=0;i<=(length-1)/2;i++)
wwin[i]=(2*i/(length-1));//*4;
for(i=(length+1)/2;i<length;i++)
wwin[i]=(2-2*i/(length-1));//*4;
break;
case 2: //'汉宁窗'
for(i=0;i<length;i++)
wwin[i]=0.5*(1-cos(2*pi*i/(length-1)));//*4;
break;
case 3: //'海明窗'
for(i=0;i<length;i++)
wwin[i]=(0.54-0.46*cos(2*pi*i/(length-1)));//*4;
break;
case 4: //'布拉克曼窗'
for(i=0;i<length;i++)
wwin[i]=(0.42-0.5*cos(2*pi*i/(length-1))+0.08*cos(4*pi*i/(length-1)));//*4;
break;
default:
break;
}
return;
}
void CFilterDlg::conv(Ccomplex *x, Ccomplex *h, UINT l)
{
//这里的x是时域信号,h是频域信号,处理后的信号仍存入x
fft(x,l);
UINT i;
for(i=0;i<l;i++)
x[i]=x[i]*h[i];
ifft(x,l);
return;
}
void CFilterDlg::processing(CSignal &thesignal, Ccomplex *thefilter, Cnumber &thenum)
{
//这个程序用于分段处理音频信号
fft(thefilter,thenum.fftnum); //滤波器变到时域
Ccomplex * temp=new Ccomplex[thenum.fftnum]; //用于临时存储待处理的分段信号
UINT totalloop;//=(UINT)floor(thesignal.dwTotalDatalength/thenum.signalnum); //分段数
UINT counter,i; //计数器
//处理
switch(thesignal.signalkind)
{
case 0: //通道数1,采样位数8
{
totalloop=(UINT)floor(thesignal.dwTotalDatalength/thenum.signalnum);
for(counter=0;counter<totalloop;counter++)
{
//UINT i; //内部计数器
//读取数据到临时存储空间
for(i=0;i<thenum.signalnum;i++)
temp[i].set(thesignal.m_pcurbuffer[counter*thenum.signalnum+i],0);
for(i=thenum.signalnum;i<thenum.fftnum;i++)
temp[i].set(0,0);
//读取数据到临时存储空间完毕
conv(temp,thefilter,thenum.fftnum); //卷积
for(i=0;i<thenum.fftnum;i++)
{
thesignal.m_pAfter[counter*thenum.signalnum+i]+=(UINT)(temp[i].getreal());
}
}
//处理最后不够一个分段的
{
UINT remainnum=(UINT)(thesignal.dwTotalDatalength-(DWORD)(totalloop*thenum.signalnum));
//UINT i; //内部计数器
for(i=0;i<remainnum;i++)
temp[i].set(thesignal.m_pcurbuffer[totalloop*thenum.signalnum+i],0);
for(i=remainnum;i<thenum.fftnum;i++)
temp[i].set(0,0);
conv(temp,thefilter,thenum.fftnum); //卷积
for(i=0;i<remainnum;i++)
{
thesignal.m_pAfter[totalloop*thenum.signalnum+i]+=(UINT)(temp[i].getreal());
}
}
for(i=0;i<thesignal.dwTotalDatalength;i++)
{
if(thesignal.m_pAfter[i]>127)
thesignal.m_pAfter[i]=127;
if(thesignal.m_pAfter[i]<-128)
thesignal.m_pAfter[i]=-128;
}
} //通道数1,采样位数8完毕
break;
case 1: //通道数1,采样位数16
{
totalloop=(UINT)floor(thesignal.dwTotalDatalength/thenum.signalnum);
for(counter=0;counter<totalloop;counter++)
{
//UINT i; //内部计数器
//读取数据到临时存储空间
for(i=0;i<thenum.signalnum;i++)
temp[i].set(((short *)thesignal.m_pcurbuffer)[counter*thenum.signalnum+i],0);
for(;i<thenum.fftnum;i++)
temp[i].set(0,0);
//读取数据到临时存储空间完毕
conv(temp,thefilter,thenum.fftnum); //卷积
//delete [] temp;
for(i=0;i<thenum.fftnum;i++)
{
((short *)thesignal.m_pAfter)[counter*thenum.signalnum+i]+=(short)(temp[i].getreal());
}
}
//处理最后不够一个分段的
{
UINT remainnum=(UINT)(thesignal.dwTotalDatalength-(DWORD)(totalloop*thenum.signalnum));
//UINT i; //内部计数器
for(i=0;i<remainnum;i++)
temp[i].set(((short *)thesignal.m_pcurbuffer)[totalloop*thenum.signalnum+i],0);
for(;i<thenum.fftnum;i++)
temp[i].set(0,0);
conv(temp,thefilter,thenum.fftnum); //卷积
for(i=0;i<remainnum;i++)
{
((short *)thesignal.m_pAfter)[totalloop*thenum.signalnum+i]+=(short)(temp[i].getreal());
}
}
for(i=0;i<thesignal.dwTotalDatalength;i++)
{
if(((short *)thesignal.m_pAfter)[i]>32767)
((short *)thesignal.m_pAfter)[i]=32767;
if(((short *)thesignal.m_pAfter)[i]<-32768)
((short *)thesignal.m_pAfter)[i]=-32768;
}
} //通道数1,采样位数16完毕
break;
case 2: //通道数2,采样位数8,这里需要处理两轮
{
totalloop=(UINT)floor(thesignal.dwTotalDatalength/thenum.signalnum/2);
for(counter=0;counter<totalloop;counter++)
{
//UINT i; //内部计数器
//读取数据到临时存储空间
for(i=0;i<thenum.signalnum;i++)
temp[i].set(thesignal.m_pcurbuffer[2*counter*thenum.signalnum+2*i],0);
for(;i<thenum.fftnum;i++)
temp[i].set(0,0);
//读取数据到临时存储空间完毕
conv(temp,thefilter,thenum.fftnum); //卷积
for(i=0;i<thenum.fftnum;i++)
{
thesignal.m_pAfter[2*counter*thenum.signalnum+2*i]+=(UINT)(temp[i].getreal());
}
}
//处理最后不够一个分段的
{
UINT remainnum=(UINT)(thesignal.dwTotalDatalength/2-(DWORD)(totalloop*thenum.signalnum));
//UINT i; //内部计数器
for(i=0;i<remainnum;i++)
temp[i].set(thesignal.m_pcurbuffer[2*totalloop*thenum.signalnum+2*i],0);
for(;i<thenum.fftnum;i++)
temp[i].set(0,0);
conv(temp,thefilter,thenum.fftnum); //卷积
for(i=0;i<remainnum;i++)
{
thesignal.m_pAfter[2*totalloop*thenum.signalnum+2*i]+=(UINT)(temp[i].getreal());
}
}
for(counter=0;counter<totalloop;counter++)
{
//UINT i; //内部计数器
//读取数据到临时存储空间
for(i=0;i<thenum.signalnum;i++)
temp[i].set(thesignal.m_pcurbuffer[2*counter*thenum.signalnum+2*i+1],0);
for(;i<thenum.fftnum;i++)
temp[i].set(0,0);
//读取数据到临时存储空间完毕
conv(temp,thefilter,thenum.fftnum); //卷积
for(i=0;i<thenum.fftnum;i++)
{
thesignal.m_pAfter[2*counter*thenum.signalnum+2*i+1]+=(UINT)(temp[i].getreal());
}
}
//处理最后不够一个分段的
{
UINT remainnum=(UINT)(thesignal.dwTotalDatalength/2-(DWORD)(totalloop*thenum.signalnum));
//UINT i; //内部计数器
for(i=0;i<remainnum;i++)
temp[i].set(thesignal.m_pcurbuffer[2*totalloop*thenum.signalnum+2*i+1],0);
for(;i<thenum.fftnum;i++)
temp[i].set(0,0);
conv(temp,thefilter,thenum.fftnum); //卷积
for(i=0;i<remainnum;i++)
{
thesignal.m_pAfter[2*totalloop*thenum.signalnum+2*i+1]+=(UINT)(temp[i].getreal());
}
}
for(i=0;i<thesignal.dwTotalDatalength;i++)
{
if(thesignal.m_pAfter[i]>127)
thesignal.m_pAfter[i]=127;
if(thesignal.m_pAfter[i]<-128)
thesignal.m_pAfter[i]=-128;
}
} //通道数2,采样位数8完毕
break;
case 3: ////通道数2,采样位数16,需要两轮
{
totalloop=(UINT)floor(thesignal.dwTotalDatalength/thenum.signalnum/2);
for(counter=0;counter<totalloop;counter++)
{
//UINT i; //内部计数器
//读取数据到临时存储空间
for(i=0;i<thenum.signalnum;i++)
temp[i].set(((short *)thesignal.m_pcurbuffer)[2*counter*thenum.signalnum+2*i],0);
for(;i<thenum.fftnum;i++)
temp[i].set(0,0);
//读取数据到临时存储空间完毕
conv(temp,thefilter,thenum.fftnum); //卷积
for(i=0;i<thenum.fftnum;i++)
{
((short *)thesignal.m_pAfter)[2*counter*thenum.signalnum+2*i]+=(short)(temp[i].getreal());
}
}
//处理最后不够一个分段的
{
UINT remainnum=(UINT)(thesignal.dwTotalDatalength/2-(DWORD)(totalloop*thenum.signalnum));
//UINT i; //内部计数器
for(i=0;i<remainnum;i++)
temp[i].set(((short *)thesignal.m_pcurbuffer)[2*totalloop*thenum.signalnum+2*i],0);
for(;i<thenum.fftnum;i++)
temp[i].set(0,0);
conv(temp,thefilter,thenum.fftnum); //卷积
for(i=0;i<remainnum;i++)
{
((short *)thesignal.m_pAfter)[2*totalloop*thenum.signalnum+2*i]+=(short)(temp[i].getreal());
}
}
for(counter=0;counter<totalloop;counter++)
{
//UINT i; //内部计数器
//读取数据到临时存储空间
for(i=0;i<thenum.signalnum;i++)
temp[i].set(((short *)thesignal.m_pcurbuffer)[2*counter*thenum.signalnum+2*i+1],0);
for(;i<thenum.fftnum;i++)
temp[i].set(0,0);
//读取数据到临时存储空间完毕
conv(temp,thefilter,thenum.fftnum); //卷积
for(i=0;i<thenum.fftnum;i++)
{
((short *)thesignal.m_pAfter)[2*counter*thenum.signalnum+2*i+1]+=(short)(temp[i].getreal());
}
}
//处理最后不够一个分段的
{
UINT remainnum=(UINT)(thesignal.dwTotalDatalength/2-(DWORD)(totalloop*thenum.signalnum));
//UINT i; //内部计数器
for(i=0;i<remainnum;i++)
temp[i].set(((short *)thesignal.m_pcurbuffer)[2*totalloop*thenum.signalnum+2*i+1],0);
for(;i<thenum.fftnum;i++)
temp[i].set(0,0);
conv(temp,thefilter,thenum.fftnum); //卷积
for(i=0;i<remainnum;i++)
{
((short *)thesignal.m_pAfter)[2*totalloop*thenum.signalnum+2*i+1]+=(short)(temp[i].getreal());
}
}
for(i=0;i<thesignal.dwTotalDatalength;i++)
{
if(((short *)thesignal.m_pAfter)[i]>32767)
((short *)thesignal.m_pAfter)[i]=32767;
if(((short *)thesignal.m_pAfter)[i]<-32768)
((short *)thesignal.m_pAfter)[i]=-32768;
}
//通道数2,采样位数16完毕
break;
}
default:
break;
}
//处理完毕
delete [] temp;
return;
}
void CFilterDlg::setkind(CSignal &thesignal)
{
//这个程序用来识别通道数,抽样的位数,并进行相应处理
if(thesignal.nChannels==1)
{
if(thesignal.wBitsPerSample==8)
{
thesignal.signalkind=0;
thesignal.dwTotalDatalength=thesignal.dwDatalength;
}
else
{
thesignal.signalkind=1;
thesignal.dwTotalDatalength=thesignal.dwDatalength/2;
}
}
else
{
if(thesignal.wBitsPerSample==8)
{
thesignal.signalkind=2;
thesignal.dwTotalDatalength=thesignal.dwDatalength;
}
else
{
thesignal.signalkind=3;
thesignal.dwTotalDatalength=thesignal.dwDatalength/2;
}
}
}
void CFilterDlg::DrawSignal(CSignal &thesignal)
{
long m_x;
long m_y;
CWnd *p1=GetDlgItem(IDC_DRAW1);
CWnd *p2=GetDlgItem(IDC_DRAW2);
CDC *m_cdc1=p1->GetDC();
CDC *m_cdc2=p2->GetDC();
CRect m_crect1;
CRect m_crect2;
p1->GetClientRect(&m_crect1);
p2->GetClientRect(&m_crect2);
UINT i;
this->ClearDraw();
switch(thesignal.signalkind)
{
//通道1,位数8
case 0:
{
m_x=0;
m_y=(long)((1.1 - thesignal.m_pcurbuffer [0] / 256.f) * m_crect1.Height() / 1.2);
m_cdc1->MoveTo(m_x,m_y);
m_y=(long)((1.1 - thesignal.m_pAfter [0] / 256.f) * m_crect2.Height() / 1.2);
m_cdc2->MoveTo(m_x,m_y);
for(i=0;i<thesignal.dwTotalDatalength;i++)
{
m_x= (long)(i/thesignal.dwTotalDatalength*m_crect1.Width());
m_y= (long)((1.1 - thesignal.m_pcurbuffer [i] / 256.f) * m_crect1.Height() / 1.2);
m_cdc1->LineTo(m_x, m_y);
m_y= (long)((1.1 - thesignal.m_pAfter [i] / 256.f) * m_crect2.Height() / 1.2);
m_cdc2->LineTo(m_x, m_y);
}
break;
}
//通道1,位数16
case 1:
{
m_x=0;
m_y=(long)((0.6 - ((short*)thesignal.m_pcurbuffer) [0] / 65536.f) * m_crect1.Height() / 1.2);
m_cdc1->MoveTo(m_x,m_y);
m_y=(long)((0.6 - ((short*)thesignal.m_pAfter) [0] / 65536.f) * m_crect2.Height() / 1.2);
m_cdc2->MoveTo(m_x,m_y);
for(i=0;i<thesignal.dwTotalDatalength;i++)
{
m_x= (long)((double)i/thesignal.dwTotalDatalength*m_crect1.Width());
m_y= (long)((0.6 - ((short*)thesignal.m_pcurbuffer) [i] / 65536.f) * m_crect1.Height() / 1.2);
m_cdc1->LineTo(m_x, m_y);
m_y= (long)((0.6 - ((short*)thesignal.m_pAfter) [i] / 65536.f) * m_crect2.Height() / 1.2);
m_cdc2->LineTo(m_x, m_y);
}
break;
}
//通道2,位数8
case 2:
{
m_x=0;
m_y=(long)((1.1 - thesignal.m_pcurbuffer [0] / 256.f) * m_crect1.Height() / 1.2);
m_cdc1->MoveTo(m_x,m_y);
m_y=(long)((1.1 - thesignal.m_pAfter [0] / 256.f) * m_crect2.Height() / 1.2);
m_cdc2->MoveTo(m_x,m_y);
for(i=0;i<thesignal.dwTotalDatalength;i++)
{
m_x= (long)(i/thesignal.dwTotalDatalength*m_crect1.Width());
m_y= (long)((1.1 - thesignal.m_pcurbuffer [i] / 256.f) * m_crect1.Height() / 1.2);
m_cdc1->LineTo(m_x, m_y);
m_y= (long)((1.1 - thesignal.m_pAfter [i] / 256.f) * m_crect2.Height() / 1.2);
m_cdc2->LineTo(m_x, m_y);
}
break;
}
//通道2,位数16
case 3:
m_x=0;
m_y=(long)((0.6 - ((short*)thesignal.m_pcurbuffer) [0] / 65536.f) * m_crect1.Height() / 1.2);
m_cdc1->MoveTo(m_x,m_y);
m_y=(long)((0.6 - ((short*)thesignal.m_pAfter) [0] / 65536.f) * m_crect2.Height() / 1.2);
m_cdc2->MoveTo(m_x,m_y);
for(i=0;i<thesignal.dwTotalDatalength;i++)
{
m_x= (long)((double)i/thesignal.dwTotalDatalength*m_crect1.Width());
m_y= (long)((0.6 - ((short*)thesignal.m_pcurbuffer) [i] / 65536.f) * m_crect1.Height() / 1.2);
m_cdc1->LineTo(m_x, m_y);
m_y= (long)((0.6 - ((short*)thesignal.m_pAfter) [i] / 65536.f) * m_crect2.Height() / 1.2);
m_cdc2->LineTo(m_x, m_y);
}
break;
default:
break;
}
}
void CFilterDlg::ClearDraw()
{
CWnd *p1=GetDlgItem(IDC_DRAW1);
CWnd *p2=GetDlgItem(IDC_DRAW2);
CDC *m_cdc1=p1->GetDC();
CDC *m_cdc2=p2->GetDC();
CRect m_crect1;
CRect m_crect2;
p1->GetClientRect(&m_crect1);
p2->GetClientRect(&m_crect2);
m_cdc1->Rectangle(0,0,m_crect1.Width(),m_crect1.Height());
m_cdc2->Rectangle(0,0,m_crect2.Width(),m_crect2.Height());
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -