The basic timer datatype is mad_timer_t; it represents a unit of time. You can initialize a timer by setting it either to a zero constant or to some other explicit value:
mad_timer_t timer;
timer = mad_timer_zero; /* or */ mad_timer_set(&timer, seconds, frac_numer, frac_denom);
Timers have a precision of 1/352800000 second, so you can use the frac_numer and frac_denom arguments to specify a fractional value as a rational number. The resulting timer value, in seconds, is:
seconds + (frac_numer / frac_denom)
You can add one timer value to another with:
mad_timer_add(&timer, timer2);
You can also multiply a timer value by an integer:
mad_timer_multiply(&timer, scalar);
Timer values can be either positive or negative; to change the sign of a timer:
mad_timer_negate(&timer);
To get the absolute value:
timer2 = mad_timer_abs(timer);
Or, to determine the sign:
sign = mad_timer_sign(timer); /* < 0 negative; = 0 zero; > 0 positive */
In general you can compare any two timer values:
comp = mad_timer_compare(timer1, timer2); /* comp < 0 : timer1 < timer2 */ /* comp = 0 : timer1 = timer2 */ /* comp > 0 : timer1 > timer2 */
Finally, there are methods for extracting the value of a timer. To convert a timer value to selected UNITS (see libmad/timer.h for unit constants):
count = mad_timer_count(timer, UNITS); /* rounded down */
If you assume a basic unit of seconds, you can get the remaining fractional part of a timer in arbitrary terms with:
frac_numer = mad_timer_fraction(timer, frac_denom);
The precision of the timers is such that frac_denom can be any valid MPEG audio sampling frequency to get sample-granular results.
Finally, you can get a string representation by supplying a sprintf-style format and selecting various units:
mad_timer_string(timer, dest, format, UNITS, frac_UNITS, subparts);
For example, to get HH:MM:SS.DDD you could use:
mad_timer_t timer; char dest[13];
mad_timer_string(timer, dest, "%02lu:%02u:%02.%03u", MAD_UNITS_HOURS, MAD_UNITS_MILLISECONDS, 0);
(MAD_UNITS_HOURS implies the next two format specifiers are for minutes and seconds.) There are also selectors for video frame units, and even drop-frame time coding is supported:
mad_timer_string(timer, dest, "%02lu:%02u:%02u;%02u", MAD_UNITS_HOURS, MAD_UNITS_29_97_FPS, 0);
After each call to mad_frame_decode() (or mad_header_decode()), frame.header.duration is filled with a timer value representing the playing time of the audio in the frame. You can accumulate these times with mad_timer_add() to keep an accurate time position as you play the audio.