summaryrefslogtreecommitdiff
path: root/lib/rbcodec/codecs/libopus/celt/celt_lpc.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rbcodec/codecs/libopus/celt/celt_lpc.c')
-rw-r--r--lib/rbcodec/codecs/libopus/celt/celt_lpc.c196
1 files changed, 158 insertions, 38 deletions
diff --git a/lib/rbcodec/codecs/libopus/celt/celt_lpc.c b/lib/rbcodec/codecs/libopus/celt/celt_lpc.c
index 66aed1de09..7ffe90a357 100644
--- a/lib/rbcodec/codecs/libopus/celt/celt_lpc.c
+++ b/lib/rbcodec/codecs/libopus/celt/celt_lpc.c
@@ -26,12 +26,13 @@
26*/ 26*/
27 27
28#ifdef HAVE_CONFIG_H 28#ifdef HAVE_CONFIG_H
29#include "opus_config.h" 29#include "config.h"
30#endif 30#endif
31 31
32#include "celt_lpc.h" 32#include "celt_lpc.h"
33#include "stack_alloc.h" 33#include "stack_alloc.h"
34#include "mathops.h" 34#include "mathops.h"
35#include "pitch.h"
35 36
36void _celt_lpc( 37void _celt_lpc(
37 opus_val16 *_lpc, /* out: [0...p-1] LPC coefficients */ 38 opus_val16 *_lpc, /* out: [0...p-1] LPC coefficients */
@@ -87,42 +88,71 @@ int p
87#endif 88#endif
88} 89}
89 90
90void celt_fir(const opus_val16 *x, 91void celt_fir(const opus_val16 *_x,
91 const opus_val16 *num, 92 const opus_val16 *num,
92 opus_val16 *y, 93 opus_val16 *_y,
93 int N, 94 int N,
94 int ord, 95 int ord,
95 opus_val16 *mem) 96 opus_val16 *mem)
96{ 97{
97 int i,j; 98 int i,j;
99 VARDECL(opus_val16, rnum);
100 VARDECL(opus_val16, x);
101 SAVE_STACK;
98 102
103 ALLOC(rnum, ord, opus_val16);
104 ALLOC(x, N+ord, opus_val16);
105 for(i=0;i<ord;i++)
106 rnum[i] = num[ord-i-1];
107 for(i=0;i<ord;i++)
108 x[i] = mem[ord-i-1];
109 for (i=0;i<N;i++)
110 x[i+ord]=_x[i];
111 for(i=0;i<ord;i++)
112 mem[i] = _x[N-i-1];
113#ifdef SMALL_FOOTPRINT
99 for (i=0;i<N;i++) 114 for (i=0;i<N;i++)
100 { 115 {
101 opus_val32 sum = SHL32(EXTEND32(x[i]), SIG_SHIFT); 116 opus_val32 sum = SHL32(EXTEND32(_x[i]), SIG_SHIFT);
102 for (j=0;j<ord;j++) 117 for (j=0;j<ord;j++)
103 { 118 {
104 sum += MULT16_16(num[j],mem[j]); 119 sum = MAC16_16(sum,rnum[j],x[i+j]);
105 }
106 for (j=ord-1;j>=1;j--)
107 {
108 mem[j]=mem[j-1];
109 } 120 }
110 mem[0] = x[i]; 121 _y[i] = SATURATE16(PSHR32(sum, SIG_SHIFT));
111 y[i] = ROUND16(sum, SIG_SHIFT);
112 } 122 }
123#else
124 for (i=0;i<N-3;i+=4)
125 {
126 opus_val32 sum[4]={0,0,0,0};
127 xcorr_kernel(rnum, x+i, sum, ord);
128 _y[i ] = SATURATE16(ADD32(EXTEND32(_x[i ]), PSHR32(sum[0], SIG_SHIFT)));
129 _y[i+1] = SATURATE16(ADD32(EXTEND32(_x[i+1]), PSHR32(sum[1], SIG_SHIFT)));
130 _y[i+2] = SATURATE16(ADD32(EXTEND32(_x[i+2]), PSHR32(sum[2], SIG_SHIFT)));
131 _y[i+3] = SATURATE16(ADD32(EXTEND32(_x[i+3]), PSHR32(sum[3], SIG_SHIFT)));
132 }
133 for (;i<N;i++)
134 {
135 opus_val32 sum = 0;
136 for (j=0;j<ord;j++)
137 sum = MAC16_16(sum,rnum[j],x[i+j]);
138 _y[i] = SATURATE16(ADD32(EXTEND32(_x[i]), PSHR32(sum, SIG_SHIFT)));
139 }
140#endif
141 RESTORE_STACK;
113} 142}
114 143
115void celt_iir(const opus_val32 *x, 144void celt_iir(const opus_val32 *_x,
116 const opus_val16 *den, 145 const opus_val16 *den,
117 opus_val32 *y, 146 opus_val32 *_y,
118 int N, 147 int N,
119 int ord, 148 int ord,
120 opus_val16 *mem) 149 opus_val16 *mem)
121{ 150{
151#ifdef SMALL_FOOTPRINT
122 int i,j; 152 int i,j;
123 for (i=0;i<N;i++) 153 for (i=0;i<N;i++)
124 { 154 {
125 opus_val32 sum = x[i]; 155 opus_val32 sum = _x[i];
126 for (j=0;j<ord;j++) 156 for (j=0;j<ord;j++)
127 { 157 {
128 sum -= MULT16_16(den[j],mem[j]); 158 sum -= MULT16_16(den[j],mem[j]);
@@ -132,11 +162,65 @@ void celt_iir(const opus_val32 *x,
132 mem[j]=mem[j-1]; 162 mem[j]=mem[j-1];
133 } 163 }
134 mem[0] = ROUND16(sum,SIG_SHIFT); 164 mem[0] = ROUND16(sum,SIG_SHIFT);
135 y[i] = sum; 165 _y[i] = sum;
136 } 166 }
167#else
168 int i,j;
169 VARDECL(opus_val16, rden);
170 VARDECL(opus_val16, y);
171 SAVE_STACK;
172
173 celt_assert((ord&3)==0);
174 ALLOC(rden, ord, opus_val16);
175 ALLOC(y, N+ord, opus_val16);
176 for(i=0;i<ord;i++)
177 rden[i] = den[ord-i-1];
178 for(i=0;i<ord;i++)
179 y[i] = -mem[ord-i-1];
180 for(;i<N+ord;i++)
181 y[i]=0;
182 for (i=0;i<N-3;i+=4)
183 {
184 /* Unroll by 4 as if it were an FIR filter */
185 opus_val32 sum[4];
186 sum[0]=_x[i];
187 sum[1]=_x[i+1];
188 sum[2]=_x[i+2];
189 sum[3]=_x[i+3];
190 xcorr_kernel(rden, y+i, sum, ord);
191
192 /* Patch up the result to compensate for the fact that this is an IIR */
193 y[i+ord ] = -ROUND16(sum[0],SIG_SHIFT);
194 _y[i ] = sum[0];
195 sum[1] = MAC16_16(sum[1], y[i+ord ], den[0]);
196 y[i+ord+1] = -ROUND16(sum[1],SIG_SHIFT);
197 _y[i+1] = sum[1];
198 sum[2] = MAC16_16(sum[2], y[i+ord+1], den[0]);
199 sum[2] = MAC16_16(sum[2], y[i+ord ], den[1]);
200 y[i+ord+2] = -ROUND16(sum[2],SIG_SHIFT);
201 _y[i+2] = sum[2];
202
203 sum[3] = MAC16_16(sum[3], y[i+ord+2], den[0]);
204 sum[3] = MAC16_16(sum[3], y[i+ord+1], den[1]);
205 sum[3] = MAC16_16(sum[3], y[i+ord ], den[2]);
206 y[i+ord+3] = -ROUND16(sum[3],SIG_SHIFT);
207 _y[i+3] = sum[3];
208 }
209 for (;i<N;i++)
210 {
211 opus_val32 sum = _x[i];
212 for (j=0;j<ord;j++)
213 sum -= MULT16_16(rden[j],y[i+j]);
214 y[i+ord] = ROUND16(sum,SIG_SHIFT);
215 _y[i] = sum;
216 }
217 for(i=0;i<ord;i++)
218 mem[i] = _y[N-i-1];
219 RESTORE_STACK;
220#endif
137} 221}
138 222
139void _celt_autocorr( 223int _celt_autocorr(
140 const opus_val16 *x, /* in: [0...n-1] samples x */ 224 const opus_val16 *x, /* in: [0...n-1] samples x */
141 opus_val32 *ac, /* out: [0...lag-1] ac values */ 225 opus_val32 *ac, /* out: [0...lag-1] ac values */
142 const opus_val16 *window, 226 const opus_val16 *window,
@@ -146,43 +230,79 @@ void _celt_autocorr(
146 ) 230 )
147{ 231{
148 opus_val32 d; 232 opus_val32 d;
149 int i; 233 int i, k;
234 int fastN=n-lag;
235 int shift;
236 const opus_val16 *xptr;
150 VARDECL(opus_val16, xx); 237 VARDECL(opus_val16, xx);
151 SAVE_STACK; 238 SAVE_STACK;
152 ALLOC(xx, n, opus_val16); 239 ALLOC(xx, n, opus_val16);
153 celt_assert(n>0); 240 celt_assert(n>0);
154 celt_assert(overlap>=0); 241 celt_assert(overlap>=0);
155 for (i=0;i<n;i++) 242 if (overlap == 0)
156 xx[i] = x[i];
157 for (i=0;i<overlap;i++)
158 { 243 {
159 xx[i] = MULT16_16_Q15(x[i],window[i]); 244 xptr = x;
160 xx[n-i-1] = MULT16_16_Q15(x[n-i-1],window[i]); 245 } else {
246 for (i=0;i<n;i++)
247 xx[i] = x[i];
248 for (i=0;i<overlap;i++)
249 {
250 xx[i] = MULT16_16_Q15(x[i],window[i]);
251 xx[n-i-1] = MULT16_16_Q15(x[n-i-1],window[i]);
252 }
253 xptr = xx;
161 } 254 }
255 shift=0;
162#ifdef FIXED_POINT 256#ifdef FIXED_POINT
163 { 257 {
164 opus_val32 ac0=0; 258 opus_val32 ac0;
165 int shift; 259 ac0 = 1+(n<<7);
166 for(i=0;i<n;i++) 260 if (n&1) ac0 += SHR32(MULT16_16(xptr[0],xptr[0]),9);
167 ac0 += SHR32(MULT16_16(xx[i],xx[i]),9); 261 for(i=(n&1);i<n;i+=2)
168 ac0 += 1+n; 262 {
263 ac0 += SHR32(MULT16_16(xptr[i],xptr[i]),9);
264 ac0 += SHR32(MULT16_16(xptr[i+1],xptr[i+1]),9);
265 }
169 266
170 shift = celt_ilog2(ac0)-30+10; 267 shift = celt_ilog2(ac0)-30+10;
171 shift = (shift+1)/2; 268 shift = (shift)/2;
172 for(i=0;i<n;i++) 269 if (shift>0)
173 xx[i] = VSHR32(xx[i], shift); 270 {
271 for(i=0;i<n;i++)
272 xx[i] = PSHR32(xptr[i], shift);
273 xptr = xx;
274 } else
275 shift = 0;
174 } 276 }
175#endif 277#endif
176 while (lag>=0) 278 celt_pitch_xcorr(xptr, xptr, ac, fastN, lag+1);
279 for (k=0;k<=lag;k++)
177 { 280 {
178 for (i = lag, d = 0; i < n; i++) 281 for (i = k+fastN, d = 0; i < n; i++)
179 d += xx[i] * xx[i-lag]; 282 d = MAC16_16(d, xptr[i], xptr[i-k]);
180 ac[lag] = d; 283 ac[k] += d;
181 /*printf ("%f ", ac[lag]);*/
182 lag--;
183 } 284 }
184 /*printf ("\n");*/ 285#ifdef FIXED_POINT
185 ac[0] += 10; 286 shift = 2*shift;
287 if (shift<=0)
288 ac[0] += SHL32((opus_int32)1, -shift);
289 if (ac[0] < 268435456)
290 {
291 int shift2 = 29 - EC_ILOG(ac[0]);
292 for (i=0;i<=lag;i++)
293 ac[i] = SHL32(ac[i], shift2);
294 shift -= shift2;
295 } else if (ac[0] >= 536870912)
296 {
297 int shift2=1;
298 if (ac[0] >= 1073741824)
299 shift2++;
300 for (i=0;i<=lag;i++)
301 ac[i] = SHR32(ac[i], shift2);
302 shift += shift2;
303 }
304#endif
186 305
187 RESTORE_STACK; 306 RESTORE_STACK;
307 return shift;
188} 308}