| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| #ifdef HAVE_CONFIG_H |
| #include "config.h" |
| #endif |
|
|
| #include "celt_lpc.h" |
| #include "arch.h" |
| #include "common.h" |
| #include "pitch.h" |
| #include "denoise.h" |
|
|
| void rnn_lpc( |
| opus_val16 *_lpc, |
| const opus_val32 *ac, |
| int p |
| ) |
| { |
| int i, j; |
| opus_val32 r; |
| opus_val32 error = ac[0]; |
| #ifdef FIXED_POINT |
| opus_val32 lpc[LPC_ORDER]; |
| #else |
| float *lpc = _lpc; |
| #endif |
|
|
| RNN_CLEAR(lpc, p); |
| if (ac[0] != 0) |
| { |
| for (i = 0; i < p; i++) { |
| |
| opus_val32 rr = 0; |
| for (j = 0; j < i; j++) |
| rr += MULT32_32_Q31(lpc[j],ac[i - j]); |
| rr += SHR32(ac[i + 1],3); |
| r = -SHL32(rr,3)/error; |
| |
| lpc[i] = SHR32(r,3); |
| for (j = 0; j < (i+1)>>1; j++) |
| { |
| opus_val32 tmp1, tmp2; |
| tmp1 = lpc[j]; |
| tmp2 = lpc[i-1-j]; |
| lpc[j] = tmp1 + MULT32_32_Q31(r,tmp2); |
| lpc[i-1-j] = tmp2 + MULT32_32_Q31(r,tmp1); |
| } |
|
|
| error = error - MULT32_32_Q31(MULT32_32_Q31(r,r),error); |
| |
| #ifdef FIXED_POINT |
| if (error<SHR32(ac[0],10)) |
| break; |
| #else |
| if (error<.001f*ac[0]) |
| break; |
| #endif |
| } |
| } |
| #ifdef FIXED_POINT |
| for (i=0;i<p;i++) |
| _lpc[i] = ROUND16(lpc[i],16); |
| #endif |
| } |
|
|
|
|
| int rnn_autocorr( |
| const opus_val16 *x, |
| opus_val32 *ac, |
| const opus_val16 *window, |
| int overlap, |
| int lag, |
| int n) |
| { |
| opus_val32 d; |
| int i, k; |
| int fastN=n-lag; |
| int shift; |
| const opus_val16 *xptr; |
| opus_val16 xx[PITCH_BUF_SIZE/2]; |
| celt_assert(n>0); |
| celt_assert(n<=PITCH_BUF_SIZE/2) |
| celt_assert(overlap>=0); |
| if (overlap == 0) |
| { |
| 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; |
| 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(xptr[i],xptr[i]),9); |
| ac0 += SHR32(MULT16_16(xptr[i+1],xptr[i+1]),9); |
| } |
|
|
| shift = celt_ilog2(ac0)-30+10; |
| shift = (shift)/2; |
| if (shift>0) |
| { |
| for(i=0;i<n;i++) |
| xx[i] = PSHR32(xptr[i], shift); |
| xptr = xx; |
| } else |
| shift = 0; |
| } |
| #endif |
| rnn_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) |
| { |
| 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; |
| } |
| #endif |
|
|
| return shift; |
| } |
|
|