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