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

📄 voicectrldlg.cpp

📁 声音识别系统的源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// 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 + -