diff options
author | Jean-Marc Valin <jmvalin@jmvalin.ca> | 2013-08-29 01:55:34 +0400 |
---|---|---|
committer | Jean-Marc Valin <jmvalin@jmvalin.ca> | 2013-08-29 01:55:34 +0400 |
commit | 6a7ee7fb55b4a41fca2dea19624600fe42d3b7f7 (patch) | |
tree | e64ce7be7536a89105ad6fa460782785b28769f5 /celt/celt_lpc.c | |
parent | a156c5ece7133383468d4cba33f067595d9da391 (diff) |
Share auto-correlation code between SILK and CELT
Diffstat (limited to 'celt/celt_lpc.c')
-rw-r--r-- | celt/celt_lpc.c | 78 |
1 files changed, 54 insertions, 24 deletions
diff --git a/celt/celt_lpc.c b/celt/celt_lpc.c index 1861b890..523c36aa 100644 --- a/celt/celt_lpc.c +++ b/celt/celt_lpc.c @@ -221,7 +221,7 @@ void celt_iir(const opus_val32 *_x, #endif } -void _celt_autocorr( +int _celt_autocorr( const opus_val16 *x, /* in: [0...n-1] samples x */ opus_val32 *ac, /* out: [0...lag-1] ac values */ const opus_val16 *window, @@ -231,49 +231,79 @@ void _celt_autocorr( ) { opus_val32 d; - int i; + int i, k; int fastN=n-lag; + int shift; + const opus_val16 *xptr; VARDECL(opus_val16, xx); SAVE_STACK; ALLOC(xx, n, opus_val16); celt_assert(n>0); celt_assert(overlap>=0); - for (i=0;i<n;i++) - xx[i] = x[i]; - for (i=0;i<overlap;i++) + if (overlap == 0) { - xx[i] = MULT16_16_Q15(x[i],window[i]); - xx[n-i-1] = MULT16_16_Q15(x[n-i-1],window[i]); + xptr = x; + } else { + for (i=0;i<n;i++) + xx[i] = x[i]; + for (i=0;i<overlap;i++) + { + xx[i] = MULT16_16_Q15(x[i],window[i]); + xx[n-i-1] = MULT16_16_Q15(x[n-i-1],window[i]); + } + xptr = xx; } + shift=0; #ifdef FIXED_POINT { opus_val32 ac0; - int shift; - ac0 = 1+n; - if (n&1) ac0 += SHR32(MULT16_16(xx[0],xx[0]),9); + ac0 = 1+(n<<7); + if (n&1) ac0 += SHR32(MULT16_16(xptr[0],xptr[0]),9); for(i=(n&1);i<n;i+=2) { - ac0 += SHR32(MULT16_16(xx[i],xx[i]),9); - ac0 += SHR32(MULT16_16(xx[i+1],xx[i+1]),9); + ac0 += SHR32(MULT16_16(xptr[i],xptr[i]),9); + ac0 += SHR32(MULT16_16(xptr[i+1],xptr[i+1]),9); } shift = celt_ilog2(ac0)-30+10; - shift = (shift+1)/2; - for(i=0;i<n;i++) - xx[i] = VSHR32(xx[i], shift); + shift = (shift)/2; + if (shift>0) + { + for(i=0;i<n;i++) + xx[i] = PSHR32(xptr[i], shift); + xptr = xx; + } else + shift = 0; } #endif - celt_pitch_xcorr(xx, xx, ac, fastN, lag+1); - while (lag>=0) + celt_pitch_xcorr(xptr, xptr, ac, fastN, lag+1); + for (k=0;k<=lag;k++) + { + for (i = k+fastN, d = 0; i < n; i++) + d = MAC16_16(d, xptr[i], xptr[i-k]); + ac[k] += d; + } +#ifdef FIXED_POINT + shift = 2*shift; + if (shift<=0) + ac[0] += SHL32((opus_int32)1, -shift); + if (ac[0] < 268435456) { - for (i = lag+fastN, d = 0; i < n; i++) - d = MAC16_16(d, xx[i], xx[i-lag]); - ac[lag] += d; - /*printf ("%f ", ac[lag]);*/ - lag--; + int shift2 = 29 - EC_ILOG(ac[0]); + for (i=0;i<=lag;i++) + ac[i] = SHL32(ac[i], shift2); + shift -= shift2; + } else if (ac[0] >= 536870912) + { + int shift2=1; + if (ac[0] >= 1073741824) + shift2++; + for (i=0;i<=lag;i++) + ac[i] = SHR32(ac[i], shift2); + shift += shift2; } - /*printf ("\n");*/ - ac[0] += 10; +#endif RESTORE_STACK; + return shift; } |