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

Dependencies:   FatFileSystemCpp I2SSlave TLV320 mbed

Fork of madplayer by Andreas Grün

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers timer.cpp Source File

timer.cpp

00001 /*
00002  * libmad - MPEG audio decoder library
00003  * Copyright (C) 2000-2004 Underbit Technologies, Inc.
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018  *
00019  * $Id: timer.c,v 1.1 2010/11/23 20:12:57 andy Exp $
00020  */
00021 
00022 #  include "config.h"
00023 
00024 # include "global.h"
00025 
00026 # include <stdio.h>
00027 
00028 # include "timer.h"
00029 
00030 mad_timer_t const mad_timer_zero = { 0, 0 };
00031 
00032 /*
00033  * NAME:    timer->compare()
00034  * DESCRIPTION: indicate relative order of two timers
00035  */
00036 int mad_timer_compare(mad_timer_t timer1, mad_timer_t timer2)
00037 {
00038   signed long diff;
00039 
00040   diff = timer1.seconds - timer2.seconds;
00041   if (diff < 0)
00042     return -1;
00043   else if (diff > 0)
00044     return +1;
00045 
00046   diff = timer1.fraction - timer2.fraction;
00047   if (diff < 0)
00048     return -1;
00049   else if (diff > 0)
00050     return +1;
00051 
00052   return 0;
00053 }
00054 
00055 /*
00056  * NAME:    timer->negate()
00057  * DESCRIPTION: invert the sign of a timer
00058  */
00059 void mad_timer_negate(mad_timer_t *timer)
00060 {
00061   timer->seconds = -timer->seconds;
00062 
00063   if (timer->fraction) {
00064     timer->seconds -= 1;
00065     timer->fraction = MAD_TIMER_RESOLUTION - timer->fraction;
00066   }
00067 }
00068 
00069 /*
00070  * NAME:    timer->abs()
00071  * DESCRIPTION: return the absolute value of a timer
00072  */
00073 mad_timer_t mad_timer_abs(mad_timer_t timer)
00074 {
00075   if (timer.seconds < 0)
00076     mad_timer_negate(&timer);
00077 
00078   return timer;
00079 }
00080 
00081 /*
00082  * NAME:    reduce_timer()
00083  * DESCRIPTION: carry timer fraction into seconds
00084  */
00085 static
00086 void reduce_timer(mad_timer_t *timer)
00087 {
00088   timer->seconds  += timer->fraction / MAD_TIMER_RESOLUTION;
00089   timer->fraction %= MAD_TIMER_RESOLUTION;
00090 }
00091 
00092 /*
00093  * NAME:    gcd()
00094  * DESCRIPTION: compute greatest common denominator
00095  */
00096 static
00097 unsigned long gcd(unsigned long num1, unsigned long num2)
00098 {
00099   unsigned long tmp;
00100 
00101   while (num2) {
00102     tmp  = num2;
00103     num2 = num1 % num2;
00104     num1 = tmp;
00105   }
00106 
00107   return num1;
00108 }
00109 
00110 /*
00111  * NAME:    reduce_rational()
00112  * DESCRIPTION: convert rational expression to lowest terms
00113  */
00114 static
00115 void reduce_rational(unsigned long *numer, unsigned long *denom)
00116 {
00117   unsigned long factor;
00118 
00119   factor = gcd(*numer, *denom);
00120 
00121 /*  assert(factor != 0); */
00122 
00123   *numer /= factor;
00124   *denom /= factor;
00125 }
00126 
00127 /*
00128  * NAME:    scale_rational()
00129  * DESCRIPTION: solve numer/denom == ?/scale avoiding overflowing
00130  */
00131 static
00132 unsigned long scale_rational(unsigned long numer, unsigned long denom,
00133                  unsigned long scale)
00134 {
00135   reduce_rational(&numer, &denom);
00136   reduce_rational(&scale, &denom);
00137 
00138 /*  assert(denom != 0);*/
00139 
00140   if (denom < scale)
00141     return numer * (scale / denom) + numer * (scale % denom) / denom;
00142   if (denom < numer)
00143     return scale * (numer / denom) + scale * (numer % denom) / denom;
00144 
00145   return numer * scale / denom;
00146 }
00147 
00148 /*
00149  * NAME:    timer->set()
00150  * DESCRIPTION: set timer to specific (positive) value
00151  */
00152 void mad_timer_set(mad_timer_t *timer, unsigned long seconds,
00153            unsigned long numer, unsigned long denom)
00154 {
00155   timer->seconds = seconds;
00156   if (numer >= denom && denom > 0) {
00157     timer->seconds += numer / denom;
00158     numer %= denom;
00159   }
00160 
00161   switch (denom) {
00162   case 0:
00163   case 1:
00164     timer->fraction = 0;
00165     break;
00166 
00167   case MAD_TIMER_RESOLUTION:
00168     timer->fraction = numer;
00169     break;
00170 
00171   case 1000:
00172     timer->fraction = numer * (MAD_TIMER_RESOLUTION /  1000);
00173     break;
00174 
00175   case 8000:
00176     timer->fraction = numer * (MAD_TIMER_RESOLUTION /  8000);
00177     break;
00178 
00179   case 11025:
00180     timer->fraction = numer * (MAD_TIMER_RESOLUTION / 11025);
00181     break;
00182 
00183   case 12000:
00184     timer->fraction = numer * (MAD_TIMER_RESOLUTION / 12000);
00185     break;
00186 
00187   case 16000:
00188     timer->fraction = numer * (MAD_TIMER_RESOLUTION / 16000);
00189     break;
00190 
00191   case 22050:
00192     timer->fraction = numer * (MAD_TIMER_RESOLUTION / 22050);
00193     break;
00194 
00195   case 24000:
00196     timer->fraction = numer * (MAD_TIMER_RESOLUTION / 24000);
00197     break;
00198 
00199   case 32000:
00200     timer->fraction = numer * (MAD_TIMER_RESOLUTION / 32000);
00201     break;
00202 
00203   case 44100:
00204     timer->fraction = numer * (MAD_TIMER_RESOLUTION / 44100);
00205     break;
00206 
00207   case 48000:
00208     timer->fraction = numer * (MAD_TIMER_RESOLUTION / 48000);
00209     break;
00210 
00211   default:
00212     timer->fraction = scale_rational(numer, denom, MAD_TIMER_RESOLUTION);
00213     break;
00214   }
00215 
00216   if (timer->fraction >= MAD_TIMER_RESOLUTION)
00217     reduce_timer(timer);
00218 }
00219 
00220 /*
00221  * NAME:    timer->add()
00222  * DESCRIPTION: add one timer to another
00223  */
00224 void mad_timer_add(mad_timer_t *timer, mad_timer_t incr)
00225 {
00226   timer->seconds  += incr.seconds;
00227   timer->fraction += incr.fraction;
00228 
00229   if (timer->fraction >= MAD_TIMER_RESOLUTION)
00230     reduce_timer(timer);
00231 }
00232 
00233 /*
00234  * NAME:    timer->multiply()
00235  * DESCRIPTION: multiply a timer by a scalar value
00236  */
00237 void mad_timer_multiply(mad_timer_t *timer, signed long scalar)
00238 {
00239   mad_timer_t addend;
00240   unsigned long factor;
00241 
00242   factor = scalar;
00243   if (scalar < 0) {
00244     factor = -scalar;
00245     mad_timer_negate(timer);
00246   }
00247 
00248   addend = *timer;
00249   *timer = mad_timer_zero;
00250 
00251   while (factor) {
00252     if (factor & 1)
00253       mad_timer_add(timer, addend);
00254 
00255     mad_timer_add(&addend, addend);
00256     factor >>= 1;
00257   }
00258 }
00259 
00260 /*
00261  * NAME:    timer->count()
00262  * DESCRIPTION: return timer value in selected units
00263  */
00264 signed long mad_timer_count(mad_timer_t timer, enum mad_units units)
00265 {
00266   switch (units) {
00267   case MAD_UNITS_HOURS:
00268     return timer.seconds / 60 / 60;
00269 
00270   case MAD_UNITS_MINUTES:
00271     return timer.seconds / 60;
00272 
00273   case MAD_UNITS_SECONDS:
00274     return timer.seconds;
00275 
00276   case MAD_UNITS_DECISECONDS:
00277   case MAD_UNITS_CENTISECONDS:
00278   case MAD_UNITS_MILLISECONDS:
00279 
00280   case MAD_UNITS_8000_HZ:
00281   case MAD_UNITS_11025_HZ:
00282   case MAD_UNITS_12000_HZ:
00283   case MAD_UNITS_16000_HZ:
00284   case MAD_UNITS_22050_HZ:
00285   case MAD_UNITS_24000_HZ:
00286   case MAD_UNITS_32000_HZ:
00287   case MAD_UNITS_44100_HZ:
00288   case MAD_UNITS_48000_HZ:
00289 
00290   case MAD_UNITS_24_FPS:
00291   case MAD_UNITS_25_FPS:
00292   case MAD_UNITS_30_FPS:
00293   case MAD_UNITS_48_FPS:
00294   case MAD_UNITS_50_FPS:
00295   case MAD_UNITS_60_FPS:
00296   case MAD_UNITS_75_FPS:
00297     return timer.seconds * (signed long) units +
00298       (signed long) scale_rational(timer.fraction, MAD_TIMER_RESOLUTION,
00299                    units);
00300 
00301   case MAD_UNITS_23_976_FPS:
00302   case MAD_UNITS_24_975_FPS:
00303   case MAD_UNITS_29_97_FPS:
00304   case MAD_UNITS_47_952_FPS:
00305   case MAD_UNITS_49_95_FPS:
00306   case MAD_UNITS_59_94_FPS:
00307     return (mad_timer_count(timer, (enum mad_units)-units) + 1) * 1000 / 1001;
00308   }
00309 
00310   /* unsupported units */
00311   return 0;
00312 }
00313 
00314 /*
00315  * NAME:    timer->fraction()
00316  * DESCRIPTION: return fractional part of timer in arbitrary terms
00317  */
00318 unsigned long mad_timer_fraction(mad_timer_t timer, unsigned long denom)
00319 {
00320   timer = mad_timer_abs(timer);
00321 
00322   switch (denom) {
00323   case 0:
00324     return timer.fraction ?
00325       MAD_TIMER_RESOLUTION / timer.fraction : MAD_TIMER_RESOLUTION + 1;
00326 
00327   case MAD_TIMER_RESOLUTION:
00328     return timer.fraction;
00329 
00330   default:
00331     return scale_rational(timer.fraction, MAD_TIMER_RESOLUTION, denom);
00332   }
00333 }
00334 
00335 /*
00336  * NAME:    timer->string()
00337  * DESCRIPTION: write a string representation of a timer using a template
00338  */
00339 void mad_timer_string(mad_timer_t timer,
00340               char *dest, char const *format, enum mad_units units,
00341               enum mad_units fracunits, unsigned long subparts)
00342 {
00343   unsigned long hours, minutes, seconds, sub;
00344   unsigned int frac;
00345 
00346   timer = mad_timer_abs(timer);
00347 
00348   seconds = timer.seconds;
00349   frac = sub = 0;
00350 
00351   switch (fracunits) {
00352   case MAD_UNITS_HOURS:
00353   case MAD_UNITS_MINUTES:
00354   case MAD_UNITS_SECONDS:
00355     break;
00356 
00357   case MAD_UNITS_DECISECONDS:
00358   case MAD_UNITS_CENTISECONDS:
00359   case MAD_UNITS_MILLISECONDS:
00360 
00361   case MAD_UNITS_8000_HZ:
00362   case MAD_UNITS_11025_HZ:
00363   case MAD_UNITS_12000_HZ:
00364   case MAD_UNITS_16000_HZ:
00365   case MAD_UNITS_22050_HZ:
00366   case MAD_UNITS_24000_HZ:
00367   case MAD_UNITS_32000_HZ:
00368   case MAD_UNITS_44100_HZ:
00369   case MAD_UNITS_48000_HZ:
00370 
00371   case MAD_UNITS_24_FPS:
00372   case MAD_UNITS_25_FPS:
00373   case MAD_UNITS_30_FPS:
00374   case MAD_UNITS_48_FPS:
00375   case MAD_UNITS_50_FPS:
00376   case MAD_UNITS_60_FPS:
00377   case MAD_UNITS_75_FPS:
00378     {
00379       unsigned long denom;
00380 
00381       denom = MAD_TIMER_RESOLUTION / fracunits;
00382 
00383       frac = timer.fraction / denom;
00384       sub  = scale_rational(timer.fraction % denom, denom, subparts);
00385     }
00386     break;
00387 
00388   case MAD_UNITS_23_976_FPS:
00389   case MAD_UNITS_24_975_FPS:
00390   case MAD_UNITS_29_97_FPS:
00391   case MAD_UNITS_47_952_FPS:
00392   case MAD_UNITS_49_95_FPS:
00393   case MAD_UNITS_59_94_FPS:
00394     /* drop-frame encoding */
00395     /* N.B. this is only well-defined for MAD_UNITS_29_97_FPS */
00396     {
00397       unsigned long frame, cycle, d, m;
00398 
00399       frame = mad_timer_count(timer, fracunits);
00400 
00401       cycle = -fracunits * 60 * 10 - (10 - 1) * 2;
00402 
00403       d = frame / cycle;
00404       m = frame % cycle;
00405       frame += (10 - 1) * 2 * d;
00406       if (m > 2)
00407     frame += 2 * ((m - 2) / (cycle / 10));
00408 
00409       frac    = frame % -fracunits;
00410       seconds = frame / -fracunits;
00411     }
00412     break;
00413   }
00414 
00415   switch (units) {
00416   case MAD_UNITS_HOURS:
00417     minutes = seconds / 60;
00418     hours   = minutes / 60;
00419 
00420     sprintf(dest, format,
00421         hours,
00422         (unsigned int) (minutes % 60),
00423         (unsigned int) (seconds % 60),
00424         frac, sub);
00425     break;
00426 
00427   case MAD_UNITS_MINUTES:
00428     minutes = seconds / 60;
00429 
00430     sprintf(dest, format,
00431         minutes,
00432         (unsigned int) (seconds % 60),
00433         frac, sub);
00434     break;
00435 
00436   case MAD_UNITS_SECONDS:
00437     sprintf(dest, format,
00438         seconds,
00439         frac, sub);
00440     break;
00441 
00442   case MAD_UNITS_23_976_FPS:
00443   case MAD_UNITS_24_975_FPS:
00444   case MAD_UNITS_29_97_FPS:
00445   case MAD_UNITS_47_952_FPS:
00446   case MAD_UNITS_49_95_FPS:
00447   case MAD_UNITS_59_94_FPS:
00448     if (fracunits < 0) {
00449       /* not yet implemented */
00450       sub = 0;
00451     }
00452 
00453     /* fall through */
00454 
00455   case MAD_UNITS_DECISECONDS:
00456   case MAD_UNITS_CENTISECONDS:
00457   case MAD_UNITS_MILLISECONDS:
00458 
00459   case MAD_UNITS_8000_HZ:
00460   case MAD_UNITS_11025_HZ:
00461   case MAD_UNITS_12000_HZ:
00462   case MAD_UNITS_16000_HZ:
00463   case MAD_UNITS_22050_HZ:
00464   case MAD_UNITS_24000_HZ:
00465   case MAD_UNITS_32000_HZ:
00466   case MAD_UNITS_44100_HZ:
00467   case MAD_UNITS_48000_HZ:
00468 
00469   case MAD_UNITS_24_FPS:
00470   case MAD_UNITS_25_FPS:
00471   case MAD_UNITS_30_FPS:
00472   case MAD_UNITS_48_FPS:
00473   case MAD_UNITS_50_FPS:
00474   case MAD_UNITS_60_FPS:
00475   case MAD_UNITS_75_FPS:
00476     sprintf(dest, format, mad_timer_count(timer, units), sub);
00477     break;
00478   }
00479 }