KLMp3Music.cpp
上传用户:dzyhzl
上传日期:2019-04-29
资源大小:56270k
文件大小:7k
源码类别:

模拟服务器

开发平台:

C/C++

  1. //---------------------------------------------------------------------------
  2. // Sword3 Engine (c) 1999-2000 by Kingsoft
  3. //
  4. // File: KLMp3Music.cpp
  5. // Date: 2000.08.08
  6. // Code: Daniel Wang
  7. // Desc: MP3 Stream Music Class
  8. //---------------------------------------------------------------------------
  9. #include <stdafx.h>
  10. #include "mp3lib.h"
  11. #include "KLMp3Music.h"
  12. //---------------------------------------------------------------------------
  13. #define MP3_BUFSIZE  60000 // mp3 data buffer
  14. //---------------------------------------------------------------------------
  15. // 函数: Open
  16. // 功能: 打开音乐文件
  17. // 参数: FileName 文件名
  18. // 返回: TRUE-成功 FALSE-失败
  19. //---------------------------------------------------------------------------
  20. BOOL KLMp3Music::Open(LPSTR FileName)
  21. {
  22. if (m_pSoundBuffer)
  23. Close();
  24. if (!Mp3FileOpen(FileName))
  25. return FALSE;
  26. if (!Mp3Init())
  27. return FALSE;
  28. return Init();
  29. }
  30. void KLMp3Music::Close()
  31. {
  32. KLMusic::Close();
  33. SAFE_DELETE_ARRAY(mp3_buffer);
  34. }
  35. //---------------------------------------------------------------------------
  36. // 函数: InitSoundFormat
  37. // 功能:
  38. // 参数: void
  39. // 返回: void
  40. //---------------------------------------------------------------------------
  41. void KLMp3Music::InitSoundFormat()
  42. {
  43. // align buffer size with mp3 frame 4608
  44. m_dwBufferSize = m_WaveFormat.nAvgBytesPerSec;
  45. m_dwBufferSize = (m_dwBufferSize + 4607) / 4608 * 4608;
  46. // 2 second sound buffer
  47. m_dwBufferSize *= 2;
  48. }
  49. //---------------------------------------------------------------------------
  50. // 函数: ReadWaveData
  51. // 功能: 读取波形数据
  52. // 参数: lpBuf 缓存
  53. // dwLen 长度
  54. // 返回: DWORD 实际读取的长度
  55. //---------------------------------------------------------------------------
  56. DWORD KLMp3Music::ReadWaveData(LPBYTE lpBuf, DWORD dwLen)
  57. {
  58. return Mp3Decode(lpBuf, dwLen);
  59. }
  60. //---------------------------------------------------------------------------
  61. // 函数: Seek
  62. // 功能:
  63. // 参数: void
  64. // 返回: void
  65. //---------------------------------------------------------------------------
  66. void KLMp3Music::Seek(int nPercent)
  67. {
  68. }
  69. //---------------------------------------------------------------------------
  70. // 函数: Rewind
  71. // 功能: 从头播放音乐
  72. // 参数: void
  73. // 返回: void
  74. //---------------------------------------------------------------------------
  75. void KLMp3Music::Rewind()
  76. {
  77. Mp3FileSeek(0);
  78. mp3_bufbytes = 0;
  79. }
  80. //---------------------------------------------------------------------------
  81. // 函数: Mp3FileOpen
  82. // 功能:
  83. // 参数: FileName
  84. // 返回: BOOL
  85. //---------------------------------------------------------------------------
  86. BOOL KLMp3Music::Mp3FileOpen(LPSTR FileName)
  87. {
  88. return m_Mp3File.Open(FileName);
  89. }
  90. //---------------------------------------------------------------------------
  91. // 函数: Mp3FileRead
  92. // 功能:
  93. // 参数: pBuf
  94. // dwlen
  95. // 返回: void
  96. //---------------------------------------------------------------------------
  97. DWORD KLMp3Music::Mp3FileRead(PBYTE pBuf, DWORD dwLen)
  98. {
  99. return m_Mp3File.Read(pBuf, dwLen);
  100. }
  101. //---------------------------------------------------------------------------
  102. // 函数: Mp3FileSeek
  103. // 功能:
  104. // 参数: lOffset
  105. // 返回: void
  106. //---------------------------------------------------------------------------
  107. DWORD KLMp3Music::Mp3FileSeek(LONG lOffset)
  108. {
  109. return m_Mp3File.Seek(lOffset, FILE_BEGIN);
  110. }
  111. //---------------------------------------------------------------------------
  112. // 函数: Mp3Init
  113. // 功能: 初始化MP3文件
  114. // 参数: void
  115. // 返回: void
  116. //---------------------------------------------------------------------------
  117. BOOL KLMp3Music::Mp3Init()
  118. {
  119. MPEG_HEAD mpeg_head;
  120. DEC_INFO  dec_info;
  121. // reduction_code: sample rate reduction code
  122. // 0 = full rate
  123. // 1 = half rate
  124. // 2 = quarter rate
  125. int reduction_code = 0;
  126. // transform_code: ignored
  127. int transform_code = 0;
  128. // convert_code: channel conversion
  129. // 0 = two chan output
  130. // 1 = convert two chan to mono
  131. // 2 = convert two chan to left chan
  132. // 3 = convert two chan to right chan
  133. int convert_code = 0;
  134. // freq_limit: limits bandwidth of pcm output to specified
  135. // frequency. Special use. Set to 24000 for normal use.
  136. int freq_limit = 24000;
  137. // alloc mp3 stream buffer
  138. mp3_buffer = new BYTE[MP3_BUFSIZE];
  139. if(!mp3_buffer)
  140. return FALSE;
  141. // init mp3 buffer
  142. mp3_bufbytes = 0;
  143. mp3_bufptr = mp3_buffer;
  144. mp3_trigger = 2500;
  145. // seek to begin of mp3 file
  146. Mp3FileSeek(0);
  147. // fill mp3 buffer
  148. if (!Mp3FillBuffer())
  149. return FALSE;
  150. // parse mpeg header
  151. mp3_frmbytes = mp3_decode_head(mp3_buffer, &mpeg_head);
  152. if (mp3_frmbytes == 0)
  153. {
  154. return FALSE;
  155. }
  156. // init mp3 decoder
  157. if (!mp3_decode_init(&mpeg_head, mp3_frmbytes,
  158. reduction_code, transform_code, convert_code, freq_limit))
  159. {
  160. return FALSE;
  161. }
  162. // get mp3 info
  163. mp3_decode_info(&dec_info);
  164. // set pcm wave format
  165. m_WaveFormat.wFormatTag  = WAVE_FORMAT_PCM;
  166. m_WaveFormat.nChannels  = dec_info.channels;
  167. m_WaveFormat.nSamplesPerSec  = dec_info.samprate;
  168. m_WaveFormat.nAvgBytesPerSec = (dec_info.channels * dec_info.samprate * dec_info.bits + 7) / 8;
  169. m_WaveFormat.nBlockAlign  = (dec_info.channels * dec_info.bits + 7) / 8;
  170. m_WaveFormat.wBitsPerSample  = dec_info.bits;
  171. m_WaveFormat.cbSize  = 0;
  172. return TRUE;
  173. }
  174. //---------------------------------------------------------------------------
  175. // 函数: Mp3Decode
  176. // 功能: 解码MP3
  177. // 参数: lpPcmBuf PCM buffer pointer
  178. // dwBufLen buffer size in bytes
  179. // 返回: void
  180. //---------------------------------------------------------------------------
  181. DWORD KLMp3Music::Mp3Decode(PBYTE lpPcmBuf, DWORD dwBufLen)
  182. {
  183. PBYTE pcm_buffer = lpPcmBuf;
  184. int pcm_trigger = dwBufLen;
  185. int pcm_bufbytes = 0;
  186. IN_OUT res = {0, 0};
  187. while (TRUE)
  188. {
  189. // fill mp3 buffer
  190. if (!Mp3FillBuffer())
  191. break;
  192. // end of mp3 file
  193. if (mp3_bufbytes < mp3_frmbytes)
  194. break;
  195. // decode one frame to pcm buffer
  196. res = mp3_decode_frame(mp3_bufptr, pcm_buffer);
  197. if (res.in_bytes <= 0)
  198. {
  199. break;
  200. }
  201. // update buffer pointer and buffer size
  202. mp3_bufptr += res.in_bytes;
  203. mp3_bufbytes -= res.in_bytes;
  204. pcm_buffer += res.out_bytes;
  205. pcm_bufbytes += res.out_bytes;
  206. // is pcm buffer full
  207. if (pcm_bufbytes >= pcm_trigger)
  208. break;
  209. }
  210. return pcm_bufbytes;
  211. }
  212. //---------------------------------------------------------------------------
  213. // 函数: Mp3FillBuffer
  214. // 功能:
  215. // 参数: void
  216. // 返回: void
  217. //---------------------------------------------------------------------------
  218. BOOL KLMp3Music::Mp3FillBuffer()
  219. {
  220. DWORD dwRead;
  221. // signed var could be negative
  222. if (mp3_bufbytes < 0)
  223. mp3_bufbytes = 0;
  224. // read mp3 data to buffer
  225. if (mp3_bufbytes < mp3_trigger)
  226. {
  227. memmove(mp3_buffer, mp3_bufptr, mp3_bufbytes);
  228. dwRead = Mp3FileRead(mp3_buffer + mp3_bufbytes, 
  229. MP3_BUFSIZE - mp3_bufbytes);
  230. mp3_bufbytes += dwRead;
  231. mp3_bufptr = mp3_buffer;
  232. }
  233. return TRUE;
  234. }
  235. //---------------------------------------------------------------------------