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

控制台编程

开发平台:

C/C++

  1. // PlatformView.cpp : CPlatformView 类的实现
  2. //
  3. #include "stdafx.h"
  4. #include "Platform.h"
  5. #include "PlatformDoc.h"
  6. #include "PlatformView.h"
  7. #include ".platformview.h"
  8. #include <math.h>
  9. #ifdef _DEBUG
  10. #define new DEBUG_NEW
  11. #endif
  12. // CPlatformView
  13. IMPLEMENT_DYNCREATE(CPlatformView, CFormView)
  14. BEGIN_MESSAGE_MAP(CPlatformView, CFormView)
  15. ON_WM_SIZE()
  16. ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
  17. ON_BN_CLICKED(IDC_CONTROL_LOAD, OnBnClickedControlLoad)
  18. ON_COMMAND(ID_DISPLAY_OPTION, OnDisplayOption)
  19. ON_BN_CLICKED(IDC_CONTROL_PREVIOUS, OnBnClickedControlPrevious)
  20. ON_BN_CLICKED(IDC_CONTROL_NEXT, OnBnClickedControlNext)
  21. ON_BN_CLICKED(IDC_CONTROL_STOP, OnBnClickedControlStop)
  22. ON_BN_CLICKED(IDC_CONTROL_PLAY, OnBnClickedControlPlay)
  23. ON_COMMAND(ID_DISPLAY_WAVE, OnDisplayWave)
  24. ON_COMMAND(ID_DISPLAY_ZERO, OnDisplayZero)
  25. ON_COMMAND(ID_DISPLAY_POWER, OnDisplayPower)
  26. ON_COMMAND(ID_DISPLAY_VIBRATION, OnDisplayVibration)
  27. ON_UPDATE_COMMAND_UI(ID_DISPLAY_WAVE, OnUpdateDisplayWave)
  28. ON_UPDATE_COMMAND_UI(ID_DISPLAY_ZERO, OnUpdateDisplayZero)
  29. ON_UPDATE_COMMAND_UI(ID_DISPLAY_POWER, OnUpdateDisplayPower)
  30. ON_UPDATE_COMMAND_UI(ID_DISPLAY_VIBRATION, OnUpdateDisplayVibration)
  31. ON_COMMAND(ID_DISPLAY_ZOOMIN, OnDisplayZoomin)
  32. ON_COMMAND(ID_DISPLAY_ZOOMOUT, OnDisplayZoomout)
  33. ON_COMMAND(ID_DISPLAY_SPECTRUM, OnDisplaySpectrum)
  34. ON_UPDATE_COMMAND_UI(ID_DISPLAY_SPECTRUM, OnUpdateDisplaySpectrum)
  35. ON_COMMAND(ID_DISPLAY_LOGSPECTRUM, OnDisplayLogspectrum)
  36. ON_UPDATE_COMMAND_UI(ID_DISPLAY_LOGSPECTRUM, OnUpdateDisplayLogspectrum)
  37. ON_COMMAND(ID_DISPLAY_CEPSTRUM, OnDisplayCepstrum)
  38. ON_UPDATE_COMMAND_UI(ID_DISPLAY_CEPSTRUM, OnUpdateDisplayCepstrum)
  39. ON_WM_MOUSEWHEEL()
  40. ON_BN_CLICKED(IDC_CONTROL_DISPLAYWAVE_ALL, OnBnClickedControlDisplaywaveAll)
  41. ON_COMMAND(ID_SECTION_END, OnSectionEnd)
  42. ON_COMMAND(ID_SECTION_SY, OnSectionSy)
  43. ON_COMMAND(ID_VQ_KMEANS, OnVqKmeans)
  44. ON_COMMAND(ID_HMM_ADDMODEL, OnHmmAddmodel)
  45. ON_COMMAND(ID_HMM_TRAINMODEL, OnHmmTrainmodel)
  46. ON_COMMAND(ID_HMM_DEMO, OnHmmDemo)
  47. ON_COMMAND(ID_DISPLAY_AFTERWINDOW, OnDisplayAfterwindow)
  48. ON_UPDATE_COMMAND_UI(ID_DISPLAY_BEFOREWINDOW, OnUpdateDisplayBeforewindow)
  49. ON_UPDATE_COMMAND_UI(ID_DISPLAY_AFTERWINDOW, OnUpdateDisplayAfterwindow)
  50. ON_COMMAND(ID_DISPLAY_BEFOREWINDOW, OnDisplayBeforewindow)
  51. END_MESSAGE_MAP()
  52. // CPlatformView 构造/析构
  53. CPlatformView::CPlatformView()
  54. : CFormView(CPlatformView::IDD)
  55. , m_ctlDisplay(CWnd::GetSafeHwnd())
  56. , m_strResult(_T(""))
  57. {
  58. // TODO: 在此处添加构造代码
  59. // 设置默认参数
  60. this->m_nFrameSize = SETTING_FRAME_SIZE;
  61. this->m_nTotalFrames = 0;
  62. this->m_nCurrentFrame = 0;
  63. this->m_ctlDisplay.SetXMetrics(SETTING_XMETRICS);
  64. this->m_ctlDisplay.SetYMetrics(SETTING_YMETRICS);
  65. this->m_ctlDisplay.SetZoomStep(SETTING_ZOOMSTEP);
  66. // 默认显示时域波形
  67. this->m_displayType = DisplayWave;
  68. // 设定部分控件不可用
  69. this->EnableControl(TRUE);
  70. }
  71. CPlatformView::~CPlatformView()
  72. {
  73. }
  74. void CPlatformView::DoDataExchange(CDataExchange* pDX)
  75. {
  76. CFormView::DoDataExchange(pDX);
  77. DDX_Control(pDX, IDC_DISPLAYAREA, m_ctlDisplay);
  78. DDX_Text(pDX, IDC_EDIT_RESULT, m_strResult);
  79. }
  80. BOOL CPlatformView::PreCreateWindow(CREATESTRUCT& cs)
  81. {
  82. // TODO: 在此处通过修改 CREATESTRUCT cs 来修改窗口类或
  83. // 样式
  84. return CFormView::PreCreateWindow(cs);
  85. }
  86. void CPlatformView::OnInitialUpdate()
  87. {
  88. CFormView::OnInitialUpdate();
  89. GetParentFrame()->RecalcLayout();
  90. ResizeParentToFit();
  91. }
  92. // CPlatformView 诊断
  93. #ifdef _DEBUG
  94. void CPlatformView::AssertValid() const
  95. {
  96. CFormView::AssertValid();
  97. }
  98. void CPlatformView::Dump(CDumpContext& dc) const
  99. {
  100. CFormView::Dump(dc);
  101. }
  102. CPlatformDoc* CPlatformView::GetDocument() const // 非调试版本是内联的
  103. {
  104. ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CPlatformDoc)));
  105. return (CPlatformDoc*)m_pDocument;
  106. }
  107. #endif //_DEBUG
  108. // CPlatformView 消息处理程序
  109. //////////////////////////////////////////////////////////////////////////
  110. // 更改显示区域宽度
  111. void CPlatformView::OnSize(UINT nType, int cx, int cy)
  112. {
  113. CFormView::OnSize(nType, cx, cy);
  114. // TODO: 在此处添加消息处理程序代码
  115. CWnd* pWnd = NULL;
  116. // 计算控件left
  117. UINT nLeft = 0;
  118. // 计算控件宽度
  119. UINT nWidth = 0;
  120. // 控件区域
  121. CRect ctlRect;
  122. // 视图区域
  123. CRect viewRect;
  124. CSize size;
  125. // 若不是最小化窗口,更改显示控件宽度
  126. if (this->m_ctlDisplay.m_hWnd && nType == SIZE_RESTORED)
  127. {
  128. nWidth = cx - 20;
  129. nLeft = 10;
  130. CWnd::GetWindowRect(&viewRect);
  131. // 取得显示区域当前位置和大小
  132. this->m_ctlDisplay.GetWindowRect(&ctlRect);
  133. size = ctlRect.Size();
  134. // 设置显示区域的新宽度和位置
  135. this->m_ctlDisplay.SetWindowPos(NULL, nLeft, 10, 
  136. nWidth, size.cy, SWP_NOREDRAW);
  137. // 修改Result信息控件宽度和长度
  138. pWnd = CWnd::GetDlgItem(IDC_EDIT_RESULT);
  139. pWnd->GetWindowRect(&ctlRect);
  140. pWnd->SetWindowPos(
  141. NULL, nLeft, ctlRect.top - viewRect.top, 
  142. nWidth, viewRect.bottom - ctlRect.top - 5, SWP_SHOWWINDOW);
  143. }
  144. }
  145. //////////////////////////////////////////////////////////////////////////
  146. // 打开Wave文件,计算总帧数,并设置语音参数显示
  147. void CPlatformView::OnFileOpen()
  148. {
  149. // TODO: 在此添加命令处理程序代码
  150. CFileDialog dlg(TRUE, "*.wav");
  151. if (dlg.DoModal() == IDOK)
  152. {
  153. // 打开分析文件,设定回调方式
  154. this->m_strWaveFile = dlg.GetPathName();
  155. this->m_fileWaveOut.LoadFile(
  156. this->m_strWaveFile, (DWORD) this->GetSafeHwnd());
  157. // 设定控件显示
  158. // 默认显示时域波形
  159. this->m_displayType = DisplayWave;
  160. this->EnableControl(TRUE);
  161. this->EnableFrameControl();
  162. this->UpdateFrameControl(TRUE);
  163. }
  164. }
  165. void CPlatformView::OnBnClickedControlLoad()
  166. {
  167. // TODO: 在此添加控件通知处理程序代码
  168. this->OnFileOpen();
  169. }
  170. //////////////////////////////////////////////////////////////////////////
  171. // 显示参数设定对话框
  172. void CPlatformView::OnDisplayOption()
  173. {
  174. // 获取设置参数
  175. this->m_dlgSetting.m_fXMetrics = this->m_ctlDisplay.GetXMetrics();
  176. this->m_dlgSetting.m_fYMetrics = this->m_ctlDisplay.GetYMetrics();
  177. // TODO: 在此添加命令处理程序代码
  178. if (this->m_dlgSetting.DoModal() == IDOK)
  179. {
  180. // 设定每帧包含样本数
  181. if (this->m_nFrameSize != this->m_dlgSetting.m_nFrameSize)
  182. {
  183. this->m_nFrameSize = this->m_dlgSetting.m_nFrameSize;
  184. // 更新帧信息
  185. this->UpdateFrameControl(TRUE);
  186. }
  187. // 设定Y放大系数
  188. this->m_ctlDisplay.SetYMetrics(this->m_dlgSetting.m_fYMetrics);
  189. // 设定X放大系数
  190. this->m_ctlDisplay.SetXMetrics(this->m_dlgSetting.m_fXMetrics);
  191. // 设定显示精度
  192. this->m_ctlDisplay.SetPrecision(this->m_dlgSetting.m_nPrecision);
  193. // 设定显示微调系数
  194. this->m_ctlDisplay.SetZoomStep(this->m_dlgSetting.m_nZoomStep);
  195. // 刷新显示
  196. this->m_ctlDisplay.Invalidate();
  197. }
  198. }
  199. //////////////////////////////////////////////////////////////////////////
  200. // 播放控制函数,播放上一帧数据
  201. void CPlatformView::OnBnClickedControlPrevious()
  202. {
  203. // TODO: 在此添加控件通知处理程序代码
  204. // 发送指定帧
  205. if (this->m_nCurrentFrame > 1)
  206. {
  207. this->m_nCurrentFrame -- ;
  208. // 显示当前播放帧的参数信息
  209. this->UpdateDisplay(TRUE, 
  210. this->m_nCurrentFrame - 1, this->m_nCurrentFrame);
  211. // 显示帧数信息
  212. this->UpdateFrameControl();
  213. // 播放指定数据
  214. this->m_fileWaveOut.PlaySamples(
  215. (this->m_nCurrentFrame - 1) * this->m_nFrameSize, this->m_nFrameSize);
  216. }
  217. else
  218. {
  219. AfxMessageBox("已经是第1帧");
  220. }
  221. }
  222. //////////////////////////////////////////////////////////////////////////
  223. // 播放控制函数,播放下一帧数据
  224. void CPlatformView::OnBnClickedControlNext()
  225. {
  226. // TODO: 在此添加控件通知处理程序代码
  227. // 发送指定帧
  228. if (this->m_nCurrentFrame < this->m_nTotalFrames)
  229. {
  230. this->m_nCurrentFrame ++ ;
  231. // 显示当前播放帧的参数信息
  232. this->UpdateDisplay(TRUE, 
  233. this->m_nCurrentFrame - 1, this->m_nCurrentFrame);
  234. // 显示帧数信息
  235. this->UpdateFrameControl();
  236. // 播放指定数据
  237. this->m_fileWaveOut.PlaySamples(
  238. (this->m_nCurrentFrame - 1) * this->m_nFrameSize, this->m_nFrameSize);
  239. }
  240. else
  241. {
  242. AfxMessageBox("已经是最后帧");
  243. }
  244. }
  245. //////////////////////////////////////////////////////////////////////////
  246. // 播放控制函数,结束播放
  247. void CPlatformView::OnBnClickedControlStop()
  248. {
  249. // TODO: 在此添加控件通知处理程序代码
  250. // 停止当前播放
  251. this->m_fileWaveOut.Stop();
  252. // 设置控件
  253. this->EnableControl(FALSE);
  254. this->EnableFrameControl(FALSE, FALSE);
  255. // 清空显示
  256. this->m_ctlDisplay.LoadData(NULL, 0);
  257. }
  258. //////////////////////////////////////////////////////////////////////////
  259. // 播放控制函数,连续播放
  260. void CPlatformView::OnBnClickedControlPlay()
  261. {
  262. // TODO: 在此添加控件通知处理程序代码
  263. this->m_fileWaveOut.Start();
  264. }
  265. //////////////////////////////////////////////////////////////////////////
  266. // 显示类型为时域波形
  267. void CPlatformView::OnDisplayWave()
  268. {
  269. // TODO: 在此添加命令处理程序代码
  270. this->m_displayType = DisplayWave;
  271. // 显示当前播放帧的参数信息
  272. this->UpdateDisplay(TRUE, 
  273. this->m_nCurrentFrame - 1, this->m_nCurrentFrame);
  274. }
  275. //////////////////////////////////////////////////////////////////////////
  276. // 显示类型为短时过零率
  277. void CPlatformView::OnDisplayZero()
  278. {
  279. // TODO: 在此添加命令处理程序代码
  280. this->m_displayType = DisplayZero;
  281. // 显示当前播放帧的参数信息
  282. this->UpdateDisplay();
  283. }
  284. //////////////////////////////////////////////////////////////////////////
  285. // 显示类型为短时能量
  286. void CPlatformView::OnDisplayPower()
  287. {
  288. // TODO: 在此添加命令处理程序代码
  289. this->m_displayType = DisplayPower;
  290. // 显示当前播放帧的参数信息
  291. this->UpdateDisplay();
  292. }
  293. //////////////////////////////////////////////////////////////////////////
  294. // 显示类型为平均振幅
  295. void CPlatformView::OnDisplayVibration()
  296. {
  297. // TODO: 在此添加命令处理程序代码
  298. this->m_displayType = DisplayVibration;
  299. // 显示当前播放帧的参数信息
  300. this->UpdateDisplay();
  301. }
  302. //////////////////////////////////////////////////////////////////////////
  303. // 选择显示类型为时域波形
  304. void CPlatformView::OnUpdateDisplayWave(CCmdUI *pCmdUI)
  305. {
  306. // TODO: 在此添加命令更新用户界面处理程序代码
  307. pCmdUI->SetCheck(this->m_displayType == DisplayWave);
  308. }
  309. //////////////////////////////////////////////////////////////////////////
  310. // 选择显示类型为短时过零率
  311. void CPlatformView::OnUpdateDisplayZero(CCmdUI *pCmdUI)
  312. {
  313. // TODO: 在此添加命令更新用户界面处理程序代码
  314. pCmdUI->SetCheck(this->m_displayType == DisplayZero);
  315. }
  316. //////////////////////////////////////////////////////////////////////////
  317. // 选择显示类型为短时能量
  318. void CPlatformView::OnUpdateDisplayPower(CCmdUI *pCmdUI)
  319. {
  320. // TODO: 在此添加命令更新用户界面处理程序代码
  321. pCmdUI->SetCheck(this->m_displayType == DisplayPower);
  322. }
  323. //////////////////////////////////////////////////////////////////////////
  324. // 选择显示类型为平均振幅
  325. void CPlatformView::OnUpdateDisplayVibration(CCmdUI *pCmdUI)
  326. {
  327. // TODO: 在此添加命令更新用户界面处理程序代码
  328. pCmdUI->SetCheck(this->m_displayType == DisplayVibration);
  329. }
  330. //////////////////////////////////////////////////////////////////////////
  331. // 是否允许使用wav控制功能
  332. void CPlatformView::EnableControl(BOOL bEnabled /* = TRUE */)
  333. {
  334. CWnd* pWnd = NULL;
  335. CString strInfo;
  336. // 设置部分控件是否可用
  337. if (this->m_hWnd)
  338. {
  339. // 设定播放按钮
  340. pWnd = CWnd::GetDlgItem(IDC_CONTROL_PLAY);
  341. pWnd->EnableWindow(bEnabled);
  342. // 设定结束按钮
  343. pWnd = CWnd::GetDlgItem(IDC_CONTROL_STOP);
  344. pWnd->EnableWindow(bEnabled);
  345. // 设定显示全部时域波形按钮
  346. pWnd = CWnd::GetDlgItem(IDC_CONTROL_DISPLAYWAVE_ALL);
  347. pWnd->EnableWindow(bEnabled);
  348. // 若为打开文件,显示文件信息
  349. if (bEnabled)
  350. {
  351. // 获取文件格式信息
  352. WAVEFORMATEX fmt = this->m_fileWaveOut.m_wavFile.GetWaveFormat();
  353. // 显示文件格式信息
  354. strInfo.Format("分析文件:%srn采样频率:%drn声道数:%drn位数:%drn样本点数:%drn",
  355. this->m_strWaveFile,
  356. fmt.nSamplesPerSec,
  357. fmt.nChannels,
  358. fmt.wBitsPerSample,
  359. this->m_fileWaveOut.m_wavFile.GetSampleFramesCount()
  360. );
  361. CWnd::SetDlgItemText(IDC_EDIT_VOICEINFO, strInfo);
  362. }
  363. // 若为关闭文件,清空文件信息
  364. else
  365. {
  366. CWnd::SetDlgItemText(IDC_VOICE_INFO, "");
  367. CWnd::SetDlgItemText(IDC_EDIT_VOICEINFO, "");
  368. CWnd::SetDlgItemText(IDC_EDIT_RESULT, "");
  369. }
  370. }
  371. }
  372. //////////////////////////////////////////////////////////////////////////
  373. // 显示指定帧或全部裸音频数据的相应波形
  374. void CPlatformView::UpdateDisplay( 
  375.   BOOL bDisplayByFrame /* = FALSE */,  
  376.   unsigned int nFromFrame /* = 0 */,  
  377.   unsigned int nToFrame /* = 0   */)
  378. {
  379. // 裸音频的数据
  380. WAVEHDR waveHdr;
  381. waveHdr.lpData = NULL;
  382. // 待显示的数据
  383. double* pData = NULL;
  384. // 待显示得数据长度
  385. UINT nCount = 0;
  386. // wave裸音频数据长度
  387. unsigned int nRawCount = 0;
  388. // 用于数据转换的临时指针
  389. double* pTemp = NULL;
  390. // 获取裸音频的数据
  391. if (bDisplayByFrame)
  392. {
  393. if (nFromFrame < nToFrame)
  394. {
  395. this->m_fileWaveOut.GetSamples(
  396. &waveHdr, nFromFrame * this->m_nFrameSize, 
  397. (nToFrame - nFromFrame) * this->m_nFrameSize);
  398. }
  399. }
  400. else
  401. {
  402. this->m_fileWaveOut.GetSamples(&waveHdr, 0);
  403. }
  404. // 显示相应的波形
  405. if (waveHdr.lpData != NULL)
  406. {
  407. // 按输入音频格式进行数据转换
  408. // 进行8位数据的转换
  409. if (this->m_fileWaveOut.m_wavFile.GetWaveFormat().wBitsPerSample == 8)
  410. {
  411. // 计算原始数据长度
  412. nRawCount = waveHdr.dwBufferLength;
  413. pTemp = new double[nRawCount];
  414. CWaveConvertor::ConvertToDoubleMono(
  415. (byte*) waveHdr.lpData, waveHdr.dwBufferLength, pTemp);
  416. }
  417. // 进行16位数据转换
  418. else
  419. {
  420. // 计算原始数据长度
  421. nRawCount = waveHdr.dwBufferLength / 2;
  422. pTemp = new double[nRawCount];
  423. CWaveConvertor::ConvertToDoubleMono(
  424. (int*) waveHdr.lpData, waveHdr.dwBufferLength, pTemp);
  425. }
  426. // 按选定的显示方式进行数据转换
  427. switch (this->m_displayType)
  428. {
  429. // 显示时域波形
  430. case DisplayWave:
  431. // 显示加窗前时域波形
  432. case DisplayBeforeWindow:
  433. {
  434. pData = pTemp;
  435. nCount = nRawCount;
  436. // 上下帧可用
  437. this->EnableFrameControl();
  438. break;
  439. }
  440. // 显示加窗后时域波形
  441. case DisplayAfterWindow:
  442. {
  443. pData = pTemp;
  444. nCount = nRawCount;
  445. // 对输入数据进行加窗处理
  446. CSpeech::AddWindow(this->m_nFrameSize, pData, nCount);
  447. // 上下帧可用
  448. this->EnableFrameControl();
  449. break;
  450. }
  451. // 显示平均过零率
  452. case DisplayZero:
  453. {
  454. nCount = nRawCount / this->m_nFrameSize;
  455. pData = new double[nCount];
  456. // 对输入数据进行加窗处理
  457. CSpeech::AddWindow(this->m_nFrameSize, pData, nCount);
  458. // 获取平均过零率
  459. CSpeech::GetZero(
  460. this->m_nFrameSize, pTemp, nRawCount, pData);
  461. // 上下帧不可用
  462. this->EnableFrameControl(FALSE, FALSE);
  463. break;
  464. }
  465. // 显示短时能量
  466. case DisplayPower:
  467. {
  468. nCount = nRawCount / this->m_nFrameSize;
  469. pData = new double[nCount];
  470. // 对输入数据进行加窗处理
  471. CSpeech::AddWindow(this->m_nFrameSize, pData, nCount);
  472. // 获取短时能量
  473. CSpeech::GetEnergy(
  474. this->m_nFrameSize, pTemp, nRawCount, pData);
  475. // 上下帧不可用
  476. this->EnableFrameControl(FALSE, FALSE);
  477. break;
  478. }
  479. // 显示平均振幅
  480. case DisplayVibration:
  481. {
  482. nCount = nRawCount / this->m_nFrameSize;
  483. pData = new double[nCount];
  484. // 对输入数据进行加窗处理
  485. CSpeech::AddWindow(this->m_nFrameSize, pData, nCount);
  486. // 获取平均振幅
  487. CSpeech::GetAvgVibration(
  488. this->m_nFrameSize, pTemp, nRawCount, pData);
  489. // 上下帧不可用
  490. this->EnableFrameControl(FALSE, FALSE);
  491. break;
  492. }
  493. // 显示功率谱
  494. case DisplaySpectrum:
  495. {
  496. nCount = nRawCount;
  497. pData = new double[nCount];
  498. // 对输入数据进行加窗处理
  499. CSpeech::AddWindow(this->m_nFrameSize, pData, nCount);
  500. // 获取功率谱
  501. CWaveConvertor::ConvertToPowerSpectral(
  502. nRawCount, this->m_nFrameSize, pTemp, pData);
  503. // 上下帧可用
  504. this->EnableFrameControl();
  505. break;
  506. }
  507. // 显示对数功率谱
  508. case DisplayLogSpectrum:
  509. {
  510. nCount = nRawCount;
  511. pData = new double[nCount];
  512. // 对输入数据进行加窗处理
  513. CSpeech::AddWindow(this->m_nFrameSize, pData, nCount);
  514. // 获取对数功率谱
  515. CWaveConvertor::ConvertToLogPowerSpectral(
  516. nRawCount, this->m_nFrameSize, pTemp, pData);
  517. // 上下帧可用
  518. this->EnableFrameControl();
  519. break;
  520. }
  521. // 显示倒谱
  522. case DisplayCepstrum:
  523. {
  524. nCount = nRawCount;
  525. pData = new double[nCount];
  526. // 对输入数据进行加窗处理
  527. CSpeech::AddWindow(this->m_nFrameSize, pData, nCount);
  528. // 获取倒谱
  529. CWaveConvertor::ConvertToCepStrum(
  530. nRawCount, this->m_nFrameSize, pTemp, pData);
  531. // 上下帧可用
  532. this->EnableFrameControl();
  533. break;
  534. }
  535. }
  536. }
  537. // 显示相关信息
  538. this->UpdateResult(pData, nCount, this->m_displayType);
  539. // 显示数据
  540. this->m_ctlDisplay.LoadData(pData, nCount);
  541. if (pTemp != NULL)
  542. {
  543. delete[] pTemp;
  544. if (pData != pTemp && pData != NULL)
  545. {
  546. delete[] pData;
  547. }
  548. }
  549. }
  550. //////////////////////////////////////////////////////////////////////////
  551. // 更新帧数信息
  552. void CPlatformView::UpdateFrameControl( BOOL bReset /* = FALSE   */)
  553. {
  554. CString strInfo;
  555. // 是否重新计算帧数
  556. if (bReset)
  557. {
  558. // 获取文件格式信息
  559. WAVEFORMATEX fmt = this->m_fileWaveOut.m_wavFile.GetWaveFormat();
  560. // 计算总样本数
  561. this->m_nTotalFrames = 
  562. ceil((double) this->m_fileWaveOut.m_wavFile.GetSampleFramesCount() / this->m_nFrameSize);
  563. this->m_nCurrentFrame = 0;
  564. // 显示第一帧信息
  565. if (this->m_nTotalFrames > 0)
  566. {
  567. this->OnBnClickedControlNext();
  568. }
  569. }
  570. // 显示帧数信息
  571. strInfo.Format("每帧包含样本数: %dt可播放帧数: %dt当前播放帧: %d",
  572. this->m_nFrameSize,
  573. this->m_nTotalFrames, 
  574. this->m_nCurrentFrame);
  575. CWnd::SetDlgItemText(IDC_VOICE_INFO, strInfo);
  576. }
  577. //////////////////////////////////////////////////////////////////////////
  578. // 按帧查看是否可用
  579. void CPlatformView::EnableFrameControl( BOOL bPre /* = TRUE */,  BOOL bNext /* = TRUE   */)
  580. {
  581. CWnd* pWnd = NULL;
  582. // 设定上一帧按钮是否可用
  583. pWnd = CWnd::GetDlgItem(IDC_CONTROL_PREVIOUS);
  584. pWnd->EnableWindow(bPre);
  585. // 设定下一帧按钮是否可用
  586. pWnd = CWnd::GetDlgItem(IDC_CONTROL_NEXT);
  587. pWnd->EnableWindow(bNext);
  588. }
  589. //////////////////////////////////////////////////////////////////////////
  590. // Y放大倍数 *10
  591. void CPlatformView::OnDisplayZoomin()
  592. {
  593. // TODO: 在此添加命令处理程序代码
  594. // 设定Y放大系数
  595. this->m_dlgSetting.m_fYMetrics *= 10;
  596. this->m_ctlDisplay.SetYMetrics(this->m_dlgSetting.m_fYMetrics);
  597. // 刷新波形显示
  598. this->m_ctlDisplay.Invalidate();
  599. }
  600. //////////////////////////////////////////////////////////////////////////
  601. // Y放大倍数 /10
  602. void CPlatformView::OnDisplayZoomout()
  603. {
  604. // TODO: 在此添加命令处理程序代码
  605. // 设定Y放大系数
  606. this->m_dlgSetting.m_fYMetrics /= 10;
  607. this->m_ctlDisplay.SetYMetrics(this->m_dlgSetting.m_fYMetrics);
  608. // 刷新波形显示
  609. this->m_ctlDisplay.Invalidate();
  610. }
  611. //////////////////////////////////////////////////////////////////////////
  612. // 显示类型为功率谱
  613. void CPlatformView::OnDisplaySpectrum()
  614. {
  615. // TODO: 在此添加命令处理程序代码
  616. this->m_displayType = DisplaySpectrum;
  617. // 显示当前播放帧的参数信息
  618. this->UpdateDisplay(TRUE, 
  619. this->m_nCurrentFrame - 1, this->m_nCurrentFrame);
  620. }
  621. //////////////////////////////////////////////////////////////////////////
  622. // 选择显示类型为功率谱
  623. void CPlatformView::OnUpdateDisplaySpectrum(CCmdUI *pCmdUI)
  624. {
  625. // TODO: 在此添加命令更新用户界面处理程序代码
  626. pCmdUI->SetCheck(this->m_displayType == DisplaySpectrum);
  627. }
  628. //////////////////////////////////////////////////////////////////////////
  629. // 显示类型为对数功率谱
  630. void CPlatformView::OnDisplayLogspectrum()
  631. {
  632. // TODO: 在此添加命令处理程序代码
  633. this->m_displayType = DisplayLogSpectrum;
  634. // 显示当前播放帧的参数信息
  635. this->UpdateDisplay(TRUE, 
  636. this->m_nCurrentFrame - 1, this->m_nCurrentFrame);
  637. }
  638. //////////////////////////////////////////////////////////////////////////
  639. // 选择显示类型为对数功率谱
  640. void CPlatformView::OnUpdateDisplayLogspectrum(CCmdUI *pCmdUI)
  641. {
  642. // TODO: 在此添加命令更新用户界面处理程序代码
  643. pCmdUI->SetCheck(this->m_displayType == DisplayLogSpectrum);
  644. }
  645. //////////////////////////////////////////////////////////////////////////
  646. // 显示类型为倒谱
  647. void CPlatformView::OnDisplayCepstrum()
  648. {
  649. // TODO: 在此添加命令处理程序代码
  650. this->m_displayType = DisplayCepstrum;
  651. // 显示当前播放帧的参数信息
  652. this->UpdateDisplay(TRUE, 
  653. this->m_nCurrentFrame - 1, this->m_nCurrentFrame);
  654. }
  655. //////////////////////////////////////////////////////////////////////////
  656. // 选择显示类型为倒谱
  657. void CPlatformView::OnUpdateDisplayCepstrum(CCmdUI *pCmdUI)
  658. {
  659. // TODO: 在此添加命令更新用户界面处理程序代码
  660. pCmdUI->SetCheck(this->m_displayType == DisplayCepstrum);
  661. }
  662. //////////////////////////////////////////////////////////////////////////
  663. // 进行显示微调
  664. BOOL CPlatformView::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
  665. {
  666. // TODO: 在此添加消息处理程序代码和/或调用默认值
  667. return this->m_ctlDisplay.OnMouseWheel(nFlags, zDelta, pt);
  668. }
  669. //////////////////////////////////////////////////////////////////////////
  670. // 显示全部时域波形
  671. void CPlatformView::OnBnClickedControlDisplaywaveAll()
  672. {
  673. // TODO: 在此添加控件通知处理程序代码
  674. this->m_displayType = DisplayWave;
  675. this->UpdateDisplay();
  676. }
  677. // 显示波形的相应信息
  678. void CPlatformView::UpdateResult(
  679.  double* pData, // 显示数据
  680.  unsigned int nCount, // 显示数据数量
  681.  DisplayType disType // 显示类型
  682.  )
  683. {
  684. // 格式化输出
  685. CString strFormat;
  686. // 清空原来的显示
  687. this->m_strResult = "";
  688. CWnd::UpdateData(FALSE);
  689. // 循环变量, ugly vc
  690. unsigned int i = 0;
  691. if (pData != NULL)
  692. {
  693. // 根据显示类型设置相应的信息
  694. switch (disType)
  695. {
  696. // 显示时域波形
  697. case DisplayWave:
  698. {
  699. break;
  700. }
  701. // 显示平均过零率
  702. case DisplayZero:
  703. {
  704. // 显示每帧的过零率信息
  705. for (i = 0; i < nCount; i ++)
  706. {
  707. strFormat.Format("第%d帧的平均过零率: %frn", i, pData[i]);
  708. this->m_strResult += strFormat;
  709. }
  710. break;
  711. }
  712. // 显示短时能量
  713. case DisplayPower:
  714. {
  715. // 显示每帧的短时能量信息
  716. for (i = 0; i < nCount; i ++)
  717. {
  718. strFormat.Format("第%d帧的短时能量: %frn", i, pData[i]);
  719. this->m_strResult += strFormat;
  720. }
  721. break;
  722. }
  723. // 显示平均振幅
  724. case DisplayVibration:
  725. {
  726. // 显示每帧的平均振幅信息
  727. for (i = 0; i < nCount; i ++)
  728. {
  729. strFormat.Format("第%d帧的平均振幅: %frn", i, pData[i]);
  730. this->m_strResult += strFormat;
  731. }
  732. break;
  733. }
  734. // 显示功率谱
  735. case DisplaySpectrum:
  736. {
  737. break;
  738. }
  739. // 显示对数功率谱
  740. case DisplayLogSpectrum:
  741. {
  742. break;
  743. }
  744. // 显示倒谱
  745. case DisplayCepstrum:
  746. {
  747. break;
  748. }
  749. }
  750. // 显示相关信息
  751. CWnd::UpdateData(FALSE);
  752. }
  753. }
  754. //////////////////////////////////////////////////////////////////////////
  755. // 显示端点检测图形
  756. void CPlatformView::OnSectionEnd()
  757. {
  758. // TODO: 在此添加命令处理程序代码
  759. WAVEHDR waveHdr;
  760. waveHdr.lpData = NULL;
  761. double* pRawData = NULL;
  762. unsigned int nDataLen = 0;
  763. // 原始数据是否已经设定
  764. this->m_fileWaveOut.GetSamples(&waveHdr, 0);
  765. if (waveHdr.lpData != NULL)
  766. {
  767. // 获取原始数据
  768. // 进行8位数据的转换
  769. if (this->m_fileWaveOut.m_wavFile.GetWaveFormat().wBitsPerSample == 8)
  770. {
  771. // 计算数据长度
  772. nDataLen = waveHdr.dwBufferLength;
  773. pRawData = new double[nDataLen];
  774. CWaveConvertor::ConvertToDoubleMono(
  775. (byte*) waveHdr.lpData, waveHdr.dwBufferLength, pRawData);
  776. }
  777. // 进行16位数据转换
  778. else
  779. {
  780. // 计算数据长度
  781. nDataLen = waveHdr.dwBufferLength / 2;
  782. pRawData = new double[nDataLen];
  783. CWaveConvertor::ConvertToDoubleMono(
  784. (int*) waveHdr.lpData, waveHdr.dwBufferLength, pRawData);
  785. }
  786. // 对输入数据进行加窗处理
  787. // CSpeech::AddWindow(this->m_nFrameSize, pRawData, nDataLen);
  788. // 设定显示数据
  789. this->m_dlgSection.SetDisplayData(
  790. pRawData, nDataLen, this->m_nFrameSize, SectionEnd);
  791. }
  792. this->m_dlgSection.DoModal();
  793. this->m_dlgSection.ReleaseData();
  794. }
  795. //////////////////////////////////////////////////////////////////////////
  796. // 显示声韵切割图形
  797. void CPlatformView::OnSectionSy()
  798. {
  799. // TODO: 在此添加命令处理程序代码
  800. //WAVEHDR waveHdr;
  801. //waveHdr.lpData = NULL;
  802. //double* pRowData = NULL;
  803. //double* pSectionData = NULL;
  804. //double* pTemp = NULL;
  805. //unsigned int nDataLen = 0;
  806. //// 原始数据是否已经设定
  807. //this->m_fileWaveOut.GetSamples(
  808. // 0, this->m_nTotalFrames * this->m_nFrameSize, &waveHdr);
  809. //if (waveHdr.lpData != NULL)
  810. //{
  811. // // 获取原始数据
  812. // // 进行8位数据的转换
  813. // if (this->m_fileWaveOut.m_wavFile.GetWaveFormat().wBitsPerSample == 8)
  814. // {
  815. // // 计算数据长度
  816. // nDataLen = waveHdr.dwBufferLength;
  817. // pRowData = new double[nDataLen];
  818. // CWaveConvertor::ConvertToDoubleMono(
  819. // (byte*) waveHdr.lpData, waveHdr.dwBufferLength, pRowData);
  820. // }
  821. // // 进行16位数据转换
  822. // else
  823. // {
  824. // // 计算数据长度
  825. // nDataLen = waveHdr.dwBufferLength / 2;
  826. // pRowData = new double[nDataLen];
  827. // CWaveConvertor::ConvertToDoubleMono(
  828. // (int*) waveHdr.lpData, waveHdr.dwBufferLength, pRowData);
  829. // }
  830. // // 设定显示数据
  831. // this->m_dlgSection.SetDisplayData(
  832. // pTemp, nDataLen, this->m_nFrameSize, SectionSY);
  833. //}
  834. //this->m_dlgSection.DoModal();
  835. //this->m_dlgSection.ReleaseData();
  836. }
  837. //////////////////////////////////////////////////////////////////////////
  838. // 显示K-Means VQ结果
  839. void CPlatformView::OnVqKmeans()
  840. {
  841. // TODO: 在此添加命令处理程序代码
  842. WAVEHDR waveHdr;
  843. waveHdr.lpData = NULL;
  844. double* pRawData = NULL;
  845. double* pTemp = NULL;
  846. unsigned int nDataLen = 0;
  847. // 原始数据是否已经设定
  848. this->m_fileWaveOut.GetSamples(&waveHdr, 0);
  849. if (waveHdr.lpData != NULL)
  850. {
  851. // 获取原始数据
  852. // 进行8位数据的转换
  853. if (this->m_fileWaveOut.m_wavFile.GetWaveFormat().wBitsPerSample == 8)
  854. {
  855. // 计算数据长度
  856. nDataLen = waveHdr.dwBufferLength;
  857. pTemp = new double[nDataLen];
  858. CWaveConvertor::ConvertToDoubleMono(
  859. (byte*) waveHdr.lpData, waveHdr.dwBufferLength, pTemp);
  860. }
  861. // 进行16位数据转换
  862. else
  863. {
  864. // 计算数据长度
  865. nDataLen = waveHdr.dwBufferLength / 2;
  866. pTemp = new double[nDataLen];
  867. CWaveConvertor::ConvertToDoubleMono(
  868. (int*) waveHdr.lpData, waveHdr.dwBufferLength, pTemp);
  869. }
  870. // 对输入数据进行加窗处理
  871. CSpeech::AddWindow(this->m_nFrameSize, pTemp, nDataLen);
  872. // 计算LPC倒谱
  873. pRawData = new double[nDataLen];
  874. CWaveConvertor::ConvertToCepStrum(
  875. nDataLen, this->m_nFrameSize, pTemp, pRawData);
  876. // 设定显示数据
  877. this->m_dlgCluster.LoadRawData(pRawData, nDataLen);
  878. }
  879. this->m_dlgCluster.DoModal();
  880. if (pRawData != NULL)
  881. {
  882. delete[] pRawData;
  883. }
  884. if (pTemp != NULL)
  885. {
  886. delete[] pTemp;
  887. }
  888. }
  889. //////////////////////////////////////////////////////////////////////////
  890. // 添加HMM模型
  891. void CPlatformView::OnHmmAddmodel()
  892. {
  893. // TODO: 在此添加命令处理程序代码
  894. CAddModelDlg dlg;
  895. dlg.DoModal();
  896. }
  897. //////////////////////////////////////////////////////////////////////////
  898. // 训练HMM模型
  899. void CPlatformView::OnHmmTrainmodel()
  900. {
  901. // TODO: 在此添加命令处理程序代码
  902. CTrainModelDlg dlg;
  903. dlg.DoModal();
  904. }
  905. //////////////////////////////////////////////////////////////////////////
  906. // HMM数字识别演示
  907. void CPlatformView::OnHmmDemo()
  908. {
  909. // TODO: 在此添加命令处理程序代码
  910. CDemoHMMDlg dlg;
  911. dlg.DoModal();
  912. }
  913. //////////////////////////////////////////////////////////////////////////
  914. // 显示加窗后时域波形
  915. void CPlatformView::OnDisplayAfterwindow()
  916. {
  917. // TODO: 在此添加命令处理程序代码
  918. this->m_displayType = DisplayAfterWindow;
  919. // 显示当前播放帧的参数信息
  920. this->UpdateDisplay(TRUE, 
  921. this->m_nCurrentFrame - 1, this->m_nCurrentFrame);
  922. }
  923. //////////////////////////////////////////////////////////////////////////
  924. // 设定显示未加窗前时域波形
  925. void CPlatformView::OnUpdateDisplayBeforewindow(CCmdUI *pCmdUI)
  926. {
  927. // TODO: 在此添加命令更新用户界面处理程序代码
  928. pCmdUI->SetCheck(this->m_displayType == DisplayBeforeWindow);
  929. }
  930. //////////////////////////////////////////////////////////////////////////
  931. // 设定显示加窗后时域波形
  932. void CPlatformView::OnUpdateDisplayAfterwindow(CCmdUI *pCmdUI)
  933. {
  934. // TODO: 在此添加命令更新用户界面处理程序代码
  935. pCmdUI->SetCheck(this->m_displayType == DisplayAfterWindow);
  936. }
  937. //////////////////////////////////////////////////////////////////////////
  938. // 显示加窗前时域波形
  939. void CPlatformView::OnDisplayBeforewindow()
  940. {
  941. // TODO: 在此添加命令处理程序代码
  942. this->m_displayType = DisplayBeforeWindow;
  943. // 显示当前播放帧的参数信息
  944. this->UpdateDisplay(TRUE, 
  945. this->m_nCurrentFrame - 1, this->m_nCurrentFrame);
  946. }