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

📄 lcyszdlg.cpp

📁 对PC声卡进行操作
💻 CPP
字号:
// lcySZDlg.cpp : implementation file
//

#include "stdafx.h"
#include "lcySZ.h"
#include "lcySZDlg.h"
#include "LcyWaveIn.h"//添加的头文件

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

UINT CLcySZDlg::m_SAMPLE_NUM=4096;
short *CLcySZDlg::x_lcy=new short[m_SAMPLE_NUM+1024];
CLcySZDlg::CLcySZDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CLcySZDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CLcySZDlg)
	m_edit1v = 50;
	//}}AFX_DATA_INIT
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CLcySZDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CLcySZDlg)
	DDX_Control(pDX, IDC_SLIDER1, m_slider1);
	DDX_Text(pDX, IDC_EDIT1, m_edit1v);
	//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CLcySZDlg, CDialog)
	//{{AFX_MSG_MAP(CLcySZDlg)
	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_CLOSE()
	ON_NOTIFY(NM_CUSTOMDRAW, IDC_SLIDER1, OnCustomdrawSlider1)
	ON_WM_CTLCOLOR()
	ON_WM_TIMER()
	ON_EN_CHANGE(IDC_EDIT1, OnChangeEdit1)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()
BOOL CLcySZDlg::OnInitDialog()
{
	CDialog::OnInitDialog();
	SetIcon(m_hIcon, TRUE);			
	SetIcon(m_hIcon, FALSE);		
	samplaRate=44100;
	m_fudu=2100;
	m_max_edit1v=400;
	m_slider1.SetRange(1,100,1);
	m_slider1pos=50;
	m_slider1.SetPos(50);
	penred.CreatePen(PS_SOLID,1,RGB(255,0,0)),
	penblack.CreatePen(PS_SOLID,1,RGB(0,0,0));
	font1.CreateFont(140,86,0,0,FW_DONTCARE,FALSE,FALSE,FALSE,
		ANSI_CHARSET,OUT_CHARACTER_PRECIS,CLIP_CHARACTER_PRECIS,
        DEFAULT_QUALITY,DEFAULT_PITCH|FF_DONTCARE,"Times New Roman");
	font2.CreateFont(140,32,0,0,FW_DONTCARE,FALSE,FALSE,FALSE,
		ANSI_CHARSET,OUT_CHARACTER_PRECIS,CLIP_CHARACTER_PRECIS,
        DEFAULT_QUALITY,DEFAULT_PITCH|FF_DONTCARE,"Times New Roman");
	m_glys=0;
	CWnd *wnd1;
	wnd1=GetDlgItem(IDC_DISPLAY1);//获取显示窗口的指针
	wnd1->GetWindowRect(&m_display1_rect);//获取显示窗口的矩形框
	wnd2=GetDlgItem(IDC_DISPLAY2);//获取显示窗口的指针
	wnd2->GetWindowRect(&m_display2_rect);//获取显示窗口的矩形框
	m_display1_rect.OffsetRect(-3,-24);
	m_display2_rect.OffsetRect(-3,-24);
	rgn1.CreateRectRgnIndirect(&m_display1_rect);
	centerH1=m_display1_rect.CenterPoint();
	m_with=m_display1_rect.Width()+10;	
	win1bottom=m_display1_rect.BottomRight();
	win1top=m_display1_rect.TopLeft();
	ShowWindow(SW_SHOWMAXIMIZED);
	//调打开声卡输入端函数
	LCY_OpenSoundCardIn(
	1,//声卡输入端地址
	1,//单声道输入工作方式
	samplaRate,//采样频率(Hz)
	1024,//每个声道缓冲区数量
	lcy_Callback//回调函数
	);
	return TRUE;  
}
void CLcySZDlg::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 CLcySZDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}
void CLcySZDlg::OnButton1() 
{
	SetTimer(1,300,NULL);
}
void CLcySZDlg::OnButton2() 
{
	KillTimer(1);
}
void CLcySZDlg::OnButton3() 
{
	delete []x_lcy;
	LCY_CloseSoundCardIn();
	DestroyWindow();
}
void CLcySZDlg::OnClose() 
{
	delete []x_lcy;
	LCY_CloseSoundCardIn();
	CDialog::OnClose();	
}
void CLcySZDlg::OnCustomdrawSlider1(NMHDR* pNMHDR, LRESULT* pResult) 
{
	m_slider1pos=m_slider1.GetPos();
	*pResult = 0;
}
//采样回调函数
int CLcySZDlg::lcy_Callback(
				void *inputBuffer,
				unsigned long framesPerBuffer)			 
{
  short  *rptr = (short *)inputBuffer;
  short  *wptr =&x_lcy[frameIndex];
  unsigned framesToCalc,i;
  int finished;
  unsigned  framesLeft =m_SAMPLE_NUM+1024 - 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;
}
HBRUSH CLcySZDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
{
	HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
    CString str;
	str.Format("%.1f",m_glys);
	if(wnd2->m_hWnd==pWnd->m_hWnd){
	    pDC->SetTextColor(RGB(255,0,0));
		if(m_fudu>2000){
			oldfont=pDC->SelectObject(&font1);
			pDC->TextOut(0,0,str);
			pDC->SelectObject(oldfont);
		}
		else{
			oldfont=pDC->SelectObject(&font2);
			pDC->TextOut(0,0,"信号幅度太小");
			pDC->SelectObject(oldfont);
		}
	}
	return hbr;
}
void CLcySZDlg::OnChangeEdit1() 
{
	UpdateData(1);
	if(m_edit1v>m_max_edit1v) m_edit1v=m_max_edit1v;
	if(m_edit1v<=1) m_edit1v=2;
	UpdateData(0);
}
void CLcySZDlg::OnTimer(UINT nIDEvent) 
{
	CClientDC dc(this);    
	StartRecord();//调采样函数
	UINT j,yp;
	j=50;
	while(x_lcy[j]>=0&&j<1024)
		j++;
	while(x_lcy[j]<=0&&j<1024)
		j++;
	yp=j;
	bool sign1,sign2;
	UINT j2,n=0,n1=0,m=0;
	for(j2=0;j2<m_SAMPLE_NUM;j2++){
		sign1=0;sign2=0;
		while(x_lcy[j2+j]>=0&&j2<m_SAMPLE_NUM){
			j2++;sign1=1;
		}
		while(x_lcy[j2+j]<=0&&j2<m_SAMPLE_NUM){
			j2++;sign2=1;
		}
		if(sign1==1&&sign2==1){
			n1++;
		}
	}
	for(j2=0;j2<m_SAMPLE_NUM;j2++){
		sign1=0;sign2=0;
		while(x_lcy[j2+j]>=0&&j2<m_SAMPLE_NUM){
			j2++;sign1=1;
		}
		while(x_lcy[j2+j]<=0&&j2<m_SAMPLE_NUM){
			j2++;sign2=1;
		}
		if(sign1==1&&sign2==1){
			n++;m=j2;
		}
		if(n==n1-1) break;
	}
	if(n<0) n=0;
	if(m>=m_SAMPLE_NUM) m=m_SAMPLE_NUM-2;
	int yzhi,p=5;
	dc.SelectClipRgn(&rgn1);
	oldpen=dc.SelectObject(&penblack);
	dc.MoveTo(0,win1bottom.y);
	dc.LineTo(0,win1top.y-2);
	for(j=0;j<m_with;j++){
	  /*用背景色抹去旧的波形曲线*/
	  dc.MoveTo(j+1,win1bottom.y);
	  dc.SelectObject(&penblack);
	  dc.LineTo(j+2,win1top.y-2);

	  /*用红色画出新的波形曲线*/
	  yzhi=centerH1.y-x_lcy[j*p+yp]/m_slider1pos;
	  dc.MoveTo(j,yzhi);
	  dc.SelectObject(&penred);
	  yzhi=centerH1.y-x_lcy[(j+1)*p+yp]/m_slider1pos;
	  dc.LineTo(j+1,yzhi);
	}
	complex *xa=new complex[m_SAMPLE_NUM];
	complex *xb=new complex[m_SAMPLE_NUM];
  	UINT i;
    long pos=m_SAMPLE_NUM;
	for(i=0;i<=m;i++){
		xa[i].re=(float)x_lcy[i+yp];
		xa[i].im=0;
	}
	for(i=m+1;i<m_SAMPLE_NUM;i++){
		xa[i].re=0;
		xa[i].im=0;
		xb[i].re=0;
		xb[i].im=0;
	}
	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;
	}
	xa[0].re=0.0;//除去直流分量
	xa[0].im=0.0;//除去直流分量
	for(i=0;i<m_SAMPLE_NUM;i++){//计算变换后复数数据的摸
		xa[i].re=sqrtf(xa[i].re*xa[i].re+xa[i].im*xa[i].im);
	}
	float maxa=0;
	UINT maxpos=0;
	for(i=0;i<m_SAMPLE_NUM/2-100;i++){
		if(xa[i].re>maxa){
			maxa=xa[i].re;
			maxpos=i;
		}
	}
	if(maxpos!=0)
		m_max_edit1v=(m_SAMPLE_NUM/2)/maxpos;
	if(m_max_edit1v>400)
		m_max_edit1v=400;
	m_fudu=maxa;
	for(i=0;i<=m;i++){
		xb[i].re=sinf(2*PI*n*(i+1)/m)*maxa*2;
		xb[i].im=0;
	}
	spfftc(xb, &pos, &neg_i1);//快速复数傅立叶变换(FFTC)函数
	for(i=0;i<m_SAMPLE_NUM;i++){//把变换后的数据除以m_SAMPLE_NUM,以防数据溢出
		xb[i].re=xb[i].re/m_SAMPLE_NUM;
		xb[i].im=xb[i].im/m_SAMPLE_NUM;
	}
	xb[0].re=0.0;//除去直流分量
	xb[0].im=0.0;//除去直流分量
	for(i=0;i<m_SAMPLE_NUM;i++){//计算变换后复数数据的摸
		xb[i].re=sqrtf(xb[i].re*xb[i].re+xb[i].im*xb[i].im);
	}	
	float maxb=0;
	for(i=0;i<m_SAMPLE_NUM/2-100;i++){
		if(xb[i].re>maxb)
			maxb=xb[i].re;
	}
	float hh;
	if(maxb!=0)
		hh=maxa/maxb;
	float k1=0;
	for(i=0;i<m_edit1v*maxpos&&i<m_SAMPLE_NUM/2;i++){//奇次谐波的平方和
		k1+=(xa[i].re-xb[i].re*hh)*(xa[i].re-xb[i].re*hh);
	}
	float k2=0;
	for(i=0;i<m_edit1v*maxpos&&i<m_SAMPLE_NUM/2;i++){//奇次谐波的平方和
		k2+=(xb[i].re*xb[i].re)*hh*hh;
	}
   m_glys=sqrtf(k1/(k2))*100;
   if(m_glys>=100) m_glys=0;
   delete []xa;delete []xb;
   InvalidateRect(&m_display2_rect,1);
   dc.SelectObject(oldpen);
   CDialog::OnTimer(nIDEvent);
}
/*快速复数傅立叶变换(FFTC)函数*/
void CLcySZDlg::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 CLcySZDlg::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 + -