mp3stub.cpp 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. #include "mp3stub.h"
  2. #include "../../mp3dec/mpgadecoder.h"
  3. int mp3_quality;
  4. int mp3_downmix;
  5. class MP3_Decoder : public IAudioDecoder
  6. {
  7. public:
  8. MP3_Decoder() : mp3_dec(mp3_quality,0,mp3_downmix) { fused=0; pcm_buf_used=0; }
  9. ~MP3_Decoder() { };
  10. int decode(void *in, int in_len,
  11. void *out, int *out_len,
  12. unsigned int out_fmt[8]);
  13. void flush() { fused=0; pcm_buf_used=0; mp3_dec.Reset(); }
  14. private:
  15. CMpgaDecoder mp3_dec;
  16. char pcm_buf[1152*4*2];
  17. int pcm_buf_used;
  18. int pcm_offs;
  19. int fused;
  20. };
  21. int MP3_Decoder::decode(void *in, int in_len,
  22. void *out, int *out_len,
  23. unsigned int out_fmt[8])
  24. {
  25. int rval=1;
  26. if (fused < in_len)
  27. {
  28. int l=mp3_dec.GetInputFree();
  29. if (l > in_len-fused) l=in_len-fused;
  30. if (l) mp3_dec.Fill((unsigned char *)in + fused,l);
  31. fused+=l;
  32. }
  33. if (!pcm_buf_used)
  34. {
  35. SSC s=mp3_dec.DecodeFrame((unsigned char *)pcm_buf,sizeof(pcm_buf),&pcm_buf_used);
  36. pcm_offs=0;
  37. }
  38. if (pcm_buf_used)
  39. {
  40. int l=*out_len;
  41. if (l > pcm_buf_used) l=pcm_buf_used;
  42. memcpy(out,pcm_buf+pcm_offs,l);
  43. pcm_buf_used-=l;
  44. pcm_offs+=l;
  45. *out_len=l;
  46. }
  47. else
  48. {
  49. if (fused >= in_len) rval=fused=0;
  50. *out_len=0;
  51. }
  52. int nch=mp3_dec.m_Info.GetEffectiveChannels();
  53. int srate=mp3_dec.m_Info.GetEffectiveSFreq();
  54. out_fmt[0]=(nch && srate)?NSV_MAKETYPE('P','C','M',' '):0;
  55. out_fmt[1]=srate;
  56. out_fmt[2]=nch;
  57. out_fmt[3]=(nch && srate)?16:0;
  58. return rval;
  59. }
  60. IAudioDecoder *MP3_CREATE(unsigned int fmt)
  61. {
  62. if (fmt == NSV_MAKETYPE('M','P','3',' ')) return new MP3_Decoder;
  63. return NULL;
  64. }