annotate src/opus-1.3/celt/celt_lpc.c @ 79:91c729825bca pa_catalina

Update build for AUDIO_COMPONENT_FIX
author Chris Cannam
date Wed, 30 Oct 2019 12:40:34 +0000
parents 7aeed7906520
children
rev   line source
Chris@69 1 /* Copyright (c) 2009-2010 Xiph.Org Foundation
Chris@69 2 Written by Jean-Marc Valin */
Chris@69 3 /*
Chris@69 4 Redistribution and use in source and binary forms, with or without
Chris@69 5 modification, are permitted provided that the following conditions
Chris@69 6 are met:
Chris@69 7
Chris@69 8 - Redistributions of source code must retain the above copyright
Chris@69 9 notice, this list of conditions and the following disclaimer.
Chris@69 10
Chris@69 11 - Redistributions in binary form must reproduce the above copyright
Chris@69 12 notice, this list of conditions and the following disclaimer in the
Chris@69 13 documentation and/or other materials provided with the distribution.
Chris@69 14
Chris@69 15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
Chris@69 16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
Chris@69 17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
Chris@69 18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
Chris@69 19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
Chris@69 20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
Chris@69 21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
Chris@69 22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
Chris@69 23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
Chris@69 24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
Chris@69 25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Chris@69 26 */
Chris@69 27
Chris@69 28 #ifdef HAVE_CONFIG_H
Chris@69 29 #include "config.h"
Chris@69 30 #endif
Chris@69 31
Chris@69 32 #include "celt_lpc.h"
Chris@69 33 #include "stack_alloc.h"
Chris@69 34 #include "mathops.h"
Chris@69 35 #include "pitch.h"
Chris@69 36
Chris@69 37 void _celt_lpc(
Chris@69 38 opus_val16 *_lpc, /* out: [0...p-1] LPC coefficients */
Chris@69 39 const opus_val32 *ac, /* in: [0...p] autocorrelation values */
Chris@69 40 int p
Chris@69 41 )
Chris@69 42 {
Chris@69 43 int i, j;
Chris@69 44 opus_val32 r;
Chris@69 45 opus_val32 error = ac[0];
Chris@69 46 #ifdef FIXED_POINT
Chris@69 47 opus_val32 lpc[LPC_ORDER];
Chris@69 48 #else
Chris@69 49 float *lpc = _lpc;
Chris@69 50 #endif
Chris@69 51
Chris@69 52 OPUS_CLEAR(lpc, p);
Chris@69 53 if (ac[0] != 0)
Chris@69 54 {
Chris@69 55 for (i = 0; i < p; i++) {
Chris@69 56 /* Sum up this iteration's reflection coefficient */
Chris@69 57 opus_val32 rr = 0;
Chris@69 58 for (j = 0; j < i; j++)
Chris@69 59 rr += MULT32_32_Q31(lpc[j],ac[i - j]);
Chris@69 60 rr += SHR32(ac[i + 1],3);
Chris@69 61 r = -frac_div32(SHL32(rr,3), error);
Chris@69 62 /* Update LPC coefficients and total error */
Chris@69 63 lpc[i] = SHR32(r,3);
Chris@69 64 for (j = 0; j < (i+1)>>1; j++)
Chris@69 65 {
Chris@69 66 opus_val32 tmp1, tmp2;
Chris@69 67 tmp1 = lpc[j];
Chris@69 68 tmp2 = lpc[i-1-j];
Chris@69 69 lpc[j] = tmp1 + MULT32_32_Q31(r,tmp2);
Chris@69 70 lpc[i-1-j] = tmp2 + MULT32_32_Q31(r,tmp1);
Chris@69 71 }
Chris@69 72
Chris@69 73 error = error - MULT32_32_Q31(MULT32_32_Q31(r,r),error);
Chris@69 74 /* Bail out once we get 30 dB gain */
Chris@69 75 #ifdef FIXED_POINT
Chris@69 76 if (error<SHR32(ac[0],10))
Chris@69 77 break;
Chris@69 78 #else
Chris@69 79 if (error<.001f*ac[0])
Chris@69 80 break;
Chris@69 81 #endif
Chris@69 82 }
Chris@69 83 }
Chris@69 84 #ifdef FIXED_POINT
Chris@69 85 for (i=0;i<p;i++)
Chris@69 86 _lpc[i] = ROUND16(lpc[i],16);
Chris@69 87 #endif
Chris@69 88 }
Chris@69 89
Chris@69 90
Chris@69 91 void celt_fir_c(
Chris@69 92 const opus_val16 *x,
Chris@69 93 const opus_val16 *num,
Chris@69 94 opus_val16 *y,
Chris@69 95 int N,
Chris@69 96 int ord,
Chris@69 97 int arch)
Chris@69 98 {
Chris@69 99 int i,j;
Chris@69 100 VARDECL(opus_val16, rnum);
Chris@69 101 SAVE_STACK;
Chris@69 102 celt_assert(x != y);
Chris@69 103 ALLOC(rnum, ord, opus_val16);
Chris@69 104 for(i=0;i<ord;i++)
Chris@69 105 rnum[i] = num[ord-i-1];
Chris@69 106 for (i=0;i<N-3;i+=4)
Chris@69 107 {
Chris@69 108 opus_val32 sum[4];
Chris@69 109 sum[0] = SHL32(EXTEND32(x[i ]), SIG_SHIFT);
Chris@69 110 sum[1] = SHL32(EXTEND32(x[i+1]), SIG_SHIFT);
Chris@69 111 sum[2] = SHL32(EXTEND32(x[i+2]), SIG_SHIFT);
Chris@69 112 sum[3] = SHL32(EXTEND32(x[i+3]), SIG_SHIFT);
Chris@69 113 xcorr_kernel(rnum, x+i-ord, sum, ord, arch);
Chris@69 114 y[i ] = ROUND16(sum[0], SIG_SHIFT);
Chris@69 115 y[i+1] = ROUND16(sum[1], SIG_SHIFT);
Chris@69 116 y[i+2] = ROUND16(sum[2], SIG_SHIFT);
Chris@69 117 y[i+3] = ROUND16(sum[3], SIG_SHIFT);
Chris@69 118 }
Chris@69 119 for (;i<N;i++)
Chris@69 120 {
Chris@69 121 opus_val32 sum = SHL32(EXTEND32(x[i]), SIG_SHIFT);
Chris@69 122 for (j=0;j<ord;j++)
Chris@69 123 sum = MAC16_16(sum,rnum[j],x[i+j-ord]);
Chris@69 124 y[i] = ROUND16(sum, SIG_SHIFT);
Chris@69 125 }
Chris@69 126 RESTORE_STACK;
Chris@69 127 }
Chris@69 128
Chris@69 129 void celt_iir(const opus_val32 *_x,
Chris@69 130 const opus_val16 *den,
Chris@69 131 opus_val32 *_y,
Chris@69 132 int N,
Chris@69 133 int ord,
Chris@69 134 opus_val16 *mem,
Chris@69 135 int arch)
Chris@69 136 {
Chris@69 137 #ifdef SMALL_FOOTPRINT
Chris@69 138 int i,j;
Chris@69 139 (void)arch;
Chris@69 140 for (i=0;i<N;i++)
Chris@69 141 {
Chris@69 142 opus_val32 sum = _x[i];
Chris@69 143 for (j=0;j<ord;j++)
Chris@69 144 {
Chris@69 145 sum -= MULT16_16(den[j],mem[j]);
Chris@69 146 }
Chris@69 147 for (j=ord-1;j>=1;j--)
Chris@69 148 {
Chris@69 149 mem[j]=mem[j-1];
Chris@69 150 }
Chris@69 151 mem[0] = SROUND16(sum, SIG_SHIFT);
Chris@69 152 _y[i] = sum;
Chris@69 153 }
Chris@69 154 #else
Chris@69 155 int i,j;
Chris@69 156 VARDECL(opus_val16, rden);
Chris@69 157 VARDECL(opus_val16, y);
Chris@69 158 SAVE_STACK;
Chris@69 159
Chris@69 160 celt_assert((ord&3)==0);
Chris@69 161 ALLOC(rden, ord, opus_val16);
Chris@69 162 ALLOC(y, N+ord, opus_val16);
Chris@69 163 for(i=0;i<ord;i++)
Chris@69 164 rden[i] = den[ord-i-1];
Chris@69 165 for(i=0;i<ord;i++)
Chris@69 166 y[i] = -mem[ord-i-1];
Chris@69 167 for(;i<N+ord;i++)
Chris@69 168 y[i]=0;
Chris@69 169 for (i=0;i<N-3;i+=4)
Chris@69 170 {
Chris@69 171 /* Unroll by 4 as if it were an FIR filter */
Chris@69 172 opus_val32 sum[4];
Chris@69 173 sum[0]=_x[i];
Chris@69 174 sum[1]=_x[i+1];
Chris@69 175 sum[2]=_x[i+2];
Chris@69 176 sum[3]=_x[i+3];
Chris@69 177 xcorr_kernel(rden, y+i, sum, ord, arch);
Chris@69 178
Chris@69 179 /* Patch up the result to compensate for the fact that this is an IIR */
Chris@69 180 y[i+ord ] = -SROUND16(sum[0],SIG_SHIFT);
Chris@69 181 _y[i ] = sum[0];
Chris@69 182 sum[1] = MAC16_16(sum[1], y[i+ord ], den[0]);
Chris@69 183 y[i+ord+1] = -SROUND16(sum[1],SIG_SHIFT);
Chris@69 184 _y[i+1] = sum[1];
Chris@69 185 sum[2] = MAC16_16(sum[2], y[i+ord+1], den[0]);
Chris@69 186 sum[2] = MAC16_16(sum[2], y[i+ord ], den[1]);
Chris@69 187 y[i+ord+2] = -SROUND16(sum[2],SIG_SHIFT);
Chris@69 188 _y[i+2] = sum[2];
Chris@69 189
Chris@69 190 sum[3] = MAC16_16(sum[3], y[i+ord+2], den[0]);
Chris@69 191 sum[3] = MAC16_16(sum[3], y[i+ord+1], den[1]);
Chris@69 192 sum[3] = MAC16_16(sum[3], y[i+ord ], den[2]);
Chris@69 193 y[i+ord+3] = -SROUND16(sum[3],SIG_SHIFT);
Chris@69 194 _y[i+3] = sum[3];
Chris@69 195 }
Chris@69 196 for (;i<N;i++)
Chris@69 197 {
Chris@69 198 opus_val32 sum = _x[i];
Chris@69 199 for (j=0;j<ord;j++)
Chris@69 200 sum -= MULT16_16(rden[j],y[i+j]);
Chris@69 201 y[i+ord] = SROUND16(sum,SIG_SHIFT);
Chris@69 202 _y[i] = sum;
Chris@69 203 }
Chris@69 204 for(i=0;i<ord;i++)
Chris@69 205 mem[i] = _y[N-i-1];
Chris@69 206 RESTORE_STACK;
Chris@69 207 #endif
Chris@69 208 }
Chris@69 209
Chris@69 210 int _celt_autocorr(
Chris@69 211 const opus_val16 *x, /* in: [0...n-1] samples x */
Chris@69 212 opus_val32 *ac, /* out: [0...lag-1] ac values */
Chris@69 213 const opus_val16 *window,
Chris@69 214 int overlap,
Chris@69 215 int lag,
Chris@69 216 int n,
Chris@69 217 int arch
Chris@69 218 )
Chris@69 219 {
Chris@69 220 opus_val32 d;
Chris@69 221 int i, k;
Chris@69 222 int fastN=n-lag;
Chris@69 223 int shift;
Chris@69 224 const opus_val16 *xptr;
Chris@69 225 VARDECL(opus_val16, xx);
Chris@69 226 SAVE_STACK;
Chris@69 227 ALLOC(xx, n, opus_val16);
Chris@69 228 celt_assert(n>0);
Chris@69 229 celt_assert(overlap>=0);
Chris@69 230 if (overlap == 0)
Chris@69 231 {
Chris@69 232 xptr = x;
Chris@69 233 } else {
Chris@69 234 for (i=0;i<n;i++)
Chris@69 235 xx[i] = x[i];
Chris@69 236 for (i=0;i<overlap;i++)
Chris@69 237 {
Chris@69 238 xx[i] = MULT16_16_Q15(x[i],window[i]);
Chris@69 239 xx[n-i-1] = MULT16_16_Q15(x[n-i-1],window[i]);
Chris@69 240 }
Chris@69 241 xptr = xx;
Chris@69 242 }
Chris@69 243 shift=0;
Chris@69 244 #ifdef FIXED_POINT
Chris@69 245 {
Chris@69 246 opus_val32 ac0;
Chris@69 247 ac0 = 1+(n<<7);
Chris@69 248 if (n&1) ac0 += SHR32(MULT16_16(xptr[0],xptr[0]),9);
Chris@69 249 for(i=(n&1);i<n;i+=2)
Chris@69 250 {
Chris@69 251 ac0 += SHR32(MULT16_16(xptr[i],xptr[i]),9);
Chris@69 252 ac0 += SHR32(MULT16_16(xptr[i+1],xptr[i+1]),9);
Chris@69 253 }
Chris@69 254
Chris@69 255 shift = celt_ilog2(ac0)-30+10;
Chris@69 256 shift = (shift)/2;
Chris@69 257 if (shift>0)
Chris@69 258 {
Chris@69 259 for(i=0;i<n;i++)
Chris@69 260 xx[i] = PSHR32(xptr[i], shift);
Chris@69 261 xptr = xx;
Chris@69 262 } else
Chris@69 263 shift = 0;
Chris@69 264 }
Chris@69 265 #endif
Chris@69 266 celt_pitch_xcorr(xptr, xptr, ac, fastN, lag+1, arch);
Chris@69 267 for (k=0;k<=lag;k++)
Chris@69 268 {
Chris@69 269 for (i = k+fastN, d = 0; i < n; i++)
Chris@69 270 d = MAC16_16(d, xptr[i], xptr[i-k]);
Chris@69 271 ac[k] += d;
Chris@69 272 }
Chris@69 273 #ifdef FIXED_POINT
Chris@69 274 shift = 2*shift;
Chris@69 275 if (shift<=0)
Chris@69 276 ac[0] += SHL32((opus_int32)1, -shift);
Chris@69 277 if (ac[0] < 268435456)
Chris@69 278 {
Chris@69 279 int shift2 = 29 - EC_ILOG(ac[0]);
Chris@69 280 for (i=0;i<=lag;i++)
Chris@69 281 ac[i] = SHL32(ac[i], shift2);
Chris@69 282 shift -= shift2;
Chris@69 283 } else if (ac[0] >= 536870912)
Chris@69 284 {
Chris@69 285 int shift2=1;
Chris@69 286 if (ac[0] >= 1073741824)
Chris@69 287 shift2++;
Chris@69 288 for (i=0;i<=lag;i++)
Chris@69 289 ac[i] = SHR32(ac[i], shift2);
Chris@69 290 shift += shift2;
Chris@69 291 }
Chris@69 292 #endif
Chris@69 293
Chris@69 294 RESTORE_STACK;
Chris@69 295 return shift;
Chris@69 296 }