📄 voicectrldlg.cpp
字号:
// VoiceCtrlDlg.cpp : implementation file
//
#include "stdafx.h"
#include "VoiceCtrl.h"
#include "VoiceCtrlDlg.h"
#include "Dialog_Study.h"
#include "Dialog_Database.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CVoiceCtrlDlg dialog
CVoiceCtrlDlg::CVoiceCtrlDlg(CWnd* pParent /*=NULL*/)
: CDialog(CVoiceCtrlDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CVoiceCtrlDlg)
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CVoiceCtrlDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CVoiceCtrlDlg)
DDX_Control(pDX, IDC_EDIT_Result_Show, m_Result_Show);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CVoiceCtrlDlg, CDialog)
//{{AFX_MSG_MAP(CVoiceCtrlDlg)
ON_BN_CLICKED(IDC_BUTTON_Study, OnBUTTONStudy)
ON_BN_CLICKED(IDC_BUTTON_Database, OnBUTTONDatabase)
ON_BN_CLICKED(IDC_BUTTON_Exit, OnBUTTONExit)
ON_BN_CLICKED(IDC_BUTTON_Start, OnBUTTONStart)
ON_MESSAGE(MM_WIM_OPEN,OnMM_WIM_OPEN)
ON_MESSAGE(MM_WIM_DATA,OnMM_WIM_DATA)
ON_MESSAGE(MM_WIM_CLOSE,OnMM_WIM_CLOSE)
ON_MESSAGE(MM_WOM_OPEN,OnMM_WOM_OPEN)
ON_MESSAGE(MM_WOM_DONE,OnMM_WOM_DONE)
ON_MESSAGE(MM_WOM_CLOSE,OnMM_WOM_CLOSE)
ON_WM_TIMER()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CVoiceCtrlDlg message handlers
BOOL CVoiceCtrlDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 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
CenterWindow(GetDesktopWindow()); // center to the hpc screen
// TODO: Add extra initialization here
pWaveHdr1=reinterpret_cast<PWAVEHDR>(malloc(sizeof(WAVEHDR)));
pWaveHdr2=reinterpret_cast<PWAVEHDR>(malloc(sizeof(WAVEHDR)));
pSaveBuffer = reinterpret_cast<PBYTE>(malloc(1));
return TRUE; // return TRUE unless you set the focus to a control
}
void CVoiceCtrlDlg::OnBUTTONStudy()
{
// TODO: Add your control notification handler code here
Dialog_Study mystudy;
//
//mystudy.m_ctrl_command.SetDroppedWidth(100);
mystudy.DoModal();
}
void CVoiceCtrlDlg::OnBUTTONDatabase()
{
// TODO: Add your control notification handler code here
Dialog_Database mydatabase;
mydatabase.DoModal();
}
void CVoiceCtrlDlg::OnBUTTONExit()
{ //退出整个程序
DeleteFile(_T("current.wav"));
exit(0);
}
void CVoiceCtrlDlg::OnBUTTONStart()
{
// TODO: Add your control notification handler code here
//1判断数据库是否存在 或者已经存在,但是为空
CFile file;
if(!file.Open(_T("database.txt"),CFile::modeWrite,NULL))
{
MessageBox(_T("The wave database is not exist,please set up database first!"),_T("Mind!"),MB_OK);
return ;
}else{
if(file.GetLength()==0)
{
MessageBox(_T("The wave database is NULL,please set up database first!"),_T("Mind!"),MB_OK);
return;
}
file.Close();
}
//2 录音
pBuffer1=(PBYTE)malloc(INP_BUFFER_SIZE); //分配buffer1
pBuffer2=(PBYTE)malloc(INP_BUFFER_SIZE); //分配buffer2
if (!pBuffer1 || !pBuffer2) //如果某一个缓存分配失败,则都释放,提示,然后返回
{
if (pBuffer1) free(pBuffer1);
if (pBuffer2) free(pBuffer2);
MessageBeep(MB_ICONEXCLAMATION); //???????????
AfxMessageBox(_T("Memory erro!")); //
return ;
}
//写打开一个波形文件 CFile outWaveFile
outWaveFile.Open(_T("temp.wav"),CFile::modeCreate|CFile::modeWrite);
//初始化 waveheader文件头
WvH.dwSamplingRate = 11025; //
WvH.dwRIFF = 0x46464952; //groupid
WvH.dwWAVE = 0x45564157;
WvH.dw_fmt = 0x20746d66;
WvH.dwFmtLen = 0x14;
WvH.wDataType = 1;
WvH.wNChannels = 1;
WvH.wNBitsPerSam = 8;
// 1
WvH.wAlignment = WvH.wNChannels * WvH.wNBitsPerSam / 8;
WvH.dwNBytesPerSec = WvH.dwSamplingRate * WvH.wAlignment * WvH.wNChannels;
WvH.cbSize=0x02;
//WvH.TE03=0xff;
WvH.dwfact=0x74636166;
WvH.dwtest=0x00000004;
WvH.test1=0xbc4c;
WvH.test2=0x0001;
WvH.dwdata = 0x61746164; //"data"
WvH.dwDataLen=0;//dwDataLength;
WvH.dwFileLen=WvH.dwDataLen +50;
outWaveFile.Seek(0,CFile::begin); //定位到文件开始部位
outWaveFile.Write(&WvH,sizeof(WAVEHEADER)); //把wave 文件头写入波形文件
//open waveform audio for input
//打开waveform ,设置录音格式
waveform.wFormatTag=WAVE_FORMAT_PCM;
waveform.nChannels=1;
waveform.nSamplesPerSec=11025;
waveform.nAvgBytesPerSec=11025;
waveform.nBlockAlign=1;
waveform.wBitsPerSample=8;
waveform.cbSize=0; //
if (waveInOpen(&hWaveIn, //设备文件地址
WAVE_MAPPER, //波形输入设备打开标记
&waveform, //指向已经定义的 WAVEFORMATEX 结构
(DWORD)this->m_hWnd, //
NULL, //
CALLBACK_WINDOW)) //The dwCallback parameter is a window handle
{ //如果打开失败。。。。。
free(pBuffer1);
free(pBuffer2);
MessageBeep(MB_ICONEXCLAMATION);
AfxMessageBox(_T("Audio can not be open!"));
return ;
}
//如果打开成功了:
//pWaveHdr1是指向wavehdr数据结构的指针,用于建立起音频输入设备和数据接收缓冲区之间的联系
//
pWaveHdr1->lpData=(LPSTR)pBuffer1; //缓冲区地址
pWaveHdr1->dwBufferLength=INP_BUFFER_SIZE; //缓冲区长度
pWaveHdr1->dwBytesRecorded=0; //
pWaveHdr1->dwUser=0;
pWaveHdr1->dwFlags=0;
pWaveHdr1->dwLoops=1;
pWaveHdr1->lpNext=NULL;
pWaveHdr1->reserved=0;
// MessageBox(_T("7"));
//waveInPrepareHeader函数用于为音频输入设备 准备wavehdr数据结构,该数据结构在录音时
//指定录音数据暂存缓冲区和缓冲区的大小
waveInPrepareHeader(hWaveIn,pWaveHdr1,sizeof(WAVEHDR));
pWaveHdr2->lpData=(LPSTR)pBuffer2;
pWaveHdr2->dwBufferLength=INP_BUFFER_SIZE;
pWaveHdr2->dwBytesRecorded=0;
pWaveHdr2->dwUser=0;
pWaveHdr2->dwFlags=0;
pWaveHdr2->dwLoops=1;
pWaveHdr2->lpNext=NULL;
pWaveHdr2->reserved=0;
//同上 ,乒乓缓冲的方法
waveInPrepareHeader(hWaveIn,pWaveHdr2,sizeof(WAVEHDR));
//////////////////////////////////////////////////////////////////////////
pSaveBuffer = (PBYTE)realloc (pSaveBuffer, 100) ; //??????????
// Add the buffers
//为音频输入添加缓冲区并启动录音
waveInAddBuffer (hWaveIn, pWaveHdr1, sizeof (WAVEHDR)) ;//将缓冲区地址和输入设备相关联
waveInAddBuffer (hWaveIn, pWaveHdr2, sizeof (WAVEHDR)) ;
// Begin sampling
bRecording = TRUE ;
bEnding = FALSE ;
dwDataLength = 0 ;
//启动
waveInStart (hWaveIn) ;
GetDlgItem(IDC_BUTTON_Start)->EnableWindow(FALSE);
GetDlgItem(IDC_BUTTON_Study)->EnableWindow(FALSE);
GetDlgItem(IDC_BUTTON_Database)->EnableWindow(FALSE);
GetDlgItem(IDC_BUTTON_Exit)->EnableWindow(FALSE);
SetTimer(1,2000,NULL);
}
void CVoiceCtrlDlg::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
CString result; //得到的结果 result=command
CString strTemp,pp; //存储完整的文件
CString output;
unsigned short *ff; //16位声音数据模板
unsigned short *tt; //32位声音数据当前文件
unsigned short *cmb; //16位声音数据
int count,i=0;
CFile file;
int tk=0;
int mark=0;
int nBeg=0;
int nEnd=0;
int tem=-1; //临时权值
int re=800; //对比结果的最近权值
int mqz=0; //当前声音的i值
int jing=126; //记录当前环境的静音值
int duichen1=0; //16000个数据对称度(当前)
int max1=0; //最高幅度值(当前)
int maxc1=0; //极点个数(当前)
int duichen2=0; //16000个数据对称度(文件)
int max2=0; //最高幅度值(文件)
int maxc2=0; //极点个数(文件)
CFile filedatabase; //database.txt
CString alltext; //database
CString index,command,meaning,filename;
m_Result_Show.SetWindowText(_T(" ")); //清空输出框
GetDlgItem(IDC_BUTTON_Start)->EnableWindow(TRUE);
GetDlgItem(IDC_BUTTON_Study)->EnableWindow(TRUE);
GetDlgItem(IDC_BUTTON_Database)->EnableWindow(TRUE);
GetDlgItem(IDC_BUTTON_Exit)->EnableWindow(TRUE);
CDialog::OnTimer(nIDEvent);
////////////////1停止////////////////////////////////////////////
bEnding=TRUE;
bRecording=FALSE;
KillTimer(1);
WvH.dwDataLen=dwDataLength;
WvH.dwFileLen=WvH.dwDataLen +50; //+ 16 + 20;
outWaveFile.SeekToBegin();
outWaveFile.Write(&WvH,sizeof(WAVEHEADER));
waveInReset(hWaveIn); //停止录音
//在停止录音之后,调用下面的函数,断开wavehdr数据结构和音频输入设备的联系
waveInUnprepareHeader (hWaveIn, pWaveHdr1, sizeof (WAVEHDR)) ;
waveInUnprepareHeader (hWaveIn, pWaveHdr2, sizeof (WAVEHDR)) ;
//释放缓冲区
free(pBuffer1) ;
free(pBuffer2) ;
//如果声音文件有数据
if (dwDataLength <= 0) {
MessageBox(_T("wave file was bad!"));
return;
}
outWaveFile.Close();
//将声音存到文件,current
UpdateData(true);
CopyFile(_T("temp.wav") , _T("current.wav") , FALSE);
DeleteFile(_T("temp.wav"));
//将声音读回来,转为16位存到tt中
if(!file.Open(_T("current.wav"),CFile::modeRead)){ //创建一个标准格式文件
MessageBox(_T("Wave file was bad!")); //打不开文件说明用户的文件不存在
return;
}
cmb=(unsigned short *)malloc((file.GetLength()+1) * sizeof(char));
tt=(unsigned short *)malloc((file.GetLength()+1) * 2 * sizeof(char));
file.Read(cmb,file.GetLength());
//得到当前环境的静音值
for(count=800;count<1500;count++){
jing=(cmb[count]%256+jing)/2;
jing=(cmb[count]/256+jing)/2;
}
//pp.Format(_T("jing=%d,"),jing);//显示结果
//MessageBox(pp);
//拆分cmb数据到tt,cmb从3000开始,读取8000个
tt[0]=cmb[3000]%256;
tt[1]=cmb[3000]/256;
for(count=1;count<8000;count++){
tt[count*2]=cmb[count+3000]%256;
tt[count*2+1]=cmb[count+3000]/256;
}
//提取tt数据到cmb,精度2,静音值122
for(count=0;count<15998;count++){
if((i<100||i>600)){
if(abs(tt[count]-jing)>2 && abs(tt[count+1]-jing)>2 && abs(tt[count+2]-jing)>2){
cmb[i]=tt[count];
i++;
}
}
else{
cmb[i]=tt[count];
i++;
}
//计算对称度(当前)
duichen1=duichen1+(tt[count+1]-tt[count]);
//计算最高幅度值
if(tt[count]>max1)
max1=tt[count];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -