blob: 8d284f8a4ca68ce18fe94e9e2b5e223a794adcda [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
Jean-Marc Valin02fa9132008-02-20 12:09:29 +110032#ifdef HAVE_CONFIG_H
33#include "config.h"
34#endif
35
Jean-Marc Valin41af4212007-11-30 18:35:37 +110036#include <math.h>
37#include <stdlib.h>
Jean-Marc Valin29ccab82007-12-06 15:39:38 +110038#include "cwrs.h"
Jean-Marc Valin9cace642007-12-06 17:44:09 +110039#include "vq.h"
Jean-Marc Valin9a0bba12008-02-20 14:08:50 +110040#include "arch.h"
Jean-Marc Valin41af4212007-11-30 18:35:37 +110041
Jean-Marc Valin883bd8e2008-02-15 00:34:01 +110042/* Enable this or define your own implementation if you want to speed up the
43 VQ search (used in inner loop only) */
44#if 0
45#include <xmmintrin.h>
46static inline float approx_sqrt(float x)
47{
48 _mm_store_ss(&x, _mm_sqrt_ss(_mm_set_ss(x)));
49 return x;
50}
51static inline float approx_inv(float x)
52{
53 _mm_store_ss(&x, _mm_rcp_ss(_mm_set_ss(x)));
54 return x;
55}
56#else
57#define approx_sqrt(x) (sqrt(x))
58#define approx_inv(x) (1.f/(x))
59#endif
60
Jean-Marc Valin879fbfd2008-02-20 17:17:13 +110061/** All the info necessary to keep track of a hypothesis during the search */
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +110062struct NBest {
63 float score;
64 float gain;
65 int sign;
66 int pos;
67 int orig;
68 float xy;
69 float yy;
70 float yp;
71};
Jean-Marc Valin41af4212007-11-30 18:35:37 +110072
Jean-Marc Valin46014ca2007-12-14 13:47:04 +110073void 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 +110074{
Jean-Marc Valin4a897682007-12-12 00:45:15 +110075 int L = 3;
Jean-Marc Valin9a0bba12008-02-20 14:08:50 +110076 VARDECL(float *_y);
77 VARDECL(float *_ny);
78 VARDECL(int *_iy);
79 VARDECL(int *_iny);
80 VARDECL(float **y);
81 VARDECL(float **ny);
82 VARDECL(int **iy);
83 VARDECL(int **iny);
Jean-Marc Valin0d587d82008-02-14 21:29:50 +110084 int i, j, k, m;
Jean-Marc Valin846d4e22008-02-12 13:48:48 +110085 int pulsesLeft;
Jean-Marc Valin9a0bba12008-02-20 14:08:50 +110086 VARDECL(float *xy);
87 VARDECL(float *yy);
88 VARDECL(float *yp);
89 VARDECL(struct NBest *_nbest);
90 VARDECL(struct NBest **nbest);
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +110091 float Rpp=0, Rxp=0;
Jean-Marc Valin41af4212007-11-30 18:35:37 +110092 int maxL = 1;
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +110093
Jean-Marc Valin9a0bba12008-02-20 14:08:50 +110094 ALLOC(_y, L*N, float);
95 ALLOC(_ny, L*N, float);
96 ALLOC(_iy, L*N, int);
97 ALLOC(_iny, L*N, int);
98 ALLOC(y, L*N, float*);
99 ALLOC(ny, L*N, float*);
100 ALLOC(iy, L*N, int*);
101 ALLOC(iny, L*N, int*);
102
103 ALLOC(xy, L, float);
104 ALLOC(yy, L, float);
105 ALLOC(yp, L, float);
106 ALLOC(_nbest, L, struct NBest);
107 ALLOC(nbest, L, struct NBest *);
108
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100109 for (m=0;m<L;m++)
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100110 nbest[m] = &_nbest[m];
111
112 for (m=0;m<L;m++)
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100113 {
Jean-Marc Valin9a0bba12008-02-20 14:08:50 +1100114 ny[m] = &_ny[m*N];
115 iny[m] = &_iny[m*N];
116 y[m] = &_y[m*N];
117 iy[m] = &_iy[m*N];
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100118 }
119
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100120 for (j=0;j<N;j++)
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100121 {
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100122 Rpp += p[j]*p[j];
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100123 Rxp += x[j]*p[j];
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100124 }
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100125
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100126 /* We only need to initialise the zero because the first iteration only uses that */
127 for (i=0;i<N;i++)
128 y[0][i] = 0;
129 for (i=0;i<N;i++)
130 iy[0][i] = 0;
131 xy[0] = yy[0] = yp[0] = 0;
132
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100133 pulsesLeft = K;
134 while (pulsesLeft > 0)
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100135 {
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100136 int pulsesAtOnce=1;
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100137 int Lupdate = L;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100138 int L2 = L;
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100139
140 /* Decide on complexity strategy */
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100141 pulsesAtOnce = pulsesLeft/N;
142 if (pulsesAtOnce<1)
143 pulsesAtOnce = 1;
144 if (pulsesLeft-pulsesAtOnce > 3 || N > 30)
145 Lupdate = 1;
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100146 /*printf ("%d %d %d/%d %d\n", Lupdate, pulsesAtOnce, pulsesLeft, K, N);*/
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100147 L2 = Lupdate;
148 if (L2>maxL)
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100149 {
150 L2 = maxL;
151 maxL *= N;
152 }
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100153
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100154 for (m=0;m<Lupdate;m++)
Jean-Marc Valin883bd8e2008-02-15 00:34:01 +1100155 nbest[m]->score = -1e10f;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100156
157 for (m=0;m<L2;m++)
158 {
159 for (j=0;j<N;j++)
160 {
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100161 int sign;
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100162 /*if (x[j]>0) sign=1; else sign=-1;*/
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100163 for (sign=-1;sign<=1;sign+=2)
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100164 {
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100165 /*fprintf (stderr, "%d/%d %d/%d %d/%d\n", i, K, m, L2, j, N);*/
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100166 float tmp_xy, tmp_yy, tmp_yp;
167 float score;
168 float g;
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100169 float s = sign*pulsesAtOnce;
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100170
Jean-Marc Valin9a0bba12008-02-20 14:08:50 +1100171 /* All pulses at one location must have the same sign. */
172 if (iy[m][j]*sign < 0)
173 continue;
174
Jean-Marc Valina073c7b2008-02-14 16:58:04 +1100175 /* Updating the sums of the new pulse(s) */
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100176 tmp_xy = xy[m] + s*x[j] - alpha*s*p[j]*Rxp;
Jean-Marc Valin883bd8e2008-02-15 00:34:01 +1100177 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];
178 tmp_yp = yp[m] + s*p[j] *(1.f-alpha*Rpp);
Jean-Marc Valina073c7b2008-02-14 16:58:04 +1100179
180 /* Compute the gain such that ||p + g*y|| = 1 */
Jean-Marc Valin883bd8e2008-02-15 00:34:01 +1100181 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 +1100182 /* Knowing that gain, what the error: (x-g*y)^2
183 (result is negated and we discard x^2 because it's constant) */
Jean-Marc Valin883bd8e2008-02-15 00:34:01 +1100184 score = 2.f*g*tmp_xy - g*g*tmp_yy;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100185
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100186 if (score>nbest[Lupdate-1]->score)
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100187 {
Jean-Marc Valin472a5f02008-02-19 13:12:32 +1100188 int k;
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100189 int id = Lupdate-1;
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100190 struct NBest *tmp_best;
191
192 /* Save some pointers that would be deleted and use them for the current entry*/
193 tmp_best = nbest[Lupdate-1];
194 while (id > 0 && score > nbest[id-1]->score)
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100195 id--;
196
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100197 for (k=Lupdate-1;k>id;k--)
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100198 nbest[k] = nbest[k-1];
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100199
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100200 nbest[id] = tmp_best;
201 nbest[id]->score = score;
202 nbest[id]->pos = j;
203 nbest[id]->orig = m;
204 nbest[id]->sign = sign;
205 nbest[id]->gain = g;
206 nbest[id]->xy = tmp_xy;
207 nbest[id]->yy = tmp_yy;
208 nbest[id]->yp = tmp_yp;
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100209 }
Jean-Marc Valin636f5c82008-02-12 17:40:27 +1100210 }
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100211 }
Jean-Marc Valin636f5c82008-02-12 17:40:27 +1100212
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100213 }
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100214 /* Only now that we've made the final choice, update ny/iny and others */
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100215 for (k=0;k<Lupdate;k++)
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100216 {
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100217 int n;
218 int is;
219 float s;
220 is = nbest[k]->sign*pulsesAtOnce;
221 s = is;
222 for (n=0;n<N;n++)
223 ny[k][n] = y[nbest[k]->orig][n] - alpha*s*p[nbest[k]->pos]*p[n];
224 ny[k][nbest[k]->pos] += s;
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100225
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100226 for (n=0;n<N;n++)
227 iny[k][n] = iy[nbest[k]->orig][n];
228 iny[k][nbest[k]->pos] += is;
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100229
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100230 xy[k] = nbest[k]->xy;
231 yy[k] = nbest[k]->yy;
232 yp[k] = nbest[k]->yp;
233 }
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100234 /* Swap ny/iny with y/iy */
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100235 for (k=0;k<Lupdate;k++)
236 {
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100237 float *tmp_ny;
238 int *tmp_iny;
239
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100240 tmp_ny = ny[k];
241 ny[k] = y[k];
242 y[k] = tmp_ny;
243 tmp_iny = iny[k];
244 iny[k] = iy[k];
245 iy[k] = tmp_iny;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100246 }
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100247 pulsesLeft -= pulsesAtOnce;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100248 }
249
Jean-Marc Valinac1e03d2008-02-12 23:00:18 +1100250 if (0) {
251 float err=0;
252 for (i=0;i<N;i++)
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100253 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 +1100254 /*if (N<=10)
255 printf ("%f %d %d\n", err, K, N);*/
Jean-Marc Valinac1e03d2008-02-12 23:00:18 +1100256 }
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100257 for (i=0;i<N;i++)
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100258 x[i] = p[i]+nbest[0]->gain*y[0][i];
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100259 /* Sanity checks, don't bother */
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100260 if (0) {
261 float E=1e-15;
262 int ABS = 0;
263 for (i=0;i<N;i++)
264 ABS += abs(iy[0][i]);
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100265 /*if (K != ABS)
266 printf ("%d %d\n", K, ABS);*/
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100267 for (i=0;i<N;i++)
268 E += x[i]*x[i];
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100269 /*printf ("%f\n", E);*/
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100270 E = 1/sqrt(E);
271 for (i=0;i<N;i++)
272 x[i] *= E;
273 }
Jean-Marc Valin5fa59952008-02-14 13:50:44 +1100274
275 encode_pulses(iy[0], N, K, enc);
276
Jean-Marc Valina4833ff2008-01-10 15:34:00 +1100277 /* Recompute the gain in one pass to reduce the encoder-decoder mismatch
Jean-Marc Valin636f5c82008-02-12 17:40:27 +1100278 due to the recursive computation used in quantisation.
279 Not quite sure whether we need that or not */
Jean-Marc Valina4833ff2008-01-10 15:34:00 +1100280 if (1) {
Jean-Marc Valin4a897682007-12-12 00:45:15 +1100281 float Ryp=0;
Jean-Marc Valin4a897682007-12-12 00:45:15 +1100282 float Ryy=0;
283 float g=0;
Jean-Marc Valin4a897682007-12-12 00:45:15 +1100284
285 for (i=0;i<N;i++)
286 Ryp += iy[0][i]*p[i];
287
288 for (i=0;i<N;i++)
289 y[0][i] = iy[0][i] - alpha*Ryp*p[i];
290
Jean-Marc Valin4a897682007-12-12 00:45:15 +1100291 Ryp = 0;
292 for (i=0;i<N;i++)
293 Ryp += y[0][i]*p[i];
294
295 for (i=0;i<N;i++)
296 Ryy += y[0][i]*y[0][i];
297
298 g = (sqrt(Ryp*Ryp + Ryy - Ryy*Rpp) - Ryp)/Ryy;
299
300 for (i=0;i<N;i++)
301 x[i] = p[i] + g*y[0][i];
302
303 }
304
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100305}
306
Jean-Marc Valin879fbfd2008-02-20 17:17:13 +1100307/** Decode pulse vector and combine the result with the pitch vector to produce
308 the final normalised signal in the current band. */
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100309void alg_unquant(float *x, int N, int K, float *p, float alpha, ec_dec *dec)
310{
311 int i;
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100312 float Rpp=0, Ryp=0, Ryy=0;
313 float g;
Jean-Marc Valin9a0bba12008-02-20 14:08:50 +1100314 VARDECL(int *iy);
315 VARDECL(float *y);
316
317 ALLOC(iy, N, int);
318 ALLOC(y, N, float);
Jean-Marc Valin25298f22007-12-03 15:24:11 +1100319
Jean-Marc Valin5fa59952008-02-14 13:50:44 +1100320 decode_pulses(iy, N, K, dec);
321
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100322 /*for (i=0;i<N;i++)
323 printf ("%d ", iy[i]);*/
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100324 for (i=0;i<N;i++)
325 Rpp += p[i]*p[i];
326
327 for (i=0;i<N;i++)
328 Ryp += iy[i]*p[i];
329
330 for (i=0;i<N;i++)
331 y[i] = iy[i] - alpha*Ryp*p[i];
332
333 /* Recompute after the projection (I think it's right) */
334 Ryp = 0;
335 for (i=0;i<N;i++)
336 Ryp += y[i]*p[i];
337
338 for (i=0;i<N;i++)
339 Ryy += y[i]*y[i];
340
341 g = (sqrt(Ryp*Ryp + Ryy - Ryy*Rpp) - Ryp)/Ryy;
342
343 for (i=0;i<N;i++)
344 x[i] = p[i] + g*y[i];
345}
346
347
348static const float pg[11] = {1.f, .75f, .65f, 0.6f, 0.6f, .6f, .55f, .55f, .5f, .5f, .5f};
349
350void 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 +1100351{
352 int i,j;
353 int best=0;
Jean-Marc Valin50d11162007-12-03 14:34:52 +1100354 float best_score=0;
355 float s = 1;
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100356 int sign;
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100357 float E;
Jean-Marc Valin9a0bba12008-02-20 14:08:50 +1100358 float pred_gain;
Jean-Marc Valin8f0f4b92008-02-11 13:52:44 +1100359 int max_pos = N0-N/B;
360 if (max_pos > 32)
361 max_pos = 32;
362
363 for (i=0;i<max_pos*B;i+=B)
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100364 {
365 int j;
366 float xy=0, yy=0;
367 float score;
368 for (j=0;j<N;j++)
369 {
Jean-Marc Valind501f612008-02-21 12:16:57 +1100370 xy += x[j]*Y[i+N-j-1];
371 yy += Y[i+N-j-1]*Y[i+N-j-1];
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100372 }
Jean-Marc Valin50d11162007-12-03 14:34:52 +1100373 score = xy*xy/(.001+yy);
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100374 if (score > best_score)
375 {
376 best_score = score;
377 best = i;
Jean-Marc Valin50d11162007-12-03 14:34:52 +1100378 if (xy>0)
379 s = 1;
380 else
381 s = -1;
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100382 }
383 }
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100384 if (s<0)
385 sign = 1;
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100386 else
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100387 sign = 0;
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100388 /*printf ("%d %d ", sign, best);*/
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100389 ec_enc_uint(enc,sign,2);
Jean-Marc Valin8f0f4b92008-02-11 13:52:44 +1100390 ec_enc_uint(enc,best/B,max_pos);
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100391 /*printf ("%d %f\n", best, best_score);*/
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100392
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100393 if (K>10)
394 pred_gain = pg[10];
395 else
396 pred_gain = pg[K];
397 E = 1e-10;
398 for (j=0;j<N;j++)
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100399 {
Jean-Marc Valind501f612008-02-21 12:16:57 +1100400 P[j] = s*Y[best+N-j-1];
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100401 E += P[j]*P[j];
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100402 }
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100403 E = pred_gain/sqrt(E);
404 for (j=0;j<N;j++)
405 P[j] *= E;
406 if (K>0)
407 {
408 for (j=0;j<N;j++)
409 x[j] -= P[j];
410 } else {
411 for (j=0;j<N;j++)
412 x[j] = P[j];
413 }
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100414 /*printf ("quant ");*/
415 /*for (j=0;j<N;j++) printf ("%f ", P[j]);*/
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100416
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100417}
Jean-Marc Valinfc08d0a2007-12-07 13:26:15 +1100418
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100419void 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 +1100420{
Jean-Marc Valin11f01722007-12-09 01:19:36 +1100421 int j;
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100422 int sign;
423 float s;
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100424 int best;
425 float E;
Jean-Marc Valin9a0bba12008-02-20 14:08:50 +1100426 float pred_gain;
Jean-Marc Valin8f0f4b92008-02-11 13:52:44 +1100427 int max_pos = N0-N/B;
428 if (max_pos > 32)
429 max_pos = 32;
430
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100431 sign = ec_dec_uint(dec, 2);
432 if (sign == 0)
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100433 s = 1;
434 else
435 s = -1;
436
Jean-Marc Valin8f0f4b92008-02-11 13:52:44 +1100437 best = B*ec_dec_uint(dec, max_pos);
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100438 /*printf ("%d %d ", sign, best);*/
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100439
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100440 if (K>10)
441 pred_gain = pg[10];
442 else
443 pred_gain = pg[K];
444 E = 1e-10;
445 for (j=0;j<N;j++)
446 {
Jean-Marc Valind501f612008-02-21 12:16:57 +1100447 P[j] = s*Y[best+N-j-1];
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100448 E += P[j]*P[j];
449 }
450 E = pred_gain/sqrt(E);
451 for (j=0;j<N;j++)
452 P[j] *= E;
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100453 if (K==0)
454 {
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100455 for (j=0;j<N;j++)
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100456 x[j] = P[j];
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100457 }
458}
Jean-Marc Valin0e20ca02008-02-11 15:33:53 +1100459
Jean-Marc Valin0df0eb42008-02-13 16:00:10 +1100460void intra_fold(float *x, int N, float *Y, float *P, int B, int N0, int Nmax)
Jean-Marc Valin0e20ca02008-02-11 15:33:53 +1100461{
Jean-Marc Valin0df0eb42008-02-13 16:00:10 +1100462 int i, j;
Jean-Marc Valin0e20ca02008-02-11 15:33:53 +1100463 float E;
464
465 E = 1e-10;
Jean-Marc Valin0df0eb42008-02-13 16:00:10 +1100466 if (N0 >= Nmax/2)
Jean-Marc Valin0e20ca02008-02-11 15:33:53 +1100467 {
Jean-Marc Valin0df0eb42008-02-13 16:00:10 +1100468 for (i=0;i<B;i++)
469 {
470 for (j=0;j<N/B;j++)
471 {
472 P[j*B+i] = Y[(Nmax-N0-j-1)*B+i];
473 E += P[j*B+i]*P[j*B+i];
474 }
475 }
476 } else {
477 for (j=0;j<N;j++)
478 {
479 P[j] = Y[j];
480 E += P[j]*P[j];
481 }
Jean-Marc Valin0e20ca02008-02-11 15:33:53 +1100482 }
483 E = 1.f/sqrt(E);
484 for (j=0;j<N;j++)
485 P[j] *= E;
486 for (j=0;j<N;j++)
487 x[j] = P[j];
488}
489