Progress meter

Hamish Allan <[email protected]>
Newsgroups gmane.comp.audio.mad.devel
Message-ID <[email protected]>
Hi folks,

I've just started writing an audio processing utility, using libmad to 
read from MP3 files.

I've modelled my code on minimad.c and it works fine, but as I'm 
decoding each file all at once, I want to provide a progress meter. In 
minimad.c the whole file is mmapped, so the read function only gets 
called once. I figured I would change my read function to make 
available a small fraction of the data, update the progress bar, then 
make the next block available, etc.

Unfortunately this doesn't work, I get "lost synchronisation" , 
"reserved sample frequency value", "bad main_data_begin pointer", 
"forbidden bitrate value" and "Huffman data overrun" errors each time I 
return a new block of data. As far as I can tell, my code is doing the 
right thing (I've included it below). In madllc.c, there is provision 
for when a frame is not wholly included by a buffer, but I would expect 
in the case of the high-level functions that this would be detected by 
mad_decoder_run and the input function would be polled for more data 
automatically.

Am I missing something obvious? Also, is there a better way to 
implement a progress bar?

Thanks in advance,
Hamish

P.S. this code is in Objective-C: "[inputData length]" does what the 
C++ "inputdata.length()" would do, and "id" is like "NSObject *" 
(NSObject is the root object).

struct dataDescriptor {
	NSData *inputData;
	NSMutableData *outputData;
	unsigned int bytesRead;
	unsigned int byteChunk; // number of bytes to read at a time
	id progressObject;
};

static enum mad_flow madInput(void *data, struct mad_stream *stream)
{
	struct dataDescriptor *descriptor = data;
	NSData *inputData = descriptor->inputData;
	unsigned int bytesTotal = [inputData length];
	unsigned int bytesLeft = bytesTotal - descriptor->bytesRead;
	double progress = (double)(descriptor->bytesRead) / (double)bytesTotal;

	[descriptor->progressObject showProgress:progress]

	if (bytesLeft == 0)
		return MAD_FLOW_STOP;

	fprintf(stderr, "Bytes read=%d, left=%d\n",
		descriptor->bytesRead, bytesLeft);

	if (bytesLeft > descriptor->byteChunk)
		bytesLeft = descriptor->byteChunk;
	mad_stream_buffer(stream, [inputData bytes] + (descriptor->bytesRead), 
bytesLeft);
	descriptor->bytesRead += bytesLeft;

	return MAD_FLOW_CONTINUE;
}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.