Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

misc.h

Go to the documentation of this file.
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 #if BYTE_ORDER==LITTLE_ENDIAN
00034 union magic {
00035   struct {
00036     ogg_int32_t lo;
00037     ogg_int32_t hi;
00038   } halves;
00039   ogg_int64_t whole;
00040 };
00041 #endif 
00042 
00043 #if BYTE_ORDER==BIG_ENDIAN
00044 union magic {
00045   struct {
00046     ogg_int32_t hi;
00047     ogg_int32_t lo;
00048   } halves;
00049   ogg_int64_t whole;
00050 };
00051 #endif
00052 
00053 static inline ogg_int32_t MULT32(ogg_int32_t x, ogg_int32_t y) {
00054   union magic magic;
00055   magic.whole = (ogg_int64_t)x * y;
00056   return magic.halves.hi;
00057 }
00058 
00059 static inline ogg_int32_t MULT31(ogg_int32_t x, ogg_int32_t y) {
00060   return MULT32(x,y)<<1;
00061 }
00062 
00063 static inline ogg_int32_t MULT31_SHIFT15(ogg_int32_t x, ogg_int32_t y) {
00064   union magic magic;
00065   magic.whole  = (ogg_int64_t)x * y;
00066   return ((ogg_uint32_t)(magic.halves.lo)>>15) | ((magic.halves.hi)<<17);
00067 }
00068 
00069 #else
00070 /* 32 bit multiply, more portable but less accurate */
00071 
00072 /*
00073  * Note: Precision is biased towards the first argument therefore ordering
00074  * is important.  Shift values were chosen for the best sound quality after
00075  * many listening tests.
00076  */
00077 
00078 /*
00079  * For MULT32 and MULT31: The second argument is always a lookup table
00080  * value already preshifted from 31 to 8 bits.  We therefore take the 
00081  * opportunity to save on text space and use unsigned char for those
00082  * tables in this case.
00083  */
00084 
00085 static inline ogg_int32_t MULT32(ogg_int32_t x, ogg_int32_t y) {
00086   return (x >> 9) * y;  /* y preshifted >>23 */
00087 }
00088 
00089 static inline ogg_int32_t MULT31(ogg_int32_t x, ogg_int32_t y) {
00090   return (x >> 8) * y;  /* y preshifted >>23 */
00091 }
00092 
00093 static inline ogg_int32_t MULT31_SHIFT15(ogg_int32_t x, ogg_int32_t y) {
00094   return (x >> 6) * y;  /* y preshifted >>9 */
00095 }
00096 
00097 #endif
00098 
00099 /*
00100  * This should be used as a memory barrier, forcing all cached values in
00101  * registers to wr writen back to memory.  Might or might not be beneficial
00102  * depending on the architecture and compiler.
00103  */
00104 #define MB()
00105 
00106 /*
00107  * The XPROD functions are meant to optimize the cross products found all
00108  * over the place in mdct.c by forcing memory operation ordering to avoid
00109  * unnecessary register reloads as soon as memory is being written to.
00110  * However this is only beneficial on CPUs with a sane number of general
00111  * purpose registers which exclude the Intel x86.  On Intel, better let the
00112  * compiler actually reload registers directly from original memory by using
00113  * macros.
00114  */
00115 
00116 #ifdef __i386__
00117 
00118 #define XPROD32(_a, _b, _t, _v, _x, _y)         \
00119   { *(_x)=MULT32(_a,_t)+MULT32(_b,_v);          \
00120     *(_y)=MULT32(_b,_t)-MULT32(_a,_v); }
00121 #define XPROD31(_a, _b, _t, _v, _x, _y)         \
00122   { *(_x)=MULT31(_a,_t)+MULT31(_b,_v);          \
00123     *(_y)=MULT31(_b,_t)-MULT31(_a,_v); }
00124 #define XNPROD31(_a, _b, _t, _v, _x, _y)        \
00125   { *(_x)=MULT31(_a,_t)-MULT31(_b,_v);          \
00126     *(_y)=MULT31(_b,_t)+MULT31(_a,_v); }
00127 
00128 #else
00129 
00130 static inline void XPROD32(ogg_int32_t  a, ogg_int32_t  b,
00131                            ogg_int32_t  t, ogg_int32_t  v,
00132                            ogg_int32_t *x, ogg_int32_t *y)
00133 {
00134   *x = MULT32(a, t) + MULT32(b, v);
00135   *y = MULT32(b, t) - MULT32(a, v);
00136 }
00137 
00138 static inline void XPROD31(ogg_int32_t  a, ogg_int32_t  b,
00139                            ogg_int32_t  t, ogg_int32_t  v,
00140                            ogg_int32_t *x, ogg_int32_t *y)
00141 {
00142   *x = MULT31(a, t) + MULT31(b, v);
00143   *y = MULT31(b, t) - MULT31(a, v);
00144 }
00145 
00146 static inline void XNPROD31(ogg_int32_t  a, ogg_int32_t  b,
00147                             ogg_int32_t  t, ogg_int32_t  v,
00148                             ogg_int32_t *x, ogg_int32_t *y)
00149 {
00150   *x = MULT31(a, t) - MULT31(b, v);
00151   *y = MULT31(b, t) + MULT31(a, v);
00152 }
00153 
00154 #endif
00155 
00156 #endif
00157 
00158 #ifndef _V_CLIP_MATH
00159 #define _V_CLIP_MATH
00160 
00161 static inline ogg_int32_t CLIP_TO_15(ogg_int32_t x) {
00162   int ret=x;
00163   ret-= ((x<=32767)-1)&(x-32767);
00164   ret-= ((x>=-32768)-1)&(x+32768);
00165   return(ret);
00166 }
00167 
00168 #endif
00169 
00170 static inline ogg_int32_t VFLOAT_MULT(ogg_int32_t a,ogg_int32_t ap,
00171                                       ogg_int32_t b,ogg_int32_t bp,
00172                                       ogg_int32_t *p){
00173   if(a && b){
00174 #ifndef _LOW_ACCURACY_
00175     *p=ap+bp+32;
00176     return MULT32(a,b);
00177 #else
00178     *p=ap+bp+31;
00179     return (a>>15)*(b>>16); 
00180 #endif
00181   }else
00182     return 0;
00183 }
00184 
00185 static inline ogg_int32_t VFLOAT_MULTI(ogg_int32_t a,ogg_int32_t ap,
00186                                       ogg_int32_t i,
00187                                       ogg_int32_t *p){
00188 
00189   int ip=_ilog(abs(i))-31;
00190   return VFLOAT_MULT(a,ap,i<<-ip,ip,p);
00191 }
00192 
00193 static inline ogg_int32_t VFLOAT_ADD(ogg_int32_t a,ogg_int32_t ap,
00194                                       ogg_int32_t b,ogg_int32_t bp,
00195                                       ogg_int32_t *p){
00196 
00197   if(!a){
00198     *p=bp;
00199     return b;
00200   }else if(!b){
00201     *p=ap;
00202     return a;
00203   }
00204 
00205   /* yes, this can leak a bit. */
00206   if(ap>bp){
00207     int shift=ap-bp+1;
00208     *p=ap+1;
00209     a>>=1;
00210     if(shift<32){
00211       b=(b+(1<<(shift-1)))>>shift;
00212     }else{
00213       b=0;
00214     }
00215   }else{
00216     int shift=bp-ap+1;
00217     *p=bp+1;
00218     b>>=1;
00219     if(shift<32){
00220       a=(a+(1<<(shift-1)))>>shift;
00221     }else{
00222       a=0;
00223     }
00224   }
00225 
00226   a+=b;
00227   if((a&0xc0000000)==0xc0000000 || 
00228      (a&0xc0000000)==0){
00229     a<<=1;
00230     (*p)--;
00231   }
00232   return(a);
00233 }
00234 
00235 #endif
00236 
00237 
00238 
00239 

Generated on Sat Nov 5 16:15:44 2005 for OPIE by  doxygen 1.4.2