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);
}
}