⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 filterdlg.cpp

📁 能够读取wav格式的音频文件
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	}
 
 //递推计算
 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 + -