cannam@154: /* Copyright (c) 2008-2011 Xiph.Org Foundation, Mozilla Corporation, cannam@154: Gregory Maxwell cannam@154: Written by Jean-Marc Valin, Gregory Maxwell, and Timothy B. Terriberry */ cannam@154: /* cannam@154: Redistribution and use in source and binary forms, with or without cannam@154: modification, are permitted provided that the following conditions cannam@154: are met: cannam@154: cannam@154: - Redistributions of source code must retain the above copyright cannam@154: notice, this list of conditions and the following disclaimer. cannam@154: cannam@154: - Redistributions in binary form must reproduce the above copyright cannam@154: notice, this list of conditions and the following disclaimer in the cannam@154: documentation and/or other materials provided with the distribution. cannam@154: cannam@154: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS cannam@154: ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT cannam@154: LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR cannam@154: A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER cannam@154: OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, cannam@154: EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, cannam@154: PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR cannam@154: PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF cannam@154: LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING cannam@154: NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS cannam@154: SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. cannam@154: */ cannam@154: cannam@154: #ifdef HAVE_CONFIG_H cannam@154: #include "config.h" cannam@154: #endif cannam@154: cannam@154: #ifndef CUSTOM_MODES cannam@154: #define CUSTOM_MODES cannam@154: #endif cannam@154: cannam@154: #include cannam@154: #include cannam@154: #include "mathops.h" cannam@154: #include "bands.h" cannam@154: cannam@154: #ifdef FIXED_POINT cannam@154: #define WORD "%d" cannam@154: #else cannam@154: #define WORD "%f" cannam@154: #endif cannam@154: cannam@154: int ret = 0; cannam@154: cannam@154: void testdiv(void) cannam@154: { cannam@154: opus_int32 i; cannam@154: for (i=1;i<=327670;i++) cannam@154: { cannam@154: double prod; cannam@154: opus_val32 val; cannam@154: val = celt_rcp(i); cannam@154: #ifdef FIXED_POINT cannam@154: prod = (1./32768./65526.)*val*i; cannam@154: #else cannam@154: prod = val*i; cannam@154: #endif cannam@154: if (fabs(prod-1) > .00025) cannam@154: { cannam@154: fprintf (stderr, "div failed: 1/%d="WORD" (product = %f)\n", i, val, prod); cannam@154: ret = 1; cannam@154: } cannam@154: } cannam@154: } cannam@154: cannam@154: void testsqrt(void) cannam@154: { cannam@154: opus_int32 i; cannam@154: for (i=1;i<=1000000000;i++) cannam@154: { cannam@154: double ratio; cannam@154: opus_val16 val; cannam@154: val = celt_sqrt(i); cannam@154: ratio = val/sqrt(i); cannam@154: if (fabs(ratio - 1) > .0005 && fabs(val-sqrt(i)) > 2) cannam@154: { cannam@154: fprintf (stderr, "sqrt failed: sqrt(%d)="WORD" (ratio = %f)\n", i, val, ratio); cannam@154: ret = 1; cannam@154: } cannam@154: i+= i>>10; cannam@154: } cannam@154: } cannam@154: cannam@154: void testbitexactcos(void) cannam@154: { cannam@154: int i; cannam@154: opus_int32 min_d,max_d,last,chk; cannam@154: chk=max_d=0; cannam@154: last=min_d=32767; cannam@154: for(i=64;i<=16320;i++) cannam@154: { cannam@154: opus_int32 d; cannam@154: opus_int32 q=bitexact_cos(i); cannam@154: chk ^= q*i; cannam@154: d = last - q; cannam@154: if (d>max_d)max_d=d; cannam@154: if (dmax_d)max_d=d; cannam@154: if (d0.0009) cannam@154: { cannam@154: fprintf (stderr, "celt_log2 failed: fabs((1.442695040888963387*log(x))-celt_log2(x))>0.001 (x = %f, error = %f)\n", x,error); cannam@154: ret = 1; cannam@154: } cannam@154: } cannam@154: } cannam@154: cannam@154: void testexp2(void) cannam@154: { cannam@154: float x; cannam@154: for (x=-11.0;x<24.0;x+=0.0007) cannam@154: { cannam@154: float error = fabs(x-(1.442695040888963387*log(celt_exp2(x)))); cannam@154: if (error>0.0002) cannam@154: { cannam@154: fprintf (stderr, "celt_exp2 failed: fabs(x-(1.442695040888963387*log(celt_exp2(x))))>0.0005 (x = %f, error = %f)\n", x,error); cannam@154: ret = 1; cannam@154: } cannam@154: } cannam@154: } cannam@154: cannam@154: void testexp2log2(void) cannam@154: { cannam@154: float x; cannam@154: for (x=-11.0;x<24.0;x+=0.0007) cannam@154: { cannam@154: float error = fabs(x-(celt_log2(celt_exp2(x)))); cannam@154: if (error>0.001) cannam@154: { cannam@154: 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: ret = 1; cannam@154: } cannam@154: } cannam@154: } cannam@154: #else cannam@154: void testlog2(void) cannam@154: { cannam@154: opus_val32 x; cannam@154: for (x=8;x<1073741824;x+=(x>>3)) cannam@154: { cannam@154: float error = fabs((1.442695040888963387*log(x/16384.0))-celt_log2(x)/1024.0); cannam@154: if (error>0.003) cannam@154: { cannam@154: fprintf (stderr, "celt_log2 failed: x = %ld, error = %f\n", (long)x,error); cannam@154: ret = 1; cannam@154: } cannam@154: } cannam@154: } cannam@154: cannam@154: void testexp2(void) cannam@154: { cannam@154: opus_val16 x; cannam@154: for (x=-32768;x<15360;x++) cannam@154: { cannam@154: float error1 = fabs(x/1024.0-(1.442695040888963387*log(celt_exp2(x)/65536.0))); cannam@154: float error2 = fabs(exp(0.6931471805599453094*x/1024.0)-celt_exp2(x)/65536.0); cannam@154: if (error1>0.0002&&error2>0.00004) cannam@154: { cannam@154: fprintf (stderr, "celt_exp2 failed: x = "WORD", error1 = %f, error2 = %f\n", x,error1,error2); cannam@154: ret = 1; cannam@154: } cannam@154: } cannam@154: } cannam@154: cannam@154: void testexp2log2(void) cannam@154: { cannam@154: opus_val32 x; cannam@154: for (x=8;x<65536;x+=(x>>3)) cannam@154: { cannam@154: float error = fabs(x-0.25*celt_exp2(celt_log2(x)))/16384; cannam@154: if (error>0.004) cannam@154: { cannam@154: 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: ret = 1; cannam@154: } cannam@154: } cannam@154: } cannam@154: cannam@154: void testilog2(void) cannam@154: { cannam@154: opus_val32 x; cannam@154: for (x=1;x<=268435455;x+=127) cannam@154: { cannam@154: opus_val32 lg; cannam@154: opus_val32 y; cannam@154: cannam@154: lg = celt_ilog2(x); cannam@154: if (lg<0 || lg>=31) cannam@154: { cannam@154: printf("celt_ilog2 failed: 0<=celt_ilog2(x)<31 (x = %d, celt_ilog2(x) = %d)\n",x,lg); cannam@154: ret = 1; cannam@154: } cannam@154: y = 1<>1)>=y) cannam@154: { cannam@154: 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: ret = 1; cannam@154: } cannam@154: } cannam@154: } cannam@154: #endif cannam@154: cannam@154: int main(void) cannam@154: { cannam@154: testbitexactcos(); cannam@154: testbitexactlog2tan(); cannam@154: testdiv(); cannam@154: testsqrt(); cannam@154: testlog2(); cannam@154: testexp2(); cannam@154: testexp2log2(); cannam@154: #ifdef FIXED_POINT cannam@154: testilog2(); cannam@154: #endif cannam@154: return ret; cannam@154: }