timer.c 10 KB

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