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