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