123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- #ifdef HAVE_CONFIG_H
- #include "config.h"
- #endif
- #include "celt_lpc.h"
- #include "stack_alloc.h"
- #include "mathops.h"
- void _celt_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
- for (i = 0; i < p; i++)
- lpc[i] = 0;
- 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 = -frac_div32(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
- }
- void celt_fir(const opus_val16 *x,
- const opus_val16 *num,
- opus_val16 *y,
- int N,
- int ord,
- opus_val16 *mem)
- {
- int i,j;
- for (i=0;i<N;i++)
- {
- opus_val32 sum = SHL32(EXTEND32(x[i]), SIG_SHIFT);
- for (j=0;j<ord;j++)
- {
- sum += MULT16_16(num[j],mem[j]);
- }
- for (j=ord-1;j>=1;j--)
- {
- mem[j]=mem[j-1];
- }
- mem[0] = x[i];
- y[i] = ROUND16(sum, SIG_SHIFT);
- }
- }
- void celt_iir(const opus_val32 *x,
- const opus_val16 *den,
- opus_val32 *y,
- int N,
- int ord,
- opus_val16 *mem)
- {
- int i,j;
- for (i=0;i<N;i++)
- {
- opus_val32 sum = x[i];
- for (j=0;j<ord;j++)
- {
- sum -= MULT16_16(den[j],mem[j]);
- }
- for (j=ord-1;j>=1;j--)
- {
- mem[j]=mem[j-1];
- }
- mem[0] = ROUND16(sum,SIG_SHIFT);
- y[i] = sum;
- }
- }
- void _celt_autocorr(
- const opus_val16 *x,
- opus_val32 *ac,
- const opus_val16 *window,
- int overlap,
- int lag,
- int n
- )
- {
- opus_val32 d;
- int i;
- 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++)
- {
- xx[i] = MULT16_16_Q15(x[i],window[i]);
- xx[n-i-1] = MULT16_16_Q15(x[n-i-1],window[i]);
- }
- #ifdef FIXED_POINT
- {
- opus_val32 ac0=0;
- int shift;
- for(i=0;i<n;i++)
- ac0 += SHR32(MULT16_16(xx[i],xx[i]),9);
- ac0 += 1+n;
- shift = celt_ilog2(ac0)-30+10;
- shift = (shift+1)/2;
- for(i=0;i<n;i++)
- xx[i] = VSHR32(xx[i], shift);
- }
- #endif
- while (lag>=0)
- {
- for (i = lag, d = 0; i < n; i++)
- d += xx[i] * xx[i-lag];
- ac[lag] = d;
-
- lag--;
- }
-
- ac[0] += 10;
- RESTORE_STACK;
- }
|