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