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

📄 lcypldlg.cpp

📁 该程序是在VC++6.0环境中
💻 CPP
字号:
// lcyPLDlg.cpp : implementation file
//

#include "stdafx.h"
#include "lcyPL.h"
#include "lcyPLDlg.h"
#include "LcyWaveIn.h"//新添加的头文件

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

float *CLcyPLDlg::x_lcy;
/*设置初始采样长度*/
unsigned long CLcyPLDlg::m_SAMPLE_NUM =32768;
/////////////////////////////////////////////////////////////////////////////
// CLcyPLDlg dialog

CLcyPLDlg::CLcyPLDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CLcyPLDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CLcyPLDlg)
	m_f = 0;
	//}}AFX_DATA_INIT
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CLcyPLDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CLcyPLDlg)
	DDX_Control(pDX, IDC_EDIT1, m_edit);
	DDX_Text(pDX, IDC_EDIT1, m_f);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CLcyPLDlg, CDialog)
	//{{AFX_MSG_MAP(CLcyPLDlg)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
	ON_BN_CLICKED(IDC_BUTTON2, OnButton2)
	ON_BN_CLICKED(IDC_BUTTON3, OnButton3)
	ON_WM_CTLCOLOR()
	ON_WM_TIMER()
	ON_WM_CLOSE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CLcyPLDlg message handlers

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

	SetIcon(m_hIcon, TRUE);			
	SetIcon(m_hIcon, FALSE);		
	Brush1.CreateSolidBrush(RGB(0,0,0));//创建黑色画刷
	//创建字体
	font.CreateFont(300,120,0,0,FW_DONTCARE,FALSE,FALSE,FALSE,
		ANSI_CHARSET,OUT_CHARACTER_PRECIS,CLIP_CHARACTER_PRECIS,
        DEFAULT_QUALITY,DEFAULT_PITCH|FF_DONTCARE,"Times New Roman");
	fontL.CreateFont(300,95,0,0,FW_DONTCARE,FALSE,FALSE,FALSE,
		ANSI_CHARSET,OUT_CHARACTER_PRECIS,CLIP_CHARACTER_PRECIS,
        DEFAULT_QUALITY,DEFAULT_PITCH|FF_DONTCARE,"Times New Roman");
	pengreen.CreatePen(PS_SOLID,16,RGB(0,255,0));//创建绿色画笔
	pengray.CreatePen(PS_SOLID,16,RGB(190,190,190));//创建灰色画笔
	CWnd *wnd;
	wnd=GetDlgItem(IDC_Indicater);//获取电平指示显示窗口的指针
	wnd->GetWindowRect(&m_Indicater_rect);//获取电平指示显示窗口的矩形框
	m_Indicater_rect.OffsetRect(-4,-24);//位移电平指示显示窗口的矩形框
	Indicater_centerH=m_Indicater_rect.CenterPoint();//获取电平指示显示窗口的矩形框中心
	x_lcy=new float[m_SAMPLE_NUM+100];//开劈数据内存
	m_f = 12345;
	//调打开声卡函数
	if(LCY_OpenSoundCardIn(
		1,//单声道输入工作方式
		m_SAMPLE_NUM,//采样频率(Hz)
		1024,//每个声道缓冲区数量
		lcy_Callback/*回调函数*/)!=0)
		OnButton3();
	return TRUE;  
}
void CLcyPLDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); 
		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
		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;
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

HCURSOR CLcyPLDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}
/*采样回调函数*/
int CLcyPLDlg::lcy_Callback(
				void *inputBuffer,
				unsigned long framesPerBuffer)			 
{
  short  *rptr = (short *)inputBuffer;
  float  *wptr =&x_lcy[frameIndex];  
  int finished;
  unsigned long framesToCalc,i;
  unsigned long framesLeft =m_SAMPLE_NUM+100 - frameIndex;
/*把输入端缓冲区的数据写入开劈内存空间*/
  if( framesLeft < framesPerBuffer ){
	  framesToCalc = framesLeft;
	  finished = 1;
  }
  else{
	  framesToCalc = framesPerBuffer;
	  finished = 0;
  }
  if( inputBuffer == NULL ){
	  for( i=0; i<framesToCalc; i++ ){
			*wptr++ = 0;/*清零 */
	  }
	}
 else{
	 for( i=0; i<framesToCalc; i++ ){
			*wptr++ = *rptr++;/* 读采样的数据 */
	 }
 }
    frameIndex+= framesToCalc;
	return finished;
}
/*声卡采样及计算频率值函数*/
void CLcyPLDlg::lcycyFFTC(void)
{
  if(StartRecord()!=0)//调声卡采样函数
	  OnButton3();
  unsigned long i;
  complex *xa=new complex[m_SAMPLE_NUM];//为FFTC开辟的内存空间
	for(i=0;i<m_SAMPLE_NUM;i++){//把才得的数据存入为FFTC开辟的内存空间
		xa[i].re=x_lcy[i+100];
		xa[i].im=0;
	}
	long pos=m_SAMPLE_NUM;//FFTC长度
	spfftc(xa, &pos, &neg_i1);//快速复数傅立叶变换(FFTC)函数
	for(i=0;i<m_SAMPLE_NUM;i++){//把变换后的数据除以m_SAMPLE_NUM,以防数据溢出
		xa[i].re=xa[i].re/m_SAMPLE_NUM;
		xa[i].im=xa[i].im/m_SAMPLE_NUM;
	}	
	for(i=0;i<m_SAMPLE_NUM;i++){//计算变换后复数数据的摸
		xa[i].re=sqrtf(xa[i].re*xa[i].re+xa[i].im*xa[i].im);
	}
	xa[0].re=0;
	float Max=0;
	for(i=0;i<=m_SAMPLE_NUM/2;i++){//找出基波的位置及幅度
		if(xa[i].re>Max){
			Max=xa[i].re;
			m_f=i;//被测信号大于等于5000Hz时的频率值
		}
	}
	IndicaterL=(int)(Max/10);//信号幅度
	if(IndicaterL<2)//如果信号幅度太小
		m_f=0;//频率只值显示0
	m_FL=0;
	if(IndicaterL>10&&m_f>1&&m_f<5000){
		unsigned long j0,j=50;
		while(x_lcy[j]>=0&&j<m_SAMPLE_NUM/2)//信号幅值大于0时,循环
			j++;
		while(x_lcy[j]<=0&&j<m_SAMPLE_NUM/2)//信号幅值小于0时,循环
			j++;
		j0=j;//信号第一个由小于0变为大于0时的点
		bool a=0,b=0;
		unsigned long c=0,d=0;
		while(j<m_SAMPLE_NUM){
			while(x_lcy[j]>=0&&j<m_SAMPLE_NUM+100){//信号幅值大于0时,循环
				j++;
				a=1;//已进行了循环的标记
			}
			while(x_lcy[j]<=0&&j<m_SAMPLE_NUM+100){//信号幅值小于0时,循环
				j++;
				b=1;//已进行了循环的标记
			}
			if(a==1&&b==1){//a,b都进行循环时
				c++;//采得被测信号的周期数
				d=j-j0;//在采得被测信号的周期数内的采样点数
			}
			a=0;b=0;//循环标记复位
		}
		if(d!=0)//如果在采得被测信号的周期数内的采样点数不位0
			m_FL=(float)m_SAMPLE_NUM*c/d;//被测信号小于5000Hz时的频率值
		else
			m_FL=0;
	}
	delete []xa;//释放为FFTC开辟的内存空间	
}
/*画电平指示线函数*/
void CLcyPLDlg::lcyIndicaterLine(void)
{
	CClientDC dc(this);
	oldpen=dc.SelectObject(&pengray);//选择灰色画笔
	dc.MoveTo(12,Indicater_centerH.y);
	dc.LineTo(m_Indicater_rect.right-14,Indicater_centerH.y);//清除老指示线
	dc.SelectObject(&pengreen);//选择绿色画笔	
	if(IndicaterL>m_Indicater_rect.Width()-14)
		IndicaterL=m_Indicater_rect.Width()-14;
	if(IndicaterL<12)
		IndicaterL=12;
	dc.MoveTo(12,Indicater_centerH.y);
	dc.LineTo(IndicaterL,Indicater_centerH.y);//画新指示线
	dc.SelectObject(oldpen);//恢复原画笔
}
/*“开始测量”按钮函数*/
void CLcyPLDlg::OnButton1() 
{
	SetTimer(1,100,NULL);//设置定时器
}
/*“暂停测量”按钮函数*/
void CLcyPLDlg::OnButton2() 
{
	KillTimer(1);//取消定时器
}
/*“退出程序”按钮函数*/
void CLcyPLDlg::OnButton3() 
{
	LCY_CloseSoundCardIn();//调关闭声卡函数
	delete []x_lcy;//释放内存
	CDialog::OnCancel();//关闭窗口
}
//WM_CTLCOLOR消息函数
HBRUSH CLcyPLDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
{
	HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);		
	if(m_edit.m_hWnd==pWnd->m_hWnd){
		CString str,strL;
		str.Format("%ld",m_f);//高频数据输出格式		
	    pDC->SetTextColor(RGB(255,0,0));//文本色
		pDC->SetBkColor(RGB(0,0,0));//背景色
		float err=(float)m_f-m_FL;
		if(m_f<5000&&m_FL>1&&err<1&&err>-1){
				if(m_f>500)
					strL.Format("%.1f",m_FL);//低频数据输出格式
				else if(m_f>50)
					strL.Format("%.2f",m_FL);
				else
					strL.Format("%.3f",m_FL);
				oldfont=pDC->SelectObject(&fontL);//选择字体
				pDC->TextOut(1,1,strL);//输出低频频率值
		}
		else{
			oldfont=pDC->SelectObject(&font);//选择字体
			pDC->TextOut(1,1,str);//输出高频频率值
		}
		pDC->SelectObject(oldfont);//恢复原笔
		return (HBRUSH) Brush1;//返回黑色画刷
	}
	return hbr;
}
//定时器响应函数
void CLcyPLDlg::OnTimer(UINT nIDEvent) 
{
    lcycyFFTC();//调声卡采样及计算频率值函数
	lcyIndicaterLine();//调画电平指示线函数
    m_edit.SetRedraw(1); //刷新频率显示窗口	
	CDialog::OnTimer(nIDEvent);
}
//关闭程序响应函数
void CLcyPLDlg::OnClose() 
{
	LCY_CloseSoundCardIn();//调关闭声卡函数
	delete []x_lcy;//释放内存
	CDialog::OnClose();
}
/*快速复数傅立叶变换(FFTC)函数*/
void CLcyPLDlg::spfftc(complex *x, long *n, long *isign)
{
    long i, l, m, mr,tmp_int;
    complex t, tmp_complex, tmp;
    float pisign;
    pisign = (float) (*isign * PI);
    mr = 0;
    for (m = 1 ; m < *n ; ++m){
        l = *n;
        l /= 2;
		while (mr + l >= *n){
			l /= 2;
        }
        mr = mr % l + l;
		if (mr > m){
            t.re = x[m].re;
            t.im = x[m].im;
            x[m].re = x[mr].re;
            x[m].im = x[mr].im;
            x[mr].re = t.re;
            x[mr].im = t.im;
        }
    }
    l = 1;
    while (l < *n){
		for (m = 0 ; m < l ; ++m){
            tmp_int = l * 2;
            for (i = m ; tmp_int < 0 ? i >= (*n - 1) : i < *n ;
                 i += tmp_int){
                tmp.re = 0.0;
                tmp.im = (float) m * pisign / (float) l;
                complex_exp(&tmp_complex, &tmp);//调数据变换函数
                t.re = x[i + l].re * tmp_complex.re - 
					x[i + l].im * tmp_complex.im;
                t.im = x[i + l].re * tmp_complex.im + 
					x[i + l].im * tmp_complex.re;
                x[i + l].re = x[i].re - t.re;
                x[i + l].im = x[i].im - t.im;
                x[i].re = x[i].re + t.re;
                x[i].im = x[i].im + t.im;
            }
        }
        l *= 2;
    }
}
/*数据变换函数*/
void CLcyPLDlg::complex_exp(complex *r, complex *z)
{
    double expx;
    expx = exp((double) z->re);
    r->re = (float) (expx * cosf(z->im));
    r->im = (float) (expx * sinf(z->im));
}

⌨️ 快捷键说明

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