blob: fa5cebdbac883d948813b223e6a1c4a1b15dcacc [file] [log] [blame]
Jean-Marc Valin41af4212007-11-30 18:35:37 +11001/* (C) 2007 Jean-Marc Valin, CSIRO
2*/
3/*
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 - Neither the name of the Xiph.org Foundation nor the names of its
16 contributors may be used to endorse or promote products derived from
17 this software without specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
23 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30*/
31
32#include <math.h>
33#include <stdlib.h>
Jean-Marc Valin29ccab82007-12-06 15:39:38 +110034#include "cwrs.h"
Jean-Marc Valin9cace642007-12-06 17:44:09 +110035#include "vq.h"
Jean-Marc Valin41af4212007-11-30 18:35:37 +110036
Jean-Marc Valin883bd8e2008-02-15 00:34:01 +110037/* Enable this or define your own implementation if you want to speed up the
38 VQ search (used in inner loop only) */
39#if 0
40#include <xmmintrin.h>
41static inline float approx_sqrt(float x)
42{
43 _mm_store_ss(&x, _mm_sqrt_ss(_mm_set_ss(x)));
44 return x;
45}
46static inline float approx_inv(float x)
47{
48 _mm_store_ss(&x, _mm_rcp_ss(_mm_set_ss(x)));
49 return x;
50}
51#else
52#define approx_sqrt(x) (sqrt(x))
53#define approx_inv(x) (1.f/(x))
54#endif
55
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +110056struct NBest {
57 float score;
58 float gain;
59 int sign;
60 int pos;
61 int orig;
62 float xy;
63 float yy;
64 float yp;
65};
Jean-Marc Valin41af4212007-11-30 18:35:37 +110066
67/* Improved algebraic pulse-base quantiser. The signal x is replaced by the sum of the pitch
68 a combination of pulses such that its norm is still equal to 1. The only difference with
69 the quantiser above is that the search is more complete. */
Jean-Marc Valin46014ca2007-12-14 13:47:04 +110070void alg_quant(float *x, float *W, int N, int K, float *p, float alpha, ec_enc *enc)
Jean-Marc Valin41af4212007-11-30 18:35:37 +110071{
Jean-Marc Valin4a897682007-12-12 00:45:15 +110072 int L = 3;
Jean-Marc Valin41af4212007-11-30 18:35:37 +110073 //float tata[200];
Jean-Marc Valinfe419832008-02-12 15:05:01 +110074 float _y[L][N];
75 int _iy[L][N];
Jean-Marc Valin41af4212007-11-30 18:35:37 +110076 //float tata2[200];
Jean-Marc Valinfe419832008-02-12 15:05:01 +110077 float _ny[L][N];
78 int _iny[L][N];
79 float *(ny[L]), *(y[L]);
80 int *(iny[L]), *(iy[L]);
Jean-Marc Valin0d587d82008-02-14 21:29:50 +110081 int i, j, k, m;
Jean-Marc Valin846d4e22008-02-12 13:48:48 +110082 int pulsesLeft;
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +110083 float xy[L];
84 float yy[L];
85 float yp[L];
86 struct NBest _nbest[L];
87 struct NBest *(nbest[L]);
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +110088 float Rpp=0, Rxp=0;
Jean-Marc Valin41af4212007-11-30 18:35:37 +110089 int maxL = 1;
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +110090
Jean-Marc Valinfe419832008-02-12 15:05:01 +110091 for (m=0;m<L;m++)
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +110092 nbest[m] = &_nbest[m];
93
94 for (m=0;m<L;m++)
Jean-Marc Valinfe419832008-02-12 15:05:01 +110095 {
96 ny[m] = _ny[m];
97 iny[m] = _iny[m];
98 y[m] = _y[m];
99 iy[m] = _iy[m];
100 }
101
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100102 for (j=0;j<N;j++)
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100103 {
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100104 Rpp += p[j]*p[j];
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100105 Rxp += x[j]*p[j];
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100106 }
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100107
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100108 /* We only need to initialise the zero because the first iteration only uses that */
109 for (i=0;i<N;i++)
110 y[0][i] = 0;
111 for (i=0;i<N;i++)
112 iy[0][i] = 0;
113 xy[0] = yy[0] = yp[0] = 0;
114
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100115 pulsesLeft = K;
116 while (pulsesLeft > 0)
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100117 {
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100118 int pulsesAtOnce=1;
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100119 int Lupdate = L;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100120 int L2 = L;
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100121
122 /* Decide on complexity strategy */
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100123 pulsesAtOnce = pulsesLeft/N;
124 if (pulsesAtOnce<1)
125 pulsesAtOnce = 1;
126 if (pulsesLeft-pulsesAtOnce > 3 || N > 30)
127 Lupdate = 1;
128 //printf ("%d %d %d/%d %d\n", Lupdate, pulsesAtOnce, pulsesLeft, K, N);
129 L2 = Lupdate;
130 if (L2>maxL)
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100131 {
132 L2 = maxL;
133 maxL *= N;
134 }
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100135
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100136 for (m=0;m<Lupdate;m++)
Jean-Marc Valin883bd8e2008-02-15 00:34:01 +1100137 nbest[m]->score = -1e10f;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100138
139 for (m=0;m<L2;m++)
140 {
141 for (j=0;j<N;j++)
142 {
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100143 int sign;
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100144 /*if (x[j]>0) sign=1; else sign=-1;*/
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100145 for (sign=-1;sign<=1;sign+=2)
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100146 {
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100147 /* All pulses at one location must have the same sign. */
148 if (iy[m][j]*sign < 0)
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100149 continue;
150 //fprintf (stderr, "%d/%d %d/%d %d/%d\n", i, K, m, L2, j, N);
151 float tmp_xy, tmp_yy, tmp_yp;
152 float score;
153 float g;
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100154 float s = sign*pulsesAtOnce;
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100155
Jean-Marc Valina073c7b2008-02-14 16:58:04 +1100156 /* Updating the sums of the new pulse(s) */
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100157 tmp_xy = xy[m] + s*x[j] - alpha*s*p[j]*Rxp;
Jean-Marc Valin883bd8e2008-02-15 00:34:01 +1100158 tmp_yy = yy[m] + 2.f*s*y[m][j] + s*s +s*s*alpha*alpha*p[j]*p[j]*Rpp - 2.f*alpha*s*p[j]*yp[m] - 2.f*s*s*alpha*p[j]*p[j];
159 tmp_yp = yp[m] + s*p[j] *(1.f-alpha*Rpp);
Jean-Marc Valina073c7b2008-02-14 16:58:04 +1100160
161 /* Compute the gain such that ||p + g*y|| = 1 */
Jean-Marc Valin883bd8e2008-02-15 00:34:01 +1100162 g = (approx_sqrt(tmp_yp*tmp_yp + tmp_yy - tmp_yy*Rpp) - tmp_yp)*approx_inv(tmp_yy);
Jean-Marc Valina073c7b2008-02-14 16:58:04 +1100163 /* Knowing that gain, what the error: (x-g*y)^2
164 (result is negated and we discard x^2 because it's constant) */
Jean-Marc Valin883bd8e2008-02-15 00:34:01 +1100165 score = 2.f*g*tmp_xy - g*g*tmp_yy;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100166
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100167 if (score>nbest[Lupdate-1]->score)
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100168 {
Jean-Marc Valin472a5f02008-02-19 13:12:32 +1100169 int k;
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100170 int id = Lupdate-1;
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100171 struct NBest *tmp_best;
172
173 /* Save some pointers that would be deleted and use them for the current entry*/
174 tmp_best = nbest[Lupdate-1];
175 while (id > 0 && score > nbest[id-1]->score)
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100176 id--;
177
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100178 for (k=Lupdate-1;k>id;k--)
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100179 nbest[k] = nbest[k-1];
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100180
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100181 nbest[id] = tmp_best;
182 nbest[id]->score = score;
183 nbest[id]->pos = j;
184 nbest[id]->orig = m;
185 nbest[id]->sign = sign;
186 nbest[id]->gain = g;
187 nbest[id]->xy = tmp_xy;
188 nbest[id]->yy = tmp_yy;
189 nbest[id]->yp = tmp_yp;
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100190 }
Jean-Marc Valin636f5c82008-02-12 17:40:27 +1100191 }
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100192 }
Jean-Marc Valin636f5c82008-02-12 17:40:27 +1100193
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100194 }
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100195 /* Only now that we've made the final choice, update ny/iny and others */
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100196 for (k=0;k<Lupdate;k++)
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100197 {
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100198 int n;
199 int is;
200 float s;
201 is = nbest[k]->sign*pulsesAtOnce;
202 s = is;
203 for (n=0;n<N;n++)
204 ny[k][n] = y[nbest[k]->orig][n] - alpha*s*p[nbest[k]->pos]*p[n];
205 ny[k][nbest[k]->pos] += s;
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100206
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100207 for (n=0;n<N;n++)
208 iny[k][n] = iy[nbest[k]->orig][n];
209 iny[k][nbest[k]->pos] += is;
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100210
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100211 xy[k] = nbest[k]->xy;
212 yy[k] = nbest[k]->yy;
213 yp[k] = nbest[k]->yp;
214 }
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100215 /* Swap ny/iny with y/iy */
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100216 for (k=0;k<Lupdate;k++)
217 {
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100218 float *tmp_ny;
219 int *tmp_iny;
220
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100221 tmp_ny = ny[k];
222 ny[k] = y[k];
223 y[k] = tmp_ny;
224 tmp_iny = iny[k];
225 iny[k] = iy[k];
226 iy[k] = tmp_iny;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100227 }
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100228 pulsesLeft -= pulsesAtOnce;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100229 }
230
Jean-Marc Valinac1e03d2008-02-12 23:00:18 +1100231 if (0) {
232 float err=0;
233 for (i=0;i<N;i++)
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100234 err += (x[i]-nbest[0]->gain*y[0][i])*(x[i]-nbest[0]->gain*y[0][i]);
Jean-Marc Valinac1e03d2008-02-12 23:00:18 +1100235 //if (N<=10)
236 //printf ("%f %d %d\n", err, K, N);
237 }
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100238 for (i=0;i<N;i++)
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100239 x[i] = p[i]+nbest[0]->gain*y[0][i];
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100240 /* Sanity checks, don't bother */
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100241 if (0) {
242 float E=1e-15;
243 int ABS = 0;
244 for (i=0;i<N;i++)
245 ABS += abs(iy[0][i]);
246 //if (K != ABS)
247 // printf ("%d %d\n", K, ABS);
248 for (i=0;i<N;i++)
249 E += x[i]*x[i];
250 //printf ("%f\n", E);
251 E = 1/sqrt(E);
252 for (i=0;i<N;i++)
253 x[i] *= E;
254 }
Jean-Marc Valin5fa59952008-02-14 13:50:44 +1100255
256 encode_pulses(iy[0], N, K, enc);
257
Jean-Marc Valina4833ff2008-01-10 15:34:00 +1100258 /* Recompute the gain in one pass to reduce the encoder-decoder mismatch
Jean-Marc Valin636f5c82008-02-12 17:40:27 +1100259 due to the recursive computation used in quantisation.
260 Not quite sure whether we need that or not */
Jean-Marc Valina4833ff2008-01-10 15:34:00 +1100261 if (1) {
Jean-Marc Valin4a897682007-12-12 00:45:15 +1100262 float Ryp=0;
Jean-Marc Valin4a897682007-12-12 00:45:15 +1100263 float Ryy=0;
264 float g=0;
Jean-Marc Valin4a897682007-12-12 00:45:15 +1100265
266 for (i=0;i<N;i++)
267 Ryp += iy[0][i]*p[i];
268
269 for (i=0;i<N;i++)
270 y[0][i] = iy[0][i] - alpha*Ryp*p[i];
271
Jean-Marc Valin4a897682007-12-12 00:45:15 +1100272 Ryp = 0;
273 for (i=0;i<N;i++)
274 Ryp += y[0][i]*p[i];
275
276 for (i=0;i<N;i++)
277 Ryy += y[0][i]*y[0][i];
278
279 g = (sqrt(Ryp*Ryp + Ryy - Ryy*Rpp) - Ryp)/Ryy;
280
281 for (i=0;i<N;i++)
282 x[i] = p[i] + g*y[0][i];
283
284 }
285
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100286}
287
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100288void alg_unquant(float *x, int N, int K, float *p, float alpha, ec_dec *dec)
289{
290 int i;
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100291 int iy[N];
292 float y[N];
293 float Rpp=0, Ryp=0, Ryy=0;
294 float g;
Jean-Marc Valin25298f22007-12-03 15:24:11 +1100295
Jean-Marc Valin5fa59952008-02-14 13:50:44 +1100296 decode_pulses(iy, N, K, dec);
297
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100298 //for (i=0;i<N;i++)
299 // printf ("%d ", iy[i]);
300 for (i=0;i<N;i++)
301 Rpp += p[i]*p[i];
302
303 for (i=0;i<N;i++)
304 Ryp += iy[i]*p[i];
305
306 for (i=0;i<N;i++)
307 y[i] = iy[i] - alpha*Ryp*p[i];
308
309 /* Recompute after the projection (I think it's right) */
310 Ryp = 0;
311 for (i=0;i<N;i++)
312 Ryp += y[i]*p[i];
313
314 for (i=0;i<N;i++)
315 Ryy += y[i]*y[i];
316
317 g = (sqrt(Ryp*Ryp + Ryy - Ryy*Rpp) - Ryp)/Ryy;
318
319 for (i=0;i<N;i++)
320 x[i] = p[i] + g*y[i];
321}
322
323
324static const float pg[11] = {1.f, .75f, .65f, 0.6f, 0.6f, .6f, .55f, .55f, .5f, .5f, .5f};
325
326void intra_prediction(float *x, float *W, int N, int K, float *Y, float *P, int B, int N0, ec_enc *enc)
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100327{
328 int i,j;
329 int best=0;
Jean-Marc Valin50d11162007-12-03 14:34:52 +1100330 float best_score=0;
331 float s = 1;
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100332 int sign;
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100333 float E;
Jean-Marc Valin8f0f4b92008-02-11 13:52:44 +1100334 int max_pos = N0-N/B;
335 if (max_pos > 32)
336 max_pos = 32;
337
338 for (i=0;i<max_pos*B;i+=B)
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100339 {
340 int j;
341 float xy=0, yy=0;
342 float score;
343 for (j=0;j<N;j++)
344 {
345 xy += x[j]*Y[i+j];
346 yy += Y[i+j]*Y[i+j];
347 }
Jean-Marc Valin50d11162007-12-03 14:34:52 +1100348 score = xy*xy/(.001+yy);
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100349 if (score > best_score)
350 {
351 best_score = score;
352 best = i;
Jean-Marc Valin50d11162007-12-03 14:34:52 +1100353 if (xy>0)
354 s = 1;
355 else
356 s = -1;
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100357 }
358 }
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100359 if (s<0)
360 sign = 1;
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100361 else
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100362 sign = 0;
363 //printf ("%d %d ", sign, best);
364 ec_enc_uint(enc,sign,2);
Jean-Marc Valin8f0f4b92008-02-11 13:52:44 +1100365 ec_enc_uint(enc,best/B,max_pos);
Jean-Marc Valin50d11162007-12-03 14:34:52 +1100366 //printf ("%d %f\n", best, best_score);
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100367
368 float pred_gain;
369 if (K>10)
370 pred_gain = pg[10];
371 else
372 pred_gain = pg[K];
373 E = 1e-10;
374 for (j=0;j<N;j++)
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100375 {
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100376 P[j] = s*Y[best+j];
377 E += P[j]*P[j];
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100378 }
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100379 E = pred_gain/sqrt(E);
380 for (j=0;j<N;j++)
381 P[j] *= E;
382 if (K>0)
383 {
384 for (j=0;j<N;j++)
385 x[j] -= P[j];
386 } else {
387 for (j=0;j<N;j++)
388 x[j] = P[j];
389 }
390 //printf ("quant ");
391 //for (j=0;j<N;j++) printf ("%f ", P[j]);
392
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100393}
Jean-Marc Valinfc08d0a2007-12-07 13:26:15 +1100394
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100395void intra_unquant(float *x, int N, int K, float *Y, float *P, int B, int N0, ec_dec *dec)
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100396{
Jean-Marc Valin11f01722007-12-09 01:19:36 +1100397 int j;
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100398 int sign;
399 float s;
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100400 int best;
401 float E;
Jean-Marc Valin8f0f4b92008-02-11 13:52:44 +1100402 int max_pos = N0-N/B;
403 if (max_pos > 32)
404 max_pos = 32;
405
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100406 sign = ec_dec_uint(dec, 2);
407 if (sign == 0)
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100408 s = 1;
409 else
410 s = -1;
411
Jean-Marc Valin8f0f4b92008-02-11 13:52:44 +1100412 best = B*ec_dec_uint(dec, max_pos);
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100413 //printf ("%d %d ", sign, best);
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100414
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100415 float pred_gain;
416 if (K>10)
417 pred_gain = pg[10];
418 else
419 pred_gain = pg[K];
420 E = 1e-10;
421 for (j=0;j<N;j++)
422 {
423 P[j] = s*Y[best+j];
424 E += P[j]*P[j];
425 }
426 E = pred_gain/sqrt(E);
427 for (j=0;j<N;j++)
428 P[j] *= E;
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100429 if (K==0)
430 {
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100431 for (j=0;j<N;j++)
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100432 x[j] = P[j];
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100433 }
434}
Jean-Marc Valin0e20ca02008-02-11 15:33:53 +1100435
Jean-Marc Valin0df0eb42008-02-13 16:00:10 +1100436void intra_fold(float *x, int N, float *Y, float *P, int B, int N0, int Nmax)
Jean-Marc Valin0e20ca02008-02-11 15:33:53 +1100437{
Jean-Marc Valin0df0eb42008-02-13 16:00:10 +1100438 int i, j;
Jean-Marc Valin0e20ca02008-02-11 15:33:53 +1100439 float E;
440
441 E = 1e-10;
Jean-Marc Valin0df0eb42008-02-13 16:00:10 +1100442 if (N0 >= Nmax/2)
Jean-Marc Valin0e20ca02008-02-11 15:33:53 +1100443 {
Jean-Marc Valin0df0eb42008-02-13 16:00:10 +1100444 for (i=0;i<B;i++)
445 {
446 for (j=0;j<N/B;j++)
447 {
448 P[j*B+i] = Y[(Nmax-N0-j-1)*B+i];
449 E += P[j*B+i]*P[j*B+i];
450 }
451 }
452 } else {
453 for (j=0;j<N;j++)
454 {
455 P[j] = Y[j];
456 E += P[j]*P[j];
457 }
Jean-Marc Valin0e20ca02008-02-11 15:33:53 +1100458 }
459 E = 1.f/sqrt(E);
460 for (j=0;j<N;j++)
461 P[j] *= E;
462 for (j=0;j<N;j++)
463 x[j] = P[j];
464}
465