1 /* Copyright (c) 2008-2011 Xiph.Org Foundation, Mozilla Corporation,
2 Gregory Maxwell
3 Written by Jean-Marc Valin, Gregory Maxwell, and Timothy B. Terriberry */
4 /*
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8
9 - Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11
12 - Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
20 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #ifndef CUSTOM_MODES
34 #define CUSTOM_MODES
35 #endif
36
37 #define CELT_C
38
39 #include <stdio.h>
40 #include <math.h>
41 #include "mathops.c"
42 #include "entenc.c"
43 #include "entdec.c"
44 #include "entcode.c"
45 #include "bands.c"
46 #include "quant_bands.c"
47 #include "laplace.c"
48 #include "vq.c"
49 #include "cwrs.c"
50 #include "pitch.c"
51 #include "celt_lpc.c"
52 #include "celt.c"
53
54 #if defined(OPUS_X86_MAY_HAVE_SSE) || defined(OPUS_X86_MAY_HAVE_SSE2) || defined(OPUS_X86_MAY_HAVE_SSE4_1)
55 # if defined(OPUS_X86_MAY_HAVE_SSE)
56 # include "x86/pitch_sse.c"
57 # endif
58 # if defined(OPUS_X86_MAY_HAVE_SSE2)
59 # include "x86/pitch_sse2.c"
60 # endif
61 # if defined(OPUS_X86_MAY_HAVE_SSE4_1)
62 # include "x86/pitch_sse4_1.c"
63 # include "x86/celt_lpc_sse.c"
64 # endif
65 # include "x86/x86_celt_map.c"
66 #elif defined(OPUS_ARM_ASM) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
67 # include "arm/armcpu.c"
68 # if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
69 # include "arm/celt_neon_intr.c"
70 # if defined(HAVE_ARM_NE10)
71 # include "kiss_fft.c"
72 # include "mdct.c"
73 # include "arm/celt_ne10_fft.c"
74 # include "arm/celt_ne10_mdct.c"
75 # endif
76 # endif
77 # include "arm/arm_celt_map.c"
78 #endif
79
80 #ifdef FIXED_POINT
81 #define WORD "%d"
82 #else
83 #define WORD "%f"
84 #endif
85
86 int ret = 0;
87
testdiv(void)88 void testdiv(void)
89 {
90 opus_int32 i;
91 for (i=1;i<=327670;i++)
92 {
93 double prod;
94 opus_val32 val;
95 val = celt_rcp(i);
96 #ifdef FIXED_POINT
97 prod = (1./32768./65526.)*val*i;
98 #else
99 prod = val*i;
100 #endif
101 if (fabs(prod-1) > .00025)
102 {
103 fprintf (stderr, "div failed: 1/%d="WORD" (product = %f)\n", i, val, prod);
104 ret = 1;
105 }
106 }
107 }
108
testsqrt(void)109 void testsqrt(void)
110 {
111 opus_int32 i;
112 for (i=1;i<=1000000000;i++)
113 {
114 double ratio;
115 opus_val16 val;
116 val = celt_sqrt(i);
117 ratio = val/sqrt(i);
118 if (fabs(ratio - 1) > .0005 && fabs(val-sqrt(i)) > 2)
119 {
120 fprintf (stderr, "sqrt failed: sqrt(%d)="WORD" (ratio = %f)\n", i, val, ratio);
121 ret = 1;
122 }
123 i+= i>>10;
124 }
125 }
126
testbitexactcos(void)127 void testbitexactcos(void)
128 {
129 int i;
130 opus_int32 min_d,max_d,last,chk;
131 chk=max_d=0;
132 last=min_d=32767;
133 for(i=64;i<=16320;i++)
134 {
135 opus_int32 d;
136 opus_int32 q=bitexact_cos(i);
137 chk ^= q*i;
138 d = last - q;
139 if (d>max_d)max_d=d;
140 if (d<min_d)min_d=d;
141 last = q;
142 }
143 if ((chk!=89408644)||(max_d!=5)||(min_d!=0)||(bitexact_cos(64)!=32767)||
144 (bitexact_cos(16320)!=200)||(bitexact_cos(8192)!=23171))
145 {
146 fprintf (stderr, "bitexact_cos failed\n");
147 ret = 1;
148 }
149 }
150
testbitexactlog2tan(void)151 void testbitexactlog2tan(void)
152 {
153 int i,fail;
154 opus_int32 min_d,max_d,last,chk;
155 fail=chk=max_d=0;
156 last=min_d=15059;
157 for(i=64;i<8193;i++)
158 {
159 opus_int32 d;
160 opus_int32 mid=bitexact_cos(i);
161 opus_int32 side=bitexact_cos(16384-i);
162 opus_int32 q=bitexact_log2tan(mid,side);
163 chk ^= q*i;
164 d = last - q;
165 if (q!=-1*bitexact_log2tan(side,mid))
166 fail = 1;
167 if (d>max_d)max_d=d;
168 if (d<min_d)min_d=d;
169 last = q;
170 }
171 if ((chk!=15821257)||(max_d!=61)||(min_d!=-2)||fail||
172 (bitexact_log2tan(32767,200)!=15059)||(bitexact_log2tan(30274,12540)!=2611)||
173 (bitexact_log2tan(23171,23171)!=0))
174 {
175 fprintf (stderr, "bitexact_log2tan failed\n");
176 ret = 1;
177 }
178 }
179
180 #ifndef FIXED_POINT
testlog2(void)181 void testlog2(void)
182 {
183 float x;
184 for (x=0.001;x<1677700.0;x+=(x/8.0))
185 {
186 float error = fabs((1.442695040888963387*log(x))-celt_log2(x));
187 if (error>0.0009)
188 {
189 fprintf (stderr, "celt_log2 failed: fabs((1.442695040888963387*log(x))-celt_log2(x))>0.001 (x = %f, error = %f)\n", x,error);
190 ret = 1;
191 }
192 }
193 }
194
testexp2(void)195 void testexp2(void)
196 {
197 float x;
198 for (x=-11.0;x<24.0;x+=0.0007)
199 {
200 float error = fabs(x-(1.442695040888963387*log(celt_exp2(x))));
201 if (error>0.0002)
202 {
203 fprintf (stderr, "celt_exp2 failed: fabs(x-(1.442695040888963387*log(celt_exp2(x))))>0.0005 (x = %f, error = %f)\n", x,error);
204 ret = 1;
205 }
206 }
207 }
208
testexp2log2(void)209 void testexp2log2(void)
210 {
211 float x;
212 for (x=-11.0;x<24.0;x+=0.0007)
213 {
214 float error = fabs(x-(celt_log2(celt_exp2(x))));
215 if (error>0.001)
216 {
217 fprintf (stderr, "celt_log2/celt_exp2 failed: fabs(x-(celt_log2(celt_exp2(x))))>0.001 (x = %f, error = %f)\n", x,error);
218 ret = 1;
219 }
220 }
221 }
222 #else
testlog2(void)223 void testlog2(void)
224 {
225 opus_val32 x;
226 for (x=8;x<1073741824;x+=(x>>3))
227 {
228 float error = fabs((1.442695040888963387*log(x/16384.0))-celt_log2(x)/1024.0);
229 if (error>0.003)
230 {
231 fprintf (stderr, "celt_log2 failed: x = %ld, error = %f\n", (long)x,error);
232 ret = 1;
233 }
234 }
235 }
236
testexp2(void)237 void testexp2(void)
238 {
239 opus_val16 x;
240 for (x=-32768;x<15360;x++)
241 {
242 float error1 = fabs(x/1024.0-(1.442695040888963387*log(celt_exp2(x)/65536.0)));
243 float error2 = fabs(exp(0.6931471805599453094*x/1024.0)-celt_exp2(x)/65536.0);
244 if (error1>0.0002&&error2>0.00004)
245 {
246 fprintf (stderr, "celt_exp2 failed: x = "WORD", error1 = %f, error2 = %f\n", x,error1,error2);
247 ret = 1;
248 }
249 }
250 }
251
testexp2log2(void)252 void testexp2log2(void)
253 {
254 opus_val32 x;
255 for (x=8;x<65536;x+=(x>>3))
256 {
257 float error = fabs(x-0.25*celt_exp2(celt_log2(x)))/16384;
258 if (error>0.004)
259 {
260 fprintf (stderr, "celt_log2/celt_exp2 failed: fabs(x-(celt_exp2(celt_log2(x))))>0.001 (x = %ld, error = %f)\n", (long)x,error);
261 ret = 1;
262 }
263 }
264 }
265
testilog2(void)266 void testilog2(void)
267 {
268 opus_val32 x;
269 for (x=1;x<=268435455;x+=127)
270 {
271 opus_val32 lg;
272 opus_val32 y;
273
274 lg = celt_ilog2(x);
275 if (lg<0 || lg>=31)
276 {
277 printf("celt_ilog2 failed: 0<=celt_ilog2(x)<31 (x = %d, celt_ilog2(x) = %d)\n",x,lg);
278 ret = 1;
279 }
280 y = 1<<lg;
281
282 if (x<y || (x>>1)>=y)
283 {
284 printf("celt_ilog2 failed: 2**celt_ilog2(x)<=x<2**(celt_ilog2(x)+1) (x = %d, 2**celt_ilog2(x) = %d)\n",x,y);
285 ret = 1;
286 }
287 }
288 }
289 #endif
290
main(void)291 int main(void)
292 {
293 testbitexactcos();
294 testbitexactlog2tan();
295 testdiv();
296 testsqrt();
297 testlog2();
298 testexp2();
299 testexp2log2();
300 #ifdef FIXED_POINT
301 testilog2();
302 #endif
303 return ret;
304 }
305