>As part of mpg123 emulation, I've got to be able to seek in files and also
>> report where in the file we're currently playing (in verbose mode, at
>> least). Now, seeking isn't difficult: I just get the frame to which the
>> user wants to seek, count the frames mad's passing to the header function,
>> and return MAD_FLOW_IGNORE for every frame up to the one the user wants.
>> 
>> However, the second one is a bit more difficult. I need to know (a) how
>> many frames there are in any given file, and (b) how long the file is,
>> in time. Now there is a solution similar to the above one: do an initial
>> pass, returning MAD_FLOW_IGNORE for all the frames, and counting (a) the
>> frames and (b) the total length of the file. Now that I'm looking in
>> madplay, I notice that's somewhat along the lines of what's done in scan().
>> and calc() in madtime.c. Is this the only option? I assume it's not
>> horribly inefficient, anyways, as it seems to be in use in madplay.


This is only used by `madtime' (which isn't built by default), and it's not
terribly efficient but it is accurate for all types of files.

There is a faster method you can use in the case of constant bitrate files:
divide the file size in bits by the bitrate in bps to get the playing time
of the file in seconds:

  time = (size * 8) / (bitrate * 1000)

This assumes the entire file consists of MPEG audio frames, ignoring ID3
tags in particular, but it may still produce an acceptable estimate.

>From the playing time, and knowing the sample rate and audio layer, you can
compute the number of frames. First, the number of samples per frame:

  samples = 32 * MAD_NSBSAMPLES(&header)

Then, the number of frames:

  frames = samplerate * time / samples

Note that you need to decode at least one frame header in order to determine
the bit rate, sample rate, and layer. Also note that this doesn't work for
VBR files, because in those cases the bit rate changes throughout the file.

For VBR, if there is a so-called Xing tag in the first frame, you can
compute the playing time and number of frames from that. Otherwise, the only
guaranteed method to determine either is to scan the entire file.

You can find some Xing tag-parsing code in the MAD plug-in for Winamp.