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
45 union magic {
46   struct {
47     ogg_int32_t lo;
48     ogg_int32_t hi;
49   } halves;
50   ogg_int64_t whole;
51 };
52 #endif
53 
54 #if BYTE_ORDER==BIG_ENDIAN
55 union magic {
56   struct {
57     ogg_int32_t hi;
58     ogg_int32_t lo;
59   } halves;
60   ogg_int64_t whole;
61 };
62 #endif
63 
MULT32(ogg_int32_t x,ogg_int32_t y)64 STIN ogg_int32_t MULT32(ogg_int32_t x, ogg_int32_t y) {
65   union magic magic;
66   magic.whole = (ogg_int64_t)x * y;
67   return magic.halves.hi;
68 }
69 
MULT31(ogg_int32_t x,ogg_int32_t y)70 STIN ogg_int32_t MULT31(ogg_int32_t x, ogg_int32_t y) {
71   return MULT32(x,y)<<1;
72 }
73 
MULT31_SHIFT15(ogg_int32_t x,ogg_int32_t y)74 STIN ogg_int32_t MULT31_SHIFT15(ogg_int32_t x, ogg_int32_t y) {
75   union magic magic;
76   magic.whole  = (ogg_int64_t)x * y;
77   return ((ogg_uint32_t)(magic.halves.lo)>>15) | ((magic.halves.hi)<<17);
78 }
79 
80 #else
81 /* 32 bit multiply, more portable but less accurate */
82 
83 /*
84  * Note: Precision is biased towards the first argument therefore ordering
85  * is important.  Shift values were chosen for the best sound quality after
86  * many listening tests.
87  */
88 
89 /*
90  * For MULT32 and MULT31: The second argument is always a lookup table
91  * value already preshifted from 31 to 8 bits.  We therefore take the
92  * opportunity to save on text space and use unsigned char for those
93  * tables in this case.
94  */
95 
MULT32(ogg_int32_t x,ogg_int32_t y)96 STIN ogg_int32_t MULT32(ogg_int32_t x, ogg_int32_t y) {
97   return (x >> 9) * y;  /* y preshifted >>23 */
98 }
99 
MULT31(ogg_int32_t x,ogg_int32_t y)100 STIN ogg_int32_t MULT31(ogg_int32_t x, ogg_int32_t y) {
101   return (x >> 8) * y;  /* y preshifted >>23 */
102 }
103 
MULT31_SHIFT15(ogg_int32_t x,ogg_int32_t y)104 STIN ogg_int32_t MULT31_SHIFT15(ogg_int32_t x, ogg_int32_t y) {
105   return (x >> 6) * y;  /* y preshifted >>9 */
106 }
107 
108 #endif
109 
110 /*
111  * This should be used as a memory barrier, forcing all cached values in
112  * registers to wr writen back to memory.  Might or might not be beneficial
113  * depending on the architecture and compiler.
114  */
115 #define MB()
116 
117 /*
118  * The XPROD functions are meant to optimize the cross products found all
119  * over the place in mdct.c by forcing memory operation ordering to avoid
120  * unnecessary register reloads as soon as memory is being written to.
121  * However this is only beneficial on CPUs with a sane number of general
122  * purpose registers which exclude the Intel x86.  On Intel, better let the
123  * compiler actually reload registers directly from original memory by using
124  * macros.
125  */
126 
127 #ifdef __i386__
128 
129 #define XPROD32(_a, _b, _t, _v, _x, _y)		\
130   { *(_x)=MULT32(_a,_t)+MULT32(_b,_v);		\
131     *(_y)=MULT32(_b,_t)-MULT32(_a,_v); }
132 #define XPROD31(_a, _b, _t, _v, _x, _y)		\
133   { *(_x)=MULT31(_a,_t)+MULT31(_b,_v);		\
134     *(_y)=MULT31(_b,_t)-MULT31(_a,_v); }
135 #define XNPROD31(_a, _b, _t, _v, _x, _y)	\
136   { *(_x)=MULT31(_a,_t)-MULT31(_b,_v);		\
137     *(_y)=MULT31(_b,_t)+MULT31(_a,_v); }
138 
139 #else
140 
XPROD32(ogg_int32_t a,ogg_int32_t b,ogg_int32_t t,ogg_int32_t v,ogg_int32_t * x,ogg_int32_t * y)141 STIN void XPROD32(ogg_int32_t  a, ogg_int32_t  b,
142 			   ogg_int32_t  t, ogg_int32_t  v,
143 			   ogg_int32_t *x, ogg_int32_t *y)
144 {
145   *x = MULT32(a, t) + MULT32(b, v);
146   *y = MULT32(b, t) - MULT32(a, v);
147 }
148 
XPROD31(ogg_int32_t a,ogg_int32_t b,ogg_int32_t t,ogg_int32_t v,ogg_int32_t * x,ogg_int32_t * y)149 STIN void XPROD31(ogg_int32_t  a, ogg_int32_t  b,
150 			   ogg_int32_t  t, ogg_int32_t  v,
151 			   ogg_int32_t *x, ogg_int32_t *y)
152 {
153   *x = MULT31(a, t) + MULT31(b, v);
154   *y = MULT31(b, t) - MULT31(a, v);
155 }
156 
XNPROD31(ogg_int32_t a,ogg_int32_t b,ogg_int32_t t,ogg_int32_t v,ogg_int32_t * x,ogg_int32_t * y)157 STIN void XNPROD31(ogg_int32_t  a, ogg_int32_t  b,
158 			    ogg_int32_t  t, ogg_int32_t  v,
159 			    ogg_int32_t *x, ogg_int32_t *y)
160 {
161   *x = MULT31(a, t) - MULT31(b, v);
162   *y = MULT31(b, t) + MULT31(a, v);
163 }
164 
165 #endif
166 
167 #endif
168 
169 #ifndef _V_CLIP_MATH
170 #define _V_CLIP_MATH
171 
CLIP_TO_15(ogg_int32_t x)172 STIN ogg_int32_t CLIP_TO_15(ogg_int32_t x) {
173   int ret=x;
174   ret-= ((x<=32767)-1)&(x-32767);
175   ret-= ((x>=-32768)-1)&(x+32768);
176   return(ret);
177 }
178 
179 #endif
180 
VFLOAT_MULT(ogg_int32_t a,ogg_int32_t ap,ogg_int32_t b,ogg_int32_t bp,ogg_int32_t * p)181 STIN ogg_int32_t VFLOAT_MULT(ogg_int32_t a,ogg_int32_t ap,
182 				      ogg_int32_t b,ogg_int32_t bp,
183 				      ogg_int32_t *p){
184   if(a && b){
185 #ifndef _LOW_ACCURACY_
186     *p=ap+bp+32;
187     return MULT32(a,b);
188 #else
189     *p=ap+bp+31;
190     return (a>>15)*(b>>16);
191 #endif
192   }else
193     return 0;
194 }
195 
196 int _ilog(unsigned int);
197 
VFLOAT_MULTI(ogg_int32_t a,ogg_int32_t ap,ogg_int32_t i,ogg_int32_t * p)198 STIN ogg_int32_t VFLOAT_MULTI(ogg_int32_t a,ogg_int32_t ap,
199 				      ogg_int32_t i,
200 				      ogg_int32_t *p){
201 
202   int ip=_ilog(abs(i))-31;
203   return VFLOAT_MULT(a,ap,i<<-ip,ip,p);
204 }
205 
VFLOAT_ADD(ogg_int32_t a,ogg_int32_t ap,ogg_int32_t b,ogg_int32_t bp,ogg_int32_t * p)206 STIN ogg_int32_t VFLOAT_ADD(ogg_int32_t a,ogg_int32_t ap,
207 				      ogg_int32_t b,ogg_int32_t bp,
208 				      ogg_int32_t *p){
209 
210   if(!a){
211     *p=bp;
212     return b;
213   }else if(!b){
214     *p=ap;
215     return a;
216   }
217 
218   /* yes, this can leak a bit. */
219   if(ap>bp){
220     int shift=ap-bp+1;
221     *p=ap+1;
222     a>>=1;
223     if(shift<32){
224       b=(b+(1<<(shift-1)))>>shift;
225     }else{
226       b=0;
227     }
228   }else{
229     int shift=bp-ap+1;
230     *p=bp+1;
231     b>>=1;
232     if(shift<32){
233       a=(a+(1<<(shift-1)))>>shift;
234     }else{
235       a=0;
236     }
237   }
238 
239   a+=b;
240   if((a&0xc0000000)==0xc0000000 ||
241      (a&0xc0000000)==0){
242     a<<=1;
243     (*p)--;
244   }
245   return(a);
246 }
247 
248 #endif
249 
250 
251 
252 
253