www.pudn.com > hmmPlatform.rar > TrainModelDlg.cpp


// TrainModelDlg.cpp : 实现文件 
// 
 
#include "stdafx.h" 
#include "Platform.h" 
#include "TrainModelDlg.h" 
#include ".\trainmodeldlg.h" 
 
 
// CTrainModelDlg 对话框 
 
IMPLEMENT_DYNAMIC(CTrainModelDlg, CDialog) 
CTrainModelDlg::CTrainModelDlg(CWnd* pParent /*=NULL*/) 
	: CDialog(CTrainModelDlg::IDD, pParent) 
	, m_strWord(_T("")) 
	, m_nStatusNums(0) 
	, m_nCodeNums(0) 
	, m_strModel(_T("")) 
	, m_strModelFile(_T("")) 
	, m_strWaveFile(_T("")) 
{ 
} 
 
CTrainModelDlg::~CTrainModelDlg() 
{ 
} 
 
void CTrainModelDlg::DoDataExchange(CDataExchange* pDX) 
{ 
	CDialog::DoDataExchange(pDX); 
	DDX_Text(pDX, IDC_EDIT_WORD, m_strWord); 
	DDX_Text(pDX, IDC_EDIT_STATUSNUMS, m_nStatusNums); 
	DDX_Text(pDX, IDC_EDIT_CODENUMS, m_nCodeNums); 
	DDX_Text(pDX, IDC_EDIT_MODEL, m_strModel); 
	DDX_Text(pDX, IDC_EDIT_WAVFILE, m_strModelFile); 
	DDX_Text(pDX, IDC_EDIT_NEW_WAVE, m_strWaveFile); 
} 
 
 
BEGIN_MESSAGE_MAP(CTrainModelDlg, CDialog) 
	ON_BN_CLICKED(IDC_BTN_OPENFILE, OnBnClickedBtnOpenfile) 
	ON_BN_CLICKED(IDC_BTBADD, OnBnClickedBtbadd) 
	ON_BN_CLICKED(IDC_BTN_OPENWAVE, OnBnClickedBtnOpenwave) 
END_MESSAGE_MAP() 
 
 
// CTrainModelDlg 消息处理程序 
 
void CTrainModelDlg::OnBnClickedBtnOpenfile() 
{ 
	// TODO: 在此添加控件通知处理程序代码 
	CFileDialog dlg(TRUE); 
 
	if (dlg.DoModal() == IDOK) 
	{ 
		// 设定模板文件路径 
		this->m_strModelFile = dlg.GetPathName(); 
 
		if (this->m_hmmModel.LoadModel(this->m_strModelFile)) 
		{ 
			// 显示模型参数 
			this->UpdateShow(); 
		} 
		else 
		{ 
			// 提示用户模板文件错误 
			AfxMessageBox("模板文件错误!"); 
		} 
	} 
} 
 
////////////////////////////////////////////////////////////////////////// 
// 进行训练 
void CTrainModelDlg::OnBnClickedBtbadd() 
{ 
	CSmallFileWaveOut waveOut; 
	WAVEHDR waveHdr; 
	waveHdr.lpData = NULL; 
	// 原始裸音频数据 
	double* pRawData = NULL; 
	// 端点检测后的数据 
	double* pSection = NULL; 
	// 倒谱数据 
	double* pCepstrum = NULL; 
	unsigned int nDataLen = 0; 
	// HMM模型 
	CHMM hmmModel; 
 
	// 获取设置数据 
	CWnd::UpdateData(TRUE); 
 
	// 打开所训练文件 
	if (waveOut.LoadFile(this->m_strWaveFile, (DWORD) CWnd::GetSafeHwnd())) 
	{ 
		// 获取原始数据 
		waveOut.GetSamples(&waveHdr, 0); 
 
		if (waveHdr.lpData != NULL) 
		{ 
			// 获取原始数据 
			// 进行8位数据的转换 
			if (waveOut.m_wavFile.GetWaveFormat().wBitsPerSample == 8) 
			{ 
				// 计算数据长度 
				nDataLen = waveHdr.dwBufferLength; 
				pRawData = new double[nDataLen]; 
 
				CWaveConvertor::ConvertToDoubleMono( 
					(byte*) waveHdr.lpData, waveHdr.dwBufferLength, pRawData); 
			} 
			// 进行16位数据转换 
			else 
			{ 
				// 计算数据长度 
				nDataLen = waveHdr.dwBufferLength / 2; 
				pRawData = new double[nDataLen]; 
 
				CWaveConvertor::ConvertToDoubleMono( 
					(int*) waveHdr.lpData, waveHdr.dwBufferLength, pRawData); 
			} 
 
			// 对输入数据进行加窗处理 
			CSpeech::AddWindow(this->m_hmmModel.m_nFrameSize, pRawData, nDataLen); 
			// 对输入数据进行端点检测 
			// pSection = new double[nDataLen]; 
			// nDataLen = CSpeech::SubSection( 
			// 	pRawData, nDataLen, this->m_hmmModel.m_nFrameSize, pSection); 
 
			// 计算LPC倒谱 
			pCepstrum = new double[nDataLen]; 
			CWaveConvertor::ConvertToCepStrum( 
				nDataLen, this->m_hmmModel.m_nFrameSize, pRawData, pCepstrum); 
 
			// 进行hmm初始化训练 
			this->m_hmmModel.Train(pCepstrum, nDataLen); 
			// 保存hmmModel初始化训练结果 
			this->m_hmmModel.SaveModel(this->m_strModelFile); 
 
			// 释放所占用资源  
			delete[] pRawData; 
			delete[] pCepstrum; 
			// delete[] pSection; 
			waveOut.Stop();	 
 
			// 训练文件打开失败 
			AfxMessageBox("训练完毕!"); 
			// 更新模型参数显示 
			this->UpdateShow(); 
		} 
	} 
	else 
	{ 
		// 训练文件打开失败 
		AfxMessageBox("训练文件格式错误!"); 
	} 
} 
 
////////////////////////////////////////////////////////////////////////// 
// 打开训练文件 
void CTrainModelDlg::OnBnClickedBtnOpenwave() 
{ 
	// TODO: 在此添加控件通知处理程序代码 
	CFileDialog dlg(true); 
 
 
	if (dlg.DoModal() == IDOK) 
	{ 
		this->m_strWaveFile = dlg.GetPathName(); 
 
		CWnd::UpdateData(FALSE); 
	} 
} 
 
////////////////////////////////////////////////////////////////////////// 
// 更新HMM模型参数显示 
void CTrainModelDlg::UpdateShow() 
{ 
	// 循环变量 
	unsigned int i = 0; 
	unsigned int j = 0; 
	CString strFormat; 
 
	if (this->m_hmmModel.m_pPi != NULL) 
	{ 
		this->m_strWord = this->m_hmmModel.m_strWord; 
		this->m_nStatusNums = this->m_hmmModel.m_nStatusNums; 
		this->m_nCodeNums = this->m_hmmModel.m_nCodeNums; 
 
		// 显示模板参数 
		this->m_strModel = ""; 
 
		// 显示Pi参数 
		this->m_strModel += "Pi:\r\n"; 
		for (i = 0; i < this->m_nStatusNums; i++) 
		{ 
			strFormat.Format("Pi(%d): %f\r\n", i, this->m_hmmModel.m_pPi[i]); 
			this->m_strModel += strFormat; 
		} 
 
		// 显示pA参数 
		this->m_strModel += "\r\nA:\r\n"; 
		for (i = 0; i < this->m_nStatusNums; i++) 
		{ 
			for (j = 0; j < this->m_nStatusNums; j++) 
			{ 
				strFormat.Format("A(%d, %d): %f\r\n",  
					i, j, this->m_hmmModel.m_pA[i * this->m_nStatusNums + j]); 
 
				this->m_strModel += strFormat; 
			} 
		} 
 
		// 显示pB参数 
		this->m_strModel += "\r\nB:\r\n"; 
		for (i = 0; i < this->m_nStatusNums; i++) 
		{ 
			for (j = 0; j < this->m_nCodeNums; j++) 
			{ 
				strFormat.Format("B(%d, %d): %f\r\n",  
					i, j, this->m_hmmModel.m_pB[i * this->m_nCodeNums + j]); 
 
				this->m_strModel += strFormat; 
			} 
		} 
 
		// 显示码本信息 
		this->m_strModel += "\r\n码本:\r\n"; 
		for (i = 0; i < this->m_nCodeNums; i++) 
		{ 
			strFormat.Format("V(%d): %f\r\n", i, this->m_hmmModel.m_pCodeBook[i]); 
 
			this->m_strModel += strFormat; 
		} 
 
		// 更新页面显示 
		CWnd::UpdateData(FALSE); 
	} 
}