📄 testfilterdlg.cpp
字号:
//TestFilterDlg.cpp : implementation file
#include "stdafx.h"
#include "TestFilter.h"
#include "TestFilterDlg.h"
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#endif
typedef struct TWaveFileHeadStruct{ char FileHead1[4]; int FileLength; char FileHead2[8]; int Reserve; PCMWAVEFORMAT PcmWaveFormat; char DataPoint[4]; int nWaveLength;}WAVEFILEHEADSTRUCT;
typedef struct TWave{ WAVEFILEHEADSTRUCT WaveFileHead; byte *lpChannelData[2]; byte *lpWaveData;}WAVE;
//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()
//CTestFilterDlg dialog
CTestFilterDlg::CTestFilterDlg(CWnd* pParent/*=NULL*/)
: CDialog(CTestFilterDlg::IDD,pParent)
{
//{{AFX_DATA_INIT(CTestFilterDlg)
m_bFilter=FALSE;
m_FilterLow = 0;
m_FilterHigh=0;
m_bBaudPass = FALSE;
//}}AFX_DATA_INIT
//Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon=AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CTestFilterDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CTestFilterDlg)
DDX_Control(pDX, IDC_EDIT_FILTER3, m_FreqList);
DDX_Control(pDX, IDC_STATIC_WAVE2, m_CtrlWave2);
DDX_Control(pDX, IDC_STATIC_FREQ, m_CtrlFreq);
DDX_Control(pDX, IDC_STATIC_WAVE, m_CtrlWave);
DDX_Check(pDX,IDC_CHECK_FILTER,m_bFilter);
DDX_Text(pDX, IDC_EDIT_FILTER, m_FilterLow);
DDX_Text(pDX, IDC_EDIT_FILTER2, m_FilterHigh);
DDX_Check(pDX, IDC_CHECK_BAUDPASS, m_bBaudPass);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CTestFilterDlg,CDialog)
//{{AFX_MSG_MAP(CTestFilterDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BTN_GENWAVE,OnBtnGenwave)
ON_BN_CLICKED(IDC_BTN_FFT,OnBtnFft)
ON_WM_TIMER()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
//CTestFilterDlg message handlers
BOOL CTestFilterDlg::OnInitDialog()
{
CDialog::OnInitDialog();
//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
//TODO: Add extra initialization here
m_CtrlWave.GetClientRect(&m_WaveRect);
m_CtrlWave2.GetClientRect(&m_Wave2Rect);
m_CtrlFreq.GetClientRect(&m_FreqRect);
pWaveDC=m_CtrlWave.GetDC();
memWaveDC.CreateCompatibleDC(pWaveDC);
memBitmapWave.CreateCompatibleBitmap(pWaveDC,m_WaveRect.Width(),m_WaveRect.Height());
memWaveDC.SelectObject(&memBitmapWave);
pFreqDC=m_CtrlFreq.GetDC();
memFreqDC.CreateCompatibleDC(pFreqDC);
memBitmapFreq.CreateCompatibleBitmap(pFreqDC,m_FreqRect.Width(),m_FreqRect.Height());
memFreqDC.SelectObject(&memBitmapFreq);
pWave2DC=m_CtrlWave2.GetDC();
memWave2DC.CreateCompatibleDC(pWave2DC);
memBitmapWave2.CreateCompatibleBitmap(pWave2DC,m_Wave2Rect.Width(),m_Wave2Rect.Height());
memWave2DC.SelectObject(&memBitmapWave2);
fMaxFreq=1024;
fdt=1/fMaxFreq;
//创建字体
NONCLIENTMETRICS ncm;
ncm.cbSize=sizeof(NONCLIENTMETRICS);
SystemParametersInfo(SPI_GETNONCLIENTMETRICS,sizeof(NONCLIENTMETRICS),&ncm,0);
mWaveFont.CreateFontIndirect(&(ncm.lfMessageFont));
DrawWaveData(&memWaveDC,m_WaveRect,fAccWave,N,1.2,TIME_FIELD);
DrawWaveData(&memFreqDC,m_FreqRect,fFreqData,N,30,FREQ_FIELD);
DrawWaveData(&memWave2DC,m_Wave2Rect,fAcc2Wave,N,0.5,TIME_FIELD);
SetTimer(1,100,NULL);
return TRUE;//return TRUE unless you set the focus to a control
}
void CTestFilterDlg::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 CTestFilterDlg::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 CTestFilterDlg::OnQueryDragIcon()
{
return(HCURSOR) m_hIcon;
}
void CTestFilterDlg::DrawWaveData(CDC *pDC,CRect mRect,FLOAT data[],INT ptNum,FLOAT fDataMax,int Mode)
{
CPen GrayPen;
CPen GreenPen;
CPen *pOldPen;
INT nIndex;
FLOAT fX0,fY0,fW,fH;
FLOAT fTemp;
INT nTemp;
INT i;
CString str;
CRect mInRect;
mInRect=mRect;
pDC->SetTextColor(RGB(255,255,255));
pDC->SetBkMode(TRANSPARENT);
pDC->SelectObject(&mWaveFont);
GrayPen.CreatePen(PS_SOLID,1,RGB(128,128,128));
GreenPen.CreatePen(PS_SOLID,1,RGB(0,255,0));
//绘制波形部分
pOldPen=pDC->SelectObject(&GrayPen);
pDC->Rectangle(mInRect);
pDC->FillSolidRect(mInRect,RGB(50,50,50));
mInRect.left=mInRect.left+30;
mInRect.bottom=mInRect.bottom-20;
fX0=(FLOAT)mInRect.left;
fY0=(FLOAT)(mInRect.top+mInRect.bottom)/2.0f;
fW=(FLOAT)mInRect.Width();
fH=(FLOAT)mInRect.Height()/2.0f;
//垂直线
for(nIndex=0;nIndex<10;nIndex++)
{
fTemp=fX0+fW*nIndex/10.0f;
nTemp=(INT)fTemp;
pDC->MoveTo(nTemp,mInRect.top);
pDC->LineTo(nTemp,mInRect.bottom);
if(Mode==TIME_FIELD)
{
str.Format(_T("0.%d"),nIndex);
}
else
{
str.Format(_T("%d"),nIndex*100);
}
pDC->TextOut(nTemp,mRect.bottom-15,str);
}
if(Mode==TIME_FIELD)
pDC->TextOut(mRect.right-15,mRect.bottom-15,"S");
else
pDC->TextOut(mRect.right-15,mRect.bottom-15,"Hz");
//水平线
for(nIndex=0;nIndex<5;nIndex++)
{
fTemp=fH*2.0f*nIndex/4.0f;
nTemp=mInRect.top+(INT)fTemp;
pDC->MoveTo(mInRect.left,nTemp);
pDC->LineTo(mInRect.right,nTemp);
}
for(nIndex=0;nIndex<3;nIndex++)
{
fTemp=fH*2.0f*nIndex/4.0f;
nTemp=mInRect.top+(INT)fTemp;
if(Mode==TIME_FIELD)
{
str.Format(_T("%d"),1-nIndex);
}
else
{
str.Format(_T("%d"),200-nIndex*200);
}
pDC->TextOut(mRect.left+5,mRect.top+20+fTemp,str);
}
//绘制曲线
pOldPen=pDC->SelectObject(&GreenPen);
fTemp=SetWaveDataInScope(data[0],fDataMax);
pDC->MoveTo((INT)(fX0+fW*0/ptNum),(INT)(fY0-fTemp/fDataMax*fH));
for(i=1;i<=ptNum-1;i++)
{
//限制波形范围
fTemp=SetWaveDataInScope(data[i],fDataMax);
pDC->LineTo((INT)(fX0+fW*i/ptNum),(INT)(fY0-fTemp/fDataMax*fH));
}
pDC->SelectObject(pOldPen);
GreenPen.DeleteObject();
GrayPen.DeleteObject();
}
//设置在波形的范围内
float CTestFilterDlg::SetWaveDataInScope(FLOAT fValue,FLOAT fMax)
{
FLOAT fTemp=0.0f;
if((fValue<fMax)&&(fValue>(-1.0f)*fMax))
{
fTemp=fValue;
}
else if(fValue>=fMax)
{
fTemp=fMax;
}
else if(fValue<=(-1.0f)*fMax)
{
fTemp=fMax*(-1.0f);
}
return fTemp;
}
void CTestFilterDlg::OnBtnGenwave()
{
//TODO: Add your control notification handler code here
int i;
CString str;
int freq0=rand()%10;
int freq1=rand()%100;
int freq2=rand()%200;
int freq3=rand()%500;
int freq4=rand()%10;
str.Format("%d,%d,%d,%d,%d",freq0,freq1,freq2,freq3,freq4);
m_FreqList.SetWindowText(str);
for(i=0;i<N;i++)
{
fAccWave[i]=0.7*sin(2*PI*freq0*i*fdt)+0.5*sin(2*PI*freq1*i*fdt)
+0.2*sin(2*PI*freq2*i*fdt)+0.1*sin(2*PI*freq3*i*fdt)+0.7*sin(2*PI*freq4*i*fdt);
}
DrawWaveData(&memWaveDC,m_WaveRect,fAccWave,N,1.2,TIME_FIELD);
OnBtnFft();
}
//设置在频谱的范围内
FLOAT CTestFilterDlg::SetFreqDataInScope(FLOAT fValue,FLOAT fMax)
{
FLOAT fTemp=0.0f;
//限制范围
if((fValue<fMax)&&(fValue>(-1*fMax)))
{
fTemp=fValue;
}
else
{
fTemp=0.5f;
}
return fTemp;
}
void CTestFilterDlg::OnBtnFft()
{
//TODO: Add your control notification handler code here
//计算频谱
//时域 -FFT-- >频域 --> 滤波 -IFFT-->时域
int i;
float xreal[N],ximag[N],xres[N];
UpdateData(TRUE);
for(i=0;i<N;i++)
{
xreal[i]=fAccWave[i];
ximag[i]=0.0;
}
FourieTrans(xreal,ximag,N);
GetResult(xreal,ximag,xres,N);
//在频域上滤波
if(m_bFilter)
{
if(m_FilterLow>=0 && m_FilterLow<N/2 &&m_FilterHigh>m_FilterLow && m_FilterHigh<N/2)
{
if(m_bBaudPass)
{
for(i=0;i<m_FilterLow;i++)
{
xres[i]=0;
xres[N-i]=0;
}
for(i=m_FilterHigh;i<N/2;i++)
{
xres[i]=0;
xres[N-i]=0;
}
}
else
{
for(i=m_FilterLow;i<m_FilterHigh;i++)
{
xres[i]=0;
xres[N-i]=0;
}
}
}
}
for(i=0;i<N;i++)
{
fFreqData[i]=xres[i];
}
for(i=0;i<N;i++)
{
xreal[i]=xres[i];
ximag[i]=0.0;
}
IFourieTrans(xreal,ximag,N);
for(i=0;i<N;i++)
{
xres[i]=(1/(float)N)*4*(xreal[i]+ximag[i]);
}
for(i=0;i<N;i++)
{
fAcc2Wave[i]=xres[i];
}
DrawWaveData(&memFreqDC,m_FreqRect,fFreqData,N,30,FREQ_FIELD);
DrawWaveData(&memWave2DC,m_Wave2Rect,fAcc2Wave,N,0.5,TIME_FIELD);
}
void CTestFilterDlg::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
pWaveDC->BitBlt(m_WaveRect.left,m_WaveRect.top,m_WaveRect.right,m_WaveRect.bottom,
&memWaveDC,0,0,SRCCOPY);
pFreqDC->BitBlt(m_FreqRect.left,m_FreqRect.top,m_FreqRect.right,m_FreqRect.bottom,
&memFreqDC,0,0,SRCCOPY);
pWave2DC->BitBlt(m_Wave2Rect.left,m_Wave2Rect.top,m_Wave2Rect.right,m_Wave2Rect.bottom,
&memWave2DC,0,0,SRCCOPY);
CDialog::OnTimer(nIDEvent);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -