📄 lcyszdlg.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 + -