123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- #include "../nsv/nsvlib.h"
- #include "../nsv/dec_if.h"
- #include "nsvmain.h"
- #include "../nsutil/pcm.h"
- MP3_Decoder::MP3_Decoder()
- {
- decoder = mpg123_new(NULL, NULL);
- long flags = MPG123_QUIET|MPG123_FORCE_FLOAT|MPG123_SKIP_ID3V2|MPG123_IGNORE_STREAMLENGTH|MPG123_IGNORE_INFOFRAME;
- mpg123_param(decoder, MPG123_FLAGS, flags, 0);
- mpg123_param(decoder, MPG123_RVA, MPG123_RVA_OFF, 0);
- memset(pcm_buf, 0, sizeof(pcm_buf));
- mpg123_open_feed(decoder);
- fused = 0; pcm_buf_used = 0; pcm_offs = 0;
- }
- int MP3_Decoder::decode(void *in, int in_len,
- void *out, int *out_len,
- unsigned int out_fmt[8])
- {
- int rval = 1;
- if (fused < in_len)
- {
- int l = 4096;
- if (l > in_len - fused) l = in_len - fused;
- if (l) mpg123_feed(decoder, (unsigned char *)in + fused, l);
- fused += l;
- }
- if (!pcm_buf_used)
- {
- mpg123_read(decoder, (unsigned char *)pcm_buf, sizeof(pcm_buf), &pcm_buf_used);
-
- pcm_offs = 0;
- }
- if (pcm_buf_used)
- {
- size_t numSamples = *out_len / 2;
- if (numSamples > (pcm_buf_used/sizeof(float)))
- numSamples = pcm_buf_used/sizeof(float);
- nsutil_pcm_FloatToInt_Interleaved(out, pcm_buf+pcm_offs, 16, numSamples);
- pcm_buf_used -= numSamples*sizeof(float);
- pcm_offs += (int)numSamples;
- *out_len = 2*(int)numSamples;
- }
- else
- {
- if (fused >= in_len) { fused = 0; rval = 0; }
- *out_len = 0;
- }
- mpg123_frameinfo frameInfo;
- if (mpg123_info(decoder, &frameInfo) == MPG123_OK) {
- int nch = (frameInfo.mode == MPG123_M_MONO)?1:2;
- int srate = frameInfo.rate;
- out_fmt[0] = (nch && srate) ? NSV_MAKETYPE('P', 'C', 'M', ' ') : 0;
- out_fmt[1] = srate;
- out_fmt[2] = nch;
- out_fmt[3] = (nch && srate) ? 16 : 0;
- out_fmt[4] = frameInfo.bitrate;
- }
- return rval;
- }
- void MP3_Decoder::flush()
- {
- fused = 0;
- pcm_buf_used = 0;
- pcm_offs = 0;
- mpg123_open_feed(decoder);
- }
- extern "C"
- {
- __declspec(dllexport) IAudioDecoder *CreateAudioDecoder(unsigned int fmt, IAudioOutput **output)
- {
- switch (fmt)
- {
- case NSV_MAKETYPE('M', 'P', '3', ' '):
- return new MP3_Decoder;
- default:
- return NULL;
- }
- }
- __declspec(dllexport) void DeleteAudioDecoder(IAudioDecoder *decoder)
- {
- if (decoder)
- delete decoder;
- }
- }
|