timer.c
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:11k
源码类别:

多媒体编程

开发平台:

Visual C++

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