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

📄 firfilterdlg.cpp

📁 用Visual c++写的有限长单位脉冲响应滤波器
💻 CPP
📖 第 1 页 / 共 4 页
字号:
// FIRFilterDlg.cpp : implementation file
//

#include "stdafx.h"
#include "FIRFilter.h"
#include "FIRFilterDlg.h"
#include "math.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define PI 3.1415926535897931

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CFIRFilterDlg dialog

CFIRFilterDlg::CFIRFilterDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CFIRFilterDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CFIRFilterDlg)
	m_disturbamp = _T("");
	m_disturbper = _T("");
	m_window_length = _T("");
	m_cutoff_frequency = _T("");
	m_low_cutfrequency = _T("");
	m_high_cutfrequency = _T("");
	m_ampmsg = _T("");
	m_permsg = _T("");
	m_highcutmsg = _T("");
	m_lowcutmsg = _T("");
	m_cutmsg = _T("");
	m_unitcut = _T("");
	m_unithighcut = _T("");
	m_unitlowcut = _T("");
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CFIRFilterDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CFIRFilterDlg)
	DDX_Control(pDX, IDC_WINDOW_TYPE, m_window_type);
	DDX_Control(pDX, IDC_FILTER_TYPE, m_filter_type);
	DDX_Control(pDX, IDC_FREQUENCY, m_period);
	DDX_Control(pDX, IDC_AMPLITUDE, m_amplitude);
	DDX_Text(pDX, IDC_EDIT_DISTURBAMP, m_disturbamp);
	DDX_Text(pDX, IDC_EDIT_DISTURBPER, m_disturbper);
	DDX_Text(pDX, IDC_WINDOW_LENGTH, m_window_length);
	DDX_Text(pDX, IDC_CUTOFF_FREQUENCY, m_cutoff_frequency);
	DDX_Text(pDX, IDC_LOW_CUTFREQUENCY, m_low_cutfrequency);
	DDX_Text(pDX, IDC_HIGH_CUTFREQUENCY, m_high_cutfrequency);
	DDX_Text(pDX, IDC_AMPMSG, m_ampmsg);
	DDX_Text(pDX, IDC_PERMSG, m_permsg);
	DDX_Text(pDX, IDC_HIGHCUTMSG, m_highcutmsg);
	DDX_Text(pDX, IDC_LOWCUTMSG, m_lowcutmsg);
	DDX_Text(pDX, IDC_CUTMSG, m_cutmsg);
	DDX_Text(pDX, IDC_UNIT_CUT, m_unitcut);
	DDX_Text(pDX, IDC_UNIT_HIGHCUT, m_unithighcut);
	DDX_Text(pDX, IDC_UNIT_LOWCUT, m_unitlowcut);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CFIRFilterDlg, CDialog)
	//{{AFX_MSG_MAP(CFIRFilterDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_WM_HSCROLL()
	ON_EN_CHANGE(IDC_EDIT_DISTURBAMP, OnChangeEditDisturbamp)
	ON_EN_CHANGE(IDC_EDIT_DISTURBPER, OnChangeEditDisturbper)
	ON_CBN_SELCHANGE(IDC_FILTER_TYPE, OnSelchangeFilterType)
	ON_CBN_SELCHANGE(IDC_WINDOW_TYPE, OnSelchangeWindowType)
	ON_EN_CHANGE(IDC_CUTOFF_FREQUENCY, OnChangeCutoffFrequency)
	ON_EN_CHANGE(IDC_LOW_CUTFREQUENCY, OnChangeLowCutfrequency)
	ON_EN_CHANGE(IDC_HIGH_CUTFREQUENCY, OnChangeHighCutfrequency)
	ON_EN_CHANGE(IDC_WINDOW_LENGTH, OnChangeWindowLength)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CFIRFilterDlg message handlers

BOOL CFIRFilterDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon

	//有用信号的设置
	m_amplitude.SetScrollRange(0,20);   //正弦曲线的幅值范围0---4
	m_period.SetScrollRange(0,250);
//	m_noiamp.SetScrollRange(0,20);   //正弦曲线的幅值范围0---4
//	m_noiper.SetScrollRange(0,250);

	m_amplitude.SetScrollPos(10);       //设置初始的幅值为2
	m_period.SetScrollPos(50);
//	m_noiamp.SetScrollPos(5);       //设置初始的幅值为2
//	m_noiper.SetScrollPos(50);

	amplitude = m_amplitude.GetScrollPos();  //对数据成员进行赋值操作
	period = m_period.GetScrollPos();	
//	noiamp = m_noiamp.GetScrollPos();  //对数据成员进行赋值操作
//	noiper = m_noiper.GetScrollPos();

	/**********干扰信号的参数设置************************/
	UpdateData(TRUE);
	m_disturbamp="1.0";
	m_disturbper="0.7";
	disturbamp=atof(m_disturbamp);
	disturbper=atof(m_disturbper);
	UpdateData(FALSE);

	/**********滤波器的参数设置*******************/
	UpdateData(TRUE);
	m_window_length="64";
	m_cutoff_frequency="0.5";
	m_low_cutfrequency="0.5";
	m_high_cutfrequency="0.8";
	m_filter_type.SetCurSel(0);  //滤波方式的选择
	m_window_type.SetCurSel(0);  //窗函数的选择

	windowlength =atoi(m_window_length);
	double temp_cutofffrequency = atof(m_cutoff_frequency);
	double temp_highcutfrequency = atof(m_high_cutfrequency);
	double temp_lowcutfrequency = atof(m_low_cutfrequency);

	cutofffrequency = (int)(temp_cutofffrequency * 100 / PI);
	highcutfrequency =(int)(temp_highcutfrequency * 100 / PI);
	lowcutfrequency =(int) (temp_lowcutfrequency * 100 / PI);

	UpdateData(FALSE);

	OnSelchangeFilterType();    //滤波方式改变时调用的响应函数

	OnSelchangeWindowType();    //输入序列改变时调用的响应函数
	
	// TODO: Add extra initialization here
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CFIRFilterDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CFIRFilterDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CFIRFilterDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CFIRFilterDlg::OnOK() 
{
	// TODO: Add extra validation here
	MainFunction();
//	CDialog::OnOK();
}

/************************* MainFunction()函数**************************************/
void CFIRFilterDlg::MainFunction()
{
	int i;
	DrawCoordinate();                     //画坐标轴函数
	UpdateShowText();
	DrawScale();
//	UpdateShowText();                     //更新显示文字函数
	Complex *x=new Complex[1024];          //动态创建对象指针
	Complex *y=new Complex[1024];
	Complex *z=new Complex[1024];
//	int ftype=m_wave_shape.GetCurSel();   //获取当前输入序列类型的种类
//	InitData(ftype,x);                    //x在InitData函数中被赋值

	// TODO: Add your control notification handler code here
	int N=200;  //序列长度,T/N是序列的周期,通过改变N和T可以改变频率
	int M=1024;
	//double T=0.0;

	double T=(double)period/10.0;
//	double noiseperiod=(double)noiper/10.0;

//	Complex *x=new Complex[1024];
//	Complex *y=new Complex[1024];
//	Complex *z=new Complex[1024];

	GetSinData(N,M,T,x);

	for(i=1;i<=1024;i++)
		y[i]=x[i];
//	GetNoiseData(N,M,noiseperiod,y);

/*	for(int i=1;i<=1024;i++)
	{
		z[i].real=x[i].real+y[i].real;
		z[i].image=x[i].image+y[i].image;
	}
*/
	DrawSinWave(N,M,x); //画正弦信号加干扰噪声的波形
	DrawOriginalSinWave(); //画原始信号的波形
	//delete []x;

//	DrawInPic1(wavepoint,x);              //画出输入序列的图形

	FFT(256,10,y);
	DrawInPic2(256,y);       //画出输入序列频谱的图形

/*	int pointtemp=wavepoint;    //wavepoint是序列长度
	int ffttime=0;
	while(pointtemp!=0)
	{
		pointtemp/=2;
		ffttime++;
	}
	ffttime--;
	if(wavepoint>pow(2,ffttime))
	{
		ffttime++;
	}
	for(i=wavepoint+1;i<=pow(2,ffttime);i++)
	{
		x[i].real=0;
		x[i].image=0;
	}
	FFT((int)pow(2,ffttime),ffttime,X);
	DrawInPic2((int)pow(2,ffttime),X);       //画出输入序列频谱的图形
*/
	Complex *a=new Complex[1024];
	FirFunction(x, z);                       //此函数中花了系统响应的图形,并且X,y的值发生改变,即是卷积以后的值
	for(i=1;i<1024;i++)
	{
		a[i].real=z[i].real;
		a[i].image=z[i].image;
	}

	DrawOutputWave(N+windowlength,z); //画出滤波后的信号波形

	FFT(256,8,a);
	DrawOutputSpectrum(256,a);
//	DrawOriginalSinWave();

//	DrawOutPic1(wavepoint+windowpoint,y);    //画出输出序列的图形

/*	pointtemp=wavepoint+windowpoint;
	ffttime=0;
	while(pointtemp!=0)
	{
		pointtemp/=2;
		ffttime++;
	}
	ffttime--;
	if(wavepoint>pow(2,ffttime))
	{
		ffttime++;
	}
	for(i=wavepoint+1;i<=pow(2,ffttime);i++)
	{
		x[i].real=0;
		x[i].image=0;
	}
	FFT((int)pow(2,ffttime),ffttime,y);
	DrawOutPic2((int)pow(2,ffttime),y);   //画出输出序列频谱的图形
*/
	UpdateData(false);
	
}


/*****************************更新文字显示的函数**********************************/
void CFIRFilterDlg::UpdateShowText()
{
	double temp=2.0*PI*((double)period/10.0)/200.0;
	m_ampmsg.Format("%.1f",amplitude*0.1);
	m_permsg.Format("%.3f rad",temp);
}

/*************************滑块的消息响应函数**************************************/
void CFIRFilterDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
	// TODO: Add your message handler code here and/or call default
	amplitude=m_amplitude.GetScrollPos();
	period=m_period.GetScrollPos();

//	noiamp=m_noiamp.GetScrollPos();
//	noiper=m_noiper.GetScrollPos();

	if(pScrollBar->GetDlgCtrlID()==IDC_AMPLITUDE)
	{
		switch(nSBCode)
		{
		case SB_LINERIGHT: if(amplitude < 20)
							   amplitude+=1;
			pScrollBar->SetScrollPos(amplitude);
//			DrawCoordinate();
//			CCordinateDlg::OnDrawScale();
//			CCordinateDlg::OnGetsindata(); 
//			CCordinateDlg::OnSpectrumdisplay() ;
			MainFunction();
			break;
		case SB_LINELEFT: if(amplitude > 0)
							  amplitude-=1;
			pScrollBar->SetScrollPos(amplitude);
//			DrawCoordinate();
//			CCordinateDlg::OnDrawScale();
//			CCordinateDlg::OnGetsindata(); 
//			CCordinateDlg::OnSpectrumdisplay() ;
			MainFunction();
			break;
		case SB_THUMBPOSITION:
			pScrollBar->SetScrollPos(nPos);
//			DrawCoordinate();
//			CCordinateDlg::OnDrawScale();
//			CCordinateDlg::OnGetsindata(); 
//			CCordinateDlg::OnSpectrumdisplay(); 
			MainFunction();
			break;
		case SB_THUMBTRACK:
			pScrollBar->SetScrollPos(nPos);
//			DrawCoordinate();
//			CCordinateDlg::OnDrawScale();
//			CCordinateDlg::OnGetsindata();
//			CCordinateDlg::OnSpectrumdisplay(); 
			MainFunction();
			break;
		}
	}
	
	if(pScrollBar->GetDlgCtrlID()==IDC_FREQUENCY)
	{
		switch(nSBCode)
		{
		case SB_LINERIGHT: if(period < 250)
						   period+=1;
		pScrollBar->SetScrollPos(period);
//		DrawCoordinate();
//		CCordinateDlg::OnDrawScale();
//		CCordinateDlg::OnGetsindata(); 
//		CCordinateDlg::OnSpectrumdisplay(); 
		MainFunction();
		break;

		case SB_LINELEFT: if(period > 0)
							  period-=1;
		pScrollBar->SetScrollPos(period);
//		DrawCoordinate();
//		CCordinateDlg::OnDrawScale();
//		CCordinateDlg::OnGetsindata();
//		CCordinateDlg::OnSpectrumdisplay(); 
		MainFunction();
		break;

		case SB_THUMBPOSITION:
			pScrollBar->SetScrollPos(nPos);
//			DrawCoordinate();
//			CCordinateDlg::OnDrawScale();
//			CCordinateDlg::OnGetsindata(); 
//			CCordinateDlg::OnSpectrumdisplay(); 
			MainFunction();
			break;

		case SB_THUMBTRACK:
			pScrollBar->SetScrollPos(nPos);
//			DrawCoordinate();
//			CCordinateDlg::OnDrawScale();
//			CCordinateDlg::OnGetsindata();
//			CCordinateDlg::OnSpectrumdisplay();
			MainFunction();
			break;
		}		
	}
   
/*	if(pScrollBar->GetDlgCtrlID()==IDC_NOIAMP)
	{
		switch(nSBCode)
		{
		case SB_LINERIGHT: if(noiamp < 20)
							   noiamp+=1;
			pScrollBar->SetScrollPos(noiamp);
			DrawCoordinate();
			CCordinateDlg::OnDrawScale();
			CCordinateDlg::OnGetsindata(); 
			break;
		case SB_LINELEFT: if(noiamp > 0)
							  noiamp-=1;
			pScrollBar->SetScrollPos(noiamp);
			DrawCoordinate();
			CCordinateDlg::OnDrawScale();
			CCordinateDlg::OnGetsindata(); 
			break;
		case SB_THUMBPOSITION:
			pScrollBar->SetScrollPos(nPos);
			DrawCoordinate();
			CCordinateDlg::OnDrawScale();
			CCordinateDlg::OnGetsindata(); 
			break;
		case SB_THUMBTRACK:
			pScrollBar->SetScrollPos(nPos);
			DrawCoordinate();
			CCordinateDlg::OnDrawScale();
			CCordinateDlg::OnGetsindata();
			break;
		}
	}
	
	if(pScrollBar->GetDlgCtrlID()==IDC_NOIPER)
	{
		switch(nSBCode)
		{
		case SB_LINERIGHT: if(noiper < 50)
						   noiper+=1;
		pScrollBar->SetScrollPos(noiper);
		DrawCoordinate();
		CCordinateDlg::OnDrawScale();
		CCordinateDlg::OnGetsindata(); 
		break;

		case SB_LINELEFT: if(noiper > 0)
							  noiper-=1;
		pScrollBar->SetScrollPos(noiper);
		DrawCoordinate();
		CCordinateDlg::OnDrawScale();
		CCordinateDlg::OnGetsindata();
		break;

		case SB_THUMBPOSITION:
			pScrollBar->SetScrollPos(nPos);
			DrawCoordinate();
			CCordinateDlg::OnDrawScale();
			CCordinateDlg::OnGetsindata(); 
			break;

		case SB_THUMBTRACK:
			pScrollBar->SetScrollPos(nPos);
			DrawCoordinate();
			CCordinateDlg::OnDrawScale();
			CCordinateDlg::OnGetsindata();
			break;
		}		
	}
*/
	
	CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
}

/*********************************画正弦加干扰信号网格的函数*****************************************/
void CFIRFilterDlg ::DrawCoordinate()
{
	int width=0,height=0,i=0,m=0,n=0;
	CWnd *pwnd;                           //得到图片框的窗口指针  

⌨️ 快捷键说明

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