📄 windowfilterview.cpp
字号:
// windowFilterView.cpp : implementation of the CWindowFilterView class
//
#include "stdafx.h"
#include "windowFilter.h"
#include "windowFilterDoc.h"
#include "windowFilterView.h"
#include "math.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define PI 3.14159
/////////////////////////////////////////////////////////////////////////////
// CWindowFilterView
IMPLEMENT_DYNCREATE(CWindowFilterView, CFormView)
BEGIN_MESSAGE_MAP(CWindowFilterView, CFormView)
//{{AFX_MSG_MAP(CWindowFilterView)
ON_CBN_SELCHANGE(IDC_WINDOWTIPE, OnSelchangeWindowtipe)
ON_CBN_SELCHANGE(IDC_FILTERTYPE, OnSelchangeFiltertype)
ON_BN_CLICKED(IDC_BTN_DRAW, OnBtnDraw)
ON_WM_PAINT()
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CFormView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CFormView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CFormView::OnFilePrintPreview)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CWindowFilterView construction/destruction
CWindowFilterView::CWindowFilterView()
: CFormView(CWindowFilterView::IDD)
{
//{{AFX_DATA_INIT(CWindowFilterView)
m_WindowLength = 8;
m_WcLow = 0.4f;
m_WcHigh = 0.5f;
m_iWindowType = 0;
m_iFilterType = 0;
m_bety = 0.5f;
pHdImag = NULL;
pHdReal = NULL;
pReal = NULL;
pImag = NULL;
pWindowImag = NULL;
pWindowReal = NULL;
m_bFirst = FALSE;
m_bClean = FALSE;
//}}AFX_DATA_INIT
// TODO: add construction code here
}
CWindowFilterView::~CWindowFilterView()
{
}
void CWindowFilterView::DoDataExchange(CDataExchange* pDX)
{
CFormView::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CWindowFilterView)
DDX_Text(pDX, IDC_WINDOWLENGTH, m_WindowLength);
DDV_MinMaxInt(pDX, m_WindowLength, 1, 100);
DDX_Text(pDX, IDC_EDIT_LOW, m_WcLow);
DDX_Text(pDX, IDC_EDIT_HIGH, m_WcHigh);
DDX_Text(pDX, IDC_EDIT_BETY, m_bety);
//}}AFX_DATA_MAP
}
BOOL CWindowFilterView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CFormView::PreCreateWindow(cs);
}
void CWindowFilterView::OnInitialUpdate()
{
((CComboBox *)GetDlgItem (IDC_FILTERTYPE))->SetCurSel(0);
((CComboBox *)GetDlgItem (IDC_WINDOWTIPE))->SetCurSel(0);
(CStatic *)GetDlgItem(IDC_HIGHWC)->EnableWindow(false);
(CStatic *)GetDlgItem(IDC_STATIC_BETY)->EnableWindow(false);
(CEdit *)GetDlgItem(IDC_EDIT_BETY)->EnableWindow(false);
(CEdit *)GetDlgItem(IDC_EDIT_HIGH)->EnableWindow(false);
CFormView::OnInitialUpdate();
GetParentFrame()->RecalcLayout();
ResizeParentToFit();
}
/////////////////////////////////////////////////////////////////////////////
// CWindowFilterView printing
BOOL CWindowFilterView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CWindowFilterView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CWindowFilterView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
void CWindowFilterView::OnPrint(CDC* pDC, CPrintInfo* /*pInfo*/)
{
// TODO: add customized printing code here
if (m_bFirst == FALSE)
{
m_bFirst = TRUE;
}
else
{
OnBtnDraw();
}
}
/////////////////////////////////////////////////////////////////////////////
// CWindowFilterView diagnostics
#ifdef _DEBUG
void CWindowFilterView::AssertValid() const
{
CFormView::AssertValid();
}
void CWindowFilterView::Dump(CDumpContext& dc) const
{
CFormView::Dump(dc);
}
CWindowFilterDoc* CWindowFilterView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CWindowFilterDoc)));
return (CWindowFilterDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CWindowFilterView message handlers
// 生成模值
// 入口参数:数组名和长度
// Xabs: 存储模值的数组名,相当与返回值
// Xreal: 存储实部的数组名
// Ximag: 存储虚部的数组名
// n: 数组的长度
void CWindowFilterView::CreateAbs(float *Xabs, float *Xreal, float *Ximag, int n)
{
int i;
for(i=0; i<n; i++)
{
Xabs[i] = sqrt(Xreal[i]*Xreal[i] + Ximag[i]*Ximag[i]);
Xabs[i] = 20 * log10f(Xabs[i] + 1E-8); //化为db表示
}
}
// 入口参数:数组名和长度
// Xarg: 存储角度的数组名,相当与返回值
// Xreal: 存储实部的数组名
// Ximag: 存储虚部的数组名
// n: 数组的长度
void CWindowFilterView::CreateArg(float *Xarg, float *Xreal, float *Ximag, int n)
{
int i;
for(i=0; i<n; i++)
{
Xarg[i] = atan2(Ximag[i],Xreal[i]);
}
}
// 倒位排序函数
// j为正常序列的下标
// nu为长度的log2(长度),长度为16,则为4
// nu在以后要改为长度 count
int CWindowFilterView::ibitr(int j, int count)
{
int b,j1,i,j2,nu;
int nu1;
nu = 0;
nu1 = count;
while (nu1 / 2)
{
nu1 /= 2;
nu ++;
}
j1 = j;
b = 0;
for (i=1; i<=nu; i++)
{
j2 = j1/2;
b = b*2 + (j1-2*j2);
j1 = j2;
}
return b;
}
// 生成FFT变换的实部和虚部,
// 入口参数:数组名和长度
// Xreal: 存储FFT结果实部的数组名,相当与返回值
// Ximag: 存储FFT结果虚部的数组名,相当于返回值
// xreal: 存储时间序列实部的数组名
// ximga: 存储时间序列虚部的数组名
// n: 窗口的长度
// 返回值为FFT的实际长度
// 以后可能要改为引用名
int CWindowFilterView::CreateFFT(float *Xreal, float *Ximag, float *xreal, float *ximag, int n)
{
int i,j,k,l,m,deta,p,a;
float treal,timag,temp;
int m_FFTLengthTemp;
//补成2的 n 次方倍数
i=1;
while (pow(2,i)<n)
{
i++;
}
m_FFTLengthTemp = pow(2,i); //将长度修改
if (m_FFTLengthTemp < 256)
{
m_FFTLengthTemp = 256; //本题中将长度先定为128
}
// 以后要用的时候,在View类中改为指针。将值改为Xreal,名字为引用
// 就行了
// if (Xreal != NULL)
// {
// delete []Xreal;
// Xreal = NULL;
// }
// if (Ximag != NULL)
// {
// delete []Ximag;
// Ximag = NULL;
// }
// float * //Xreal = new float [m_FFTLengthTemp];
// float * //Ximag = new float [m_FFTLengthTemp];
//赋值函数,先全部清零
memset(Xreal, 0, sizeof(float)*m_FFTLengthTemp);
memset(Ximag, 0, sizeof(float)*m_FFTLengthTemp);
for (i = 0; i<n; i++)
{
Xreal[i] = xreal[i];
Ximag[i] = ximag[i];
}
//倒位函数,交换数组内容
for (i = 0; i<m_FFTLengthTemp; i++)
{
j = ibitr(i, m_FFTLengthTemp);
if (j > i)
{
temp = Xreal[i];
Xreal[i] = Xreal[j];
Xreal[j] = temp;
temp = Ximag[i];
Ximag[i] = Ximag[j];
Ximag[j] = temp;
}
}
//FFT蝶形运算
a = 0;
k = m_FFTLengthTemp;
while (k = k/2)
{
deta = (int)pow(2,a);
l = 0;
m = 0;
for(i = 0; i < k; i++)
{
for(j = 0; j < deta; j++) // l 和 l+deta 的蝶形运算
{
p = j * k;
treal = Xreal[l+deta] * cos(2*PI/m_FFTLengthTemp*p)
+ Ximag[l+deta] * sin(2*PI/m_FFTLengthTemp*p);
timag = Ximag[l+deta] * cos(2*PI/m_FFTLengthTemp*p)
- Xreal[l+deta] * sin(2*PI/m_FFTLengthTemp*p);
Xreal[l+deta] = Xreal[l] - treal;
Ximag[l+deta] = Ximag[l] - timag;
Xreal[l] = Xreal[l] + treal;
Ximag[l] = Ximag[l] + timag;
l++;
}
m += deta * 2;
l = m;
}
a++;
}
// delete []xrealTemp;
// delete []ximagTemp;
return m_FFTLengthTemp;
}
// 利用FFT生成IFFT变换的实部和虚部,
// 入口参数:数组名和长度
// xreal: 存储IFFT结果实部的数组名,相当与返回值
// ximag: 存储IFFT结果虚部的数组名,相当于返回值
// Xreal: 存储频率序列实部的数组名
// Ximga: 存储频率序列虚部的数组名
// n: 数组的长度
void CWindowFilterView::CreateIFFT( float *xreal, float *ximag, float *Xreal, float *Ximag, int &n)
{
int i;
//赋值函数
//求共轭复数
for (i = 0; i<n; i++)
{
xreal[i] = Xreal[i];
ximag[i] = -Ximag[i];
}
CreateFFT(xreal, ximag, xreal, ximag, n);
for (i = 0; i<n; i++)
{
xreal[i] = xreal[i] / n;
ximag[i] = -ximag[i] / n;
}
}
//求最大绝对值
float CWindowFilterView::mymax(float *a, int n)
{
int i;
float *b = a;
float num = 0;
for (i=0; i<n; i++)
{
if(fabs(*b) > num)
num = fabs(*b);
b++;
}
return num;
}
//矩形窗
void CWindowFilterView::CreateRect(float *real, float *imag, int n)
{
int i;
for (i=0; i<n; i++)
{
real[i] = 1.0;
imag[i] = 0.0;
}
}
//三角形窗
void CWindowFilterView::CreateTriang(float *real, float *imag, int n)
{
int i;
float m = n;
for (i=0; i<=(n-1)/2; i++)
{
real[i] = 2*i/(m-1);
imag[i] = 0;
}
for (; i < n; i++)
{
real[i] = 2 - 2*i/(m-1);
imag[i] = 0;
}
}
//Hanning窗
void CWindowFilterView::CreateHanning(float *real, float *imag, int n)
{
int i;
for (i=0; i<n; i++)
{
real[i] = 0.5 * (1 - cos(2*PI*i/(n-1))) ;
imag[i] = 0.0;
}
}
//Hamming窗
void CWindowFilterView::CreateHamming(float *real, float *imag, int n)
{
int i;
for (i=0; i<n; i++)
{
real[i] = 0.54 - 0.46 * cos(2*PI*i/(n-1)) ;
imag[i] = 0.0;
}
}
//Blackman窗
void CWindowFilterView::CreateBlackman(float *real, float *imag, int n)
{
int i;
for (i=0; i<n; i++)
{
real[i] = 0.42 - 0.5 * cos(2*PI*i / (n-1)) + 0.08 * cos(4*PI*i / (n-1)) ;
imag[i] = 0.0;
}
}
//零阶贝塞尔函数,系数为x
float CWindowFilterView::ino(float x)
{
float y,t,e,de,sde,xi;
int i;
y = x / 2;
t = 1.e-08;
e = 1.0;
de = 1.0;
for (i=1; i<=25; i++)
{
xi = i;
de = de*y/xi;
sde = de*de;
e = e + sde;
if ((e*t-sde) > 0)
{
break;
}
}
return e;
}
//Kaiser窗
void CWindowFilterView::CreateKaiser(float *real, float *imag, int n, float beta)
{
// float ino(float x);
int i;
// int odd = n % 2;
// float xind = (n-1)*(n-1);
float temp;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -