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