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; }