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