www.pudn.com > FIRDsgn.rar > FIRDsgnDlg.cpp
//######################################################################## // This program is provided "as is" without any express // or implied warranty of any kind with respect to this software. // In particular the author shall not be liable for any direct, // indirect, special, incidental or consequential damages arising // in any way from use of the software. // // // Author : Jialong He, // Date : July, 1999. // // Contact : Jialong_He@bigfoot.com, Jialong_He@homemail.com // Web Page : www.bigfoot.com/~Jialong_He //######################################################################## // FIRDsgnDlg.cpp : implementation file // #include "stdafx.h" #include "FIRDsgn.h" #include "FIRDsgnDlg.h" #include#include #define Pi 3.1415926535 #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() ///////////////////////////////////////////////////////////////////////////// // CFIRDsgnDlg dialog CFIRDsgnDlg::CFIRDsgnDlg(CWnd* pParent /*=NULL*/) : CDialog(CFIRDsgnDlg::IDD, pParent) { //{{AFX_DATA_INIT(CFIRDsgnDlg) m_Order = 511; m_SRate = 8000; //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); Coef = NULL; Order = 0; } //==================================== // destructor //==================================== CFIRDsgnDlg::~CFIRDsgnDlg() { delete [] Coef; } void CFIRDsgnDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CFIRDsgnDlg) DDX_Control(pDX, IDC_LOWDIS, m_LowDis); DDX_Control(pDX, IDC_LOWCUT, m_LowCut); DDX_Control(pDX, IDC_HIGHDIS, m_HighDis); DDX_Control(pDX, IDC_HIGHCUT, m_HighCut); DDX_Control(pDX, IDC_COEF, m_Coef); DDX_Text(pDX, IDC_FORDER, m_Order); DDV_MinMaxInt(pDX, m_Order, 3, 400); DDX_Text(pDX, IDC_SRate, m_SRate); DDV_MinMaxInt(pDX, m_SRate, 1, 100000); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CFIRDsgnDlg, CDialog) //{{AFX_MSG_MAP(CFIRDsgnDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_SAVECOEF, OnSavecoef) ON_BN_CLICKED(IDC_CALCULATE, OnCalculate) ON_WM_HSCROLL() ON_EN_CHANGE(IDC_SRate, OnChangeSRate) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CFIRDsgnDlg message handlers BOOL CFIRDsgnDlg::OnInitDialog() { CDialog::OnInitDialog(); //---------------------------------------------------------------- // Init magnitude window, mustin OnInitDialog(), not in constructor //----------------------------------------------------------------- CRect rect; GetDlgItem(IDC_AMPLITUDE)->GetWindowRect(&rect); rect.DeflateRect(5, 5); ScreenToClient(&rect); m_wndMag.Create(NULL, _T(""), WS_VISIBLE|WS_CHILD, rect, this, NULL); //---------------------------------------------------------------- // Init member varibles //----------------------------------------------------------------- m_LowCut.SetRange(0, 1000); m_LowCut.SetPos(100); m_LowDis.SetWindowText( _T("400")); m_HighCut.SetRange(0, 1000); m_HighCut.SetPos(600); m_HighDis.SetWindowText( _T("2400")); // m_Ftype.SetCurSel(2); // 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 return TRUE; // return TRUE unless you set the focus to a control } void CFIRDsgnDlg::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 CFIRDsgnDlg::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 CFIRDsgnDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } //============================================================ // Save calculated FIR coefficients to a ASCII file //============================================================ void CFIRDsgnDlg::OnSavecoef() { CString FName, TmpStr; CFileDialog FDia(FALSE, "txt", "FIR_Coef"); if (FDia.DoModal() == IDOK) { int Cnt; FName = FDia.GetPathName(); CStdioFile outfile(FName, CFile::modeWrite|CFile::modeCreate); for (Cnt=0; Cnt GetWindowText(sRate); GetDlgItem(IDC_HIGHDIS)->GetWindowText(sHigh); GetDlgItem(IDC_LOWDIS)->GetWindowText(sLow); GetDlgItem(IDC_FORDER)->GetWindowText(sOrder); Len = atoi(sOrder); //---------------------------------- // Normalized sampling rate (2 Hz) //---------------------------------- LowCut = atof(sLow) / atof(sRate) * 2.0; HighCut = atof(sHigh) / atof(sRate) * 2.0; RtCode = fir_dsgn(Len, LowCut, HighCut); if (RtCode <0) { MessageBox("Calculating FIR coefficients failed!", "Error", MB_ICONERROR); return; } //------------------------------------- // display coefficients in list box //------------------------------------- //CListBox m_Coef; m_Coef.ResetContent( ); for (Cnt=0; Cnt GetWindowText(SR); SRate = atof(SR); CurrPos = ((CSliderCtrl*)GetDlgItem(IDC_HIGHCUT))->GetPos( ); MaxPos = ((CSliderCtrl*)GetDlgItem(IDC_HIGHCUT))->GetRangeMax( ); TCut.Format("%8.1f", SRate / 2.0 * CurrPos / MaxPos); GetDlgItem(IDC_HIGHDIS)->SetWindowText(TCut); CurrPos = ((CSliderCtrl*)GetDlgItem(IDC_LOWCUT))->GetPos( ); MaxPos = ((CSliderCtrl*)GetDlgItem(IDC_LOWCUT))->GetRangeMax( ); TCut.Format("%8.1f", SRate / 2.0 * CurrPos / MaxPos); GetDlgItem(IDC_LOWDIS)->SetWindowText(TCut); // OnCalculate(); CDialog::OnHScroll(nSBCode, nPos, pScrollBar); } /*---------------------------------------------------------------*/ /* Design FIR filter using window method. Hamming window is used */ /* If sucess, return a point to the filter coefficient array, */ /* otherwise, return NULL. Calling program should release the */ /* allocated memory in this subroutine */ /* */ /* */ /* Suppose sampling rate is 2 Hz */ /* */ /* Len : filter length, should be ODD and Len>=3 */ /* CutLow : low cutoff, when lowpass, CutLow = 0.0 */ /* CutHigh: high cutoff, when highpass, CutHigh = 1.0 */ /* when bandpass, 0.0 < CutLow < CutHigh < 1.0 */ /* */ /* example: */ /* Coef = fir_dsgn(127, 0.3, 0.8); */ /* return a bandpass filter */ /*---------------------------------------------------------------*/ int CFIRDsgnDlg::fir_dsgn(int Len, double CutLow, double CutHigh) { double Sum, TmpFloat; int CoefNum, HalfLen, Cnt; /*---------------------------------------------*/ /* adjust the number of coefficients to be ODD */ /*---------------------------------------------*/ CoefNum = Len; if (Len % 2 == 0) { CoefNum++; } HalfLen = (CoefNum - 1) / 2; //-------------------------------------------------------- // Allocate memory for coefficients if length changed //-------------------------------------------------------- delete Coef; Coef = new double[CoefNum]; if (Coef == NULL) { return (-1); } Order = CoefNum; /*------------------*/ /* Lowpass filter */ /*------------------*/ if ((CutLow == 0.0) && (CutHigh < 1.0)) { Coef[HalfLen] = CutHigh; for (Cnt=1; Cnt<=HalfLen; Cnt++) { TmpFloat = Pi * Cnt; Coef[HalfLen + Cnt] = sin(CutHigh * TmpFloat) / TmpFloat; Coef[HalfLen - Cnt] = Coef[HalfLen + Cnt]; } /*------------------------------*/ /* multiplying with a window */ /*------------------------------*/ TmpFloat = 2.0 * Pi / (CoefNum - 1.0); Sum = 0.0; for (Cnt=0; Cnt 0.0) && (CutHigh == 1.0)) { Coef[HalfLen] = CutLow; for (Cnt=1; Cnt<=HalfLen; Cnt++) { TmpFloat = Pi * Cnt; Coef[HalfLen + Cnt] = sin(CutLow * TmpFloat) / TmpFloat; Coef[HalfLen - Cnt] = Coef[HalfLen + Cnt]; } /*------------------------------*/ /* multiplying with a window */ /*------------------------------*/ TmpFloat = 2.0 * Pi / (CoefNum - 1.0); Sum = 0.0; for (Cnt=0; Cnt 0.0) && (CutHigh < 1.0) && (CutLow < CutHigh)) { Coef[HalfLen] = CutHigh - CutLow; for (Cnt=1; Cnt<=HalfLen; Cnt++) { TmpFloat = Pi * Cnt; Coef[HalfLen + Cnt] = 2.0 * sin( (CutHigh - CutLow) / 2.0 * TmpFloat) * cos( (CutHigh + CutLow) / 2.0 * TmpFloat) / TmpFloat; Coef[HalfLen - Cnt] = Coef[HalfLen + Cnt]; } /*------------------------------*/ /* multiplying with a window */ /*------------------------------*/ TmpFloat = 2.0 * Pi / (CoefNum - 1.0); Sum = 0.0; for (Cnt=0; Cnt 0.0) && (CutHigh < 1.0) && (CutLow>CutHigh)) { Coef[HalfLen] = CutLow - CutHigh; for (Cnt=1; Cnt<=HalfLen; Cnt++) { TmpFloat = Pi * Cnt; Coef[HalfLen + Cnt] = 2.0 * sin( (CutLow - CutHigh) / 2.0 * TmpFloat) * cos( (CutHigh + CutLow) / 2.0 * TmpFloat) / TmpFloat; Coef[HalfLen - Cnt] = Coef[HalfLen + Cnt]; } /*------------------------------*/ /* multiplying with a window */ /*------------------------------*/ TmpFloat = 2.0 * Pi / (CoefNum - 1.0); Sum = 0.0; for (Cnt=0; Cnt