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