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