#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "mathops.h"
unsigned isqrt32(opus_uint32 _val){
unsigned b;
unsigned g;
int bshift;
g=0;
bshift=(EC_ILOG(_val)-1)>>1;
b=1U<<bshift;
do{
opus_uint32 t;
t=(((opus_uint32)g<<1)+b)<<bshift;
if(t<=_val){
g+=b;
_val-=t;
}
b>>=1;
bshift--;
}
while(bshift>=0);
return g;
}
#ifdef FIXED_POINT
opus_val32 frac_div32(opus_val32 a, opus_val32 b)
{
opus_val16 rcp;
opus_val32 result, rem;
int shift = celt_ilog2(b)-29;
a = VSHR32(a,shift);
b = VSHR32(b,shift);
rcp = ROUND16(celt_rcp(ROUND16(b,16)),3);
result = MULT16_32_Q15(rcp, a);
rem = PSHR32(a,2)-MULT32_32_Q31(result, b);
result = ADD32(result, SHL32(MULT16_32_Q15(rcp, rem),2));
if (result >= 536870912)
return 2147483647;
else if (result <= -536870912)
return -2147483647;
else
return SHL32(result, 2);
}
opus_val16 celt_rsqrt_norm(opus_val32 x)
{
opus_val16 n;
opus_val16 r;
opus_val16 r2;
opus_val16 y;
n = x-32768;
r = ADD16(23557, MULT16_16_Q15(n, ADD16(-13490, MULT16_16_Q15(n, 6713))));
r2 = MULT16_16_Q15(r, r);
y = SHL16(SUB16(ADD16(MULT16_16_Q15(r2, n), r2), 16384), 1);
return ADD16(r, MULT16_16_Q15(r, MULT16_16_Q15(y,
SUB16(MULT16_16_Q15(y, 12288), 16384))));
}
opus_val32 celt_sqrt(opus_val32 x)
{
int k;
opus_val16 n;
opus_val32 rt;
static const opus_val16 C[5] = {23175, 11561, -3011, 1699, -664};
if (x==0)
return 0;
else if (x>=1073741824)
return 32767;
k = (celt_ilog2(x)>>1)-7;
x = VSHR32(x, 2*k);
n = x-32768;
rt = ADD16(C[0], MULT16_16_Q15(n, ADD16(C[1], MULT16_16_Q15(n, ADD16(C[2],
MULT16_16_Q15(n, ADD16(C[3], MULT16_16_Q15(n, (C[4])))))))));
rt = VSHR32(rt,7-k);
return rt;
}
#define L1 32767
#define L2 -7651
#define L3 8277
#define L4 -626
static OPUS_INLINE opus_val16 _celt_cos_pi_2(opus_val16 x)
{
opus_val16 x2;
x2 = MULT16_16_P15(x,x);
return ADD16(1,MIN16(32766,ADD32(SUB16(L1,x2), MULT16_16_P15(x2, ADD32(L2, MULT16_16_P15(x2, ADD32(L3, MULT16_16_P15(L4, x2
))))))));
}
#undef L1
#undef L2
#undef L3
#undef L4
opus_val16 celt_cos_norm(opus_val32 x)
{
x = x&0x0001ffff;
if (x>SHL32(EXTEND32(1), 16))
x = SUB32(SHL32(EXTEND32(1), 17),x);
if (x&0x00007fff)
{
if (x<SHL32(EXTEND32(1), 15))
{
return _celt_cos_pi_2(EXTRACT16(x));
} else {
return NEG32(_celt_cos_pi_2(EXTRACT16(65536-x)));
}
} else {
if (x&0x0000ffff)
return 0;
else if (x&0x0001ffff)
return -32767;
else
return 32767;
}
}
opus_val32 celt_rcp(opus_val32 x)
{
int i;
opus_val16 n;
opus_val16 r;
celt_assert2(x>0, "celt_rcp() only defined for positive values");
i = celt_ilog2(x);
n = VSHR32(x,i-15)-32768;
r = ADD16(30840, MULT16_16_Q15(-15420, n));
r = SUB16(r, MULT16_16_Q15(r,
ADD16(MULT16_16_Q15(r, n), ADD16(r, -32768))));
r = SUB16(r, ADD16(1, MULT16_16_Q15(r,
ADD16(MULT16_16_Q15(r, n), ADD16(r, -32768)))));
return VSHR32(EXTEND32(r),i-16);
}
#endif