Rob Leslie (or anyone else who
cares to help),
Hi!
First -- Thanks for making this body
of code available. Overall it's been
quite easy to work with, and works,
and reads nicely, too.
Second -- I haven't updated to the
latest source release...
We're using MAD in a demonstration of
our new little embedded CPU ("Nios").
I'm running into one little bit of
confusion. We're running our board
with no OS, so we don't have memory
mapped files or anything. So I'm trying
to stream frame-by-frame as needed.
(I'm using the "lower level API"
that the README suggests I don't. :-)
I call mad_frame_decode(&frame,&stream),
and if it returns a recoverable error,
I try to read more data in.
It appears that I should preserve the
tail end of the stream's buffer, specifically,
everything from stream.next_frame to stream.bufend.
So, I copy that tail end down to stream.buffer,
and load new data past it.
This seems to work *almost* all the time.
Am I thinking correctly?
Thanks for any insight.
-- David Van Brink
P.S. In case you're inspired to muddle through
someone else's code, my main routine follows.
Feel free not to, though.
As ever, pardon
the horrific formatting. My real question is,
can I always assume that everything from
stream.next_frame to stream.bufend is the
part to keep when the stream is lacking
for more bits.
int nios_mp3_getNextFrame(nios_mp3 *nm)
{
int result = 0;
result = mad_frame_decode(&nm->frame,&nm->stream);
//
// the decode may fail due to a lack of source data,
// in which case we'll read some and try again
//
if(result == -1 &&
(nm->stream.error == MAD_ERR_BUFLEN ||
nm->stream.error == MAD_ERR_BUFPTR))
{
long tailSave; // how much is still good in
the buffer
long size = kFileBufferSize; // amount we'll try to have
on-hand
if(nm->currentFilePosition >= nm->fileLength)
{
result = -1;
goto goHome;
}
tailSave = nm->stream.bufend - nm->stream.next_frame;
size -= tailSave;
#if NIOS_MP3_DEBUG
printf("nios_mp3_getNextFrame: size = %d, tailSave =
%d\n",size,tailSave);
#endif
// Copy the tail to the head
//
memcpy(nm->fileBuffer,nm->fileBuffer + nm->currentBufferSize
- tailSave,tailSave);
// Clamp size to fileLength
//
if(nm->currentFilePosition + size > nm->fileLength)
size = nm->fileLength - nm->currentFilePosition;
// Read in the new bytes
//
WOSFS_Read(nm->fileNumber,nm->currentFilePosition,size,nm->fileBuffer +
tailSave);
nm->currentBufferSize = size + tailSave;
nm->currentFilePosition += size;
// Give new buffer to the stream
//
mad_stream_buffer(&nm->stream, nm->fileBuffer,
nm->currentBufferSize);
// And try that frame decode again (but no more after this!)
//
result = mad_frame_decode(&nm->frame,&nm->stream);
}
#if NIOS_MP3_DEBUG || 1
if(result)
printf("nios_mp3_getNextFrame: mad_frame_decode returned
%d/%d\n",
result,nm->stream.error);
#endif
if(result == -1)
goto goHome;
nm->framesDecoded++;
mad_synth_frame(&nm->synth,&nm->frame);
nm->samplesGenerated += nm->synth.pcmlen;
goHome:
return result;
}