Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

485 lines
10 KiB

  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. # 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. }