3 #include <msp/strings/format.h>
4 #include "mp3decoder.h"
10 Msp::Int16 scale(mad_fixed_t sample)
12 if(sample<=-MAD_F_ONE)
13 return numeric_limits<Msp::Int16>::min();
14 else if(sample>=MAD_F_ONE)
15 return numeric_limits<Msp::Int16>::max();
17 return (sample + (1<<(MAD_F_FRACBITS-16))) >> (MAD_F_FRACBITS-15);
26 mp3_error::mp3_error(const std::string &func, int err):
27 runtime_error(format("%s: %s", func, get_message(err)))
30 string mp3_error::get_message(int err)
32 return format("%d", err);
36 struct Mp3Decoder::Private
44 Mp3Decoder::Mp3Decoder(IO::Seekable &io):
48 in_buffer(new char[in_buf_size]),
51 mad_stream_init(&priv->stream);
52 mad_frame_init(&priv->frame);
53 mad_synth_init(&priv->synth);
57 if(!fill_input() || !decode(false))
58 throw runtime_error("no mp3 data");
60 format = create_format(2, MAD_NCHANNELS(&priv->frame.header));
61 freq = priv->frame.header.samplerate;
70 Mp3Decoder::~Mp3Decoder()
73 mad_synth_finish(&priv->synth);
74 mad_frame_finish(&priv->frame);
75 mad_stream_finish(&priv->stream);
79 bool Mp3Decoder::detect(const string &sig)
81 if(sig.size()>=2 && sig[0]=='\xFF' && (sig[1]&0xE0)==0xE0)
84 static const char id3_sig[] = { 'I', 'D', '3' };
85 if(sig.size()<sizeof(id3_sig))
87 return !sig.compare(0, sizeof(id3_sig), id3_sig);
90 void Mp3Decoder::seek(unsigned pos)
92 unsigned unit = get_unit_size(format);
95 in.seek(0, IO::S_BEG);
96 mad_stream_buffer(&priv->stream, 0, 0);
100 priv->synth.pcm.length = 0;
106 unsigned frame_len = 32*MAD_NSBSAMPLES(&priv->frame.header);
118 unsigned Mp3Decoder::read(char *buf, unsigned len)
120 unsigned nchan = get_n_channels(format);
121 mad_pcm &pcm = priv->synth.pcm;
124 while(pos+2*nchan<=len)
126 if(read_pos>=pcm.length && !decode(true))
129 for(unsigned i=0; i<nchan; ++i)
131 Int16 sample = scale(pcm.samples[i][read_pos]);
133 buf[pos++] = sample>>8;
142 bool Mp3Decoder::fill_input()
145 if(priv->stream.next_frame && priv->stream.next_frame<priv->stream.bufend)
147 copy(priv->stream.next_frame, priv->stream.bufend, in_buffer);
148 in_pos = priv->stream.bufend-priv->stream.next_frame;
151 unsigned len = in.read(in_buffer+in_pos, in_buf_size-in_pos);
154 mad_stream_buffer(&priv->stream, reinterpret_cast<unsigned char *>(in_buffer), in_pos);
155 priv->stream.error = MAD_ERROR_NONE;
160 bool Mp3Decoder::try_decode(bool full)
163 return !mad_frame_decode(&priv->frame, &priv->stream);
165 return !mad_header_decode(&priv->frame.header, &priv->stream);
168 bool Mp3Decoder::decode(bool full)
170 while(!try_decode(full))
172 if(priv->stream.error==MAD_ERROR_BUFLEN)
177 else if(!MAD_RECOVERABLE(priv->stream.error))
178 throw mp3_error("mad_frame_decode", priv->stream.error);
184 mad_synth_frame(&priv->synth, &priv->frame);