PageRenderTime 46ms CodeModel.GetById 8ms app.highlight 30ms RepoModel.GetById 2ms app.codeStats 0ms

/media/libtremor/lib/misc.h

http://github.com/zpao/v8monkey
C Header | 250 lines | 163 code | 43 blank | 44 comment | 10 complexity | 578475bf245c6be56e2afbd357643272 MD5 | raw file
  1/********************************************************************
  2 *                                                                  *
  3 * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE.   *
  4 *                                                                  *
  5 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
  6 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
  7 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  8 *                                                                  *
  9 * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002    *
 10 * BY THE Xiph.Org FOUNDATION http://www.xiph.org/                  *
 11 *                                                                  *
 12 ********************************************************************
 13
 14 function: miscellaneous math and prototypes
 15
 16 ********************************************************************/
 17
 18#ifndef _V_RANDOM_H_
 19#define _V_RANDOM_H_
 20#include "ivorbiscodec.h"
 21#include "os.h"
 22
 23#ifdef _LOW_ACCURACY_
 24#  define X(n) (((((n)>>22)+1)>>1) - ((((n)>>22)+1)>>9))
 25#  define LOOKUP_T const unsigned char
 26#else
 27#  define X(n) (n)
 28#  define LOOKUP_T const ogg_int32_t
 29#endif
 30
 31#include "asm_arm.h"
 32#include <stdlib.h> /* for abs() */
 33  
 34#ifndef _V_WIDE_MATH
 35#define _V_WIDE_MATH
 36  
 37#ifndef  _LOW_ACCURACY_
 38/* 64 bit multiply */
 39
 40#if !(defined WIN32 && defined WINCE)
 41#include <sys/types.h>
 42#endif
 43
 44#if BYTE_ORDER==LITTLE_ENDIAN
 45union magic {
 46  struct {
 47    ogg_int32_t lo;
 48    ogg_int32_t hi;
 49  } halves;
 50  ogg_int64_t whole;
 51};
 52#elif BYTE_ORDER==BIG_ENDIAN
 53union magic {
 54  struct {
 55    ogg_int32_t hi;
 56    ogg_int32_t lo;
 57  } halves;
 58  ogg_int64_t whole;
 59};
 60#endif
 61
 62STIN ogg_int32_t MULT32(ogg_int32_t x, ogg_int32_t y) {
 63  union magic magic;
 64  magic.whole = (ogg_int64_t)x * y;
 65  return magic.halves.hi;
 66}
 67
 68STIN ogg_int32_t MULT31(ogg_int32_t x, ogg_int32_t y) {
 69  return MULT32(x,y)<<1;
 70}
 71
 72STIN ogg_int32_t MULT31_SHIFT15(ogg_int32_t x, ogg_int32_t y) {
 73  union magic magic;
 74  magic.whole  = (ogg_int64_t)x * y;
 75  return ((ogg_uint32_t)(magic.halves.lo)>>15) | ((magic.halves.hi)<<17);
 76}
 77
 78#else
 79/* 32 bit multiply, more portable but less accurate */
 80
 81/*
 82 * Note: Precision is biased towards the first argument therefore ordering
 83 * is important.  Shift values were chosen for the best sound quality after
 84 * many listening tests.
 85 */
 86
 87/*
 88 * For MULT32 and MULT31: The second argument is always a lookup table
 89 * value already preshifted from 31 to 8 bits.  We therefore take the 
 90 * opportunity to save on text space and use unsigned char for those
 91 * tables in this case.
 92 */
 93
 94STIN ogg_int32_t MULT32(ogg_int32_t x, ogg_int32_t y) {
 95  return (x >> 9) * y;  /* y preshifted >>23 */
 96}
 97
 98STIN ogg_int32_t MULT31(ogg_int32_t x, ogg_int32_t y) {
 99  return (x >> 8) * y;  /* y preshifted >>23 */
100}
101
102STIN ogg_int32_t MULT31_SHIFT15(ogg_int32_t x, ogg_int32_t y) {
103  return (x >> 6) * y;  /* y preshifted >>9 */
104}
105
106#endif
107
108/*
109 * This should be used as a memory barrier, forcing all cached values in
110 * registers to wr writen back to memory.  Might or might not be beneficial
111 * depending on the architecture and compiler.
112 */
113#define MB()
114
115/*
116 * The XPROD functions are meant to optimize the cross products found all
117 * over the place in mdct.c by forcing memory operation ordering to avoid
118 * unnecessary register reloads as soon as memory is being written to.
119 * However this is only beneficial on CPUs with a sane number of general
120 * purpose registers which exclude the Intel x86.  On Intel, better let the
121 * compiler actually reload registers directly from original memory by using
122 * macros.
123 */
124
125#ifdef __i386__
126
127#define XPROD32(_a, _b, _t, _v, _x, _y)		\
128  { *(_x)=MULT32(_a,_t)+MULT32(_b,_v);		\
129    *(_y)=MULT32(_b,_t)-MULT32(_a,_v); }
130#define XPROD31(_a, _b, _t, _v, _x, _y)		\
131  { *(_x)=MULT31(_a,_t)+MULT31(_b,_v);		\
132    *(_y)=MULT31(_b,_t)-MULT31(_a,_v); }
133#define XNPROD31(_a, _b, _t, _v, _x, _y)	\
134  { *(_x)=MULT31(_a,_t)-MULT31(_b,_v);		\
135    *(_y)=MULT31(_b,_t)+MULT31(_a,_v); }
136
137#else
138
139STIN void XPROD32(ogg_int32_t  a, ogg_int32_t  b,
140			   ogg_int32_t  t, ogg_int32_t  v,
141			   ogg_int32_t *x, ogg_int32_t *y)
142{
143  *x = MULT32(a, t) + MULT32(b, v);
144  *y = MULT32(b, t) - MULT32(a, v);
145}
146
147STIN void XPROD31(ogg_int32_t  a, ogg_int32_t  b,
148			   ogg_int32_t  t, ogg_int32_t  v,
149			   ogg_int32_t *x, ogg_int32_t *y)
150{
151  *x = MULT31(a, t) + MULT31(b, v);
152  *y = MULT31(b, t) - MULT31(a, v);
153}
154
155STIN void XNPROD31(ogg_int32_t  a, ogg_int32_t  b,
156			    ogg_int32_t  t, ogg_int32_t  v,
157			    ogg_int32_t *x, ogg_int32_t *y)
158{
159  *x = MULT31(a, t) - MULT31(b, v);
160  *y = MULT31(b, t) + MULT31(a, v);
161}
162
163#endif
164
165#endif
166
167#ifndef _V_CLIP_MATH
168#define _V_CLIP_MATH
169
170STIN ogg_int32_t CLIP_TO_15(ogg_int32_t x) {
171  int ret=x;
172  ret-= ((x<=32767)-1)&(x-32767);
173  ret-= ((x>=-32768)-1)&(x+32768);
174  return(ret);
175}
176
177#endif
178
179STIN ogg_int32_t VFLOAT_MULT(ogg_int32_t a,ogg_int32_t ap,
180				      ogg_int32_t b,ogg_int32_t bp,
181				      ogg_int32_t *p){
182  if(a && b){
183#ifndef _LOW_ACCURACY_
184    *p=ap+bp+32;
185    return MULT32(a,b);
186#else
187    *p=ap+bp+31;
188    return (a>>15)*(b>>16); 
189#endif
190  }else
191    return 0;
192}
193
194int _ilog(unsigned int);
195
196STIN ogg_int32_t VFLOAT_MULTI(ogg_int32_t a,ogg_int32_t ap,
197				      ogg_int32_t i,
198				      ogg_int32_t *p){
199
200  int ip=_ilog(abs(i))-31;
201  return VFLOAT_MULT(a,ap,i<<-ip,ip,p);
202}
203
204STIN ogg_int32_t VFLOAT_ADD(ogg_int32_t a,ogg_int32_t ap,
205				      ogg_int32_t b,ogg_int32_t bp,
206				      ogg_int32_t *p){
207
208  if(!a){
209    *p=bp;
210    return b;
211  }else if(!b){
212    *p=ap;
213    return a;
214  }
215
216  /* yes, this can leak a bit. */
217  if(ap>bp){
218    int shift=ap-bp+1;
219    *p=ap+1;
220    a>>=1;
221    if(shift<32){
222      b=(b+(1<<(shift-1)))>>shift;
223    }else{
224      b=0;
225    }
226  }else{
227    int shift=bp-ap+1;
228    *p=bp+1;
229    b>>=1;
230    if(shift<32){
231      a=(a+(1<<(shift-1)))>>shift;
232    }else{
233      a=0;
234    }
235  }
236
237  a+=b;
238  if((a&0xc0000000)==0xc0000000 || 
239     (a&0xc0000000)==0){
240    a<<=1;
241    (*p)--;
242  }
243  return(a);
244}
245
246#endif
247
248
249
250