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

📄 windowfilterview.cpp

📁 数字信号处理实验
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	for (i=0; i<n; i++)
	{
		temp = 1.0-2.0*i/(n-1);
		temp *= temp;
		temp = 1.0 - temp;
		temp = sqrt(temp);				
		real[i] = ino(beta * temp) / ino(beta);
		imag[i] = 0.0;
	}
}
//理想低通滤波器的脉冲相应
void CWindowFilterView::CreateHd(float *real, float *imag, int n, float wc)
{
	int i;
	int a;
	float a2;
	int m;
	float m2;
	//通过内部转换,在输入的时候不必再乘以pi
	wc = wc * PI; 
	if (n % 2)
	{		
		a = n / 2;
		for (i=0; i<n; i++)
		{
			m = i - a ;            //+0.0001;
			if (i == a)
			{
				real[i] = wc / PI;
			}
			else
			{
				real[i] = sin(wc*m) / (PI*m);
			}			
			imag[i] = 0.0;
		}
	}
	else
	{
		a2 = (n-1) / 2.0;
		for (i=0; i<n; i++)
		{
			m2 = i - a2 ;            //+0.0001;			
			real[i] = sin(wc*m2) / (PI*m2);						
			imag[i] = 0.0;
		}
	}
}

//对低通频率的采样函数 单位为 rad*pi
void CWindowFilterView::CreateSample(float *real, float *imag, int n, float wc)
{
	int i;
	for (i=0; i<= wc*n/2; i++)
	{
		real[i] = 1.0;
		imag[i] = 0.0;
	}
	for (; i<=n/2; i++ )
	{
		real[i] = 0.0;
		imag[i] = 0.0;
	}
	for (; i<n; i++)
	{
		real[i] = real[n - i];
		imag[i] = 0.0;
	}
}

//选择窗函数的类型
void CWindowFilterView::OnSelchangeWindowtipe() 
{
	// TODO: Add your control notification handler code here
	int index = ((CComboBox *)GetDlgItem (IDC_WINDOWTIPE))->GetCurSel();	
	m_iWindowType = index;	
	if (index == 5)
	{
		(CStatic *)GetDlgItem(IDC_STATIC_BETY)->EnableWindow(TRUE);
		(CEdit *)GetDlgItem(IDC_EDIT_BETY)->EnableWindow(TRUE);
	}
	else
	{
		(CStatic *)GetDlgItem(IDC_STATIC_BETY)->EnableWindow(false);
		(CEdit *)GetDlgItem(IDC_EDIT_BETY)->EnableWindow(false);
	}
}
//选择是低通还是高通滤波器
void CWindowFilterView::OnSelchangeFiltertype() 
{
	// TODO: Add your control notification handler code here
	int index = ((CComboBox *)GetDlgItem (IDC_FILTERTYPE))->GetCurSel();	
	m_iFilterType = index;	
	switch (index)
	{
	case 0:
	case 1:
		(CStatic *)GetDlgItem(IDC_HIGHWC)->EnableWindow(false);
		(CEdit *)GetDlgItem(IDC_EDIT_HIGH)->EnableWindow(false);
		break;
	case 2:
	case 3:
		(CStatic *)GetDlgItem(IDC_HIGHWC)->EnableWindow(TRUE);
		(CEdit *)GetDlgItem(IDC_EDIT_HIGH)->EnableWindow(TRUE);
		break;
	}
}

//根据选择创建窗函数
void CWindowFilterView::CreateWindowFun(int index, int length)
{
	//不传递额外的参数,直接调用成员变量。
//	UpdateData(TRUE);
	if (pWindowReal!=NULL)
	{
		delete []pWindowReal;
		pWindowReal = NULL;
	}
	if (pWindowImag!=NULL)
	{
		delete []pWindowImag;
		pWindowImag = NULL;
	}
	pWindowReal = new float[length];
	pWindowImag = new float[length];
	memset(pWindowReal, 0, sizeof(float)*length);
	memset(pWindowImag, 0, sizeof(float)*length);
	switch (m_iWindowType)
	{
	case 0:
		CreateRect(pWindowReal,pWindowImag,length);
		break;
	case 1:
		CreateTriang(pWindowReal,pWindowImag,length);
		break;
	case 2:
		CreateHanning(pWindowReal,pWindowImag,length);
		break;
	case 3:
		CreateHamming(pWindowReal,pWindowImag,length);
		break;
	case 4:
		CreateBlackman(pWindowReal,pWindowImag,length);
		break;
	case 5:
		CreateKaiser(pWindowReal,pWindowImag,length,m_bety);
		break;	
	}
}
//创建加窗口的实际时间序列
//index为滤波器的类型,如低通还是高通
void CWindowFilterView::CreateHFun(int index, int n)
{
	int i;
//	UpdateData(TRUE);
	//不传递参数,直接调用成员变量
	if (pHdImag!=NULL)
	{
		delete []pHdImag;
		pHdImag = NULL;
	}
	if (pHdReal!=NULL)
	{
		delete []pHdReal;
		pHdReal = NULL;
	}
	if (pReal!=NULL)
	{
		delete []pReal;
		pReal = NULL;
	}
	if (pImag!=NULL)
	{
		delete []pImag;
		pImag = NULL;
	}
	//类的成员变量
	pHdImag = new float[n];
	pHdReal = new float[n];
	float *pHdImag2 = new float [n];
	float *pHdReal2 = new float [n];
	float *pHdImag3 = new float [n];
	float *pHdReal3 = new float [n];
	pReal = new float [n];
	pImag = new float [n];
	
	memset(pHdImag, 0,sizeof(float)*n);
	memset(pHdReal,0,sizeof(float)*n);
	memset(pHdImag2, 0,sizeof(float)*n);
	memset(pHdReal2,0,sizeof(float)*n);
	memset(pHdImag3, 0,sizeof(float)*n);
	memset(pHdReal3,0,sizeof(float)*n);
	memset(pReal, 0,sizeof(float)*n);
	memset(pImag,0,sizeof(float)*n);
	switch (index)
	{
	case 0:  //低通
		CreateHd(pHdReal,pHdImag,n,m_WcLow);
		break;
	case 1:  //高通
		CreateHd(pHdReal,pHdImag,n,m_WcLow);
		CreateHd(pHdReal2,pHdImag2,n,1);
		for (i=0; i<n; i++)
		{
			pHdReal[i] = pHdReal2[i] - pHdReal[i];
		}
		break;
	case 2: //带通		
		CreateHd(pHdReal,pHdImag,n,m_WcLow);
		CreateHd(pHdReal2,pHdImag2,n,m_WcHigh);
		for (i=0; i<n; i++)
		{
			pHdReal[i] = pHdReal2[i] - pHdReal[i];
		}
		break;
	case 3:  //带阻	
		CreateHd(pHdReal,pHdImag,n,m_WcLow);
		CreateHd(pHdReal2,pHdImag2,n,m_WcHigh);
		CreateHd(pHdReal3,pHdImag3,n,1);
		for (i=0; i<n; i++)
		{
			pHdReal[i] = pHdReal3[i] + pHdReal[i] - pHdReal2[i];
		}
		break;
	}
	delete []pHdImag2;
	delete []pHdReal2;
	delete []pHdImag3;
	delete []pHdReal3;
	CreateWindowFun(m_iWindowType, n);
	if (pImag!=NULL)
	{
		delete []pImag;
		pImag = NULL;
	}
	if (pReal!=NULL)
	{
		delete []pReal;
		pReal = NULL;
	}
	pImag = new float[n];
	pReal = new float[n];
	memset(pImag, 0,sizeof(float)*n);
	memset(pReal,0,sizeof(float)*n);
	for (i=0; i<n; i++)
	{	
		pReal[i] = pHdReal[i] * pWindowReal[i];
		pImag[i] = 0.0;
	}
}



//清除画板函数
void CWindowFilterView::CleanPalette(int index)
{
	if (m_bClean == FALSE)
	{
		m_bClean = TRUE;
	}
	else
	{
		//清除画板;
		Invalidate();
	}
}

//函数重载
//这次用到的函数
//需要详细修改
//x轴的标注范围和y的取值
void CWindowFilterView::Plot(int n, int length, float max,float *num, float xmax, 
							 float ymin, float ymax)
{
	float detaX ,detaY;
	CRect rect;
	CStatic *pWndLine;
	//目前只标注5个点。
	int biaozhunum = 5;
	int xbiaozhu = length / biaozhunum;
	//得到对应的画板
	switch (n)
	{
	case 1:
		pWndLine = (CStatic *)GetDlgItem(IDC_PALETTE1);				
		break;
	case 2:
		pWndLine = (CStatic *)GetDlgItem(IDC_PALETTE2);				
		break;
	case 3:
		pWndLine = (CStatic *)GetDlgItem(IDC_PALETTE3);
		break;
	}	
	//得到画板的大小
	pWndLine->GetClientRect(&rect);
	CClientDC pLinwDC(pWndLine);
	pLinwDC.SetBkMode(TRANSPARENT);                //设置文字背景颜色
	pLinwDC.SetMapMode(MM_TEXT);                   //Y轴向下,画图时候要加负号
	//设置原点
//	pLinwDC.SetViewportOrg(int(rect.right/(length+2)),int(rect.bottom/2));
	detaX = (float)(rect.right/(length+2));               //x轴间距

//	detaY = (float)(0.5 * (rect.Height()-30) / max);       //y轴间距,重新计算,以及y的大小
	detaY = (float)((rect.Height()-30) / (ymax - ymin));  	
	//重新设置原点
//	15 = 30 / 2;
//	pLinwDC.SetViewportOrg(int(rect.right/(length+2)),int( rect.bottom-15 + ymin * detaY)));
	int y0 = rect.Height();
	//如果算出来的x原点为 0,则修正值为 15
	pLinwDC.SetViewportOrg(int(rect.right/(length+2) + 15 ),int(rect.bottom-15-(-ymin * detaY)));
	CPen axisPen, pointPen;
	CPen *pOldPen;
	CFont bigFont, smallFont;
	CFont *pOldFont;	
	axisPen.CreatePen(PS_SOLID,2,RGB(0,0,0));     //黑线
	pointPen.CreatePen(PS_SOLID,1,RGB(255,0,0));  //红线
	bigFont.CreatePointFont(100,"Arial",NULL);
	smallFont.CreatePointFont(80,"Arial",NULL);
	pOldPen = pLinwDC.SelectObject(&axisPen);	
	//绘制x,y坐标轴
	//y轴的坐标要重新计算 

	pLinwDC.MoveTo(0,  - ymax * detaY);
	pLinwDC.LineTo((int)(detaX*length), - ymax * detaY);
	pLinwDC.MoveTo((int)(detaX*length), - ymax * detaY);
	pLinwDC.LineTo((int)(detaX*length-8), - ymax * detaY -4);
	pLinwDC.MoveTo((int)(detaX*length), - ymax * detaY );
	pLinwDC.LineTo((int)(detaX*length-8), - ymax * detaY +4);
	//绘制y轴

	pLinwDC.MoveTo(0, - ymin * detaY);
	pLinwDC.LineTo(0, - ymax * detaY);
	CString str;
	pOldFont  = pLinwDC.SelectObject(&bigFont);
	str.Format("%.1f", ymax);
	pLinwDC.TextOut(0 + 2,- ymax * detaY,str);
// 	pLinwDC.SelectObject(&smallFont);
// 	int yymax =(int)log10(max);
	str.Format("%.1f", ymin);
	pLinwDC.TextOut(0 + 2, - ymin * detaY,str);
	
	//绘制线段	
	pLinwDC.SelectObject(&pointPen);
	pLinwDC.SelectObject(pOldFont);
	//关键是第一个点的位置,要考虑到是不是在表示的范围
	//very important
	
	int i,x,y;
	float y1;
	int j = 0;
	bool firstPoint = TRUE;
	for (i=0; i<length; i++)
	{
		if (i % xbiaozhu == 0 && i !=0)         //x轴坐标值标注
		{		
			j ++ ;
			str.Format("%.1f",(float )j / biaozhunum * xmax);
			pLinwDC.TextOut((int)(i * detaX - 4) , 3, str);
		}		
		x = (int)(i * detaX);
		y1 = num[i];
		if (y1 > ymax)
			 continue;
		if (y1 < ymin)
			continue;		
		y = (int)(y1 * detaY);
		//第一个点能够画出的点
		if (m_bFirst)
		{
//			CPoint firstPt(x,-y);
// 			pLinwDC.SetPixel(firstPt,RGB(255,0,0));
			pLinwDC.MoveTo(x, - y);	
			m_bFirst = FALSE;
		} 
		else
		{		
			pLinwDC.LineTo(x,-y);			
		}
	}
	pLinwDC.SelectObject(pOldPen);	
	axisPen.DeleteObject();
	pointPen.DeleteObject();	
	bigFont.DeleteObject();
	smallFont.DeleteObject();
}
//知识设置了x轴的标注范围
void CWindowFilterView::Plot(int n, int length, float max,float *num, float xmax)
{
	float detaX ,detaY;
	CRect rect;
	CStatic *pWndLine;
	//目前只标注5个点。
	int biaozhunum = 5;
	int xbiaozhu = length / biaozhunum;
	//得到对应的画板
	switch (n)
	{
	case 1:
		pWndLine = (CStatic *)GetDlgItem(IDC_PALETTE1);				
		break;
	case 2:
		pWndLine = (CStatic *)GetDlgItem(IDC_PALETTE2);				
		break;
	case 3:
		pWndLine = (CStatic *)GetDlgItem(IDC_PALETTE3);
		break;
	}	
	//得到画板的大小
	pWndLine->GetClientRect(&rect);
	CClientDC pLinwDC(pWndLine);
	pLinwDC.SetBkMode(TRANSPARENT);                //设置文字背景颜色
	pLinwDC.SetMapMode(MM_TEXT);                   //Y轴向下,画图时候要加负号
	//设置原点
	//15为修正的偏倚量
	pLinwDC.SetViewportOrg(int(rect.right/(length+2) + 15 ),int(rect.bottom/2));
	detaX = (float)(rect.right/(length+2));               //x轴间距
	detaY = (float)(0.5 * (rect.Height()-30) / max);       //y轴间距,重新计算,以及y的大小
	CPen axisPen, pointPen;
	CPen *pOldPen;
	CFont bigFont, smallFont;
	CFont *pOldFont;	
	axisPen.CreatePen(PS_SOLID,2,RGB(0,0,0));     //黑线
	pointPen.CreatePen(PS_SOLID,1,RGB(255,0,0));  //红线
	bigFont.CreatePointFont(100,"Arial",NULL);
	smallFont.CreatePointFont(80,"Arial",NULL);
	pOldPen = pLinwDC.SelectObject(&axisPen);	
	//绘制x,y坐标轴
	pLinwDC.MoveTo(0,0);
	pLinwDC.LineTo((int)(detaX*length),0);
	pLinwDC.MoveTo((int)(detaX*length),0);
	pLinwDC.LineTo((int)(detaX*length-8),-4);
	pLinwDC.MoveTo((int)(detaX*length),0);
	pLinwDC.LineTo((int)(detaX*length-8),4);
	pLinwDC.MoveTo(0,rect.bottom/2-10);
	pLinwDC.LineTo(0,-1*(rect.bottom/2-10));
	//求最大值的次方数,用于标注10的几次方
	//之后要创建字体

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -