examples/sfexamples/oggvorbiscodec/src/tremor/misc.h

00001 /********************************************************************
00002  *                                                                  *
00003  * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE.   *
00004  *                                                                  *
00005  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
00006  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
00007  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
00008  *                                                                  *
00009  * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002    *
00010  * BY THE Xiph.Org FOUNDATION http://www.xiph.org/                  *
00011  *                                                                  *
00012  ********************************************************************
00013 
00014  function: miscellaneous math and prototypes
00015 
00016  ********************************************************************/
00017 
00018 #ifndef _V_RANDOM_H_
00019 #define _V_RANDOM_H_
00020 #include "ivorbiscodec.h"
00021 #include "os_types.h"
00022 
00023 #include "asm_arm.h"
00024   
00025 #ifndef _V_WIDE_MATH
00026 #define _V_WIDE_MATH
00027   
00028 #ifndef  _LOW_ACCURACY_
00029 /* 64 bit multiply */
00030 
00031 #include <sys/types.h>
00032 
00033 
00034 #ifdef __SYMBIAN32__
00035 #  define LITTLE_ENDIAN 1
00036 #  define BYTE_ORDER LITTLE_ENDIAN
00037 #endif
00038 
00039 #if BYTE_ORDER==LITTLE_ENDIAN
00040 union magic {
00041   struct {
00042     ogg_int32_t lo;
00043     ogg_int32_t hi;
00044   } halves;
00045   ogg_int64_t whole;
00046 };
00047 #endif 
00048 
00049 #if BYTE_ORDER==BIG_ENDIAN
00050 union magic {
00051   struct {
00052     ogg_int32_t hi;
00053     ogg_int32_t lo;
00054   } halves;
00055   ogg_int64_t whole;
00056 };
00057 #endif
00058 
00059 static ogg_int32_t MULT32(ogg_int32_t x, ogg_int32_t y) {
00060   union magic magic;
00061   magic.whole = (ogg_int64_t)x * y;
00062   return magic.halves.hi;
00063 }
00064 
00065 static ogg_int32_t MULT31(ogg_int32_t x, ogg_int32_t y) {
00066   return MULT32(x,y)<<1;
00067 }
00068 
00069 static ogg_int32_t MULT31_SHIFT15(ogg_int32_t x, ogg_int32_t y) {
00070   union magic magic;
00071   magic.whole  = (ogg_int64_t)x * y;
00072   return ((ogg_uint32_t)(magic.halves.lo)>>15) | ((magic.halves.hi)<<17);
00073 }
00074 
00075 #else
00076 /* 32 bit multiply, more portable but less accurate */
00077 
00078 /*
00079  * Note: Precision is biased towards the first argument therefore ordering
00080  * is important.  Shift values were chosen for the best sound quality after
00081  * many listening tests.
00082  */
00083 
00084 /*
00085  * For MULT32 and MULT31: The second argument is always a lookup table
00086  * value already preshifted from 31 to 8 bits.  We therefore take the 
00087  * opportunity to save on text space and use unsigned char for those
00088  * tables in this case.
00089  */
00090 
00091 static ogg_int32_t MULT32(ogg_int32_t x, ogg_int32_t y) {
00092   return (x >> 9) * y;  /* y preshifted >>23 */
00093 }
00094 
00095 static ogg_int32_t MULT31(ogg_int32_t x, ogg_int32_t y) {
00096   return (x >> 8) * y;  /* y preshifted >>23 */
00097 }
00098 
00099 static ogg_int32_t MULT31_SHIFT15(ogg_int32_t x, ogg_int32_t y) {
00100   return (x >> 6) * y;  /* y preshifted >>9 */
00101 }
00102 
00103 #endif
00104 
00105 /*
00106  * This should be used as a memory barrier, forcing all cached values in
00107  * registers to wr writen back to memory.  Might or might not be beneficial
00108  * depending on the architecture and compiler.
00109  */
00110 #define MB()
00111 
00112 /*
00113  * The XPROD functions are meant to optimize the cross products found all
00114  * over the place in mdct.c by forcing memory operation ordering to avoid
00115  * unnecessary register reloads as soon as memory is being written to.
00116  * However this is only beneficial on CPUs with a sane number of general
00117  * purpose registers which exclude the Intel x86.  On Intel, better let the
00118  * compiler actually reload registers directly from original memory by using
00119  * macros.
00120  */
00121 
00122 #ifdef __i386__
00123 
00124 #define XPROD32(_a, _b, _t, _v, _x, _y)         \
00125   { *(_x)=MULT32(_a,_t)+MULT32(_b,_v);          \
00126     *(_y)=MULT32(_b,_t)-MULT32(_a,_v); }
00127 #define XPROD31(_a, _b, _t, _v, _x, _y)         \
00128   { *(_x)=MULT31(_a,_t)+MULT31(_b,_v);          \
00129     *(_y)=MULT31(_b,_t)-MULT31(_a,_v); }
00130 #define XNPROD31(_a, _b, _t, _v, _x, _y)        \
00131   { *(_x)=MULT31(_a,_t)-MULT31(_b,_v);          \
00132     *(_y)=MULT31(_b,_t)+MULT31(_a,_v); }
00133 
00134 #else
00135 
00136 static void XPROD32(ogg_int32_t  a, ogg_int32_t  b,
00137                            ogg_int32_t  t, ogg_int32_t  v,
00138                            ogg_int32_t *x, ogg_int32_t *y)
00139 {
00140   *x = MULT32(a, t) + MULT32(b, v);
00141   *y = MULT32(b, t) - MULT32(a, v);
00142 }
00143 
00144 static void XPROD31(ogg_int32_t  a, ogg_int32_t  b,
00145                            ogg_int32_t  t, ogg_int32_t  v,
00146                            ogg_int32_t *x, ogg_int32_t *y)
00147 {
00148   *x = MULT31(a, t) + MULT31(b, v);
00149   *y = MULT31(b, t) - MULT31(a, v);
00150 }
00151 
00152 static void XNPROD31(ogg_int32_t  a, ogg_int32_t  b,
00153                             ogg_int32_t  t, ogg_int32_t  v,
00154                             ogg_int32_t *x, ogg_int32_t *y)
00155 {
00156   *x = MULT31(a, t) - MULT31(b, v);
00157   *y = MULT31(b, t) + MULT31(a, v);
00158 }
00159 
00160 #endif
00161 
00162 #endif
00163 
00164 #ifndef _V_CLIP_MATH
00165 #define _V_CLIP_MATH
00166 
00167 static ogg_int32_t CLIP_TO_15(ogg_int32_t x) {
00168   int ret=x;
00169   ret-= ((x<=32767)-1)&(x-32767);
00170   ret-= ((x>=-32768)-1)&(x+32768);
00171   return(ret);
00172 }
00173 
00174 #endif
00175 
00176 static ogg_int32_t VFLOAT_MULT(ogg_int32_t a,ogg_int32_t ap,
00177                                       ogg_int32_t b,ogg_int32_t bp,
00178                                       ogg_int32_t *p){
00179   if(a && b){
00180 #ifndef _LOW_ACCURACY_
00181     *p=ap+bp+32;
00182     return MULT32(a,b);
00183 #else
00184     *p=ap+bp+31;
00185     return (a>>15)*(b>>16); 
00186 #endif
00187   }else
00188     return 0;
00189 }
00190 
00191 int _ilog(unsigned int v); //patch
00192 static ogg_int32_t VFLOAT_MULTI(ogg_int32_t a,ogg_int32_t ap,
00193                                       ogg_int32_t i,
00194                                       ogg_int32_t *p){
00195 
00196   int ip=_ilog(abs(i))-31;
00197   return VFLOAT_MULT(a,ap,i<<-ip,ip,p);
00198 }
00199 
00200 static ogg_int32_t VFLOAT_ADD(ogg_int32_t a,ogg_int32_t ap,
00201                                       ogg_int32_t b,ogg_int32_t bp,
00202                                       ogg_int32_t *p){
00203 
00204   if(!a){
00205     *p=bp;
00206     return b;
00207   }else if(!b){
00208     *p=ap;
00209     return a;
00210   }
00211 
00212   /* yes, this can leak a bit. */
00213   if(ap>bp){
00214     int shift=ap-bp+1;
00215     *p=ap+1;
00216     a>>=1;
00217     if(shift<32){
00218       b=(b+(1<<(shift-1)))>>shift;
00219     }else{
00220       b=0;
00221     }
00222   }else{
00223     int shift=bp-ap+1;
00224     *p=bp+1;
00225     b>>=1;
00226     if(shift<32){
00227       a=(a+(1<<(shift-1)))>>shift;
00228     }else{
00229       a=0;
00230     }
00231   }
00232 
00233   a+=b;
00234   if((a&0xc0000000)==0xc0000000 || 
00235      (a&0xc0000000)==0){
00236     a<<=1;
00237     (*p)--;
00238   }
00239   return(a);
00240 }
00241 
00242 #endif
00243 
00244 
00245 
00246 

Generated by  doxygen 1.6.2