diff options
Diffstat (limited to 'lib/rbcodec/codecs/libopus/celt/mathops.h')
-rw-r--r-- | lib/rbcodec/codecs/libopus/celt/mathops.h | 237 |
1 files changed, 237 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libopus/celt/mathops.h b/lib/rbcodec/codecs/libopus/celt/mathops.h new file mode 100644 index 0000000000..4e97795606 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/celt/mathops.h | |||
@@ -0,0 +1,237 @@ | |||
1 | /* Copyright (c) 2002-2008 Jean-Marc Valin | ||
2 | Copyright (c) 2007-2008 CSIRO | ||
3 | Copyright (c) 2007-2009 Xiph.Org Foundation | ||
4 | Written by Jean-Marc Valin */ | ||
5 | /** | ||
6 | @file mathops.h | ||
7 | @brief Various math functions | ||
8 | */ | ||
9 | /* | ||
10 | Redistribution and use in source and binary forms, with or without | ||
11 | modification, are permitted provided that the following conditions | ||
12 | are met: | ||
13 | |||
14 | - Redistributions of source code must retain the above copyright | ||
15 | notice, this list of conditions and the following disclaimer. | ||
16 | |||
17 | - Redistributions in binary form must reproduce the above copyright | ||
18 | notice, this list of conditions and the following disclaimer in the | ||
19 | documentation and/or other materials provided with the distribution. | ||
20 | |||
21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
22 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
23 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
24 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER | ||
25 | OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
26 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
27 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
28 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
29 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
30 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
31 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
32 | */ | ||
33 | |||
34 | #ifndef MATHOPS_H | ||
35 | #define MATHOPS_H | ||
36 | |||
37 | #include "arch.h" | ||
38 | #include "entcode.h" | ||
39 | #include "os_support.h" | ||
40 | |||
41 | /* Multiplies two 16-bit fractional values. Bit-exactness of this macro is important */ | ||
42 | #define FRAC_MUL16(a,b) ((16384+((opus_int32)(opus_int16)(a)*(opus_int16)(b)))>>15) | ||
43 | |||
44 | unsigned isqrt32(opus_uint32 _val); | ||
45 | |||
46 | #ifndef FIXED_POINT | ||
47 | |||
48 | #define PI 3.141592653f | ||
49 | #define celt_sqrt(x) ((float)sqrt(x)) | ||
50 | #define celt_rsqrt(x) (1.f/celt_sqrt(x)) | ||
51 | #define celt_rsqrt_norm(x) (celt_rsqrt(x)) | ||
52 | #define celt_cos_norm(x) ((float)cos((.5f*PI)*(x))) | ||
53 | #define celt_rcp(x) (1.f/(x)) | ||
54 | #define celt_div(a,b) ((a)/(b)) | ||
55 | #define frac_div32(a,b) ((float)(a)/(b)) | ||
56 | |||
57 | #ifdef FLOAT_APPROX | ||
58 | |||
59 | /* Note: This assumes radix-2 floating point with the exponent at bits 23..30 and an offset of 127 | ||
60 | denorm, +/- inf and NaN are *not* handled */ | ||
61 | |||
62 | /** Base-2 log approximation (log2(x)). */ | ||
63 | static inline float celt_log2(float x) | ||
64 | { | ||
65 | int integer; | ||
66 | float frac; | ||
67 | union { | ||
68 | float f; | ||
69 | opus_uint32 i; | ||
70 | } in; | ||
71 | in.f = x; | ||
72 | integer = (in.i>>23)-127; | ||
73 | in.i -= integer<<23; | ||
74 | frac = in.f - 1.5f; | ||
75 | frac = -0.41445418f + frac*(0.95909232f | ||
76 | + frac*(-0.33951290f + frac*0.16541097f)); | ||
77 | return 1+integer+frac; | ||
78 | } | ||
79 | |||
80 | /** Base-2 exponential approximation (2^x). */ | ||
81 | static inline float celt_exp2(float x) | ||
82 | { | ||
83 | int integer; | ||
84 | float frac; | ||
85 | union { | ||
86 | float f; | ||
87 | opus_uint32 i; | ||
88 | } res; | ||
89 | integer = floor(x); | ||
90 | if (integer < -50) | ||
91 | return 0; | ||
92 | frac = x-integer; | ||
93 | /* K0 = 1, K1 = log(2), K2 = 3-4*log(2), K3 = 3*log(2) - 2 */ | ||
94 | res.f = 0.99992522f + frac * (0.69583354f | ||
95 | + frac * (0.22606716f + 0.078024523f*frac)); | ||
96 | res.i = (res.i + (integer<<23)) & 0x7fffffff; | ||
97 | return res.f; | ||
98 | } | ||
99 | |||
100 | #else | ||
101 | #define celt_log2(x) ((float)(1.442695040888963387*log(x))) | ||
102 | #define celt_exp2(x) ((float)exp(0.6931471805599453094*(x))) | ||
103 | #endif | ||
104 | |||
105 | #endif | ||
106 | |||
107 | #ifdef FIXED_POINT | ||
108 | |||
109 | #include "os_support.h" | ||
110 | |||
111 | #ifndef OVERRIDE_CELT_ILOG2 | ||
112 | /** Integer log in base2. Undefined for zero and negative numbers */ | ||
113 | static inline opus_int16 celt_ilog2(opus_int32 x) | ||
114 | { | ||
115 | celt_assert2(x>0, "celt_ilog2() only defined for strictly positive numbers"); | ||
116 | return EC_ILOG(x)-1; | ||
117 | } | ||
118 | #endif | ||
119 | |||
120 | #ifndef OVERRIDE_CELT_MAXABS16 | ||
121 | static inline opus_val16 celt_maxabs16(opus_val16 *x, int len) | ||
122 | { | ||
123 | int i; | ||
124 | opus_val16 maxval = 0; | ||
125 | for (i=0;i<len;i++) | ||
126 | maxval = MAX16(maxval, ABS16(x[i])); | ||
127 | return maxval; | ||
128 | } | ||
129 | #endif | ||
130 | |||
131 | #ifndef OVERRIDE_CELT_MAXABS32 | ||
132 | static inline opus_val32 celt_maxabs32(opus_val32 *x, int len) | ||
133 | { | ||
134 | int i; | ||
135 | opus_val32 maxval = 0; | ||
136 | for (i=0;i<len;i++) | ||
137 | maxval = MAX32(maxval, ABS32(x[i])); | ||
138 | return maxval; | ||
139 | } | ||
140 | #endif | ||
141 | |||
142 | /** Integer log in base2. Defined for zero, but not for negative numbers */ | ||
143 | static inline opus_int16 celt_zlog2(opus_val32 x) | ||
144 | { | ||
145 | return x <= 0 ? 0 : celt_ilog2(x); | ||
146 | } | ||
147 | |||
148 | opus_val16 celt_rsqrt_norm(opus_val32 x); | ||
149 | |||
150 | opus_val32 celt_sqrt(opus_val32 x); | ||
151 | |||
152 | opus_val16 celt_cos_norm(opus_val32 x); | ||
153 | |||
154 | static inline opus_val16 celt_log2(opus_val32 x) | ||
155 | { | ||
156 | int i; | ||
157 | opus_val16 n, frac; | ||
158 | /* -0.41509302963303146, 0.9609890551383969, -0.31836011537636605, | ||
159 | 0.15530808010959576, -0.08556153059057618 */ | ||
160 | static const opus_val16 C[5] = {-6801+(1<<(13-DB_SHIFT)), 15746, -5217, 2545, -1401}; | ||
161 | if (x==0) | ||
162 | return -32767; | ||
163 | i = celt_ilog2(x); | ||
164 | n = VSHR32(x,i-15)-32768-16384; | ||
165 | frac = ADD16(C[0], MULT16_16_Q15(n, ADD16(C[1], MULT16_16_Q15(n, ADD16(C[2], MULT16_16_Q15(n, ADD16(C[3], MULT16_16_Q15(n, C[4])))))))); | ||
166 | return SHL16(i-13,DB_SHIFT)+SHR16(frac,14-DB_SHIFT); | ||
167 | } | ||
168 | |||
169 | /* | ||
170 | K0 = 1 | ||
171 | K1 = log(2) | ||
172 | K2 = 3-4*log(2) | ||
173 | K3 = 3*log(2) - 2 | ||
174 | */ | ||
175 | #define D0 16383 | ||
176 | #define D1 22804 | ||
177 | #define D2 14819 | ||
178 | #define D3 10204 | ||
179 | /** Base-2 exponential approximation (2^x). (Q10 input, Q16 output) */ | ||
180 | static inline opus_val32 celt_exp2(opus_val16 x) | ||
181 | { | ||
182 | int integer; | ||
183 | opus_val16 frac; | ||
184 | integer = SHR16(x,10); | ||
185 | if (integer>14) | ||
186 | return 0x7f000000; | ||
187 | else if (integer < -15) | ||
188 | return 0; | ||
189 | frac = SHL16(x-SHL16(integer,10),4); | ||
190 | frac = ADD16(D0, MULT16_16_Q15(frac, ADD16(D1, MULT16_16_Q15(frac, ADD16(D2 , MULT16_16_Q15(D3,frac)))))); | ||
191 | return VSHR32(EXTEND32(frac), -integer-2); | ||
192 | } | ||
193 | |||
194 | opus_val32 celt_rcp(opus_val32 x); | ||
195 | |||
196 | #define celt_div(a,b) MULT32_32_Q31((opus_val32)(a),celt_rcp(b)) | ||
197 | |||
198 | opus_val32 frac_div32(opus_val32 a, opus_val32 b); | ||
199 | |||
200 | #define M1 32767 | ||
201 | #define M2 -21 | ||
202 | #define M3 -11943 | ||
203 | #define M4 4936 | ||
204 | |||
205 | /* Atan approximation using a 4th order polynomial. Input is in Q15 format | ||
206 | and normalized by pi/4. Output is in Q15 format */ | ||
207 | static inline opus_val16 celt_atan01(opus_val16 x) | ||
208 | { | ||
209 | return MULT16_16_P15(x, ADD32(M1, MULT16_16_P15(x, ADD32(M2, MULT16_16_P15(x, ADD32(M3, MULT16_16_P15(M4, x))))))); | ||
210 | } | ||
211 | |||
212 | #undef M1 | ||
213 | #undef M2 | ||
214 | #undef M3 | ||
215 | #undef M4 | ||
216 | |||
217 | /* atan2() approximation valid for positive input values */ | ||
218 | static inline opus_val16 celt_atan2p(opus_val16 y, opus_val16 x) | ||
219 | { | ||
220 | if (y < x) | ||
221 | { | ||
222 | opus_val32 arg; | ||
223 | arg = celt_div(SHL32(EXTEND32(y),15),x); | ||
224 | if (arg >= 32767) | ||
225 | arg = 32767; | ||
226 | return SHR16(celt_atan01(EXTRACT16(arg)),1); | ||
227 | } else { | ||
228 | opus_val32 arg; | ||
229 | arg = celt_div(SHL32(EXTEND32(x),15),y); | ||
230 | if (arg >= 32767) | ||
231 | arg = 32767; | ||
232 | return 25736-SHR16(celt_atan01(EXTRACT16(arg)),1); | ||
233 | } | ||
234 | } | ||
235 | |||
236 | #endif /* FIXED_POINT */ | ||
237 | #endif /* MATHOPS_H */ | ||