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 #include <stdio.h>
38 #include <math.h>
39 #include "mathops.h"
40 #include "bands.h"
41 
42 #ifdef FIXED_POINT
43 #define WORD "%d"
44 #else
45 #define WORD "%f"
46 #endif
47 
48 int ret = 0;
49 
testdiv(void)50 void testdiv(void)
51 {
52    opus_int32 i;
53    for (i=1;i<=327670;i++)
54    {
55       double prod;
56       opus_val32 val;
57       val = celt_rcp(i);
58 #ifdef FIXED_POINT
59       prod = (1./32768./65526.)*val*i;
60 #else
61       prod = val*i;
62 #endif
63       if (fabs(prod-1) > .00025)
64       {
65          fprintf (stderr, "div failed: 1/%d="WORD" (product = %f)\n", i, val, prod);
66          ret = 1;
67       }
68    }
69 }
70 
testsqrt(void)71 void testsqrt(void)
72 {
73    opus_int32 i;
74    for (i=1;i<=1000000000;i++)
75    {
76       double ratio;
77       opus_val16 val;
78       val = celt_sqrt(i);
79       ratio = val/sqrt(i);
80       if (fabs(ratio - 1) > .0005 && fabs(val-sqrt(i)) > 2)
81       {
82          fprintf (stderr, "sqrt failed: sqrt(%d)="WORD" (ratio = %f)\n", i, val, ratio);
83          ret = 1;
84       }
85       i+= i>>10;
86    }
87 }
88 
testbitexactcos(void)89 void testbitexactcos(void)
90 {
91    int i;
92    opus_int32 min_d,max_d,last,chk;
93    chk=max_d=0;
94    last=min_d=32767;
95    for(i=64;i<=16320;i++)
96    {
97       opus_int32 d;
98       opus_int32 q=bitexact_cos(i);
99       chk ^= q*i;
100       d = last - q;
101       if (d>max_d)max_d=d;
102       if (d<min_d)min_d=d;
103       last = q;
104    }
105    if ((chk!=89408644)||(max_d!=5)||(min_d!=0)||(bitexact_cos(64)!=32767)||
106        (bitexact_cos(16320)!=200)||(bitexact_cos(8192)!=23171))
107    {
108       fprintf (stderr, "bitexact_cos failed\n");
109       ret = 1;
110    }
111 }
112 
testbitexactlog2tan(void)113 void testbitexactlog2tan(void)
114 {
115    int i,fail;
116    opus_int32 min_d,max_d,last,chk;
117    fail=chk=max_d=0;
118    last=min_d=15059;
119    for(i=64;i<8193;i++)
120    {
121       opus_int32 d;
122       opus_int32 mid=bitexact_cos(i);
123       opus_int32 side=bitexact_cos(16384-i);
124       opus_int32 q=bitexact_log2tan(mid,side);
125       chk ^= q*i;
126       d = last - q;
127       if (q!=-1*bitexact_log2tan(side,mid))
128         fail = 1;
129       if (d>max_d)max_d=d;
130       if (d<min_d)min_d=d;
131       last = q;
132    }
133    if ((chk!=15821257)||(max_d!=61)||(min_d!=-2)||fail||
134        (bitexact_log2tan(32767,200)!=15059)||(bitexact_log2tan(30274,12540)!=2611)||
135        (bitexact_log2tan(23171,23171)!=0))
136    {
137       fprintf (stderr, "bitexact_log2tan failed\n");
138       ret = 1;
139    }
140 }
141 
142 #ifndef FIXED_POINT
testlog2(void)143 void testlog2(void)
144 {
145    float x;
146    for (x=0.001;x<1677700.0;x+=(x/8.0))
147    {
148       float error = fabs((1.442695040888963387*log(x))-celt_log2(x));
149       if (error>0.0009)
150       {
151          fprintf (stderr, "celt_log2 failed: fabs((1.442695040888963387*log(x))-celt_log2(x))>0.001 (x = %f, error = %f)\n", x,error);
152          ret = 1;
153       }
154    }
155 }
156 
testexp2(void)157 void testexp2(void)
158 {
159    float x;
160    for (x=-11.0;x<24.0;x+=0.0007)
161    {
162       float error = fabs(x-(1.442695040888963387*log(celt_exp2(x))));
163       if (error>0.0002)
164       {
165          fprintf (stderr, "celt_exp2 failed: fabs(x-(1.442695040888963387*log(celt_exp2(x))))>0.0005 (x = %f, error = %f)\n", x,error);
166          ret = 1;
167       }
168    }
169 }
170 
testexp2log2(void)171 void testexp2log2(void)
172 {
173    float x;
174    for (x=-11.0;x<24.0;x+=0.0007)
175    {
176       float error = fabs(x-(celt_log2(celt_exp2(x))));
177       if (error>0.001)
178       {
179          fprintf (stderr, "celt_log2/celt_exp2 failed: fabs(x-(celt_log2(celt_exp2(x))))>0.001 (x = %f, error = %f)\n", x,error);
180          ret = 1;
181       }
182    }
183 }
184 #else
testlog2(void)185 void testlog2(void)
186 {
187    opus_val32 x;
188    for (x=8;x<1073741824;x+=(x>>3))
189    {
190       float error = fabs((1.442695040888963387*log(x/16384.0))-celt_log2(x)/1024.0);
191       if (error>0.003)
192       {
193          fprintf (stderr, "celt_log2 failed: x = %ld, error = %f\n", (long)x,error);
194          ret = 1;
195       }
196    }
197 }
198 
testexp2(void)199 void testexp2(void)
200 {
201    opus_val16 x;
202    for (x=-32768;x<15360;x++)
203    {
204       float error1 = fabs(x/1024.0-(1.442695040888963387*log(celt_exp2(x)/65536.0)));
205       float error2 = fabs(exp(0.6931471805599453094*x/1024.0)-celt_exp2(x)/65536.0);
206       if (error1>0.0002&&error2>0.00004)
207       {
208          fprintf (stderr, "celt_exp2 failed: x = "WORD", error1 = %f, error2 = %f\n", x,error1,error2);
209          ret = 1;
210       }
211    }
212 }
213 
testexp2log2(void)214 void testexp2log2(void)
215 {
216    opus_val32 x;
217    for (x=8;x<65536;x+=(x>>3))
218    {
219       float error = fabs(x-0.25*celt_exp2(celt_log2(x)))/16384;
220       if (error>0.004)
221       {
222          fprintf (stderr, "celt_log2/celt_exp2 failed: fabs(x-(celt_exp2(celt_log2(x))))>0.001 (x = %ld, error = %f)\n", (long)x,error);
223          ret = 1;
224       }
225    }
226 }
227 
testilog2(void)228 void testilog2(void)
229 {
230    opus_val32 x;
231    for (x=1;x<=268435455;x+=127)
232    {
233       opus_val32 lg;
234       opus_val32 y;
235 
236       lg = celt_ilog2(x);
237       if (lg<0 || lg>=31)
238       {
239          printf("celt_ilog2 failed: 0<=celt_ilog2(x)<31 (x = %d, celt_ilog2(x) = %d)\n",x,lg);
240          ret = 1;
241       }
242       y = 1<<lg;
243 
244       if (x<y || (x>>1)>=y)
245       {
246          printf("celt_ilog2 failed: 2**celt_ilog2(x)<=x<2**(celt_ilog2(x)+1) (x = %d, 2**celt_ilog2(x) = %d)\n",x,y);
247          ret = 1;
248       }
249    }
250 }
251 #endif
252 
main(void)253 int main(void)
254 {
255    testbitexactcos();
256    testbitexactlog2tan();
257    testdiv();
258    testsqrt();
259    testlog2();
260    testexp2();
261    testexp2log2();
262 #ifdef FIXED_POINT
263    testilog2();
264 #endif
265    return ret;
266 }
267