streo mp3 player see: http://mbed.org/users/okini3939/notebook/I2S_AUDIO
Dependencies: FatFileSystemCpp I2SSlave TLV320 mbed
Fork of madplayer by
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
Generated on Tue Jul 12 2022 22:28:17 by 1.7.2