|
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 #elif BYTE_ORDER==BIG_ENDIAN |
|
53 union magic { |
|
54 struct { |
|
55 ogg_int32_t hi; |
|
56 ogg_int32_t lo; |
|
57 } halves; |
|
58 ogg_int64_t whole; |
|
59 }; |
|
60 #endif |
|
61 |
|
62 STIN 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 |
|
68 STIN ogg_int32_t MULT31(ogg_int32_t x, ogg_int32_t y) { |
|
69 return MULT32(x,y)<<1; |
|
70 } |
|
71 |
|
72 STIN 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 |
|
94 STIN ogg_int32_t MULT32(ogg_int32_t x, ogg_int32_t y) { |
|
95 return (x >> 9) * y; /* y preshifted >>23 */ |
|
96 } |
|
97 |
|
98 STIN ogg_int32_t MULT31(ogg_int32_t x, ogg_int32_t y) { |
|
99 return (x >> 8) * y; /* y preshifted >>23 */ |
|
100 } |
|
101 |
|
102 STIN 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 |
|
139 STIN 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 |
|
147 STIN 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 |
|
155 STIN 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 |
|
170 STIN 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 |
|
179 STIN 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 |
|
194 int _ilog(unsigned int); |
|
195 |
|
196 STIN 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 |
|
204 STIN 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 |