AudioDecoderMP3.cpp
上传用户:tuheem
上传日期:2007-05-01
资源大小:21889k
文件大小:5k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. /**************************************************************************************
  2.  *                                                                                    *
  3.  *                                                                                    *
  4.  **************************************************************************************/
  5. #include "AudioDecoderMP3.h"
  6. /*
  7.  * ACM封装器
  8.  *
  9.  */
  10. MediaAudioDecoderMP3::MediaAudioDecoderMP3()
  11. {
  12. this->oFormat     = NULL;
  13. this->out_buffer  = NULL;
  14. this->in_buffer   = NULL;
  15. }
  16. MediaAudioDecoderMP3::~MediaAudioDecoderMP3()
  17. {
  18. }
  19. /*
  20.  * MP3解码封装器
  21.  *
  22.  */
  23. int MediaAudioDecoderMP3::DecompressMp3(char *outmemory, int outmemsize, int *done)
  24. {
  25. if(this->last_result == MP3_OK) {
  26. this->last_result = decodeMP3(&this->mp, NULL, 0, outmemory, outmemsize, done);
  27.     
  28.     if(this->last_result == MP3_NEED_MORE) {
  29.      
  30.       if( this->decaps->ReadAudioData(0, this->in_buffer, 16384) == 16384) {
  31.   this->last_result = decodeMP3(&this->mp, (char *) this->in_buffer, 16384, outmemory, outmemsize, done);
  32.   return 1;
  33.       }
  34.       else {
  35.   return 0;
  36.       }
  37.     }
  38.     else {
  39.       return 1;
  40.     }
  41.   }
  42.   else {
  43.     
  44.     if( this->decaps->ReadAudioData(0, this->in_buffer, 16384) == 16384) {
  45.       this->last_result = decodeMP3(&this->mp, (char *) this->in_buffer, 16384, outmemory, outmemsize, done);
  46.       return 1;
  47.     }
  48.     else {
  49.       
  50.       return 0;
  51.     }
  52.   }
  53. }
  54. /*
  55.  * 媒体项方法
  56.  */
  57. media_type_t  MediaAudioDecoderMP3::GetType()
  58. {
  59. return MEDIA_TYPE_AUDIO_DECODER;
  60. }
  61. char         *MediaAudioDecoderMP3::GetName()
  62. {
  63. /*
  64.  * 更新!
  65.  */
  66. return "MPEG-1 Layer III Audio Decoder";
  67. }
  68. MP_RESULT     MediaAudioDecoderMP3::Connect(MediaItem *item)
  69. {
  70. WAVEFORMATEX *inFormat;
  71. if(item && item->GetType() == MEDIA_TYPE_DECAPS) {
  72. this->decaps = (MediaItemDecaps *) item;
  73. inFormat = this->decaps->GetAudioFormat(0);
  74. if(inFormat->wFormatTag == 0x55 || inFormat->wFormatTag == 0x50) {
  75. /*
  76.  * 音频流是MPEG-1
  77.  */
  78. /* 
  79.  * 初始化解码器
  80.  */
  81. InitMP3(&this->mp);
  82.   
  83.     this->last_result = MP3_NEED_MORE;
  84.         ring_init();
  85. this->in_buffer  = (char *) new char[16384];
  86. this->out_buffer = (char *) new char[65536];
  87. if(this->DecompressMp3(this->out_buffer, 16384, &this->real_size) == MP3_ERR) {
  88. ExitMP3(&this->mp);
  89.     return MP_RESULT_ERROR;
  90. }
  91. /*
  92.  * 缓冲
  93.  */
  94. while(!ring_full(this->real_size))
  95. {
  96. if(this->DecompressMp3(this->out_buffer, 16384, &this->real_size) == 1)
  97.         ring_write(this->out_buffer, this->real_size);
  98. }
  99. /*
  100.  * 为补偿器建立输出格式(and sets up the output
  101.  * format for the renderer)
  102.  */
  103. this->oFormat = (WAVEFORMATEX *) new WAVEFORMATEX;
  104. memcpy(this->oFormat, inFormat, sizeof(WAVEFORMATEX));
  105. this->oFormat->wFormatTag = WAVE_FORMAT_PCM;
  106. if (oFormat->wBitsPerSample != 8 && oFormat->wBitsPerSample != 16)
  107. oFormat->wBitsPerSample = 16;
  108. if (oFormat->nChannels!=1 && oFormat->nChannels!=2)
  109. oFormat->nChannels = 2;
  110. oFormat->nBlockAlign = (oFormat->wBitsPerSample/8) * oFormat->nChannels;
  111. oFormat->nAvgBytesPerSec =  oFormat->nBlockAlign * oFormat->nSamplesPerSec;
  112. oFormat->cbSize         =  0;
  113. return MP_RESULT_OK;
  114. }
  115. }
  116. return MP_RESULT_ERROR;
  117. }
  118. MP_RESULT     MediaAudioDecoderMP3::ReleaseConnections()
  119. {
  120. /*
  121.  * 清除
  122.  */
  123. this->decaps = NULL;
  124. free(this->in_buffer);
  125. this->in_buffer = NULL;
  126. free(this->out_buffer);
  127. this->out_buffer = NULL;
  128. free(this->oFormat);
  129. this->oFormat = NULL;
  130. ExitMP3(&this->mp);
  131. return MP_RESULT_OK;
  132. }
  133. DWORD         MediaAudioDecoderMP3::GetCaps()
  134. {
  135. return 0;
  136. }
  137. MP_RESULT     MediaAudioDecoderMP3::Configure(HINSTANCE hInstance, HWND hwnd)
  138. {
  139. return MP_RESULT_ERROR;
  140. }
  141. /*
  142.  * 音频解码器
  143.  */
  144. WAVEFORMATEX *MediaAudioDecoderMP3::GetAudioFormat()
  145. {
  146. return this->oFormat;
  147. }
  148. MP_RESULT     MediaAudioDecoderMP3::EmptyAudioBuffer()
  149. {
  150. ring_init();
  151. this->last_result = MP3_NEED_MORE;
  152. ExitMP3(&this->mp);
  153. InitMP3(&this->mp);
  154. return MP_RESULT_OK;
  155. }
  156. unsigned int MediaAudioDecoderMP3::Decompress(void *buffer, unsigned int size)
  157. {
  158. DWORD i;
  159. if(this->oFormat && buffer) {
  160. if(size == 0)
  161. return 0;
  162. if(size < 32768) {
  163. /*
  164.  * 只读一次
  165.  */
  166. while(!ring_full(this->real_size)) {
  167.     
  168. if(this->DecompressMp3(this->out_buffer, 16384, &this->real_size) == 1) {
  169. ring_write(this->out_buffer, this->real_size);
  170. }
  171. else {
  172. return 0;
  173. }
  174. }
  175.   
  176. ring_read((char *) buffer, size);
  177. return size;
  178. }
  179. else {
  180. int blocks = size / 32768;
  181. for(i = 0; i < blocks; i++) {
  182. while(!ring_full(this->real_size)) {
  183.     
  184. if(this->DecompressMp3(this->out_buffer, 16384, &this->real_size) == 1) {
  185. ring_write(this->out_buffer, this->real_size);
  186. }
  187. else {
  188. return 0;
  189. }
  190. }
  191.   
  192. ring_read(((char *) buffer) + i*32768, 32768);
  193. }
  194. /*
  195.  * 最后一比特
  196.  */
  197. int left = size - (blocks * 32768);
  198. if(left > 0)
  199. Decompress((void *) (((char *) buffer) + size - left), left);
  200. return size;
  201. }
  202. }
  203. return 0;
  204. }