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