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 fixed.h Source File

fixed.h

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: fixed.h,v 1.1 2010/11/23 20:12:57 andy Exp $
00020  */
00021 
00022 # ifndef LIBMAD_FIXED_H
00023 # define LIBMAD_FIXED_H
00024 
00025 #include "config.h"
00026 
00027 # if SIZEOF_INT >= 4
00028 typedef   signed int mad_fixed_t;
00029 
00030 typedef   signed int mad_fixed64hi_t;
00031 typedef unsigned int mad_fixed64lo_t;
00032 # else
00033 typedef   signed long mad_fixed_t;
00034 
00035 typedef   signed long mad_fixed64hi_t;
00036 typedef unsigned long mad_fixed64lo_t;
00037 # endif
00038 
00039 # if defined(_MSC_VER)
00040 #  define mad_fixed64_t  signed __int64
00041 # elif 1 || defined(__GNUC__)
00042 #  define mad_fixed64_t  signed long long
00043 # endif
00044 
00045 # if defined(FPM_FLOAT)
00046 typedef double mad_sample_t;
00047 # else
00048 typedef mad_fixed_t mad_sample_t;
00049 # endif
00050 
00051 /*
00052  * Fixed-point format: 0xABBBBBBB
00053  * A == whole part      (sign + 3 bits)
00054  * B == fractional part (28 bits)
00055  *
00056  * Values are signed two's complement, so the effective range is:
00057  * 0x80000000 to 0x7fffffff
00058  *       -8.0 to +7.9999999962747097015380859375
00059  *
00060  * The smallest representable value is:
00061  * 0x00000001 == 0.0000000037252902984619140625 (i.e. about 3.725e-9)
00062  *
00063  * 28 bits of fractional accuracy represent about
00064  * 8.6 digits of decimal accuracy.
00065  *
00066  * Fixed-point numbers can be added or subtracted as normal
00067  * integers, but multiplication requires shifting the 64-bit result
00068  * from 56 fractional bits back to 28 (and rounding.)
00069  *
00070  * Changing the definition of MAD_F_FRACBITS is only partially
00071  * supported, and must be done with care.
00072  */
00073 
00074 # define MAD_F_FRACBITS     28
00075 
00076 # if MAD_F_FRACBITS == 28
00077 #  define MAD_F(x)      ((mad_fixed_t) (x##L))
00078 # else
00079 #  if MAD_F_FRACBITS < 28
00080 #   warning "MAD_F_FRACBITS < 28"
00081 #   define MAD_F(x)     ((mad_fixed_t)  \
00082                  (((x##L) +  \
00083                    (1L << (28 - MAD_F_FRACBITS - 1))) >>  \
00084                   (28 - MAD_F_FRACBITS)))
00085 #  elif MAD_F_FRACBITS > 28
00086 #   error "MAD_F_FRACBITS > 28 not currently supported"
00087 #   define MAD_F(x)     ((mad_fixed_t)  \
00088                  ((x##L) << (MAD_F_FRACBITS - 28)))
00089 #  endif
00090 # endif
00091 
00092 # define MAD_F_MIN      ((mad_fixed_t) -0x80000000L)
00093 # define MAD_F_MAX      ((mad_fixed_t) +0x7fffffffL)
00094 
00095 # define MAD_F_ONE      MAD_F(0x10000000)
00096 
00097 # define mad_f_tofixed(x)   ((mad_fixed_t)  \
00098                  ((x) * (double) (1L << MAD_F_FRACBITS) + 0.5))
00099 # define mad_f_todouble(x)  ((double)  \
00100                  ((x) / (double) (1L << MAD_F_FRACBITS)))
00101 
00102 # define mad_f_intpart(x)   ((x) >> MAD_F_FRACBITS)
00103 # define mad_f_fracpart(x)  ((x) & ((1L << MAD_F_FRACBITS) - 1))
00104                 /* (x should be positive) */
00105 
00106 # define mad_f_fromint(x)   ((x) << MAD_F_FRACBITS)
00107 
00108 # define mad_f_add(x, y)    ((x) + (y))
00109 # define mad_f_sub(x, y)    ((x) - (y))
00110 
00111 # if defined(FPM_FLOAT)
00112 #  error "FPM_FLOAT not yet supported"
00113 
00114 #  undef MAD_F
00115 #  define MAD_F(x)      mad_f_todouble(x)
00116 
00117 #  define mad_f_mul(x, y)   ((x) * (y))
00118 #  define mad_f_scale64
00119 
00120 #  undef ASO_ZEROCHECK
00121 
00122 # elif defined(FPM_64BIT)
00123 
00124 /*
00125  * This version should be the most accurate if 64-bit types are supported by
00126  * the compiler, although it may not be the most efficient.
00127  */
00128 #  if defined(OPT_ACCURACY)
00129 #   define mad_f_mul(x, y)  \
00130     ((mad_fixed_t)  \
00131      ((((mad_fixed64_t) (x) * (y)) +  \
00132        (1L << (MAD_F_SCALEBITS - 1))) >> MAD_F_SCALEBITS))
00133 #  else
00134 #   define mad_f_mul(x, y)  \
00135     ((mad_fixed_t) (((mad_fixed64_t) (x) * (y)) >> MAD_F_SCALEBITS))
00136 #  endif
00137 
00138 #  define MAD_F_SCALEBITS  MAD_F_FRACBITS
00139 
00140 /* --- Intel --------------------------------------------------------------- */
00141 
00142 # elif defined(FPM_INTEL)
00143 
00144 #  if defined(_MSC_VER)
00145 #   pragma warning(push)
00146 #   pragma warning(disable: 4035)  /* no return value */
00147 static __forceinline
00148 mad_fixed_t mad_f_mul_inline(mad_fixed_t x, mad_fixed_t y)
00149 {
00150   enum {
00151     fracbits = MAD_F_FRACBITS
00152   };
00153 
00154   __asm {
00155     mov eax, x
00156     imul y
00157     shrd eax, edx, fracbits
00158   }
00159 
00160   /* implicit return of eax */
00161 }
00162 #   pragma warning(pop)
00163 
00164 #   define mad_f_mul        mad_f_mul_inline
00165 #   define mad_f_scale64
00166 #  else
00167 /*
00168  * This Intel version is fast and accurate; the disposition of the least
00169  * significant bit depends on OPT_ACCURACY via mad_f_scale64().
00170  */
00171 #   define MAD_F_MLX(hi, lo, x, y)  \
00172     asm ("imull %3"  \
00173      : "=a" (lo), "=d" (hi)  \
00174      : "%a" (x), "rm" (y)  \
00175      : "cc")
00176 
00177 #   if defined(OPT_ACCURACY)
00178 /*
00179  * This gives best accuracy but is not very fast.
00180  */
00181 #    define MAD_F_MLA(hi, lo, x, y)  \
00182     ({ mad_fixed64hi_t __hi;  \
00183        mad_fixed64lo_t __lo;  \
00184        MAD_F_MLX(__hi, __lo, (x), (y));  \
00185        asm ("addl %2,%0\n\t"  \
00186         "adcl %3,%1"  \
00187         : "=rm" (lo), "=rm" (hi)  \
00188         : "r" (__lo), "r" (__hi), "0" (lo), "1" (hi)  \
00189         : "cc");  \
00190     })
00191 #   endif  /* OPT_ACCURACY */
00192 
00193 #   if defined(OPT_ACCURACY)
00194 /*
00195  * Surprisingly, this is faster than SHRD followed by ADC.
00196  */
00197 #    define mad_f_scale64(hi, lo)  \
00198     ({ mad_fixed64hi_t __hi_;  \
00199        mad_fixed64lo_t __lo_;  \
00200        mad_fixed_t __result;  \
00201        asm ("addl %4,%2\n\t"  \
00202         "adcl %5,%3"  \
00203         : "=rm" (__lo_), "=rm" (__hi_)  \
00204         : "0" (lo), "1" (hi),  \
00205           "ir" (1L << (MAD_F_SCALEBITS - 1)), "ir" (0)  \
00206         : "cc");  \
00207        asm ("shrdl %3,%2,%1"  \
00208         : "=rm" (__result)  \
00209         : "0" (__lo_), "r" (__hi_), "I" (MAD_F_SCALEBITS)  \
00210         : "cc");  \
00211        __result;  \
00212     })
00213 #   elif defined(OPT_INTEL)
00214 /*
00215  * Alternate Intel scaling that may or may not perform better.
00216  */
00217 #    define mad_f_scale64(hi, lo)  \
00218     ({ mad_fixed_t __result;  \
00219        asm ("shrl %3,%1\n\t"  \
00220         "shll %4,%2\n\t"  \
00221         "orl %2,%1"  \
00222         : "=rm" (__result)  \
00223         : "0" (lo), "r" (hi),  \
00224           "I" (MAD_F_SCALEBITS), "I" (32 - MAD_F_SCALEBITS)  \
00225         : "cc");  \
00226        __result;  \
00227     })
00228 #   else
00229 #    define mad_f_scale64(hi, lo)  \
00230     ({ mad_fixed_t __result;  \
00231        asm ("shrdl %3,%2,%1"  \
00232         : "=rm" (__result)  \
00233         : "0" (lo), "r" (hi), "I" (MAD_F_SCALEBITS)  \
00234         : "cc");  \
00235        __result;  \
00236     })
00237 #   endif  /* OPT_ACCURACY */
00238 
00239 #   define MAD_F_SCALEBITS  MAD_F_FRACBITS
00240 #  endif
00241 
00242 /* --- ARM ----------------------------------------------------------------- */
00243 
00244 # elif defined(FPM_ARM)
00245 
00246 /* 
00247  * This ARM V4 version is as accurate as FPM_64BIT but much faster. The
00248  * least significant bit is properly rounded at no CPU cycle cost!
00249  */
00250 # if 1
00251 /*
00252  * This is faster than the default implementation via MAD_F_MLX() and
00253  * mad_f_scale64().
00254  */
00255 #  define mad_f_mul(x, y)  \
00256     ({ mad_fixed64hi_t __hi;  \
00257        mad_fixed64lo_t __lo;  \
00258        mad_fixed_t __result;  \
00259        asm ("smull  %0, %1, %3, %4\n\t"  \
00260         "movs   %0, %0, lsr %5\n\t"  \
00261         "adc    %2, %0, %1, lsl %6"  \
00262         : "=&r" (__lo), "=&r" (__hi), "=r" (__result)  \
00263         : "%r" (x), "r" (y),  \
00264           "M" (MAD_F_SCALEBITS), "M" (32 - MAD_F_SCALEBITS)  \
00265         : "cc");  \
00266        __result;  \
00267     })
00268 # endif
00269 
00270 #  define MAD_F_MLX(hi, lo, x, y)  \
00271     asm ("smull %0, %1, %2, %3"  \
00272      : "=&r" (lo), "=&r" (hi)  \
00273      : "%r" (x), "r" (y))
00274 
00275 #  define MAD_F_MLA(hi, lo, x, y)  \
00276     asm ("smlal %0, %1, %2, %3"  \
00277      : "+r" (lo), "+r" (hi)  \
00278      : "%r" (x), "r" (y))
00279 
00280 #  define MAD_F_MLN(hi, lo)  \
00281     asm ("rsbs  %0, %2, #0\n\t"  \
00282      "rsc   %1, %3, #0"  \
00283      : "=r" (lo), "=r" (hi)  \
00284      : "0" (lo), "1" (hi)  \
00285      : "cc")
00286 
00287 #  define mad_f_scale64(hi, lo)  \
00288     ({ mad_fixed_t __result;  \
00289        asm ("movs   %0, %1, lsr %3\n\t"  \
00290         "adc    %0, %0, %2, lsl %4"  \
00291         : "=&r" (__result)  \
00292         : "r" (lo), "r" (hi),  \
00293           "M" (MAD_F_SCALEBITS), "M" (32 - MAD_F_SCALEBITS)  \
00294         : "cc");  \
00295        __result;  \
00296     })
00297 
00298 #  define MAD_F_SCALEBITS  MAD_F_FRACBITS
00299 
00300 /* --- MIPS ---------------------------------------------------------------- */
00301 
00302 # elif defined(FPM_MIPS)
00303 
00304 /*
00305  * This MIPS version is fast and accurate; the disposition of the least
00306  * significant bit depends on OPT_ACCURACY via mad_f_scale64().
00307  */
00308 #  define MAD_F_MLX(hi, lo, x, y)  \
00309     asm ("mult  %2,%3"  \
00310      : "=l" (lo), "=h" (hi)  \
00311      : "%r" (x), "r" (y))
00312 
00313 # if defined(HAVE_MADD_ASM)
00314 #  define MAD_F_MLA(hi, lo, x, y)  \
00315     asm ("madd  %2,%3"  \
00316      : "+l" (lo), "+h" (hi)  \
00317      : "%r" (x), "r" (y))
00318 # elif defined(HAVE_MADD16_ASM)
00319 /*
00320  * This loses significant accuracy due to the 16-bit integer limit in the
00321  * multiply/accumulate instruction.
00322  */
00323 #  define MAD_F_ML0(hi, lo, x, y)  \
00324     asm ("mult  %2,%3"  \
00325      : "=l" (lo), "=h" (hi)  \
00326      : "%r" ((x) >> 12), "r" ((y) >> 16))
00327 #  define MAD_F_MLA(hi, lo, x, y)  \
00328     asm ("madd16    %2,%3"  \
00329      : "+l" (lo), "+h" (hi)  \
00330      : "%r" ((x) >> 12), "r" ((y) >> 16))
00331 #  define MAD_F_MLZ(hi, lo)  ((mad_fixed_t) (lo))
00332 # endif
00333 
00334 # if defined(OPT_SPEED)
00335 #  define mad_f_scale64(hi, lo)  \
00336     ((mad_fixed_t) ((hi) << (32 - MAD_F_SCALEBITS)))
00337 #  define MAD_F_SCALEBITS  MAD_F_FRACBITS
00338 # endif
00339 
00340 /* --- SPARC --------------------------------------------------------------- */
00341 
00342 # elif defined(FPM_SPARC)
00343 
00344 /*
00345  * This SPARC V8 version is fast and accurate; the disposition of the least
00346  * significant bit depends on OPT_ACCURACY via mad_f_scale64().
00347  */
00348 #  define MAD_F_MLX(hi, lo, x, y)  \
00349     asm ("smul %2, %3, %0\n\t"  \
00350      "rd %%y, %1"  \
00351      : "=r" (lo), "=r" (hi)  \
00352      : "%r" (x), "rI" (y))
00353 
00354 /* --- PowerPC ------------------------------------------------------------- */
00355 
00356 # elif defined(FPM_PPC)
00357 
00358 /*
00359  * This PowerPC version is fast and accurate; the disposition of the least
00360  * significant bit depends on OPT_ACCURACY via mad_f_scale64().
00361  */
00362 #  define MAD_F_MLX(hi, lo, x, y)  \
00363     do {  \
00364       asm ("mullw %0,%1,%2"  \
00365        : "=r" (lo)  \
00366        : "%r" (x), "r" (y));  \
00367       asm ("mulhw %0,%1,%2"  \
00368        : "=r" (hi)  \
00369        : "%r" (x), "r" (y));  \
00370     }  \
00371     while (0)
00372 
00373 #  if defined(OPT_ACCURACY)
00374 /*
00375  * This gives best accuracy but is not very fast.
00376  */
00377 #   define MAD_F_MLA(hi, lo, x, y)  \
00378     ({ mad_fixed64hi_t __hi;  \
00379        mad_fixed64lo_t __lo;  \
00380        MAD_F_MLX(__hi, __lo, (x), (y));  \
00381        asm ("addc %0,%2,%3\n\t"  \
00382         "adde %1,%4,%5"  \
00383         : "=r" (lo), "=r" (hi)  \
00384         : "%r" (lo), "r" (__lo),  \
00385           "%r" (hi), "r" (__hi)  \
00386         : "xer");  \
00387     })
00388 #  endif
00389 
00390 #  if defined(OPT_ACCURACY)
00391 /*
00392  * This is slower than the truncating version below it.
00393  */
00394 #   define mad_f_scale64(hi, lo)  \
00395     ({ mad_fixed_t __result, __round;  \
00396        asm ("rotrwi %0,%1,%2"  \
00397         : "=r" (__result)  \
00398         : "r" (lo), "i" (MAD_F_SCALEBITS));  \
00399        asm ("extrwi %0,%1,1,0"  \
00400         : "=r" (__round)  \
00401         : "r" (__result));  \
00402        asm ("insrwi %0,%1,%2,0"  \
00403         : "+r" (__result)  \
00404         : "r" (hi), "i" (MAD_F_SCALEBITS));  \
00405        asm ("add %0,%1,%2"  \
00406         : "=r" (__result)  \
00407         : "%r" (__result), "r" (__round));  \
00408        __result;  \
00409     })
00410 #  else
00411 #   define mad_f_scale64(hi, lo)  \
00412     ({ mad_fixed_t __result;  \
00413        asm ("rotrwi %0,%1,%2"  \
00414         : "=r" (__result)  \
00415         : "r" (lo), "i" (MAD_F_SCALEBITS));  \
00416        asm ("insrwi %0,%1,%2,0"  \
00417         : "+r" (__result)  \
00418         : "r" (hi), "i" (MAD_F_SCALEBITS));  \
00419        __result;  \
00420     })
00421 #  endif
00422 
00423 #  define MAD_F_SCALEBITS  MAD_F_FRACBITS
00424 
00425 /* --- Default ------------------------------------------------------------- */
00426 
00427 # elif defined(FPM_DEFAULT)
00428 
00429 /*
00430  * This version is the most portable but it loses significant accuracy.
00431  * Furthermore, accuracy is biased against the second argument, so care
00432  * should be taken when ordering operands.
00433  *
00434  * The scale factors are constant as this is not used with SSO.
00435  *
00436  * Pre-rounding is required to stay within the limits of compliance.
00437  */
00438 #  if defined(OPT_SPEED)
00439 #   define mad_f_mul(x, y)  (((x) >> 12) * ((y) >> 16))
00440 #  else
00441 #   define mad_f_mul(x, y)  ((((x) + (1L << 11)) >> 12) *  \
00442                  (((y) + (1L << 15)) >> 16))
00443 #  endif
00444 
00445 /* ------------------------------------------------------------------------- */
00446 
00447 # else
00448 #  error "no FPM selected"
00449 # endif
00450 
00451 /* default implementations */
00452 
00453 # if !defined(mad_f_mul)
00454 #  define mad_f_mul(x, y)  \
00455     ({ register mad_fixed64hi_t __hi;  \
00456        register mad_fixed64lo_t __lo;  \
00457        MAD_F_MLX(__hi, __lo, (x), (y));  \
00458        mad_f_scale64(__hi, __lo);  \
00459     })
00460 # endif
00461 
00462 # if !defined(MAD_F_MLA)
00463 #  define MAD_F_ML0(hi, lo, x, y)   ((lo)  = mad_f_mul((x), (y)))
00464 #  define MAD_F_MLA(hi, lo, x, y)   ((lo) += mad_f_mul((x), (y)))
00465 #  define MAD_F_MLN(hi, lo)     ((lo)  = -(lo))
00466 #  define MAD_F_MLZ(hi, lo)     ((void) (hi), (mad_fixed_t) (lo))
00467 # endif
00468 
00469 # if !defined(MAD_F_ML0)
00470 #  define MAD_F_ML0(hi, lo, x, y)   MAD_F_MLX((hi), (lo), (x), (y))
00471 # endif
00472 
00473 # if !defined(MAD_F_MLN)
00474 #  define MAD_F_MLN(hi, lo)     ((hi) = ((lo) = -(lo)) ? ~(hi) : -(hi))
00475 # endif
00476 
00477 # if !defined(MAD_F_MLZ)
00478 #  define MAD_F_MLZ(hi, lo)     mad_f_scale64((hi), (lo))
00479 # endif
00480 
00481 # if !defined(mad_f_scale64)
00482 #  if defined(OPT_ACCURACY)
00483 #   define mad_f_scale64(hi, lo)  \
00484     ((((mad_fixed_t)  \
00485        (((hi) << (32 - (MAD_F_SCALEBITS - 1))) |  \
00486     ((lo) >> (MAD_F_SCALEBITS - 1)))) + 1) >> 1)
00487 #  else
00488 #   define mad_f_scale64(hi, lo)  \
00489     ((mad_fixed_t)  \
00490      (((hi) << (32 - MAD_F_SCALEBITS)) |  \
00491       ((lo) >> MAD_F_SCALEBITS)))
00492 #  endif
00493 #  define MAD_F_SCALEBITS  MAD_F_FRACBITS
00494 # endif
00495 
00496 /* C routines */
00497 
00498 mad_fixed_t mad_f_abs(mad_fixed_t);
00499 mad_fixed_t mad_f_div(mad_fixed_t, mad_fixed_t);
00500 
00501 # endif