TrainModelDlg.cpp
上传用户:goak128
上传日期:2013-07-17
资源大小:155k
文件大小:6k
源码类别:

控制台编程

开发平台:

C/C++

  1. // TrainModelDlg.cpp : 实现文件
  2. //
  3. #include "stdafx.h"
  4. #include "Platform.h"
  5. #include "TrainModelDlg.h"
  6. #include ".trainmodeldlg.h"
  7. // CTrainModelDlg 对话框
  8. IMPLEMENT_DYNAMIC(CTrainModelDlg, CDialog)
  9. CTrainModelDlg::CTrainModelDlg(CWnd* pParent /*=NULL*/)
  10. : CDialog(CTrainModelDlg::IDD, pParent)
  11. , m_strWord(_T(""))
  12. , m_nStatusNums(0)
  13. , m_nCodeNums(0)
  14. , m_strModel(_T(""))
  15. , m_strModelFile(_T(""))
  16. , m_strWaveFile(_T(""))
  17. {
  18. }
  19. CTrainModelDlg::~CTrainModelDlg()
  20. {
  21. }
  22. void CTrainModelDlg::DoDataExchange(CDataExchange* pDX)
  23. {
  24. CDialog::DoDataExchange(pDX);
  25. DDX_Text(pDX, IDC_EDIT_WORD, m_strWord);
  26. DDX_Text(pDX, IDC_EDIT_STATUSNUMS, m_nStatusNums);
  27. DDX_Text(pDX, IDC_EDIT_CODENUMS, m_nCodeNums);
  28. DDX_Text(pDX, IDC_EDIT_MODEL, m_strModel);
  29. DDX_Text(pDX, IDC_EDIT_WAVFILE, m_strModelFile);
  30. DDX_Text(pDX, IDC_EDIT_NEW_WAVE, m_strWaveFile);
  31. }
  32. BEGIN_MESSAGE_MAP(CTrainModelDlg, CDialog)
  33. ON_BN_CLICKED(IDC_BTN_OPENFILE, OnBnClickedBtnOpenfile)
  34. ON_BN_CLICKED(IDC_BTBADD, OnBnClickedBtbadd)
  35. ON_BN_CLICKED(IDC_BTN_OPENWAVE, OnBnClickedBtnOpenwave)
  36. END_MESSAGE_MAP()
  37. // CTrainModelDlg 消息处理程序
  38. void CTrainModelDlg::OnBnClickedBtnOpenfile()
  39. {
  40. // TODO: 在此添加控件通知处理程序代码
  41. CFileDialog dlg(TRUE);
  42. if (dlg.DoModal() == IDOK)
  43. {
  44. // 设定模板文件路径
  45. this->m_strModelFile = dlg.GetPathName();
  46. if (this->m_hmmModel.LoadModel(this->m_strModelFile))
  47. {
  48. // 显示模型参数
  49. this->UpdateShow();
  50. }
  51. else
  52. {
  53. // 提示用户模板文件错误
  54. AfxMessageBox("模板文件错误!");
  55. }
  56. }
  57. }
  58. //////////////////////////////////////////////////////////////////////////
  59. // 进行训练
  60. void CTrainModelDlg::OnBnClickedBtbadd()
  61. {
  62. CSmallFileWaveOut waveOut;
  63. WAVEHDR waveHdr;
  64. waveHdr.lpData = NULL;
  65. // 原始裸音频数据
  66. double* pRawData = NULL;
  67. // 端点检测后的数据
  68. double* pSection = NULL;
  69. // 倒谱数据
  70. double* pCepstrum = NULL;
  71. unsigned int nDataLen = 0;
  72. // HMM模型
  73. CHMM hmmModel;
  74. // 获取设置数据
  75. CWnd::UpdateData(TRUE);
  76. // 打开所训练文件
  77. if (waveOut.LoadFile(this->m_strWaveFile, (DWORD) CWnd::GetSafeHwnd()))
  78. {
  79. // 获取原始数据
  80. waveOut.GetSamples(&waveHdr, 0);
  81. if (waveHdr.lpData != NULL)
  82. {
  83. // 获取原始数据
  84. // 进行8位数据的转换
  85. if (waveOut.m_wavFile.GetWaveFormat().wBitsPerSample == 8)
  86. {
  87. // 计算数据长度
  88. nDataLen = waveHdr.dwBufferLength;
  89. pRawData = new double[nDataLen];
  90. CWaveConvertor::ConvertToDoubleMono(
  91. (byte*) waveHdr.lpData, waveHdr.dwBufferLength, pRawData);
  92. }
  93. // 进行16位数据转换
  94. else
  95. {
  96. // 计算数据长度
  97. nDataLen = waveHdr.dwBufferLength / 2;
  98. pRawData = new double[nDataLen];
  99. CWaveConvertor::ConvertToDoubleMono(
  100. (int*) waveHdr.lpData, waveHdr.dwBufferLength, pRawData);
  101. }
  102. // 对输入数据进行加窗处理
  103. CSpeech::AddWindow(this->m_hmmModel.m_nFrameSize, pRawData, nDataLen);
  104. // 对输入数据进行端点检测
  105. // pSection = new double[nDataLen];
  106. // nDataLen = CSpeech::SubSection(
  107. //  pRawData, nDataLen, this->m_hmmModel.m_nFrameSize, pSection);
  108. // 计算LPC倒谱
  109. pCepstrum = new double[nDataLen];
  110. CWaveConvertor::ConvertToCepStrum(
  111. nDataLen, this->m_hmmModel.m_nFrameSize, pRawData, pCepstrum);
  112. // 进行hmm初始化训练
  113. this->m_hmmModel.Train(pCepstrum, nDataLen);
  114. // 保存hmmModel初始化训练结果
  115. this->m_hmmModel.SaveModel(this->m_strModelFile);
  116. // 释放所占用资源 
  117. delete[] pRawData;
  118. delete[] pCepstrum;
  119. // delete[] pSection;
  120. waveOut.Stop();
  121. // 训练文件打开失败
  122. AfxMessageBox("训练完毕!");
  123. // 更新模型参数显示
  124. this->UpdateShow();
  125. }
  126. }
  127. else
  128. {
  129. // 训练文件打开失败
  130. AfxMessageBox("训练文件格式错误!");
  131. }
  132. }
  133. //////////////////////////////////////////////////////////////////////////
  134. // 打开训练文件
  135. void CTrainModelDlg::OnBnClickedBtnOpenwave()
  136. {
  137. // TODO: 在此添加控件通知处理程序代码
  138. CFileDialog dlg(true);
  139. if (dlg.DoModal() == IDOK)
  140. {
  141. this->m_strWaveFile = dlg.GetPathName();
  142. CWnd::UpdateData(FALSE);
  143. }
  144. }
  145. //////////////////////////////////////////////////////////////////////////
  146. // 更新HMM模型参数显示
  147. void CTrainModelDlg::UpdateShow()
  148. {
  149. // 循环变量
  150. unsigned int i = 0;
  151. unsigned int j = 0;
  152. CString strFormat;
  153. if (this->m_hmmModel.m_pPi != NULL)
  154. {
  155. this->m_strWord = this->m_hmmModel.m_strWord;
  156. this->m_nStatusNums = this->m_hmmModel.m_nStatusNums;
  157. this->m_nCodeNums = this->m_hmmModel.m_nCodeNums;
  158. // 显示模板参数
  159. this->m_strModel = "";
  160. // 显示Pi参数
  161. this->m_strModel += "Pi:rn";
  162. for (i = 0; i < this->m_nStatusNums; i++)
  163. {
  164. strFormat.Format("Pi(%d): %frn", i, this->m_hmmModel.m_pPi[i]);
  165. this->m_strModel += strFormat;
  166. }
  167. // 显示pA参数
  168. this->m_strModel += "rnA:rn";
  169. for (i = 0; i < this->m_nStatusNums; i++)
  170. {
  171. for (j = 0; j < this->m_nStatusNums; j++)
  172. {
  173. strFormat.Format("A(%d, %d): %frn", 
  174. i, j, this->m_hmmModel.m_pA[i * this->m_nStatusNums + j]);
  175. this->m_strModel += strFormat;
  176. }
  177. }
  178. // 显示pB参数
  179. this->m_strModel += "rnB:rn";
  180. for (i = 0; i < this->m_nStatusNums; i++)
  181. {
  182. for (j = 0; j < this->m_nCodeNums; j++)
  183. {
  184. strFormat.Format("B(%d, %d): %frn", 
  185. i, j, this->m_hmmModel.m_pB[i * this->m_nCodeNums + j]);
  186. this->m_strModel += strFormat;
  187. }
  188. }
  189. // 显示码本信息
  190. this->m_strModel += "rn码本:rn";
  191. for (i = 0; i < this->m_nCodeNums; i++)
  192. {
  193. strFormat.Format("V(%d): %frn", i, this->m_hmmModel.m_pCodeBook[i]);
  194. this->m_strModel += strFormat;
  195. }
  196. // 更新页面显示
  197. CWnd::UpdateData(FALSE);
  198. }
  199. }