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