timer.c
上传用户:tuheem
上传日期:2007-05-01
资源大小:21889k
文件大小:10k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. /*
  2.  * libmad - MPEG audio decoder library
  3.  
  4.  */
  5. # ifdef HAVE_CONFIG_H
  6. #  include "config.h"
  7. # endif
  8. # include "global.h"
  9. # include <stdio.h>
  10. # ifdef HAVE_ASSERT_H
  11. #  include <assert.h>
  12. # endif
  13. # include "timer.h"
  14. mad_timer_t const mad_timer_zero = { 0, 0 };
  15. /*
  16.  * NAME: timer->compare()
  17.  * DESCRIPTION: indicate relative order of two timers
  18.  */
  19. int mad_timer_compare(mad_timer_t timer1, mad_timer_t timer2)
  20. {
  21.   signed long diff;
  22.   diff = timer1.seconds - timer2.seconds;
  23.   if (diff < 0)
  24.     return -1;
  25.   else if (diff > 0)
  26.     return +1;
  27.   diff = timer1.fraction - timer2.fraction;
  28.   if (diff < 0)
  29.     return -1;
  30.   else if (diff > 0)
  31.     return +1;
  32.   return 0;
  33. }
  34. /*
  35.  * NAME: timer->negate()
  36.  * DESCRIPTION: invert the sign of a timer
  37.  */
  38. void mad_timer_negate(mad_timer_t *timer)
  39. {
  40.   timer->seconds = -timer->seconds;
  41.   if (timer->fraction) {
  42.     timer->seconds -= 1;
  43.     timer->fraction = MAD_TIMER_RESOLUTION - timer->fraction;
  44.   }
  45. }
  46. /*
  47.  * NAME: timer->abs()
  48.  * DESCRIPTION: return the absolute value of a timer
  49.  */
  50. mad_timer_t mad_timer_abs(mad_timer_t timer)
  51. {
  52.   if (mad_timer_sign(timer) < 0)
  53.     mad_timer_negate(&timer);
  54.   return timer;
  55. }
  56. /*
  57.  * NAME: reduce_timer()
  58.  * DESCRIPTION: carry timer fraction into seconds
  59.  */
  60. static
  61. void reduce_timer(mad_timer_t *timer)
  62. {
  63.   timer->seconds  += timer->fraction / MAD_TIMER_RESOLUTION;
  64.   timer->fraction %= MAD_TIMER_RESOLUTION;
  65. }
  66. /*
  67.  * NAME: gcd()
  68.  * DESCRIPTION: compute greatest common denominator
  69.  */
  70. static
  71. unsigned long gcd(unsigned long num1, unsigned long num2)
  72. {
  73.   unsigned long tmp;
  74.   while (num2) {
  75.     tmp  = num2;
  76.     num2 = num1 % num2;
  77.     num1 = tmp;
  78.   }
  79.   return num1;
  80. }
  81. /*
  82.  * NAME: reduce_rational()
  83.  * DESCRIPTION: convert rational expression to lowest terms
  84.  */
  85. static
  86. void reduce_rational(unsigned long *numer, unsigned long *denom)
  87. {
  88.   unsigned long factor;
  89.   factor = gcd(*numer, *denom);
  90.   assert(factor != 0);
  91.   *numer /= factor;
  92.   *denom /= factor;
  93. }
  94. /*
  95.  * NAME: scale_rational()
  96.  * DESCRIPTION: solve numer/denom == ?/scale avoiding overflowing
  97.  */
  98. static
  99. unsigned long scale_rational(unsigned long numer, unsigned long denom,
  100.      unsigned long scale)
  101. {
  102.   reduce_rational(&numer, &denom);
  103.   reduce_rational(&scale, &denom);
  104.   assert(denom != 0);
  105.   if (denom < scale)
  106.     return numer * (scale / denom) + numer * (scale % denom) / denom;
  107.   if (denom < numer)
  108.     return scale * (numer / denom) + scale * (numer % denom) / denom;
  109.   return numer * scale / denom;
  110. }
  111. /*
  112.  * NAME: timer->set()
  113.  * DESCRIPTION: set timer to specific (positive) value
  114.  */
  115. void mad_timer_set(mad_timer_t *timer, unsigned long seconds,
  116.    unsigned long numer, unsigned long denom)
  117. {
  118.   timer->seconds = seconds;
  119.   if (numer >= denom && denom > 0) {
  120.     timer->seconds += numer / denom;
  121.     numer %= denom;
  122.   }
  123.   switch (denom) {
  124.   case 0:
  125.   case 1:
  126.     timer->fraction = 0;
  127.     break;
  128.   case MAD_TIMER_RESOLUTION:
  129.     timer->fraction = numer;
  130.     break;
  131.   case 1000:
  132.     timer->fraction = numer * (MAD_TIMER_RESOLUTION /  1000);
  133.     break;
  134.   case 8000:
  135.     timer->fraction = numer * (MAD_TIMER_RESOLUTION /  8000);
  136.     break;
  137.   case 11025:
  138.     timer->fraction = numer * (MAD_TIMER_RESOLUTION / 11025);
  139.     break;
  140.   case 12000:
  141.     timer->fraction = numer * (MAD_TIMER_RESOLUTION / 12000);
  142.     break;
  143.   case 16000:
  144.     timer->fraction = numer * (MAD_TIMER_RESOLUTION / 16000);
  145.     break;
  146.   case 22050:
  147.     timer->fraction = numer * (MAD_TIMER_RESOLUTION / 22050);
  148.     break;
  149.   case 24000:
  150.     timer->fraction = numer * (MAD_TIMER_RESOLUTION / 24000);
  151.     break;
  152.   case 32000:
  153.     timer->fraction = numer * (MAD_TIMER_RESOLUTION / 32000);
  154.     break;
  155.   case 44100:
  156.     timer->fraction = numer * (MAD_TIMER_RESOLUTION / 44100);
  157.     break;
  158.   case 48000:
  159.     timer->fraction = numer * (MAD_TIMER_RESOLUTION / 48000);
  160.     break;
  161.   default:
  162.     timer->fraction = scale_rational(numer, denom, MAD_TIMER_RESOLUTION);
  163.     break;
  164.   }
  165.   if (timer->fraction >= MAD_TIMER_RESOLUTION)
  166.     reduce_timer(timer);
  167. }
  168. /*
  169.  * NAME: timer->add()
  170.  * DESCRIPTION: add one timer to another
  171.  */
  172. void mad_timer_add(mad_timer_t *timer, mad_timer_t incr)
  173. {
  174.   timer->seconds  += incr.seconds;
  175.   timer->fraction += incr.fraction;
  176.   if (timer->fraction >= MAD_TIMER_RESOLUTION)
  177.     reduce_timer(timer);
  178. }
  179. /*
  180.  * NAME: timer->multiply()
  181.  * DESCRIPTION: multiply a timer by a scalar value
  182.  */
  183. void mad_timer_multiply(mad_timer_t *timer, signed long scalar)
  184. {
  185.   mad_timer_t addend;
  186.   unsigned long factor;
  187.   factor = scalar;
  188.   if (scalar < 0) {
  189.     factor = -scalar;
  190.     mad_timer_negate(timer);
  191.   }
  192.   addend = *timer;
  193.   *timer = mad_timer_zero;
  194.   while (factor) {
  195.     if (factor & 1)
  196.       mad_timer_add(timer, addend);
  197.     mad_timer_add(&addend, addend);
  198.     factor >>= 1;
  199.   }
  200. }
  201. /*
  202.  * NAME: timer->count()
  203.  * DESCRIPTION: return timer value in selected units
  204.  */
  205. signed long mad_timer_count(mad_timer_t timer, enum mad_units units)
  206. {
  207.   switch (units) {
  208.   case MAD_UNITS_HOURS:
  209.     return timer.seconds / 60 / 60;
  210.   case MAD_UNITS_MINUTES:
  211.     return timer.seconds / 60;
  212.   case MAD_UNITS_SECONDS:
  213.     return timer.seconds;
  214.   case MAD_UNITS_DECISECONDS:
  215.   case MAD_UNITS_CENTISECONDS:
  216.   case MAD_UNITS_MILLISECONDS:
  217.   case MAD_UNITS_8000_HZ:
  218.   case MAD_UNITS_11025_HZ:
  219.   case MAD_UNITS_12000_HZ:
  220.   case MAD_UNITS_16000_HZ:
  221.   case MAD_UNITS_22050_HZ:
  222.   case MAD_UNITS_24000_HZ:
  223.   case MAD_UNITS_32000_HZ:
  224.   case MAD_UNITS_44100_HZ:
  225.   case MAD_UNITS_48000_HZ:
  226.   case MAD_UNITS_24_FPS:
  227.   case MAD_UNITS_25_FPS:
  228.   case MAD_UNITS_30_FPS:
  229.   case MAD_UNITS_48_FPS:
  230.   case MAD_UNITS_50_FPS:
  231.   case MAD_UNITS_60_FPS:
  232.   case MAD_UNITS_75_FPS:
  233.     return timer.seconds * (signed long) units +
  234.       (signed long) scale_rational(timer.fraction, MAD_TIMER_RESOLUTION,
  235.    units);
  236.   case MAD_UNITS_23_976_FPS:
  237.   case MAD_UNITS_24_975_FPS:
  238.   case MAD_UNITS_29_97_FPS:
  239.   case MAD_UNITS_47_952_FPS:
  240.   case MAD_UNITS_49_95_FPS:
  241.   case MAD_UNITS_59_94_FPS:
  242.     return (mad_timer_count(timer, -units) + 1) * 1000 / 1001;
  243.   }
  244.   /* unsupported units */
  245.   return 0;
  246. }
  247. /*
  248.  * NAME: timer->fraction()
  249.  * DESCRIPTION: return fractional part of timer in arbitrary terms
  250.  */
  251. unsigned long mad_timer_fraction(mad_timer_t timer, unsigned long denom)
  252. {
  253.   timer = mad_timer_abs(timer);
  254.   switch (denom) {
  255.   case 0:
  256.     return MAD_TIMER_RESOLUTION / timer.fraction;
  257.   case MAD_TIMER_RESOLUTION:
  258.     return timer.fraction;
  259.   default:
  260.     return scale_rational(timer.fraction, MAD_TIMER_RESOLUTION, denom);
  261.   }
  262. }
  263. /*
  264.  * NAME: timer->string()
  265.  * DESCRIPTION: write a string representation of a timer using a template
  266.  */
  267. void mad_timer_string(mad_timer_t timer,
  268.       char *dest, char const *format, enum mad_units units,
  269.       enum mad_units fracunits, unsigned long subparts)
  270. {
  271.   unsigned long hours, minutes, seconds, sub;
  272.   unsigned int frac;
  273.   timer = mad_timer_abs(timer);
  274.   seconds = timer.seconds;
  275.   frac = sub = 0;
  276.   switch (fracunits) {
  277.   case MAD_UNITS_HOURS:
  278.   case MAD_UNITS_MINUTES:
  279.   case MAD_UNITS_SECONDS:
  280.     break;
  281.   case MAD_UNITS_DECISECONDS:
  282.   case MAD_UNITS_CENTISECONDS:
  283.   case MAD_UNITS_MILLISECONDS:
  284.   case MAD_UNITS_8000_HZ:
  285.   case MAD_UNITS_11025_HZ:
  286.   case MAD_UNITS_12000_HZ:
  287.   case MAD_UNITS_16000_HZ:
  288.   case MAD_UNITS_22050_HZ:
  289.   case MAD_UNITS_24000_HZ:
  290.   case MAD_UNITS_32000_HZ:
  291.   case MAD_UNITS_44100_HZ:
  292.   case MAD_UNITS_48000_HZ:
  293.   case MAD_UNITS_24_FPS:
  294.   case MAD_UNITS_25_FPS:
  295.   case MAD_UNITS_30_FPS:
  296.   case MAD_UNITS_48_FPS:
  297.   case MAD_UNITS_50_FPS:
  298.   case MAD_UNITS_60_FPS:
  299.   case MAD_UNITS_75_FPS:
  300.     {
  301.       unsigned long denom;
  302.       denom = MAD_TIMER_RESOLUTION / fracunits;
  303.       frac = timer.fraction / denom;
  304.       sub  = scale_rational(timer.fraction % denom, denom, subparts);
  305.     }
  306.     break;
  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.     /* drop-frame encoding */
  314.     /* N.B. this is only well-defined for MAD_UNITS_29_97_FPS */
  315.     {
  316.       unsigned long frame, cycle, d, m;
  317.       frame = mad_timer_count(timer, fracunits);
  318.       cycle = -fracunits * 60 * 10 - (10 - 1) * 2;
  319.       d = frame / cycle;
  320.       m = frame % cycle;
  321.       frame += (10 - 1) * 2 * d;
  322.       if (m > 2)
  323. frame += 2 * ((m - 2) / (cycle / 10));
  324.       frac    = frame % -fracunits;
  325.       seconds = frame / -fracunits;
  326.     }
  327.     break;
  328.   }
  329.   switch (units) {
  330.   case MAD_UNITS_HOURS:
  331.     minutes = seconds / 60;
  332.     hours   = minutes / 60;
  333.     sprintf(dest, format,
  334.     hours,
  335.     (unsigned int) (minutes % 60),
  336.     (unsigned int) (seconds % 60),
  337.     frac, sub);
  338.     break;
  339.   case MAD_UNITS_MINUTES:
  340.     minutes = seconds / 60;
  341.     sprintf(dest, format,
  342.     minutes,
  343.     (unsigned int) (seconds % 60),
  344.     frac, sub);
  345.     break;
  346.   case MAD_UNITS_SECONDS:
  347.     sprintf(dest, format,
  348.     seconds,
  349.     frac, sub);
  350.     break;
  351.   case MAD_UNITS_23_976_FPS:
  352.   case MAD_UNITS_24_975_FPS:
  353.   case MAD_UNITS_29_97_FPS:
  354.   case MAD_UNITS_47_952_FPS:
  355.   case MAD_UNITS_49_95_FPS:
  356.   case MAD_UNITS_59_94_FPS:
  357.     if (fracunits < 0) {
  358.       /* not yet implemented */
  359.       sub = 0;
  360.     }
  361.     /* fall through */
  362.   case MAD_UNITS_DECISECONDS:
  363.   case MAD_UNITS_CENTISECONDS:
  364.   case MAD_UNITS_MILLISECONDS:
  365.   case MAD_UNITS_8000_HZ:
  366.   case MAD_UNITS_11025_HZ:
  367.   case MAD_UNITS_12000_HZ:
  368.   case MAD_UNITS_16000_HZ:
  369.   case MAD_UNITS_22050_HZ:
  370.   case MAD_UNITS_24000_HZ:
  371.   case MAD_UNITS_32000_HZ:
  372.   case MAD_UNITS_44100_HZ:
  373.   case MAD_UNITS_48000_HZ:
  374.   case MAD_UNITS_24_FPS:
  375.   case MAD_UNITS_25_FPS:
  376.   case MAD_UNITS_30_FPS:
  377.   case MAD_UNITS_48_FPS:
  378.   case MAD_UNITS_50_FPS:
  379.   case MAD_UNITS_60_FPS:
  380.   case MAD_UNITS_75_FPS:
  381.     sprintf(dest, format, mad_timer_count(timer, units), sub);
  382.     break;
  383.   }
  384. }