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

📄 sunview.cpp

📁 MFC编写的一个FIR的程序
💻 CPP
字号:
// sunView.cpp : implementation of the CSunView class
//

#include "stdafx.h"
#include "sun.h"

#include "sunDoc.h"
#include "sunView.h"
#include "complex.h"
#include <math.h>
#define PI_2    2*(double)3.14159265358979323846
#define PI      (double)3.14159265358979323846
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CSunView

IMPLEMENT_DYNCREATE(CSunView, CView)

BEGIN_MESSAGE_MAP(CSunView, CView)
	//{{AFX_MSG_MAP(CSunView)
	ON_COMMAND(ID_CHOSE, OnChose)
	ON_COMMAND(ID_DOFIR, OnDofir)
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CSunView construction/destruction

CSunView::CSunView()
{
	// TODO: add construction code here

}

CSunView::~CSunView()
{
}

BOOL CSunView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CSunView drawing

void CSunView::OnDraw(CDC* pDC)
{
	CSunDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
	
if(cholg.flag==1)
	{
   
  
   int count;
   count=pow(2,nn);
   int dd=count;
   complex * x;
   double * ms;
   double *phase;
	
   
  


   
   x=new complex[count];
   
   ms=new double[count];
   
   phase=new double[count];

   if(cholg.m_xuan==0)load(x,nn);
   if(cholg.m_xuan==1)sanload(x,nn);
   if(cholg.m_xuan==2)fangload(x,nn);



   



   
   
	CString str;
	int i; 
    
	// 创建画笔对象
	CPen* pPenRed=new CPen;
	// 红色画笔
	pPenRed->CreatePen(PS_SOLID,1,RGB(255,0,0));

	// 创建画笔对象
	CPen* pPenBlue=new CPen;
    // 蓝色画笔
	pPenBlue->CreatePen(PS_SOLID,1,RGB(0,0, 255));




	
		//原序列垂直轴
		pDC->MoveTo(50,10);
		pDC->LineTo(50,230);

	    //原序列水平轴
	    pDC->MoveTo(50,110);
	    pDC->LineTo(350,110);

     	//绘制原序列X轴箭头
	    pDC->MoveTo(345,105);
	    pDC->LineTo(350,110);
	    pDC->LineTo(345,115);
	
	    //绘制原序列Y轴箭头
	    pDC->MoveTo(50,10);
	    pDC->LineTo(45,15);
	    pDC->MoveTo(50,10);
	    pDC->LineTo(55,15);

		str.Format("原序列");
    	pDC->TextOut(70,10,str);

		//FFT序列幅频垂直轴
		pDC->MoveTo(400,10);
		pDC->LineTo(400,180);

	    //FFT序列幅频水平轴
	    pDC->MoveTo(400,180);
	    pDC->LineTo(700,180);

     	//绘制FFT序列幅频X轴箭头
	    pDC->MoveTo(695,175);
	    pDC->LineTo(700,180);
	    pDC->LineTo(695,185);
	
	    //绘制FFT序列幅频Y轴箭头
	    pDC->MoveTo(400,10);
	    pDC->LineTo(395,15);
	    pDC->MoveTo(400,10);
	    pDC->LineTo(405,15);

		str.Format("原序列经FFT所得的幅频特性");
    	pDC->TextOut(600,10,str);



		//FFT序列相频垂直轴
		pDC->MoveTo(400,250);
		pDC->LineTo(400,450);

	    //FFT序列相频水平轴
	    pDC->MoveTo(400,350);
	    pDC->LineTo(700,350);

     	//绘制FFT序列相频X轴箭头
	    pDC->MoveTo(695,345);
	    pDC->LineTo(700,350);
	    pDC->LineTo(695,355);
	
	    //绘制FFT序列相频Y轴箭头
	    pDC->MoveTo(400,250);
	    pDC->LineTo(395,255);
	    pDC->MoveTo(400,250);
	    pDC->LineTo(405,255);

		str.Format("原序列经FFT所得的相频特性");
    	pDC->TextOut(420,250,str);
		
		
		
		
		//IFFT序列垂直轴
		pDC->MoveTo(50,250);
		pDC->LineTo(50,450);

	    //IFFT水平轴
	    pDC->MoveTo(50,350);
	    pDC->LineTo(350,350);




       //绘制IFFT序列X轴箭头
	    pDC->MoveTo(345,345);
	    pDC->LineTo(350,350);
	    pDC->LineTo(345,355);

	
	    //绘制IFFT序列Y轴箭头
	    pDC->MoveTo(50,250);
	    pDC->LineTo(45,255);
	    pDC->MoveTo(50,250);
	    pDC->LineTo(55,255);

		str.Format("原序列经FFT和IFFT所得序列");
    pDC->TextOut(70,250,str);





		// 选中当前蓝色画笔,并保存以前的画笔
	    CGdiObject* pOldPen = pDC->SelectObject(pPenBlue);

		for(i=0;i<count;i++)
			{
				pDC->MoveTo(i+50,110);
        	    pDC->LineTo(i+50,110-int(x[i].ShowReal()));
			
			}


     fft(x,nn);

        
		for(i=0;i<count;i++){
			ms[i]=x[i].abs();
		}
       pDC->SelectObject(pPenRed);
	   
		    

			for(i=0;i<count;i++)
			{
			   pDC->MoveTo(i+400,180);
                pDC->LineTo(i+400,180-0.1*int(ms[i])); 

			}

		
		for(i=0;i<count;i++){
			phase[i]=x[i].arg();
		}

		for(i=0;i<count;i++)
			{
				pDC->MoveTo(i+400,350);
                pDC->LineTo(i+400,350-int(50*phase[i])); 
		}
       
		
		ifft(x,nn);
pDC->SelectObject(pPenBlue);

        for(i=0;i<count;i++)
			{
				pDC->MoveTo(i+50,350);
        	    pDC->LineTo(i+50,350-int(x[i].ShowReal())/dd);
			
			}




delete[]ms;
delete[]x;
delete[]phase;


	}





	if(firolg.flag==1){

	CString str;
	int i; 
    
	// 创建画笔对象
	CPen* pPenRed=new CPen;
	// 红色画笔
	pPenRed->CreatePen(PS_SOLID,1,RGB(255,0,0));

	// 创建画笔对象
	CPen* pPenBlue=new CPen;
    // 蓝色画笔
	pPenBlue->CreatePen(PS_SOLID,1,RGB(0,0, 255));




	
		//原序列垂直轴
		pDC->MoveTo(50,10);
		pDC->LineTo(50,230);

	    //原序列水平轴
	    pDC->MoveTo(50,110);
	    pDC->LineTo(350,110);

     	//绘制原序列X轴箭头
	    pDC->MoveTo(345,105);
	    pDC->LineTo(350,110);
	    pDC->LineTo(345,115);
	
	    //绘制原序列Y轴箭头
	    pDC->MoveTo(50,10);
	    pDC->LineTo(45,15);
	    pDC->MoveTo(50,10);
	    pDC->LineTo(55,15);

		str.Format("测试序列X(n)");
    	pDC->TextOut(70,10,str);

		//FFT序列幅频垂直轴
		pDC->MoveTo(400,10);
		pDC->LineTo(400,180);

	    //FFT序列幅频水平轴
	    pDC->MoveTo(400,180);
	    pDC->LineTo(700,180);

     	//绘制FFT序列幅频X轴箭头
	    pDC->MoveTo(695,175);
	    pDC->LineTo(700,180);
	    pDC->LineTo(695,185);
	
	    //绘制FFT序列幅频Y轴箭头
	    pDC->MoveTo(400,10);
	    pDC->LineTo(395,15);
	    pDC->MoveTo(400,10);
	    pDC->LineTo(405,15);

		str.Format("窗函数幅频特性|W(ejw)|");
    	pDC->TextOut(600,10,str);



		//FFT序列相频垂直轴
		pDC->MoveTo(400,250);
		pDC->LineTo(400,450);

	    //FFT序列相频水平轴
	    pDC->MoveTo(400,450);
	    pDC->LineTo(700,450);

     	//绘制FFT序列相频X轴箭头
	    pDC->MoveTo(695,445);
	    pDC->LineTo(700,450);
	    pDC->LineTo(695,455);
	
	    //绘制FFT序列相频Y轴箭头
	    pDC->MoveTo(400,250);
	    pDC->LineTo(395,255);
	    pDC->MoveTo(400,250);
	    pDC->LineTo(405,255);

		str.Format("滤波器衰减特性20lg(|H(ejw)|");
    	pDC->TextOut(420,250,str);
		
		
		
		
		//IFFT序列垂直轴
		pDC->MoveTo(50,250);
		pDC->LineTo(50,450);

	    //IFFT水平轴
	    pDC->MoveTo(50,350);
	    pDC->LineTo(350,350);




       //绘制IFFT序列X轴箭头
	    pDC->MoveTo(345,345);
	    pDC->LineTo(350,350);
	    pDC->LineTo(345,355);

	
	    //绘制IFFT序列Y轴箭头
	    pDC->MoveTo(50,250);
	    pDC->LineTo(45,255);
	    pDC->MoveTo(50,250);
	    pDC->LineTo(55,255);

		str.Format("滤波后序列Y(n)");
    pDC->TextOut(70,250,str);





		// 选中当前蓝色画笔,并保存以前的画笔
	    CGdiObject* pOldPen = pDC->SelectObject(pPenBlue);

	for(i=0;i<256;i++)
			{
				pDC->MoveTo(i+50,110);
        	    pDC->LineTo(i+50,110-int(50*Xn[i]));
			
			}

for(i=0;i<256;i++)
			{
				pDC->MoveTo(i+50,350);
        	    pDC->LineTo(i+50,350-(50*I[i]));
			
			}

pDC->SelectObject(pPenRed);
for(i=0;i<256;i++)
			{
				pDC->MoveTo(i+400,450);
                pDC->LineTo(i+400,450+int(Hd[i])); 
		}
  for(i=0;i<256;i++)
			{
			   pDC->MoveTo(i+400,180);
                pDC->LineTo(i+400,180-int(100*Hw[i])); 

			}     




	}






}

/////////////////////////////////////////////////////////////////////////////
// CSunView printing

BOOL CSunView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void CSunView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CSunView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CSunView diagnostics

#ifdef _DEBUG
void CSunView::AssertValid() const
{
	CView::AssertValid();
}

void CSunView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CSunDoc* CSunView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CSunDoc)));
	return (CSunDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CSunView message handlers





void CSunView::fft(complex *x, int m)
{   complex *w;
    float num=0;
    int n=1;
	complex u,temp,tm,wrecur,w_s;
	complex *xi,*xj,*wptr;
	int i,j,k,l,le,windex;
	double arg;
	if(m==0)return;
	n=(int)pow(2,m);
    le=n/2;
	
	w=(complex*)calloc(le,sizeof(complex));
	
	
	arg=PI/le;//计算pi/le
    xj=w;
	
	w_s.copy(cos(arg),-sin(arg));
	wrecur.copy(1,0);
	for (j=0;j<le;j++){
		*xj=wrecur;	
		xj++;		
        wrecur=wrecur*w_s;
		}

//反向调整数据//
	j=0;
	for(i=1;i<n;i++){
	k=n;	
    for(int a=1;a<=m;a++){
		k=k/2;
		if(k<=j) j=j-k;
		else{j=j+k;break;}
		}

	if(i<j){
		xi=x+i;
		xj=x+j;
		temp =*xj;
		*xj=*xi;
		*xi=temp;
	}
	}
	
//fft计算//
   le=1;
   windex=n/2;
   for(l=0;l<m;l++){
	   le=le*2;
	   wptr=w;	
	   for(j=0;j<le/2;j++){
		   u=*wptr;
		   for(i=j;i<n;i=i+le){
			   xi=x+i;
			   xj=xi+le/2;
			   temp=*xi;
			   *xi=*xi+u*(*xj);
			   *xj=temp-u*(*xj);
		   }
		   wptr=wptr+windex;		   
	   }
	   windex=windex/2;
   }
   free(w);

}





void CSunView::load(complex *x,int n)
{int m=pow(2,n);
	for(int i=0;i<m;i++){
 	x[i].copy(70*sin(i*PI/(m/2)),0);
	}

}




void CSunView::sanload(complex *x,int n)
{int mm;
	int m=1,g=0;
	int d=0;
	mm=pow(2,n);

	for(int i=0;i<mm;i++){
		g=g+m;
		if(g==(mm/4)||g==0){
			m=m*(-1);	
		}
    d=20*g/(mm/16);
 	x[i].copy(d,0);
	}


}



void CSunView::fangload(complex *x,int n)
{int m=0,g=1;
int mm;
mm=pow(2,n);
	for(int i=0;i<mm;i++){
 	m++;
	if(m<(mm/2)){
		g=1;	
	}
	if(m>(mm/2)){
		g=-1;
	}

	
	x[i].copy(50*g,0);
	}

}







void CSunView::OnChose() 
{	if(cholg.DoModal()!=IDOK)
	{
		return;
	}
	// TODO: Add your command handler code here
if(cholg.m_jie==0)nn=4;
if(cholg.m_jie==1)nn=5;
if(cholg.m_jie==2)nn=6;
if(cholg.m_jie==3)nn=7;
if(cholg.m_jie==4)nn=8;
if(cholg.m_jie==5)nn=9;
cholg.flag=1;





Invalidate();

}



void CSunView::ifft(complex *x, int m)
{   complex *w;
    float num=0;
    int n=1;
	complex u,temp,tm,wrecur,w_s;
	complex *xi,*xj,*wptr;
	int i,j,k,l,le,windex;
	double arg;
	if(m==0)return;
	n=(int)pow(2,m);
    le=n/2;
	
	w=(complex*)calloc(le,sizeof(complex));
	if(!w){
		exit(1);
	}	
	
	arg=PI/le;//计算pi/le
    xj=w;
	
	w_s.copy(cos(arg),sin(arg));
	wrecur.copy(1,0);
	for (j=0;j<le;j++){
		*xj=wrecur;	
		xj++;		
        wrecur=wrecur*w_s;
		}
	//ifft计算//
   le=n;
   windex=1;
   for(l=0;l<m;l++){
	   le=le/2;
	   wptr=w;	
	   for(j=0;j<le;j++){
		   u=*wptr;
		   for(i=j;i<n;i=i+2*le){
			   xi=x+i;
			   xj=xi+le;
			   temp=*xi;
			   *xi=((*xi+(*xj)));
			   *xj=((temp-(*xj))*u);
			  

		   }
		   wptr=wptr+windex;		   
	   }
	   windex=windex*2;
   }

//反向调整数据//
	j=0;
	for(i=1;i<n;i++){
	k=n;	
    for(int a=1;a<=m;a++){
		k=k/2;
		if(k<=j) j=j-k;
		else{j=j+k;break;}
		}

	if(i<j){
		xi=x+i;
		xj=x+j;
		temp =*xj;
		*xj=*xi;
		*xi=temp;
	}
	}
   free(w);
}

void CSunView::OnDofir() {

	if(firolg.DoModal()!=IDOK)
	{
		return;
	}
	
     UpdateData();
	 int i;
	 m_a=(firolg.m_nn-1)/2;
     Wn=new double[firolg.m_nn];
	 Hd=new double[firolg.m_nn];
Hw=new double[256];
     Hn=new double[256];
     I=new double[256];
	 Xn=new double[256];
     Hd=new double[256];
Ww=new double[256];
	 xy=new complex[256];
	 orig=new complex[256];
     buf=new complex[256];
	 double Wc=PI*firolg.m_Wc;
	 for(i=0;i<256;i++){	  
		 Hn[i]=0;  Xn[i]=0;
	 }
    


	 for(i=0;i<firolg.m_nn;i++){	 //产生窗函数
		 switch(firolg.m_type){
		 case 0:  Wn[i]=1.0;    break;
		 case 1:  Wn[i]=0.54-0.46*cos(PI_2*i/(firolg.m_nn-1));   break;
		 case 2:  Wn[i]=0.5*(1-cos(PI_2*i/(firolg.m_nn-1)));   break;      
		 case 3:  Wn[i]=0.42-0.5*cos(PI_2*i/(firolg.m_nn-1))+0.08*cos(4*PI*i/(firolg.m_nn-1));   break;
		 default:      break;      
		 }

	// TODO: Add your command handler code here
		if(i!=m_a)
		Hd[i]=sin(Wc*(i-m_a))/(i-m_a)/PI;
		else    Hd[i]=Wc/PI;   
		Hn[i]=Wn[i]*Hd[i];     
	}


 for(int j=0;j<256;j++){
     xy[j].copy(Hn[j],0);
	 }

fft(xy,8);


for(i=0;i<256;i++){
     Hw[i]=xy[i].abs();
}

	
double model;
model=Hw[0];
	
for(i=0;i<256;i++)
		{Ww[i]=Hw[i]/model;
		
			}


for(i=0;i<256;i++)
	{ Hd[i]=20*log10(Ww[i]);	}

double low=PI*firolg.m_low;//待测序列
double high=PI*firolg.m_high;
        for(i=0;i<256;i++)
	 	Xn[i]=cos(i*low)+cos(i*high);

 for(i=0;i<256;i++){
     orig[i].copy(Xn[i],0);
	 }




fft(orig,8);

for(i=0;i<256;i++){//由时域卷积定理:时域卷积==>频域乘积
	buf[i]=orig[i]*xy[i];
}

ifft(buf,8);//用付里叶反变换求得结果序列Y(n)---存入I

for(i=0;i<256;i++){
	I[i]=buf[i].ShowReal()/256;
}
firolg.flag=1;
Invalidate();
}

⌨️ 快捷键说明

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