try
{
- decode_frame();
+ if(!fill_input() || !decode(false))
+ throw runtime_error("no mp3 data");
+
format = create_format(2, MAD_NCHANNELS(&priv->frame.header));
freq = priv->frame.header.samplerate;
}
unsigned pos = 0;
while(pos+2*nchan<=len)
{
- if(read_pos>=pcm.length)
- {
- if(!decode_frame())
- break;
- }
+ if(read_pos>=pcm.length && !decode(true))
+ break;
for(unsigned i=0; i<nchan; ++i)
{
return len;
}
-bool Mp3Decoder::decode_frame()
+bool Mp3Decoder::try_decode(bool full)
{
- while(1)
+ if(full)
+ return !mad_frame_decode(&priv->frame, &priv->stream);
+ else
+ return !mad_header_decode(&priv->frame.header, &priv->stream);
+}
+
+bool Mp3Decoder::decode(bool full)
+{
+ while(!try_decode(full))
{
- if(!priv->stream.buffer || priv->stream.error==MAD_ERROR_BUFLEN)
+ if(priv->stream.error==MAD_ERROR_BUFLEN)
+ {
if(!fill_input())
return false;
-
- if(!mad_frame_decode(&priv->frame, &priv->stream))
- {
- mad_synth_frame(&priv->synth, &priv->frame);
- read_pos = 0;
- return true;
}
-
- if(priv->stream.error==MAD_ERROR_BUFLEN)
- continue;
else if(!MAD_RECOVERABLE(priv->stream.error))
throw mp3_error("mad_frame_decode", priv->stream.error);
}
+
+ if(full)
+ {
+ read_pos = 0;
+ mad_synth_frame(&priv->synth, &priv->frame);
+ }
+
+ return true;
}
} // namespace AL