00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00025 # ifdef HAVE_CONFIG_H
00026 # include "config.h"
00027 # endif
00028
00029 # include "global.h"
00030
00031 # include <stdio.h>
00032
00033 # ifdef HAVE_ASSERT_H
00034 # include <assert.h>
00035 # endif
00036
00037 # include "timer.h"
00038
00039 mad_timer_t const mad_timer_zero = { 0, 0 };
00040
00044 int mad_timer_compare(mad_timer_t timer1, mad_timer_t timer2)
00045 {
00046 signed long diff;
00047
00048 diff = timer1.seconds - timer2.seconds;
00049 if (diff < 0)
00050 return -1;
00051 else if (diff > 0)
00052 return +1;
00053
00054 diff = timer1.fraction - timer2.fraction;
00055 if (diff < 0)
00056 return -1;
00057 else if (diff > 0)
00058 return +1;
00059
00060 return 0;
00061 }
00062
00066 void mad_timer_negate(mad_timer_t *timer)
00067 {
00068 timer->seconds = -timer->seconds;
00069
00070 if (timer->fraction) {
00071 timer->seconds -= 1;
00072 timer->fraction = MAD_TIMER_RESOLUTION - timer->fraction;
00073 }
00074 }
00075
00079 mad_timer_t mad_timer_abs(mad_timer_t timer)
00080 {
00081 if (timer.seconds < 0)
00082 mad_timer_negate(&timer);
00083
00084 return timer;
00085 }
00086
00090 static
00091 void reduce_timer(mad_timer_t *timer)
00092 {
00093 timer->seconds += timer->fraction / MAD_TIMER_RESOLUTION;
00094 timer->fraction %= MAD_TIMER_RESOLUTION;
00095 }
00096
00100 static
00101 unsigned long gcd(unsigned long num1, unsigned long num2)
00102 {
00103 unsigned long tmp;
00104
00105 while (num2) {
00106 tmp = num2;
00107 num2 = num1 % num2;
00108 num1 = tmp;
00109 }
00110
00111 return num1;
00112 }
00113
00117 static
00118 void reduce_rational(unsigned long *numer, unsigned long *denom)
00119 {
00120 unsigned long factor;
00121
00122 factor = gcd(*numer, *denom);
00123
00124 assert(factor != 0);
00125
00126 *numer /= factor;
00127 *denom /= factor;
00128 }
00129
00133 static
00134 unsigned long scale_rational(unsigned long numer, unsigned long denom,
00135 unsigned long scale)
00136 {
00137 reduce_rational(&numer, &denom);
00138 reduce_rational(&scale, &denom);
00139
00140 assert(denom != 0);
00141
00142 if (denom < scale)
00143 return numer * (scale / denom) + numer * (scale % denom) / denom;
00144 if (denom < numer)
00145 return scale * (numer / denom) + scale * (numer % denom) / denom;
00146
00147 return numer * scale / denom;
00148 }
00149
00153 void mad_timer_set(mad_timer_t *timer, unsigned long seconds,
00154 unsigned long numer, unsigned long denom)
00155 {
00156 timer->seconds = seconds;
00157 if (numer >= denom && denom > 0) {
00158 timer->seconds += numer / denom;
00159 numer %= denom;
00160 }
00161
00162 switch (denom) {
00163 case 0:
00164 case 1:
00165 timer->fraction = 0;
00166 break;
00167
00168 case MAD_TIMER_RESOLUTION:
00169 timer->fraction = numer;
00170 break;
00171
00172 case 1000:
00173 timer->fraction = numer * (MAD_TIMER_RESOLUTION / 1000);
00174 break;
00175
00176 case 8000:
00177 timer->fraction = numer * (MAD_TIMER_RESOLUTION / 8000);
00178 break;
00179
00180 case 11025:
00181 timer->fraction = numer * (MAD_TIMER_RESOLUTION / 11025);
00182 break;
00183
00184 case 12000:
00185 timer->fraction = numer * (MAD_TIMER_RESOLUTION / 12000);
00186 break;
00187
00188 case 16000:
00189 timer->fraction = numer * (MAD_TIMER_RESOLUTION / 16000);
00190 break;
00191
00192 case 22050:
00193 timer->fraction = numer * (MAD_TIMER_RESOLUTION / 22050);
00194 break;
00195
00196 case 24000:
00197 timer->fraction = numer * (MAD_TIMER_RESOLUTION / 24000);
00198 break;
00199
00200 case 32000:
00201 timer->fraction = numer * (MAD_TIMER_RESOLUTION / 32000);
00202 break;
00203
00204 case 44100:
00205 timer->fraction = numer * (MAD_TIMER_RESOLUTION / 44100);
00206 break;
00207
00208 case 48000:
00209 timer->fraction = numer * (MAD_TIMER_RESOLUTION / 48000);
00210 break;
00211
00212 default:
00213 timer->fraction = scale_rational(numer, denom, MAD_TIMER_RESOLUTION);
00214 break;
00215 }
00216
00217 if (timer->fraction >= MAD_TIMER_RESOLUTION)
00218 reduce_timer(timer);
00219 }
00220
00224 void mad_timer_add(mad_timer_t *timer, mad_timer_t incr)
00225 {
00226 timer->seconds += incr.seconds;
00227 timer->fraction += incr.fraction;
00228
00229 if (timer->fraction >= MAD_TIMER_RESOLUTION)
00230 reduce_timer(timer);
00231 }
00232
00236 void mad_timer_multiply(mad_timer_t *timer, signed long scalar)
00237 {
00238 mad_timer_t addend;
00239 unsigned long factor;
00240
00241 factor = scalar;
00242 if (scalar < 0) {
00243 factor = -scalar;
00244 mad_timer_negate(timer);
00245 }
00246
00247 addend = *timer;
00248 *timer = mad_timer_zero;
00249
00250 while (factor) {
00251 if (factor & 1)
00252 mad_timer_add(timer, addend);
00253
00254 mad_timer_add(&addend, addend);
00255 factor >>= 1;
00256 }
00257 }
00258
00262 signed long mad_timer_count(mad_timer_t timer, enum mad_units units)
00263 {
00264 switch (units) {
00265 case MAD_UNITS_HOURS:
00266 return timer.seconds / 60 / 60;
00267
00268 case MAD_UNITS_MINUTES:
00269 return timer.seconds / 60;
00270
00271 case MAD_UNITS_SECONDS:
00272 return timer.seconds;
00273
00274 case MAD_UNITS_DECISECONDS:
00275 case MAD_UNITS_CENTISECONDS:
00276 case MAD_UNITS_MILLISECONDS:
00277
00278 case MAD_UNITS_8000_HZ:
00279 case MAD_UNITS_11025_HZ:
00280 case MAD_UNITS_12000_HZ:
00281 case MAD_UNITS_16000_HZ:
00282 case MAD_UNITS_22050_HZ:
00283 case MAD_UNITS_24000_HZ:
00284 case MAD_UNITS_32000_HZ:
00285 case MAD_UNITS_44100_HZ:
00286 case MAD_UNITS_48000_HZ:
00287
00288 case MAD_UNITS_24_FPS:
00289 case MAD_UNITS_25_FPS:
00290 case MAD_UNITS_30_FPS:
00291 case MAD_UNITS_48_FPS:
00292 case MAD_UNITS_50_FPS:
00293 case MAD_UNITS_60_FPS:
00294 case MAD_UNITS_75_FPS:
00295 return timer.seconds * (signed long) units +
00296 (signed long) scale_rational(timer.fraction, MAD_TIMER_RESOLUTION,
00297 units);
00298
00299 case MAD_UNITS_23_976_FPS:
00300 case MAD_UNITS_24_975_FPS:
00301 case MAD_UNITS_29_97_FPS:
00302 case MAD_UNITS_47_952_FPS:
00303 case MAD_UNITS_49_95_FPS:
00304 case MAD_UNITS_59_94_FPS:
00305 return (mad_timer_count(timer, -units) + 1) * 1000 / 1001;
00306 }
00307
00308
00309 return 0;
00310 }
00311
00315 unsigned long mad_timer_fraction(mad_timer_t timer, unsigned long denom)
00316 {
00317 timer = mad_timer_abs(timer);
00318
00319 switch (denom) {
00320 case 0:
00321 return timer.fraction ?
00322 MAD_TIMER_RESOLUTION / timer.fraction : MAD_TIMER_RESOLUTION + 1;
00323
00324 case MAD_TIMER_RESOLUTION:
00325 return timer.fraction;
00326
00327 default:
00328 return scale_rational(timer.fraction, MAD_TIMER_RESOLUTION, denom);
00329 }
00330 }
00331
00335 void mad_timer_string(mad_timer_t timer,
00336 char *dest, char const *format, enum mad_units units,
00337 enum mad_units fracunits, unsigned long subparts)
00338 {
00339 unsigned long hours, minutes, seconds, sub;
00340 unsigned int frac;
00341
00342 timer = mad_timer_abs(timer);
00343
00344 seconds = timer.seconds;
00345 frac = sub = 0;
00346
00347 switch (fracunits) {
00348 case MAD_UNITS_HOURS:
00349 case MAD_UNITS_MINUTES:
00350 case MAD_UNITS_SECONDS:
00351 break;
00352
00353 case MAD_UNITS_DECISECONDS:
00354 case MAD_UNITS_CENTISECONDS:
00355 case MAD_UNITS_MILLISECONDS:
00356
00357 case MAD_UNITS_8000_HZ:
00358 case MAD_UNITS_11025_HZ:
00359 case MAD_UNITS_12000_HZ:
00360 case MAD_UNITS_16000_HZ:
00361 case MAD_UNITS_22050_HZ:
00362 case MAD_UNITS_24000_HZ:
00363 case MAD_UNITS_32000_HZ:
00364 case MAD_UNITS_44100_HZ:
00365 case MAD_UNITS_48000_HZ:
00366
00367 case MAD_UNITS_24_FPS:
00368 case MAD_UNITS_25_FPS:
00369 case MAD_UNITS_30_FPS:
00370 case MAD_UNITS_48_FPS:
00371 case MAD_UNITS_50_FPS:
00372 case MAD_UNITS_60_FPS:
00373 case MAD_UNITS_75_FPS:
00374 {
00375 unsigned long denom;
00376
00377 denom = MAD_TIMER_RESOLUTION / fracunits;
00378
00379 frac = timer.fraction / denom;
00380 sub = scale_rational(timer.fraction % denom, denom, subparts);
00381 }
00382 break;
00383
00384 case MAD_UNITS_23_976_FPS:
00385 case MAD_UNITS_24_975_FPS:
00386 case MAD_UNITS_29_97_FPS:
00387 case MAD_UNITS_47_952_FPS:
00388 case MAD_UNITS_49_95_FPS:
00389 case MAD_UNITS_59_94_FPS:
00390
00391
00392 {
00393 unsigned long frame, cycle, d, m;
00394
00395 frame = mad_timer_count(timer, fracunits);
00396
00397 cycle = -fracunits * 60 * 10 - (10 - 1) * 2;
00398
00399 d = frame / cycle;
00400 m = frame % cycle;
00401 frame += (10 - 1) * 2 * d;
00402 if (m > 2)
00403 frame += 2 * ((m - 2) / (cycle / 10));
00404
00405 frac = frame % -fracunits;
00406 seconds = frame / -fracunits;
00407 }
00408 break;
00409 }
00410
00411 switch (units) {
00412 case MAD_UNITS_HOURS:
00413 minutes = seconds / 60;
00414 hours = minutes / 60;
00415
00416 sprintf(dest, format,
00417 hours,
00418 (unsigned int) (minutes % 60),
00419 (unsigned int) (seconds % 60),
00420 frac, sub);
00421 break;
00422
00423 case MAD_UNITS_MINUTES:
00424 minutes = seconds / 60;
00425
00426 sprintf(dest, format,
00427 minutes,
00428 (unsigned int) (seconds % 60),
00429 frac, sub);
00430 break;
00431
00432 case MAD_UNITS_SECONDS:
00433 sprintf(dest, format,
00434 seconds,
00435 frac, sub);
00436 break;
00437
00438 case MAD_UNITS_23_976_FPS:
00439 case MAD_UNITS_24_975_FPS:
00440 case MAD_UNITS_29_97_FPS:
00441 case MAD_UNITS_47_952_FPS:
00442 case MAD_UNITS_49_95_FPS:
00443 case MAD_UNITS_59_94_FPS:
00444 if (fracunits < 0) {
00445
00446 sub = 0;
00447 }
00448
00449
00450
00451 case MAD_UNITS_DECISECONDS:
00452 case MAD_UNITS_CENTISECONDS:
00453 case MAD_UNITS_MILLISECONDS:
00454
00455 case MAD_UNITS_8000_HZ:
00456 case MAD_UNITS_11025_HZ:
00457 case MAD_UNITS_12000_HZ:
00458 case MAD_UNITS_16000_HZ:
00459 case MAD_UNITS_22050_HZ:
00460 case MAD_UNITS_24000_HZ:
00461 case MAD_UNITS_32000_HZ:
00462 case MAD_UNITS_44100_HZ:
00463 case MAD_UNITS_48000_HZ:
00464
00465 case MAD_UNITS_24_FPS:
00466 case MAD_UNITS_25_FPS:
00467 case MAD_UNITS_30_FPS:
00468 case MAD_UNITS_48_FPS:
00469 case MAD_UNITS_50_FPS:
00470 case MAD_UNITS_60_FPS:
00471 case MAD_UNITS_75_FPS:
00472 sprintf(dest, format, mad_timer_count(timer, units), sub);
00473 break;
00474 }
00475 }