blob: d463892786cdf4a88d70a5d1dccf0c358e9dd9f1 [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 Valinfe419832008-02-12 15:05:01 +110073 float _y[L][N];
74 int _iy[L][N];
Jean-Marc Valinfe419832008-02-12 15:05:01 +110075 float _ny[L][N];
76 int _iny[L][N];
77 float *(ny[L]), *(y[L]);
78 int *(iny[L]), *(iy[L]);
Jean-Marc Valin0d587d82008-02-14 21:29:50 +110079 int i, j, k, m;
Jean-Marc Valin846d4e22008-02-12 13:48:48 +110080 int pulsesLeft;
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +110081 float xy[L];
82 float yy[L];
83 float yp[L];
84 struct NBest _nbest[L];
85 struct NBest *(nbest[L]);
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +110086 float Rpp=0, Rxp=0;
Jean-Marc Valin41af4212007-11-30 18:35:37 +110087 int maxL = 1;
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +110088
Jean-Marc Valinfe419832008-02-12 15:05:01 +110089 for (m=0;m<L;m++)
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +110090 nbest[m] = &_nbest[m];
91
92 for (m=0;m<L;m++)
Jean-Marc Valinfe419832008-02-12 15:05:01 +110093 {
94 ny[m] = _ny[m];
95 iny[m] = _iny[m];
96 y[m] = _y[m];
97 iy[m] = _iy[m];
98 }
99
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100100 for (j=0;j<N;j++)
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100101 {
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100102 Rpp += p[j]*p[j];
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100103 Rxp += x[j]*p[j];
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100104 }
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100105
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100106 /* We only need to initialise the zero because the first iteration only uses that */
107 for (i=0;i<N;i++)
108 y[0][i] = 0;
109 for (i=0;i<N;i++)
110 iy[0][i] = 0;
111 xy[0] = yy[0] = yp[0] = 0;
112
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100113 pulsesLeft = K;
114 while (pulsesLeft > 0)
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100115 {
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100116 int pulsesAtOnce=1;
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100117 int Lupdate = L;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100118 int L2 = L;
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100119
120 /* Decide on complexity strategy */
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100121 pulsesAtOnce = pulsesLeft/N;
122 if (pulsesAtOnce<1)
123 pulsesAtOnce = 1;
124 if (pulsesLeft-pulsesAtOnce > 3 || N > 30)
125 Lupdate = 1;
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100126 /*printf ("%d %d %d/%d %d\n", Lupdate, pulsesAtOnce, pulsesLeft, K, N);*/
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100127 L2 = Lupdate;
128 if (L2>maxL)
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100129 {
130 L2 = maxL;
131 maxL *= N;
132 }
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100133
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100134 for (m=0;m<Lupdate;m++)
Jean-Marc Valin883bd8e2008-02-15 00:34:01 +1100135 nbest[m]->score = -1e10f;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100136
137 for (m=0;m<L2;m++)
138 {
139 for (j=0;j<N;j++)
140 {
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100141 int sign;
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100142 /*if (x[j]>0) sign=1; else sign=-1;*/
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100143 for (sign=-1;sign<=1;sign+=2)
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100144 {
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100145 /* All pulses at one location must have the same sign. */
146 if (iy[m][j]*sign < 0)
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100147 continue;
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100148 /*fprintf (stderr, "%d/%d %d/%d %d/%d\n", i, K, m, L2, j, N);*/
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100149 float tmp_xy, tmp_yy, tmp_yp;
150 float score;
151 float g;
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100152 float s = sign*pulsesAtOnce;
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100153
Jean-Marc Valina073c7b2008-02-14 16:58:04 +1100154 /* Updating the sums of the new pulse(s) */
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100155 tmp_xy = xy[m] + s*x[j] - alpha*s*p[j]*Rxp;
Jean-Marc Valin883bd8e2008-02-15 00:34:01 +1100156 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];
157 tmp_yp = yp[m] + s*p[j] *(1.f-alpha*Rpp);
Jean-Marc Valina073c7b2008-02-14 16:58:04 +1100158
159 /* Compute the gain such that ||p + g*y|| = 1 */
Jean-Marc Valin883bd8e2008-02-15 00:34:01 +1100160 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 +1100161 /* Knowing that gain, what the error: (x-g*y)^2
162 (result is negated and we discard x^2 because it's constant) */
Jean-Marc Valin883bd8e2008-02-15 00:34:01 +1100163 score = 2.f*g*tmp_xy - g*g*tmp_yy;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100164
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100165 if (score>nbest[Lupdate-1]->score)
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100166 {
Jean-Marc Valin472a5f02008-02-19 13:12:32 +1100167 int k;
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100168 int id = Lupdate-1;
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100169 struct NBest *tmp_best;
170
171 /* Save some pointers that would be deleted and use them for the current entry*/
172 tmp_best = nbest[Lupdate-1];
173 while (id > 0 && score > nbest[id-1]->score)
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100174 id--;
175
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100176 for (k=Lupdate-1;k>id;k--)
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100177 nbest[k] = nbest[k-1];
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100178
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100179 nbest[id] = tmp_best;
180 nbest[id]->score = score;
181 nbest[id]->pos = j;
182 nbest[id]->orig = m;
183 nbest[id]->sign = sign;
184 nbest[id]->gain = g;
185 nbest[id]->xy = tmp_xy;
186 nbest[id]->yy = tmp_yy;
187 nbest[id]->yp = tmp_yp;
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100188 }
Jean-Marc Valin636f5c82008-02-12 17:40:27 +1100189 }
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100190 }
Jean-Marc Valin636f5c82008-02-12 17:40:27 +1100191
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100192 }
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100193 /* Only now that we've made the final choice, update ny/iny and others */
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100194 for (k=0;k<Lupdate;k++)
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100195 {
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100196 int n;
197 int is;
198 float s;
199 is = nbest[k]->sign*pulsesAtOnce;
200 s = is;
201 for (n=0;n<N;n++)
202 ny[k][n] = y[nbest[k]->orig][n] - alpha*s*p[nbest[k]->pos]*p[n];
203 ny[k][nbest[k]->pos] += s;
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100204
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100205 for (n=0;n<N;n++)
206 iny[k][n] = iy[nbest[k]->orig][n];
207 iny[k][nbest[k]->pos] += is;
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100208
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100209 xy[k] = nbest[k]->xy;
210 yy[k] = nbest[k]->yy;
211 yp[k] = nbest[k]->yp;
212 }
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100213 /* Swap ny/iny with y/iy */
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100214 for (k=0;k<Lupdate;k++)
215 {
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100216 float *tmp_ny;
217 int *tmp_iny;
218
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100219 tmp_ny = ny[k];
220 ny[k] = y[k];
221 y[k] = tmp_ny;
222 tmp_iny = iny[k];
223 iny[k] = iy[k];
224 iy[k] = tmp_iny;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100225 }
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100226 pulsesLeft -= pulsesAtOnce;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100227 }
228
Jean-Marc Valinac1e03d2008-02-12 23:00:18 +1100229 if (0) {
230 float err=0;
231 for (i=0;i<N;i++)
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100232 err += (x[i]-nbest[0]->gain*y[0][i])*(x[i]-nbest[0]->gain*y[0][i]);
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100233 /*if (N<=10)
234 printf ("%f %d %d\n", err, K, N);*/
Jean-Marc Valinac1e03d2008-02-12 23:00:18 +1100235 }
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100236 for (i=0;i<N;i++)
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100237 x[i] = p[i]+nbest[0]->gain*y[0][i];
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100238 /* Sanity checks, don't bother */
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100239 if (0) {
240 float E=1e-15;
241 int ABS = 0;
242 for (i=0;i<N;i++)
243 ABS += abs(iy[0][i]);
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100244 /*if (K != ABS)
245 printf ("%d %d\n", K, ABS);*/
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100246 for (i=0;i<N;i++)
247 E += x[i]*x[i];
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100248 /*printf ("%f\n", E);*/
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100249 E = 1/sqrt(E);
250 for (i=0;i<N;i++)
251 x[i] *= E;
252 }
Jean-Marc Valin5fa59952008-02-14 13:50:44 +1100253
254 encode_pulses(iy[0], N, K, enc);
255
Jean-Marc Valina4833ff2008-01-10 15:34:00 +1100256 /* Recompute the gain in one pass to reduce the encoder-decoder mismatch
Jean-Marc Valin636f5c82008-02-12 17:40:27 +1100257 due to the recursive computation used in quantisation.
258 Not quite sure whether we need that or not */
Jean-Marc Valina4833ff2008-01-10 15:34:00 +1100259 if (1) {
Jean-Marc Valin4a897682007-12-12 00:45:15 +1100260 float Ryp=0;
Jean-Marc Valin4a897682007-12-12 00:45:15 +1100261 float Ryy=0;
262 float g=0;
Jean-Marc Valin4a897682007-12-12 00:45:15 +1100263
264 for (i=0;i<N;i++)
265 Ryp += iy[0][i]*p[i];
266
267 for (i=0;i<N;i++)
268 y[0][i] = iy[0][i] - alpha*Ryp*p[i];
269
Jean-Marc Valin4a897682007-12-12 00:45:15 +1100270 Ryp = 0;
271 for (i=0;i<N;i++)
272 Ryp += y[0][i]*p[i];
273
274 for (i=0;i<N;i++)
275 Ryy += y[0][i]*y[0][i];
276
277 g = (sqrt(Ryp*Ryp + Ryy - Ryy*Rpp) - Ryp)/Ryy;
278
279 for (i=0;i<N;i++)
280 x[i] = p[i] + g*y[0][i];
281
282 }
283
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100284}
285
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100286void alg_unquant(float *x, int N, int K, float *p, float alpha, ec_dec *dec)
287{
288 int i;
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100289 int iy[N];
290 float y[N];
291 float Rpp=0, Ryp=0, Ryy=0;
292 float g;
Jean-Marc Valin25298f22007-12-03 15:24:11 +1100293
Jean-Marc Valin5fa59952008-02-14 13:50:44 +1100294 decode_pulses(iy, N, K, dec);
295
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100296 /*for (i=0;i<N;i++)
297 printf ("%d ", iy[i]);*/
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100298 for (i=0;i<N;i++)
299 Rpp += p[i]*p[i];
300
301 for (i=0;i<N;i++)
302 Ryp += iy[i]*p[i];
303
304 for (i=0;i<N;i++)
305 y[i] = iy[i] - alpha*Ryp*p[i];
306
307 /* Recompute after the projection (I think it's right) */
308 Ryp = 0;
309 for (i=0;i<N;i++)
310 Ryp += y[i]*p[i];
311
312 for (i=0;i<N;i++)
313 Ryy += y[i]*y[i];
314
315 g = (sqrt(Ryp*Ryp + Ryy - Ryy*Rpp) - Ryp)/Ryy;
316
317 for (i=0;i<N;i++)
318 x[i] = p[i] + g*y[i];
319}
320
321
322static const float pg[11] = {1.f, .75f, .65f, 0.6f, 0.6f, .6f, .55f, .55f, .5f, .5f, .5f};
323
324void 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 +1100325{
326 int i,j;
327 int best=0;
Jean-Marc Valin50d11162007-12-03 14:34:52 +1100328 float best_score=0;
329 float s = 1;
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100330 int sign;
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100331 float E;
Jean-Marc Valin8f0f4b92008-02-11 13:52:44 +1100332 int max_pos = N0-N/B;
333 if (max_pos > 32)
334 max_pos = 32;
335
336 for (i=0;i<max_pos*B;i+=B)
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100337 {
338 int j;
339 float xy=0, yy=0;
340 float score;
341 for (j=0;j<N;j++)
342 {
343 xy += x[j]*Y[i+j];
344 yy += Y[i+j]*Y[i+j];
345 }
Jean-Marc Valin50d11162007-12-03 14:34:52 +1100346 score = xy*xy/(.001+yy);
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100347 if (score > best_score)
348 {
349 best_score = score;
350 best = i;
Jean-Marc Valin50d11162007-12-03 14:34:52 +1100351 if (xy>0)
352 s = 1;
353 else
354 s = -1;
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100355 }
356 }
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100357 if (s<0)
358 sign = 1;
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100359 else
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100360 sign = 0;
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100361 /*printf ("%d %d ", sign, best);*/
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100362 ec_enc_uint(enc,sign,2);
Jean-Marc Valin8f0f4b92008-02-11 13:52:44 +1100363 ec_enc_uint(enc,best/B,max_pos);
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100364 /*printf ("%d %f\n", best, best_score);*/
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100365
366 float pred_gain;
367 if (K>10)
368 pred_gain = pg[10];
369 else
370 pred_gain = pg[K];
371 E = 1e-10;
372 for (j=0;j<N;j++)
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100373 {
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100374 P[j] = s*Y[best+j];
375 E += P[j]*P[j];
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100376 }
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100377 E = pred_gain/sqrt(E);
378 for (j=0;j<N;j++)
379 P[j] *= E;
380 if (K>0)
381 {
382 for (j=0;j<N;j++)
383 x[j] -= P[j];
384 } else {
385 for (j=0;j<N;j++)
386 x[j] = P[j];
387 }
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100388 /*printf ("quant ");*/
389 /*for (j=0;j<N;j++) printf ("%f ", P[j]);*/
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100390
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100391}
Jean-Marc Valinfc08d0a2007-12-07 13:26:15 +1100392
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100393void 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 +1100394{
Jean-Marc Valin11f01722007-12-09 01:19:36 +1100395 int j;
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100396 int sign;
397 float s;
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100398 int best;
399 float E;
Jean-Marc Valin8f0f4b92008-02-11 13:52:44 +1100400 int max_pos = N0-N/B;
401 if (max_pos > 32)
402 max_pos = 32;
403
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100404 sign = ec_dec_uint(dec, 2);
405 if (sign == 0)
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100406 s = 1;
407 else
408 s = -1;
409
Jean-Marc Valin8f0f4b92008-02-11 13:52:44 +1100410 best = B*ec_dec_uint(dec, max_pos);
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100411 /*printf ("%d %d ", sign, best);*/
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100412
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100413 float pred_gain;
414 if (K>10)
415 pred_gain = pg[10];
416 else
417 pred_gain = pg[K];
418 E = 1e-10;
419 for (j=0;j<N;j++)
420 {
421 P[j] = s*Y[best+j];
422 E += P[j]*P[j];
423 }
424 E = pred_gain/sqrt(E);
425 for (j=0;j<N;j++)
426 P[j] *= E;
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100427 if (K==0)
428 {
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100429 for (j=0;j<N;j++)
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100430 x[j] = P[j];
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100431 }
432}
Jean-Marc Valin0e20ca02008-02-11 15:33:53 +1100433
Jean-Marc Valin0df0eb42008-02-13 16:00:10 +1100434void intra_fold(float *x, int N, float *Y, float *P, int B, int N0, int Nmax)
Jean-Marc Valin0e20ca02008-02-11 15:33:53 +1100435{
Jean-Marc Valin0df0eb42008-02-13 16:00:10 +1100436 int i, j;
Jean-Marc Valin0e20ca02008-02-11 15:33:53 +1100437 float E;
438
439 E = 1e-10;
Jean-Marc Valin0df0eb42008-02-13 16:00:10 +1100440 if (N0 >= Nmax/2)
Jean-Marc Valin0e20ca02008-02-11 15:33:53 +1100441 {
Jean-Marc Valin0df0eb42008-02-13 16:00:10 +1100442 for (i=0;i<B;i++)
443 {
444 for (j=0;j<N/B;j++)
445 {
446 P[j*B+i] = Y[(Nmax-N0-j-1)*B+i];
447 E += P[j*B+i]*P[j*B+i];
448 }
449 }
450 } else {
451 for (j=0;j<N;j++)
452 {
453 P[j] = Y[j];
454 E += P[j]*P[j];
455 }
Jean-Marc Valin0e20ca02008-02-11 15:33:53 +1100456 }
457 E = 1.f/sqrt(E);
458 for (j=0;j<N;j++)
459 P[j] *= E;
460 for (j=0;j<N;j++)
461 x[j] = P[j];
462}
463