streo mp3 player see: http://mbed.org/users/okini3939/notebook/I2S_AUDIO

Dependencies:   FatFileSystemCpp I2SSlave TLV320 mbed

Fork of madplayer by Andreas Grün

Committer:
okini3939
Date:
Fri Jul 26 15:02:49 2013 +0000
Revision:
5:50015f4868e2
Parent:
4:30b2cf4a8ee2
fix

Who changed what in which revision?

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