2
* libmad - MPEG audio decoder library
3
* Copyright (C) 2000-2004 Underbit Technologies, Inc.
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
* $Id: timer.c,v 1.18 2004/01/23 09:41:33 rob Exp $
36
mad_timer_t const mad_timer_zero = { 0, 0 };
39
* NAME: timer->compare()
40
* DESCRIPTION: indicate relative order of two timers
42
int mad_timer_compare(mad_timer_t timer1, mad_timer_t timer2)
46
diff = timer1.seconds - timer2.seconds;
52
diff = timer1.fraction - timer2.fraction;
62
* NAME: timer->negate()
63
* DESCRIPTION: invert the sign of a timer
65
void mad_timer_negate(mad_timer_t *timer)
67
timer->seconds = -timer->seconds;
69
if (timer->fraction) {
71
timer->fraction = MAD_TIMER_RESOLUTION - timer->fraction;
77
* DESCRIPTION: return the absolute value of a timer
79
mad_timer_t mad_timer_abs(mad_timer_t timer)
81
if (timer.seconds < 0)
82
mad_timer_negate(&timer);
88
* NAME: reduce_timer()
89
* DESCRIPTION: carry timer fraction into seconds
92
void reduce_timer(mad_timer_t *timer)
94
timer->seconds += timer->fraction / MAD_TIMER_RESOLUTION;
95
timer->fraction %= MAD_TIMER_RESOLUTION;
100
* DESCRIPTION: compute greatest common denominator
103
unsigned long gcd(unsigned long num1, unsigned long num2)
117
* NAME: reduce_rational()
118
* DESCRIPTION: convert rational expression to lowest terms
121
void reduce_rational(unsigned long *numer, unsigned long *denom)
123
unsigned long factor;
125
factor = gcd(*numer, *denom);
134
* NAME: scale_rational()
135
* DESCRIPTION: solve numer/denom == ?/scale avoiding overflowing
138
unsigned long scale_rational(unsigned long numer, unsigned long denom,
141
reduce_rational(&numer, &denom);
142
reduce_rational(&scale, &denom);
147
return numer * (scale / denom) + numer * (scale % denom) / denom;
149
return scale * (numer / denom) + scale * (numer % denom) / denom;
151
return numer * scale / denom;
156
* DESCRIPTION: set timer to specific (positive) value
158
void mad_timer_set(mad_timer_t *timer, unsigned long seconds,
159
unsigned long numer, unsigned long denom)
161
timer->seconds = seconds;
162
if (numer >= denom && denom > 0) {
163
timer->seconds += numer / denom;
173
case MAD_TIMER_RESOLUTION:
174
timer->fraction = numer;
178
timer->fraction = numer * (MAD_TIMER_RESOLUTION / 1000);
182
timer->fraction = numer * (MAD_TIMER_RESOLUTION / 8000);
186
timer->fraction = numer * (MAD_TIMER_RESOLUTION / 11025);
190
timer->fraction = numer * (MAD_TIMER_RESOLUTION / 12000);
194
timer->fraction = numer * (MAD_TIMER_RESOLUTION / 16000);
198
timer->fraction = numer * (MAD_TIMER_RESOLUTION / 22050);
202
timer->fraction = numer * (MAD_TIMER_RESOLUTION / 24000);
206
timer->fraction = numer * (MAD_TIMER_RESOLUTION / 32000);
210
timer->fraction = numer * (MAD_TIMER_RESOLUTION / 44100);
214
timer->fraction = numer * (MAD_TIMER_RESOLUTION / 48000);
218
timer->fraction = scale_rational(numer, denom, MAD_TIMER_RESOLUTION);
222
if (timer->fraction >= MAD_TIMER_RESOLUTION)
228
* DESCRIPTION: add one timer to another
230
void mad_timer_add(mad_timer_t *timer, mad_timer_t incr)
232
timer->seconds += incr.seconds;
233
timer->fraction += incr.fraction;
235
if (timer->fraction >= MAD_TIMER_RESOLUTION)
240
* NAME: timer->multiply()
241
* DESCRIPTION: multiply a timer by a scalar value
243
void mad_timer_multiply(mad_timer_t *timer, signed long scalar)
246
unsigned long factor;
251
mad_timer_negate(timer);
255
*timer = mad_timer_zero;
259
mad_timer_add(timer, addend);
261
mad_timer_add(&addend, addend);
267
* NAME: timer->count()
268
* DESCRIPTION: return timer value in selected units
270
signed long mad_timer_count(mad_timer_t timer, enum mad_units units)
273
case MAD_UNITS_HOURS:
274
return timer.seconds / 60 / 60;
276
case MAD_UNITS_MINUTES:
277
return timer.seconds / 60;
279
case MAD_UNITS_SECONDS:
280
return timer.seconds;
282
case MAD_UNITS_DECISECONDS:
283
case MAD_UNITS_CENTISECONDS:
284
case MAD_UNITS_MILLISECONDS:
286
case MAD_UNITS_8000_HZ:
287
case MAD_UNITS_11025_HZ:
288
case MAD_UNITS_12000_HZ:
289
case MAD_UNITS_16000_HZ:
290
case MAD_UNITS_22050_HZ:
291
case MAD_UNITS_24000_HZ:
292
case MAD_UNITS_32000_HZ:
293
case MAD_UNITS_44100_HZ:
294
case MAD_UNITS_48000_HZ:
296
case MAD_UNITS_24_FPS:
297
case MAD_UNITS_25_FPS:
298
case MAD_UNITS_30_FPS:
299
case MAD_UNITS_48_FPS:
300
case MAD_UNITS_50_FPS:
301
case MAD_UNITS_60_FPS:
302
case MAD_UNITS_75_FPS:
303
return timer.seconds * (signed long) units +
304
(signed long) scale_rational(timer.fraction, MAD_TIMER_RESOLUTION,
307
case MAD_UNITS_23_976_FPS:
308
case MAD_UNITS_24_975_FPS:
309
case MAD_UNITS_29_97_FPS:
310
case MAD_UNITS_47_952_FPS:
311
case MAD_UNITS_49_95_FPS:
312
case MAD_UNITS_59_94_FPS:
313
return (mad_timer_count(timer, -units) + 1) * 1000 / 1001;
316
/* unsupported units */
321
* NAME: timer->fraction()
322
* DESCRIPTION: return fractional part of timer in arbitrary terms
324
unsigned long mad_timer_fraction(mad_timer_t timer, unsigned long denom)
326
timer = mad_timer_abs(timer);
330
return timer.fraction ?
331
MAD_TIMER_RESOLUTION / timer.fraction : MAD_TIMER_RESOLUTION + 1;
333
case MAD_TIMER_RESOLUTION:
334
return timer.fraction;
337
return scale_rational(timer.fraction, MAD_TIMER_RESOLUTION, denom);
342
* NAME: timer->string()
343
* DESCRIPTION: write a string representation of a timer using a template
345
void mad_timer_string(mad_timer_t timer,
346
char *dest, char const *format, enum mad_units units,
347
enum mad_units fracunits, unsigned long subparts)
349
unsigned long hours, minutes, seconds, sub;
352
timer = mad_timer_abs(timer);
354
seconds = timer.seconds;
358
case MAD_UNITS_HOURS:
359
case MAD_UNITS_MINUTES:
360
case MAD_UNITS_SECONDS:
363
case MAD_UNITS_DECISECONDS:
364
case MAD_UNITS_CENTISECONDS:
365
case MAD_UNITS_MILLISECONDS:
367
case MAD_UNITS_8000_HZ:
368
case MAD_UNITS_11025_HZ:
369
case MAD_UNITS_12000_HZ:
370
case MAD_UNITS_16000_HZ:
371
case MAD_UNITS_22050_HZ:
372
case MAD_UNITS_24000_HZ:
373
case MAD_UNITS_32000_HZ:
374
case MAD_UNITS_44100_HZ:
375
case MAD_UNITS_48000_HZ:
377
case MAD_UNITS_24_FPS:
378
case MAD_UNITS_25_FPS:
379
case MAD_UNITS_30_FPS:
380
case MAD_UNITS_48_FPS:
381
case MAD_UNITS_50_FPS:
382
case MAD_UNITS_60_FPS:
383
case MAD_UNITS_75_FPS:
387
denom = MAD_TIMER_RESOLUTION / fracunits;
389
frac = timer.fraction / denom;
390
sub = scale_rational(timer.fraction % denom, denom, subparts);
394
case MAD_UNITS_23_976_FPS:
395
case MAD_UNITS_24_975_FPS:
396
case MAD_UNITS_29_97_FPS:
397
case MAD_UNITS_47_952_FPS:
398
case MAD_UNITS_49_95_FPS:
399
case MAD_UNITS_59_94_FPS:
400
/* drop-frame encoding */
401
/* N.B. this is only well-defined for MAD_UNITS_29_97_FPS */
403
unsigned long frame, cycle, d, m;
405
frame = mad_timer_count(timer, fracunits);
407
cycle = -fracunits * 60 * 10 - (10 - 1) * 2;
411
frame += (10 - 1) * 2 * d;
413
frame += 2 * ((m - 2) / (cycle / 10));
415
frac = frame % -fracunits;
416
seconds = frame / -fracunits;
422
case MAD_UNITS_HOURS:
423
minutes = seconds / 60;
424
hours = minutes / 60;
426
sprintf(dest, format,
428
(unsigned int) (minutes % 60),
429
(unsigned int) (seconds % 60),
433
case MAD_UNITS_MINUTES:
434
minutes = seconds / 60;
436
sprintf(dest, format,
438
(unsigned int) (seconds % 60),
442
case MAD_UNITS_SECONDS:
443
sprintf(dest, format,
448
case MAD_UNITS_23_976_FPS:
449
case MAD_UNITS_24_975_FPS:
450
case MAD_UNITS_29_97_FPS:
451
case MAD_UNITS_47_952_FPS:
452
case MAD_UNITS_49_95_FPS:
453
case MAD_UNITS_59_94_FPS:
455
/* not yet implemented */
461
case MAD_UNITS_DECISECONDS:
462
case MAD_UNITS_CENTISECONDS:
463
case MAD_UNITS_MILLISECONDS:
465
case MAD_UNITS_8000_HZ:
466
case MAD_UNITS_11025_HZ:
467
case MAD_UNITS_12000_HZ:
468
case MAD_UNITS_16000_HZ:
469
case MAD_UNITS_22050_HZ:
470
case MAD_UNITS_24000_HZ:
471
case MAD_UNITS_32000_HZ:
472
case MAD_UNITS_44100_HZ:
473
case MAD_UNITS_48000_HZ:
475
case MAD_UNITS_24_FPS:
476
case MAD_UNITS_25_FPS:
477
case MAD_UNITS_30_FPS:
478
case MAD_UNITS_48_FPS:
479
case MAD_UNITS_50_FPS:
480
case MAD_UNITS_60_FPS:
481
case MAD_UNITS_75_FPS:
482
sprintf(dest, format, mad_timer_count(timer, units), sub);