annotate src/opus-1.3/celt/celt_lpc.c @ 169:223a55898ab9 tip default

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