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

控制台编程

开发平台:

C/C++

  1. #include "StdAfx.h"
  2. #include ".largefilewaveout.h"
  3. CLargeFileWaveOut::CLargeFileWaveOut(void)
  4. {
  5. // 设置默认属性
  6. this->m_nBufferNums = LARGEWAVEOUT_BUFFER_NUMS;
  7. this->m_pNextBuffer = NULL;
  8. this->m_pAllocBuffer = NULL;
  9. this->m_nBufferNums = 0;
  10. this->m_nSamplesPerBlock = LARGEWAVEOUT_SAMPLES_PER_BLOCK;
  11. this->m_dwBufferSize = 0;
  12. }
  13. CLargeFileWaveOut::~CLargeFileWaveOut(void)
  14. {
  15. this->Stop();
  16. }
  17. //////////////////////////////////////////////////////////////////////////
  18. // 打开输出设备,设置回调方式,并分配播放缓冲和读入部分数据
  19. BOOL CLargeFileWaveOut::Init(WAVEFORMATEX fmt, DWORD hWnd)
  20. {
  21. // 打开输出设备,设置回调方式
  22. BOOL bRet = CFileWaveOut::Init(fmt, hWnd);
  23. // 读取字节数
  24. UINT nRead = 0;
  25. // 分配缓存区结构
  26. if (bRet)
  27. {
  28. this->m_pAllocBuffer = new WAVEHDR[this->m_nBufferNums];
  29. this->m_pNextBuffer = this->m_pAllocBuffer;
  30. // 分配缓冲块
  31. if (this->m_pAllocBuffer != NULL)
  32. {
  33. for (unsigned int i = 0; i < this->m_nBufferNums; i++)
  34. {
  35. this->m_pAllocBuffer[i].lpData = new char[this->m_dwBufferSize];
  36. this->m_pAllocBuffer[i].lpNext = NULL;
  37. this->m_pAllocBuffer[i].dwBufferLength = 0;
  38. if (this->m_pAllocBuffer[i].lpData != NULL && 
  39. ! this->m_wavFile.IsEOF())
  40. {
  41. // 获取实际读取得byte数
  42. nRead = this->m_wavFile.ReadBytes(
  43. this->m_pAllocBuffer[i].lpData, this->m_dwBufferSize);
  44. // 填写缓冲块格式信息
  45. this->m_pAllocBuffer[i].dwBufferLength = nRead;
  46. this->m_pAllocBuffer[i].dwBytesRecorded = 0;
  47. this->m_pAllocBuffer[i].dwFlags = 0;
  48. this->m_pAllocBuffer[i].dwLoops = 0;
  49. this->m_pAllocBuffer[i].dwUser = 0;
  50. // 预制缓冲块
  51. waveOutPrepareHeader(this->m_hWaveOut, 
  52. &this->m_pAllocBuffer[i], sizeof(WAVEHDR));
  53. }
  54. }
  55. }
  56. }
  57. return bRet;
  58. }
  59. //////////////////////////////////////////////////////////////////////////
  60. // 设置缓冲块数量
  61. void CLargeFileWaveOut::SetBufferNums(UINT nCount)
  62. {
  63. this->m_nBufferNums = nCount;
  64. }
  65. //////////////////////////////////////////////////////////////////////////
  66. // 处理WOM_DONE消息,继续播放下一个缓冲块
  67. LRESULT CLargeFileWaveOut::OnDone(DWORD dwParam)
  68. {
  69. WAVEHDR* pTempHdr = (WAVEHDR*) dwParam; // 播放完的缓冲块
  70. UINT nRead = 0;
  71. // 已播放的缓冲块标记长度为0,用于标记已经播放
  72. pTempHdr->dwBufferLength = 0;
  73. // 确定待播放的缓冲块,类似使用循环队列
  74. if (this->m_pNextBuffer - this->m_pAllocBuffer >= this->m_nBufferNums)
  75. {
  76. this->m_pNextBuffer = this->m_pAllocBuffer;
  77. }
  78. // 若要播放的缓冲块未播放过,则播放此缓冲块
  79. if (this->m_pNextBuffer->dwBufferLength > 0)
  80. {
  81. waveOutWrite(this->m_hWaveOut, this->m_pNextBuffer, sizeof(WAVEHDR));
  82. this->m_pNextBuffer ++;
  83. // 若文件未读取完毕,从文件载入下一个缓冲块,装入已播放缓冲块中
  84. if (! this->m_wavFile.IsEOF())
  85. {
  86. nRead = this->m_wavFile.ReadBytes(pTempHdr->lpData, this->m_dwBufferSize);
  87. // 填写缓冲块信息
  88. pTempHdr->dwBufferLength = nRead;
  89. pTempHdr->dwBytesRecorded = 0;
  90. pTempHdr->dwFlags = 0;
  91. pTempHdr->dwLoops = 0;
  92. pTempHdr->dwUser = 0;
  93. }
  94. }
  95. // 所有缓冲块都已经播放完毕,停止播放
  96. else
  97. {
  98. this->Stop();
  99. }
  100. return 0;
  101. }
  102. //////////////////////////////////////////////////////////////////////////
  103. // 设定缓冲块大小
  104. void CLargeFileWaveOut::SetSamplesPerBlock(UINT nSamplesCount)
  105. {
  106. this->m_nSamplesPerBlock = nSamplesCount;
  107. }
  108. //////////////////////////////////////////////////////////////////////////
  109. // 清除缓冲区,初始化数据
  110. void CLargeFileWaveOut::Dispose()
  111. {
  112. // 释放播放文件分配的缓存
  113. if (this->m_pAllocBuffer != NULL)
  114. {
  115. // 释放所有缓冲块
  116. for (unsigned int i = 0; i < this->m_nBufferNums; i++)
  117. {
  118. this->m_pNextBuffer = &this->m_pAllocBuffer[i];
  119. if (this->m_pNextBuffer->lpData != NULL)
  120. {
  121. delete[] this->m_pNextBuffer->lpData;
  122. }
  123. }
  124. // 删除缓冲结构
  125. delete[] this->m_pAllocBuffer;
  126. }
  127. this->m_pAllocBuffer = NULL;
  128. this->m_pNextBuffer = NULL;
  129. // 重置CWaveOut数据
  130. CWaveOut::Dispose();
  131. }
  132. //////////////////////////////////////////////////////////////////////////
  133. // 开始播放音频逻数据,发送第一个缓冲块
  134. void CLargeFileWaveOut::Start()
  135. {
  136. if (this->m_pAllocBuffer != NULL)
  137. {
  138. CWaveOut::Start();
  139. // 发送第一个缓冲块
  140. this->m_pNextBuffer = this->m_pAllocBuffer + 1;
  141. waveOutWrite(this->m_hWaveOut, this->m_pAllocBuffer, sizeof(WAVEHDR));
  142. }
  143. }
  144. //////////////////////////////////////////////////////////////////////////
  145. // 停止播放,关闭输出设备, UnPrepare所用到的缓冲块
  146. void CLargeFileWaveOut::Stop()
  147. {
  148. // 停止播放
  149. CWaveOut::Stop();
  150. // UnPrepare所有缓冲块
  151. for (unsigned int i = 0; i < this->m_nBufferNums; i++)
  152. {
  153. this->m_pNextBuffer = &this->m_pAllocBuffer[i];
  154. waveOutUnprepareHeader(
  155. this->m_hWaveOut, this->m_pNextBuffer, sizeof(WAVEHDR));
  156. }
  157. // 关闭输出设备
  158. CWaveOut::CloseDev();
  159. // 清除缓冲区,初始化数据
  160. this->Dispose();
  161. }