📄 滤波器设计dlg.cpp
字号:
// 滤波器设计Dlg.cpp : implementation file
//
#include "stdafx.h"
#include "滤波器设计.h"
#include "滤波器设计Dlg.h"
#include "math.h"
#include "basetsd.h"
#include "comp.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// 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()
/////////////////////////////////////////////////////////////////////////////
// CMyDlg dialog
CMyDlg::CMyDlg(CWnd* pParent /*=NULL*/)
: CDialog(CMyDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CMyDlg)
m_downfre = 0.0;
m_pass = 0.0;
m_reject = 0.0;
m_upfre = 0.0;
m_addnoise = TRUE;
m_samplelen = 4;
m_filtertype = 0;
m_band = 0.0;
m_fc = 0.1;
m_beta = 7;
m_noiseamp = 3.0;
m_noisefre = 50000.0;
m_fl = 0.1;
m_fh = 0.3;
m_signalamp = 7.0;
m_signalfre = 5000.0;
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CMyDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CMyDlg)
DDX_Check(pDX, IDC_CHECK_ADDNOISE, m_addnoise);
DDX_CBIndex(pDX, IDC_COMBO_SAMPLELEN, m_samplelen);
DDX_CBIndex(pDX, IDC_COMBO_FILTERTYPE, m_filtertype);
DDX_Text(pDX, IDC_EDIT_REJECTION1, m_fc);
DDX_Text(pDX, IDC_EDIT_BETA, m_beta);
DDX_Text(pDX, IDC_EDIT_NOISEAMP, m_noiseamp);
DDX_Text(pDX, IDC_EDIT_NOISEFRE, m_noisefre);
DDX_Text(pDX, IDC_EDIT_REJECTION2, m_fl);
DDX_Text(pDX, IDC_EDIT_REJECTION3, m_fh);
DDX_Text(pDX, IDC_EDIT_SIGNALAMP, m_signalamp);
DDX_Text(pDX, IDC_EDIT_SIGNALFRE, m_signalfre);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CMyDlg, CDialog)
//{{AFX_MSG_MAP(CMyDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(ID_BOTTON_APPLY, OnBottonApply)
ON_BN_CLICKED(IDC_CHECK_ADDNOISE, OnCheckAddnoise)
ON_CBN_SELCHANGE(IDC_COMBO_SAMPLELEN, OnSelchangeComboSamplelen)
ON_BN_CLICKED(IDC_BUTTON_PLUSE, OnButtonPluse)
ON_CBN_SELCHANGE(IDC_COMBO_FILTERTYPE, OnSelchangeComboFiltertype)
ON_EN_CHANGE(IDC_EDIT_SIGNALFRE, OnChangeEditSignalfre)
ON_BN_CLICKED(IDC_NOISE_AMPLITUDE, OnNoiseAmplitude)
ON_BN_CLICKED(IDC_STATIC_SIGNALWAVE, OnStaticSignalwave)
ON_BN_CLICKED(IDC_STATIC_SIGNAL, OnStaticSignal)
ON_BN_CLICKED(IDC_STATIC_REJECTION2, OnStaticRejection2)
ON_BN_CLICKED(IDC_STATIC_FILTERSIGNAL, OnStaticFiltersignal)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMyDlg message handlers
BOOL CMyDlg::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
// TODO: Add extra initialization here
//////////////////////////////////////////////////////////////////////////////////////
hdc=::GetDC(m_hWnd); //GetDC The GetDC function retrieves a handle to a display device context for the client area of a specified window or for the entire screen.
//CWnd::m_hWnd The handle of the Windows window attached to this CWnd. The m_hWnd data member is a public variable of type HWND.
::MoveWindow(m_hWnd,0,0,959,719,TRUE); //MoveWindow The MoveWindow function changes the position and dimensions of the specified window.
CenterWindow(NULL);
GetDlgItem(IDC_STATIC_SIGNAL)->MoveWindow(25,15,250,110,TRUE);
GetDlgItem(IDC_SIGNAL_FREQUENCY)->MoveWindow(35,45,45,20,TRUE);
GetDlgItem(IDC_EDIT_SIGNALFRE)->MoveWindow(80,43,160,20,TRUE);
GetDlgItem(IDC_SIGNAL_AMPLITUDE)->MoveWindow(35,85,45,20,TRUE);
GetDlgItem(IDC_EDIT_SIGNALAMP)->MoveWindow(80,83,160,20,TRUE);
GetDlgItem(IDC_STATIC_NOISE)->MoveWindow(290,15,250,110,TRUE);
GetDlgItem(IDC_NOISE_FREQUENCY)->MoveWindow(300,45,45,20,TRUE);
GetDlgItem(IDC_EDIT_NOISEFRE)->MoveWindow(345,43,160,20,TRUE);
GetDlgItem(IDC_NOISE_AMPLITUDE)->MoveWindow(300,85,45,20,TRUE);
GetDlgItem(IDC_EDIT_NOISEAMP)->MoveWindow(345,83,160,20,TRUE);
GetDlgItem(IDC_STATIC_FILTERPARAMETER)->MoveWindow(570,15,370,110,TRUE);
GetDlgItem(IDC_STATIC_SAMPLELEN)->MoveWindow(580,70,90,20,TRUE);
GetDlgItem(IDC_COMBO_SAMPLELEN)->MoveWindow(670,68,115,80,TRUE);
GetDlgItem(IDC_STATIC_BETA)->MoveWindow(580,40,90,20,TRUE);
GetDlgItem(IDC_EDIT_BETA)->MoveWindow(670,38,115,20,TRUE);
GetDlgItem(IDC_STATIC_FILTERTYPE)->MoveWindow(580,100,90,20,TRUE);
GetDlgItem(IDC_COMBO_FILTERTYPE)->MoveWindow(670,98,115,80,TRUE);
GetDlgItem(IDC_STATIC_REJECTION1)->MoveWindow(795,40,20,20,TRUE);
GetDlgItem(IDC_STATIC_REJECTION2)->MoveWindow(795,70,20,20,TRUE);
GetDlgItem(IDC_STATIC_REJECTION3)->MoveWindow(795,100,20,20,TRUE);
GetDlgItem(IDC_EDIT_REJECTION1)->MoveWindow(815,38,115,20,TRUE);
GetDlgItem(IDC_EDIT_REJECTION2)->MoveWindow(815,68,115,20,TRUE);
GetDlgItem(IDC_EDIT_REJECTION3)->MoveWindow(815,98,115,20,TRUE);
GetDlgItem(IDC_STATIC_SIGNALWAVE)->MoveWindow(25,135,910,245,TRUE);
GetDlgItem(IDC_STATIC_FILTERSIGNAL)->MoveWindow(25,390,910,245,TRUE);
GetDlgItem(IDC_BUTTON_PLUSE)->MoveWindow(640,645,80,25,TRUE);
GetDlgItem(IDC_CHECK_ADDNOISE)->MoveWindow(25,645,120,25,TRUE);
GetDlgItem(ID_BOTTON_APPLY)->MoveWindow(500,645,80,25,TRUE);
GetDlgItem(IDCANCEL)->MoveWindow(780,645,80,25,TRUE);
GetDlgItem(IDC_STATIC_REJECTION3)->EnableWindow(FALSE);
GetDlgItem(IDC_STATIC_REJECTION2)->EnableWindow(FALSE);
GetDlgItem(IDC_EDIT_REJECTION3)->EnableWindow(FALSE);
GetDlgItem(IDC_EDIT_REJECTION2)->EnableWindow(FALSE);
analeng=128;
datalength=8192;
horigimage=GlobalAlloc(GMEM_FIXED,8*datalength); //GlobalAlloc The GlobalAlloc function allocates the specified number of bytes from the heap.If the function succeeds, the return value is a handle to the newly allocated memory object.
lporigdata=(double *)horigimage;
hsignal=GlobalAlloc(GMEM_FIXED,8*datalength+8*2048); //GlobalAlloc The GlobalAlloc function allocates the specified number of bytes from the heap.If the function succeeds, the return value is a handle to the newly allocated memory object.
lpsignal=(double *)hsignal;
hpls=GlobalAlloc(GMEM_FIXED,8*datalength); //GlobalAlloc The GlobalAlloc function allocates the specified number of bytes from the heap.If the function succeeds, the return value is a handle to the newly allocated memory object.
lppls=(double *)hpls;
hfilter=GlobalAlloc(GMEM_FIXED,8*datalength); //GlobalAlloc The GlobalAlloc function allocates the specified number of bytes from the heap.If the function succeeds, the return value is a handle to the newly allocated memory object.
lpfilter=(double *)hfilter;
horigdata=GlobalAlloc(GMEM_FIXED,16*datalength); //GlobalAlloc The GlobalAlloc function allocates the specified number of bytes from the heap.If the function succeeds, the return value is a handle to the newly allocated memory object.
lpfftdata=(complex *)horigdata;
pen2.CreatePen(PS_DOT,1,RGB(0,77,141));
penk.CreatePen(PS_SOLID,1,RGB(133,143,122));
//dark pen for the first left and up lines of background rectangle
penu1.CreatePen(PS_SOLID,1,RGB(32,32,32));
//black pen for the second left and up lines of background rectangle
penu2.CreatePen(PS_SOLID,1,RGB(222,245,10));
//Gray pen for the second right and down lines of background rectangle
pend1.CreatePen(PS_SOLID,1,RGB(128,128,128));
//Gray pen for the first right and down lines of background rectangle
pend2.CreatePen(PS_SOLID,1,RGB(6,134,73));
pen0.CreatePen(PS_SOLID,1,RGB(0,64,128));
penred.CreatePen(PS_SOLID,1,RGB(255,0,0));
r.bottom=745;//指定刷新区域
r.top=25;
r.left=220;
r.right=942;
cb.CreateSolidBrush(RGB(192,192,192));//设置画笔
hbit1=::CreateCompatibleBitmap(hdc,880,215);
hbit2=::CreateCompatibleBitmap(hdc,880,215);
hdctmp1=::CreateCompatibleDC(hdc);
hdctmp2=::CreateCompatibleDC(hdc);
SelectObject(hdctmp1,hbit1);//选位图
SelectObject(hdctmp1,cb);//选底色
SelectObject(hdctmp1,penk);//选笔
Rectangle(hdctmp1,0,0,880,215);//画框
Drawbackground(hdctmp1,0,0,880,215,10,870,10,200,105);
DrawScaleText(hdctmp1,10,870,10,200,105);
draworiginalwave(hdctmp1, m_signalfre, m_signalamp, m_noisefre, m_noiseamp,10,870,105,200);
SelectObject(hdctmp2,hbit2);//选位图
SelectObject(hdctmp2,cb);//选底色
SelectObject(hdctmp2,penk);//选笔
Rectangle(hdctmp2,0,0,880,215);//画框
Drawbackground(hdctmp2,0,0,880,215,10,870,10,200,105);
/////////////////////////////////////////////////////////////////////////////////////////
return TRUE; // return TRUE unless you set the focus to a control
}
void CMyDlg::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 CMyDlg::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
{
::BitBlt(hdc,40,155,880,215,hdctmp1,0,0,SRCCOPY);
::BitBlt(hdc,40,410,880,215,hdctmp2,0,0,SRCCOPY);
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CMyDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CMyDlg::draworiginalwave(HDC hdc, double sf, double sa, double nf, double na,int xfrom1, int xto1, int ycenter, int yto1)
{
double i;
double k1,k2;
int j1,j2,m1,m2;
SelectObject(hdc,penu2);
UpdateData(TRUE);
if(m_addnoise)
{
for(i=0;i<(xto1-xfrom1)/2-15;i++)
{
MoveToEx(hdc,xfrom1+(int)i,ycenter-(int)(9.5*sa*sin((sf/63662)*i)+9.5*na*sin((nf/63662)*i)),NULL);
LineTo(hdc,xfrom1+(int)i+1,ycenter-(int)(9.5*sa*sin((sf/63662)*(i+1))+9.5*na*sin((nf/63662)*(i+1))));
}
for(i=0;i<datalength;i++)
{
(*(lpfftdata+(int)i)).x=sa*sin((sf)*i/63662)+na*sin((nf)*i/63662);
(*(lpfftdata+(int)i)).y=0.00;
}
}
else
{
for(i=0;i<(xto1-xfrom1)/2-15;i++)
{
MoveToEx(hdc,xfrom1+(int)i,ycenter-(int)(9.5*sa*sin((sf/63662)*i)),NULL);
LineTo(hdc,xfrom1+(int)i+1,ycenter-(int)(9.5*sa*sin((sf/63662)*(i+1))));
}
for(i=0;i<datalength;i++)
{
(*(lpfftdata+(int)i)).x=sa*sin((sf)*i/63662);
(*(lpfftdata+(int)i)).y=0.00;
}
}
fft(datalength,lpfftdata);
for(i=0;i<datalength;i++)
{
k1=(*(lpfftdata+(int)i)).x;
k2=(*(lpfftdata+(int)i)).y;
*(lporigdata+(int)i)=sqrt(k1*k1+k2*k2);
}
for(i=0;i<datalength/2;i++)
{
j1=(int)(2*i*(double)((xto1-xfrom1)/2-15)/datalength);
j2=(int)(2*(i+1)*(double)((xto1-xfrom1)/2-15)/datalength);
m1=yto1-(int)(*(lporigdata+(int)i)*38.5/datalength);
m2=yto1-(int)(*(lporigdata+(int)i+1)*38.5/datalength);
MoveToEx(hdc,(xto1+xfrom1)/2+15+j1,m1,NULL);
LineTo(hdc,(xto1+xfrom1)/2+15+j2,m2);
}
}
short int CMyDlg::fft(long N, CMyDlg::complex *z)
{
long int i,j,k,l,LE,LE1,IP,M,lll;
complex T,U,W;
lll=1;
for(i=1;i<32;i++)
{
lll*=2;
if(lll>=N)break;
}
if(lll!=N)return 1;
M=i;
j=0;
for(i=0;i<N-1;i++)
{
if(i<j)
{
T=z[j];
z[j]=z[i];
z[i]=T;
}
k=N/2;
while(k<=j)
{
j=j-k;
k=k/2;
}
j=j+k;
}
for(l=1;l<=M;l++)
{
LE=1<<l;
LE1=LE/2;
U.x=1.0;
U.y=0.0;
W.x=cos(3.1415926535897/(double)LE1);
W.y=-sin(3.1415926535897/(double)LE1);
for(j=0;j<LE1;j++)
{
for(i=j;i<N;i=i+LE)
{
IP=i+LE1;
T.x=z[IP].x*U.x-z[IP].y*U.y;
T.y=z[IP].y*U.x+z[IP].x*U.y;
z[IP].x=z[i].x-T.x;
z[IP].y=z[i].y-T.y;
z[i].x=z[i].x+T.x;
z[i].y=z[i].y+T.y;
}
U.x=U.x*W.x-U.y*W.y;
U.y=U.x*W.y+U.y*W.x;
}
}
return 0;
}
short int CMyDlg::realfft(long N, CMyDlg::complex *z)
{
long int i,lll;
complex U,W,T,P,V,G;
V.x=cos(2.0*3.1415926535897/(double)N);
V.y=-sin(2.0*3.1415926535897/(double)N);
G.x=1.0;
G.y=0.0;
T.x=0.5;
T.y=0.0;
P.x=0.0;
P.y=-0.5;
lll=1;
for(i=1;i<32;i++)
{
lll*=2;
if(lll>=N)break;
}
if(lll!=N)return 1;
if(N<4)return -1;
for(i=0;i<N/2;i++)
{
z[i].y=z[2*i+1].x;
z[i].x=z[2*i].x;
}
if(fft(N/2,z)) return 1;
z[N/2].x=(z[0].x-z[0].x)*P.x-(z[0].y+z[0].y)*P.y;
z[N/2].y=(z[0].x-z[0].x)*P.y+(z[0].y+z[0].y)*P.x;
z[0].x=(z[0].x+z[0].x)*T.x-(z[0].y-z[0].y)*T.y;
z[0].y=(z[0].x+z[0].x)*T.y+(z[0].y-z[0].y)*T.x;
z[N/4*3].x=(z[N/4].x-z[N/4].x)*P.x-(z[N/4].y+z[N/4].y)*P.y;
z[N/4*3].y=(z[N/4].x-z[N/4].x)*P.y+(z[N/4].y+z[N/4].y)*P.x;
z[N/4].x=(z[N/4].x+z[N/4].x)*T.x-(z[N/4].y-z[N/4].y)*T.y;
z[N/4].y=(z[N/4].x+z[N/4].x)*T.y+(z[N/4].y-z[N/4].y)*T.x;
for(i=1;i<N/4;i++)
{
z[i+N/2].x=(z[i].x-z[N/2-i].x)*P.x-(z[i].y+z[N/2-i].y)*P.y;
z[i+N/2].y=(z[i].x-z[N/2-i].x)*P.y+(z[i].y+z[N/2-i].y)*P.x;
z[N-i].x=(z[N/2-i].x-z[i].x)*P.x-(z[N/2-i].y+z[i].y)*P.y;
z[N-i].y=(z[N/2-i].x-z[i].x)*P.y+(z[N/2-i].y+z[i].y)*P.x;
U.x=z[i].x+z[N/2-i].x;
U.y=z[i].y-z[N/2-i].y;
W.x=z[N/2-i].x+z[i].x;
W.y=z[N/2-i].y-z[i].y;
z[i].x=U.x*T.x-U.y*T.y;
z[i].y=U.x*T.y+U.y*T.x;
z[N/2-i].x=W.x*T.x-W.y*T.y;
z[N/2-i].y=W.x*T.y+W.y*T.x;
}
for(i=0;i<N/2;i++)
{
W.x=z[N/2+i].x*G.x-z[N/2+i].y*G.y;
W.y=z[N/2+i].x*G.y+z[N/2+i].y*G.x;
z[N/2+i].x=z[i].x-W.x;
z[N/2+i].y=z[i].y-W.y;
z[i].x=z[i].x+W.x;
z[i].y=z[i].y+W.y;
G.x=G.x*V.x-G.y*V.y;
G.y=G.x*V.y+G.y*V.x;
}
return 0;
}
void CMyDlg::DrawScaleText(HDC hdc,int xfrom1, int xto1, int yfrom1, int yto1, int ycenter1)
{
char tmpText[10];
//设背景及字体颜色
SetBkColor(hdc,RGB(255,255,255));
SetTextColor(hdc,RGB(0,0,0));
//显示标注
sprintf(tmpText,"%d",0);
TextOut(hdc,(xfrom1+xto1)/2-4,yto1-20,tmpText,1);
sprintf(tmpText,"%d",5);
TextOut(hdc,(xfrom1+xto1)/2-4,ycenter1-10,tmpText,1);
sprintf(tmpText,"%2.1f",0.5);
TextOut(hdc,xto1-25,yto1-20,tmpText,3);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -