diff --git a/libcelt/mathops.h b/libcelt/mathops.h index 6bc24f02..f19113cc 100644 --- a/libcelt/mathops.h +++ b/libcelt/mathops.h @@ -54,6 +54,11 @@ #include "entcode.h" +static inline celt_int16_t celt_ilog2(celt_word32_t x) +{ + return EC_ILOG(x)-1; +} + #define C0 3634 #define C1 21173 #define C2 -12627 @@ -116,6 +121,19 @@ static inline celt_word16_t celt_cos_norm(celt_word32_t x) } } +static inline celt_word16_t celt_log2(celt_word32_t x) +{ + int i; + /*-0.41446 0.96093 -0.33981 0.15600 */ + const celt_word16_t C[4] = {-6791, 7872, -1392, 319}; + if (x==0) + return -32767; + i = celt_ilog2(x); + celt_word16_t n = VSHR32(x,i-15)-32768-16384; + celt_word16_t ret = ADD16(C[0], MULT16_16_Q14(n, ADD16(C[1], MULT16_16_Q14(n, ADD16(C[2], MULT16_16_Q14(n, (C[3]))))))); + /*printf ("%d %d %d %d\n", x, n, ret, SHL16(i-13,8)+SHR16(ret,14-8));*/ + return SHL16(i-13,8)+SHR16(ret,14-8); +} #endif diff --git a/libcelt/quant_bands.c b/libcelt/quant_bands.c index a54a78da..7b3f3b62 100644 --- a/libcelt/quant_bands.c +++ b/libcelt/quant_bands.c @@ -38,6 +38,7 @@ #include #include "os_support.h" #include "arch.h" +#include "mathops.h" #ifdef FIXED_POINT const celt_word16_t eMeans[24] = {11520, -2048, -3072, -640, 256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; @@ -48,6 +49,37 @@ const float eMeans[24] = {45.f, -8.f, -12.f, -2.5f, 1.f, 0.f, 0.f, 0.f, 0.f, 0.f /*const int frac[24] = {4, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2};*/ const int frac[24] = {8, 6, 5, 4, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}; +#ifdef FIXED_POINT +static inline celt_ener_t dB2Amp( dB) +{ + celt_ener_t amp; + amp = pow(10, .05*dB)-.3; + if (amp < 0) + amp = 0; +} + +#define DBofTWO 24661 +static inline celt_word16_t amp2dB(celt_ener_t amp) +{ + /* equivalent to return 6.0207*log2(.3+amp) */ + return ROUND(MULT16_16(24661,celt_log2(ADD32(QCONST32(.3f,14),amp))),12); + /* return DB_SCALING*20*log10(.3+ENER_SCALING_1*amp); */ +} +#else +static inline celt_ener_t dB2Amp( dB) +{ + celt_ener_t amp; + amp = pow(10, .05*dB)-.3; + if (amp < 0) + amp = 0; +} +static inline celt_word16_t amp2dB(celt_ener_t amp) +{ + return 20*log10(.3+amp); +} +#endif + + #ifdef FIXED_POINT #define Q8 256.f #define Q8_1 (1.f/256.f) @@ -75,7 +107,7 @@ static void quant_energy_mono(const CELTMode *m, celt_ener_t *eBands, celt_word1 celt_word16_t x; /* dB */ celt_word16_t f; /* Q8 */ celt_word16_t mean = (1-coef)*eMeans[i]; - x = DB_SCALING*20*log10(.3+ENER_SCALING_1*eBands[i]); + x = amp2dB(eBands[i]); res = DB_SCALING*6; f = QCONST16(1.f,8)*(x-mean-coef*oldEBands[i]-prev*1.f)/res; #ifdef FIXED_POINT