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 57 int ret = 0; 58 59 void 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 80 void 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 98 void 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 122 void 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 152 void 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 166 void 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 180 void 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 194 void 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 208 void 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 223 void 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 237 void 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 262 int 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