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

📄 dialog_study.cpp

📁 声音识别系统的源代码
💻 CPP
字号:
// Dialog_Study.cpp : implementation file
//

#include "stdafx.h"
#include "VoiceCtrl.h"
#include "Dialog_Study.h"

#include "Afxwin.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//#pragma   comment(lib,   "winmm.lib")   

/////////////////////////////////////////////////////////////////////////////
// Dialog_Study dialog


Dialog_Study::Dialog_Study(CWnd* pParent /*=NULL*/)
	: CDialog(Dialog_Study::IDD, pParent)
{
	//{{AFX_DATA_INIT(Dialog_Study)
	m_name = _T("");
	m_information = _T("");
	m_command = _T("");
	//}}AFX_DATA_INIT
    pWaveHdr1=reinterpret_cast<PWAVEHDR>(malloc(sizeof(WAVEHDR)));
	pWaveHdr2=reinterpret_cast<PWAVEHDR>(malloc(sizeof(WAVEHDR)));
	pSaveBuffer = reinterpret_cast<PBYTE>(malloc(1));     
    //m_ctrl_command.ShowDropDown(true);
	//m_ctrl_command.

}


void Dialog_Study::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(Dialog_Study)
	DDX_Control(pDX, IDC_COMBO_Command, m_ctrl_command);
	DDX_Control(pDX, IDC_EDIT_Information, m_Ctrl_Info);
	DDX_Text(pDX, IDC_EDIT_Name, m_name);
	DDV_MaxChars(pDX, m_name, 20);
	DDX_Text(pDX, IDC_EDIT_Information, m_information);
	DDV_MaxChars(pDX, m_information, 50);
	DDX_CBString(pDX, IDC_COMBO_Command, m_command);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(Dialog_Study, CDialog)
	//{{AFX_MSG_MAP(Dialog_Study)
	ON_BN_CLICKED(IDC_BUTTON_Record, OnBUTTONRecord)
	ON_BN_CLICKED(IDC_BUTTON_Play, OnBUTTONPlay)
	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()
	ON_BN_CLICKED(IDC_BUTTON_Stop, OnBUTTONStop)
	ON_BN_CLICKED(IDC_BUTTON_Save, OnBUTTONSave)
	//ON_CBN_SETFOCUS(IDC_COMBO_Command, OnSetfocusCOMBOCommand)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// Dialog_Study message handlers


//开始 学习 录音
void Dialog_Study::OnBUTTONRecord() 
{
	// TODO: Add your control notification handler code here
//	MessageBox(_T("Dialog_Study::OnBUTTONRecord() "));
    //(CButton *)GetDlgItem(IDC_BUTTON_Play);
    
	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 ;
	
//	MessageBox(_T("3"));

	//启动
	waveInStart (hWaveIn) ;
	GetDlgItem(IDC_BUTTON_Record)->EnableWindow(FALSE);     
	GetDlgItem(IDC_BUTTON_Play)->EnableWindow(FALSE); 
	GetDlgItem(IDC_BUTTON_Save)->EnableWindow(FALSE); 
	SetTimer(1,2000,NULL);
}



void Dialog_Study::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
   	CDialog::OnTimer(nIDEvent);
	KillTimer(1);

	GetDlgItem(IDC_BUTTON_Record)->EnableWindow(TRUE);     
	GetDlgItem(IDC_BUTTON_Play)->EnableWindow(TRUE); 
	GetDlgItem(IDC_BUTTON_Save)->EnableWindow(TRUE);
	Dialog_Study::OnBUTTONStop();


	CDialog::OnTimer(nIDEvent);
} 
 

void Dialog_Study::OnBUTTONStop() 
{
	// TODO: Add your control notification handler code here
	 //MessageBox(_T("Close"));
	bEnding=TRUE;
	bRecording=FALSE;
	//Sleep(1500);
	WvH.dwDataLen=dwDataLength;
	WvH.dwFileLen=WvH.dwDataLen +50;//+ 16 + 20;
	outWaveFile.SeekToBegin();
    
	outWaveFile.Write(&WvH,sizeof(WAVEHEADER));
	   
	waveInReset(hWaveIn);	//停止录音

    outWaveFile.Close();   //???????????????????????????
}


void Dialog_Study::OnMM_WIM_OPEN(UINT wParam, LONG lParam) 
{   //一开始录音,就自动调用这个
	// TODO: Add your message handler code here and/or call default
    //MessageBox(_T("luyin"));
	//SetTimer(1,100,NULL);   //设置定时器1 为100ms  
	bRecording=TRUE;  
	bEnding=FALSE;
    
 //   MessageBox(_T("OnMM_WIM_OPEN"));
 
	//TRACE( L"dddd\n" );
	
}


void Dialog_Study::OnMM_WIM_DATA(UINT wParam, LONG lParam) 
{
    //缓冲区用完时,自动调用这个回调函数
	// MessageBox(_T("OnMM_WIM_DATA"));
	// TODO: Add your message handler code here and/or call default
	// Reallocate save buffer memory
	if(bEnding){
	  waveInClose(hWaveIn);  //关闭录音
      //MessageBox(_T("OnMM_WIM_DATA   wrong 11111"));
	  return;
	}
	//////////////////////////////////////////////////////////////////////////
	
	pNewBuffer =(PBYTE)realloc(pSaveBuffer, dwDataLength +((PWAVEHDR) lParam)->dwBytesRecorded) ;
	if (pNewBuffer == NULL)
	{   
		waveInClose (hWaveIn) ;
		MessageBeep (MB_ICONEXCLAMATION) ;
		AfxMessageBox(_T("erro memory"));
		return ;
	}	
	pSaveBuffer = pNewBuffer ;
    //TRACE( L"This is pNewBuffer: %s\n",pNewBuffer );
 

	CopyMemory (pSaveBuffer + dwDataLength,  //目的 //????????why to add dwDataLength??
		       ((PWAVEHDR) lParam)->lpData,   //源
	           ((PWAVEHDR) lParam)->dwBytesRecorded) ;   //长度
	
	dwDataLength += ((PWAVEHDR) lParam)->dwBytesRecorded ;

    //写入文件
    outWaveFile.SeekToEnd();
	outWaveFile.Write(pSaveBuffer,((PWAVEHDR) lParam)->dwBytesRecorded);
 
	//LPMMIOINFO lpmmioinfo;
	//mmioOpen( _T("temp.wav"), lpmmioinfo,MMIO_CREATE);

	// Send out a new buffer    //添加新的缓冲区
    //(PWAVEHDR)lParam->lpData;
    ((PWAVEHDR) lParam)->lpData=NULL;
	waveInAddBuffer (hWaveIn, (PWAVEHDR) lParam, sizeof (WAVEHDR)) ;
//	TRACE(_T("done input data\n"));
	return ;

	
}


void Dialog_Study::OnMM_WIM_CLOSE(UINT wParam, LONG lParam) 
{
	 //MessageBox(_T("OnMM_WIM_CLOSE"));
	// TODO: Add your message handler code here and/or call default
//	KillTimer(1);       //关闭定时器
	//TRACE("MM_WIM_CLOSE\n");
	if (0==dwDataLength) { 
		return;
	}
	
    //在停止录音之后,调用调用下面的函数,断开wavehdr数据结构和音频输入设备的联系
	waveInUnprepareHeader (hWaveIn, pWaveHdr1, sizeof (WAVEHDR)) ;
	waveInUnprepareHeader (hWaveIn, pWaveHdr2, sizeof (WAVEHDR)) ;
	
	//释放缓冲区
	free(pBuffer1) ;
	free(pBuffer2) ;
	//free(pSaveBuffer);
	//free(pNewBuffer);

	

	if (dwDataLength > 0)    //如果声音文件有数据(可以播放)
	{
	 // MessageBox(_T("Yes"));

	}
	else{
	   MessageBox(_T("wave file was bad!"));
	}
   
	//bRecording = FALSE ;   	
	return ;
	
}


//播放 
void Dialog_Study::OnBUTTONPlay() 
{
	// TODO: Add your control notification handler code here
    //MessageBox(_T("OnBUTTONPlay() "));
	//sndPlaySound(_T("temp.wav"),SND_ASYNC);   //!!!!!!!!!!
	if (bPlaying) 
	{
    	waveOutReset(hWaveOut);
	}

	//open waveform audio for output
	waveform.wFormatTag		=	WAVE_FORMAT_PCM;
	waveform.nChannels		=	1;
	waveform.nSamplesPerSec	=11025;
	waveform.nAvgBytesPerSec=11025;
	waveform.nBlockAlign	=1;
	waveform.wBitsPerSample	=8;
	waveform.cbSize			=0;
		
	if (waveOutOpen(&hWaveOut,WAVE_MAPPER,&waveform,(DWORD)this->m_hWnd,NULL,CALLBACK_WINDOW)) 
	{
		MessageBeep(MB_ICONEXCLAMATION);
		AfxMessageBox(_T("Audio output erro"));
	}
	
	return ;
}


//打开声音,播放
void Dialog_Study::OnMM_WOM_OPEN(UINT wParam, LONG lParam){
    

	pWaveHdr1->lpData          = (LPSTR)pSaveBuffer ;
	pWaveHdr1->dwBufferLength  = dwDataLength ;
	pWaveHdr1->dwBytesRecorded = 0 ;
	pWaveHdr1->dwUser          = 0 ;
	pWaveHdr1->dwFlags         = WHDR_BEGINLOOP | WHDR_ENDLOOP ;
	pWaveHdr1->dwLoops         = 1;//dwRepetitions ;
	pWaveHdr1->lpNext          = NULL ;
	pWaveHdr1->reserved        = 0 ;
	
	// Prepare and write
	//打开音频输出设备
	waveOutPrepareHeader (hWaveOut, pWaveHdr1, sizeof (WAVEHDR)) ;
	waveOutWrite (hWaveOut, pWaveHdr1, sizeof (WAVEHDR)) ;
	
	bEnding = FALSE ;
	bPlaying = TRUE ;
	
	
}


//打开完成
void Dialog_Study::OnMM_WOM_DONE(UINT wParam, LONG lParam){
 
//	MessageBox(_T("OnMM_WOM_DONE"));

	//TRACE("open MM_WOM_DONE\n");
	waveOutUnprepareHeader (hWaveOut, pWaveHdr1, sizeof (WAVEHDR)) ;
	waveOutClose (hWaveOut) ;
	
	bPaused = FALSE ;
	dwRepetitions = 1 ;
	bPlaying = FALSE ;	
	
	return  ;
	
}


void Dialog_Study::OnMM_WOM_CLOSE(UINT wParam, LONG lParam){
//	TRACE("open MM_WOM_CLOSE\n");
    //	MessageBox(_T("OnMM_WOM_CLOSE"));

	bPaused = FALSE ;
	dwRepetitions = 1 ;
	bPlaying = FALSE ;	
    
//	MessageBox(_T("5"));
 
	return ;
	
}



void Dialog_Study::OnBUTTONSave() 
{
	int status=0;  
	CString dataBaseFileName;
	// TODO: Add your control notification handler code here
    //把这个声音文件保存成一个数据库的名字 , 然后在文本文件中存储相应的信息

    //1 改写文本文件
    status=WriteFile();
	if(0==status)
	{
		return;   //错误 ,返回
    }   
	//2 存储声音文件   
	UpdateData(true);    
	//outWaveFile.Close();   //关闭文件  
    dataBaseFileName=m_name;
	CopyFile(_T("temp.wav") , dataBaseFileName , FALSE);
    DeleteFile(_T("temp.wav"));
	Dialog_Study::OnOK();
    //MessageBox(dataBaseFileName);
}

void Dialog_Study::OnOK() 
{
	// TODO: Add extra validation here	
    //delete temp.wav
    CFile file;
    if(file.Open(_T("temp.wav"),CFile::modeRead,NULL))
    {
		file.Close();
	    DeleteFile(_T("temp.wav"));	        
	}
	CDialog::OnOK();
}

int Dialog_Study::WriteFile(){
 	  
	 int length=0 ;
	 CString command;    //命令
	 CString meaning;    //含义
	 CString filename;   //文件名

	 int i=0;
	 CFile file;

	 UpdateData(true);

	 command = m_command;
	 filename= m_name; 
	 meaning = m_information;

     /*1 判断  
	   字符串是否空
	   文件是否已经存在
       */
    if(command.IsEmpty()){//IsEmpty()Return Nonzero if object has 0 length; otherwise 0. 
	   MessageBox(_T("Command Cannot be empty!"),_T("wrong!"),MB_OK);
	   return 0;
	}
    if(filename.IsEmpty()){//IsEmpty()Return Nonzero if object has 0 length; otherwise 0. 
	   MessageBox(_T("Filename Cannot be empty!"),_T("wrong!"),MB_OK);
	   return 0;
	}
    if(meaning.IsEmpty()){//IsEmpty()Return Nonzero if object has 0 length; otherwise 0. 
	   MessageBox(_T("Information Cannot be empty!"),_T("wrong!"),MB_OK);
	   return 0;
	}

    if(file.Open(filename,CFile::modeRead,NULL))
    {
	    MessageBox(_T("wen jian yijing cunzai!"),_T("wrong!"),MB_OK);
		file.Close();
        return 0;
	}
    if(!file.Open(_T("temp.wav"),CFile::modeRead,NULL))
    {   
	    MessageBox(_T("Cannot find the source wave file!"),_T("wrong!"),MB_OK); 
        return 0;
	}else{
	   	file.Close();
	}
    
   
     //2
     
	 file.Open(_T("database.txt"),CFile::modeNoTruncate |CFile::modeCreate|CFile::modeWrite);   //database.txt
	 file.SeekToEnd();
	 
	 length=2*command.GetLength();
	 file.Write(_T("command=")+command+_T("\r\n"),16+length+4);  //写 command
     length=2*filename.GetLength();   
     file.Write(_T("filename=")+filename+_T("\r\n"),18+length+4);//写 filename
     length=2*meaning.GetLength();  
     file.Write(_T("meaning=")+meaning+_T("\r\n"),16+length+4);  
	 
    
     file.Close();
     
	 return 1;
}

 

⌨️ 快捷键说明

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