I thought I'd mention some of the development directions I am planning for MAD.
These are not in any particular order...
1. I am currently in the midst of adding ID3v2 support to madplay. I've been thinking it might be nice to turn the ID3 tag decoding into a library to go alongside libmad, but I don't have a good interface in mind for this at the moment.
2. The Layer III IMDCT routines (III_imdct_l and III_imdct_s) are slow and absolutely must be rewritten. There are plenty of alternatives, so this is largely a matter of finding the right optimized algorithm and coding it efficiently with integer arithmetic. This will be a priority pretty soon.
3. The API for libmad will be changing slightly. I want to enable two primary interfaces, one high-level and the other low-level. Currently madplay is using the "low-level" interface, where streams, frames, and subband synthesis are all handled explicitly, like this:
mad_stream_init(&stream); /* input buffer */ mad_frame_init(&frame); /* individual frames */ mad_synth_init(&synth); /* synthesis output */
/* ... set up input stream ... */
for (each frame) { mad_frame_decode(&frame, &stream); /* frame <- decode(stream) */ mad_synth_frame(&synth, &frame); /* synth <- synthesize(frame) */
/* synth now contains the output PCM samples */ }
This interface gives opportunity to modify the frame subband samples before proceeding with synthesis. For example, madplay will transform the frame from stereo to mono if the -m switch is given. Another use would be to apply equalizer or other filters, or to mix two or more MPEG audio streams together with minimal overhead.
Every detail must be handled explicitly to use this level of interface; the stream buffer must be updated after input is consumed, and frames with CRC or other errors must be dealt with appropriately. The entire synthesis output must be used before the next frame is synthesized.
Another, easier approach from an API perspective might be something like:
mad_decoder_init(&decoder); /* contains stream, frame, and synth structs */
/* ... install input, filter, and output modules ... */
mad_decoder_run(&decoder);
With this model, the decoder calls the input, filter, and output modules itself to read from the stream, (optionally) filter the subband samples, and finally deliver the PCM output. Another callback could also be used to handle errors, with some appropriate default if no callback has been given.
This API might be more desirable for many simple types of applications. It has the added benefit that it could easily be run in a separate thread or process, using some kind of IPC for configuration and control.
4. I am in the process of obtaining a copy of the MPEG 2 standard so libmad can support this in addition to MPEG 1. MPEG 2.5 would also be nice, but I'm uncertain where to find specs as it's not an official standard.
5. It may be possible to improve performance by using 16-bit fixed-point values in some places instead of the current 32-bit ones. This is probably possible without losing quality as long as the output device isn't looking for more than 16 bits of precision. The stumbling blocks I see largely involve the places where values outside the (-1.0, +1.0) range are used, such as for scaling. This is going to be a topic of research.
I'd welcome any feedback on these plans, or on madplay or MAD in general...
Cheers, -rob