blob: 91c107e228a0e0db1b2ba65838e3efd80b19b1c4 [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 Valin2fa8aff2008-02-26 11:38:00 +110073void alg_quant(celt_norm_t *X, float *W, int N, int K, celt_norm_t *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 Valin2fa8aff2008-02-26 11:38:00 +110076 VARDECL(float *x);
77 VARDECL(float *p);
Jean-Marc Valin9a0bba12008-02-20 14:08:50 +110078 VARDECL(float *_y);
79 VARDECL(float *_ny);
80 VARDECL(int *_iy);
81 VARDECL(int *_iny);
82 VARDECL(float **y);
83 VARDECL(float **ny);
84 VARDECL(int **iy);
85 VARDECL(int **iny);
Jean-Marc Valin0d587d82008-02-14 21:29:50 +110086 int i, j, k, m;
Jean-Marc Valin846d4e22008-02-12 13:48:48 +110087 int pulsesLeft;
Jean-Marc Valin9a0bba12008-02-20 14:08:50 +110088 VARDECL(float *xy);
89 VARDECL(float *yy);
90 VARDECL(float *yp);
91 VARDECL(struct NBest *_nbest);
92 VARDECL(struct NBest **nbest);
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +110093 float Rpp=0, Rxp=0;
Jean-Marc Valin41af4212007-11-30 18:35:37 +110094 int maxL = 1;
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +110095
Jean-Marc Valin2fa8aff2008-02-26 11:38:00 +110096 ALLOC(x, N, float);
97 ALLOC(p, N, float);
Jean-Marc Valin9a0bba12008-02-20 14:08:50 +110098 ALLOC(_y, L*N, float);
99 ALLOC(_ny, L*N, float);
100 ALLOC(_iy, L*N, int);
101 ALLOC(_iny, L*N, int);
102 ALLOC(y, L*N, float*);
103 ALLOC(ny, L*N, float*);
104 ALLOC(iy, L*N, int*);
105 ALLOC(iny, L*N, int*);
106
107 ALLOC(xy, L, float);
108 ALLOC(yy, L, float);
109 ALLOC(yp, L, float);
110 ALLOC(_nbest, L, struct NBest);
111 ALLOC(nbest, L, struct NBest *);
112
Jean-Marc Valinb4dfce42008-02-25 17:41:30 +1100113 for (j=0;j<N;j++)
114 {
Jean-Marc Valin2fa8aff2008-02-26 11:38:00 +1100115 x[j] = X[j]*NORM_SCALING_1;
116 p[j] = P[j]*NORM_SCALING_1;
Jean-Marc Valinb4dfce42008-02-25 17:41:30 +1100117 }
118
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100119 for (m=0;m<L;m++)
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100120 nbest[m] = &_nbest[m];
121
122 for (m=0;m<L;m++)
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100123 {
Jean-Marc Valin9a0bba12008-02-20 14:08:50 +1100124 ny[m] = &_ny[m*N];
125 iny[m] = &_iny[m*N];
126 y[m] = &_y[m*N];
127 iy[m] = &_iy[m*N];
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100128 }
129
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100130 for (j=0;j<N;j++)
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100131 {
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100132 Rpp += p[j]*p[j];
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100133 Rxp += x[j]*p[j];
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100134 }
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100135
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100136 /* We only need to initialise the zero because the first iteration only uses that */
137 for (i=0;i<N;i++)
138 y[0][i] = 0;
139 for (i=0;i<N;i++)
140 iy[0][i] = 0;
141 xy[0] = yy[0] = yp[0] = 0;
142
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100143 pulsesLeft = K;
144 while (pulsesLeft > 0)
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100145 {
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100146 int pulsesAtOnce=1;
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100147 int Lupdate = L;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100148 int L2 = L;
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100149
150 /* Decide on complexity strategy */
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100151 pulsesAtOnce = pulsesLeft/N;
152 if (pulsesAtOnce<1)
153 pulsesAtOnce = 1;
154 if (pulsesLeft-pulsesAtOnce > 3 || N > 30)
155 Lupdate = 1;
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100156 /*printf ("%d %d %d/%d %d\n", Lupdate, pulsesAtOnce, pulsesLeft, K, N);*/
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100157 L2 = Lupdate;
158 if (L2>maxL)
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100159 {
160 L2 = maxL;
161 maxL *= N;
162 }
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100163
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100164 for (m=0;m<Lupdate;m++)
Jean-Marc Valin883bd8e2008-02-15 00:34:01 +1100165 nbest[m]->score = -1e10f;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100166
167 for (m=0;m<L2;m++)
168 {
169 for (j=0;j<N;j++)
170 {
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100171 int sign;
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100172 /*if (x[j]>0) sign=1; else sign=-1;*/
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100173 for (sign=-1;sign<=1;sign+=2)
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100174 {
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100175 /*fprintf (stderr, "%d/%d %d/%d %d/%d\n", i, K, m, L2, j, N);*/
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100176 float tmp_xy, tmp_yy, tmp_yp;
177 float score;
178 float g;
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100179 float s = sign*pulsesAtOnce;
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100180
Jean-Marc Valin9a0bba12008-02-20 14:08:50 +1100181 /* All pulses at one location must have the same sign. */
182 if (iy[m][j]*sign < 0)
183 continue;
184
Jean-Marc Valina073c7b2008-02-14 16:58:04 +1100185 /* Updating the sums of the new pulse(s) */
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100186 tmp_xy = xy[m] + s*x[j] - alpha*s*p[j]*Rxp;
Jean-Marc Valin883bd8e2008-02-15 00:34:01 +1100187 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];
188 tmp_yp = yp[m] + s*p[j] *(1.f-alpha*Rpp);
Jean-Marc Valina073c7b2008-02-14 16:58:04 +1100189
190 /* Compute the gain such that ||p + g*y|| = 1 */
Jean-Marc Valin883bd8e2008-02-15 00:34:01 +1100191 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 +1100192 /* Knowing that gain, what the error: (x-g*y)^2
193 (result is negated and we discard x^2 because it's constant) */
Jean-Marc Valin883bd8e2008-02-15 00:34:01 +1100194 score = 2.f*g*tmp_xy - g*g*tmp_yy;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100195
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100196 if (score>nbest[Lupdate-1]->score)
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100197 {
Jean-Marc Valin472a5f02008-02-19 13:12:32 +1100198 int k;
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100199 int id = Lupdate-1;
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100200 struct NBest *tmp_best;
201
202 /* Save some pointers that would be deleted and use them for the current entry*/
203 tmp_best = nbest[Lupdate-1];
204 while (id > 0 && score > nbest[id-1]->score)
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100205 id--;
206
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100207 for (k=Lupdate-1;k>id;k--)
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100208 nbest[k] = nbest[k-1];
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100209
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100210 nbest[id] = tmp_best;
211 nbest[id]->score = score;
212 nbest[id]->pos = j;
213 nbest[id]->orig = m;
214 nbest[id]->sign = sign;
215 nbest[id]->gain = g;
216 nbest[id]->xy = tmp_xy;
217 nbest[id]->yy = tmp_yy;
218 nbest[id]->yp = tmp_yp;
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100219 }
Jean-Marc Valin636f5c82008-02-12 17:40:27 +1100220 }
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100221 }
Jean-Marc Valin636f5c82008-02-12 17:40:27 +1100222
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100223 }
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100224 /* Only now that we've made the final choice, update ny/iny and others */
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100225 for (k=0;k<Lupdate;k++)
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100226 {
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100227 int n;
228 int is;
229 float s;
230 is = nbest[k]->sign*pulsesAtOnce;
231 s = is;
232 for (n=0;n<N;n++)
233 ny[k][n] = y[nbest[k]->orig][n] - alpha*s*p[nbest[k]->pos]*p[n];
234 ny[k][nbest[k]->pos] += s;
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100235
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100236 for (n=0;n<N;n++)
237 iny[k][n] = iy[nbest[k]->orig][n];
238 iny[k][nbest[k]->pos] += is;
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100239
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100240 xy[k] = nbest[k]->xy;
241 yy[k] = nbest[k]->yy;
242 yp[k] = nbest[k]->yp;
243 }
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100244 /* Swap ny/iny with y/iy */
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100245 for (k=0;k<Lupdate;k++)
246 {
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100247 float *tmp_ny;
248 int *tmp_iny;
249
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100250 tmp_ny = ny[k];
251 ny[k] = y[k];
252 y[k] = tmp_ny;
253 tmp_iny = iny[k];
254 iny[k] = iy[k];
255 iy[k] = tmp_iny;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100256 }
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100257 pulsesLeft -= pulsesAtOnce;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100258 }
259
Jean-Marc Valinac1e03d2008-02-12 23:00:18 +1100260 if (0) {
261 float err=0;
262 for (i=0;i<N;i++)
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100263 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 +1100264 /*if (N<=10)
265 printf ("%f %d %d\n", err, K, N);*/
Jean-Marc Valinac1e03d2008-02-12 23:00:18 +1100266 }
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100267 for (i=0;i<N;i++)
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100268 x[i] = p[i]+nbest[0]->gain*y[0][i];
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100269 /* Sanity checks, don't bother */
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100270 if (0) {
271 float E=1e-15;
272 int ABS = 0;
273 for (i=0;i<N;i++)
274 ABS += abs(iy[0][i]);
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100275 /*if (K != ABS)
276 printf ("%d %d\n", K, ABS);*/
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100277 for (i=0;i<N;i++)
278 E += x[i]*x[i];
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100279 /*printf ("%f\n", E);*/
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100280 E = 1/sqrt(E);
281 for (i=0;i<N;i++)
282 x[i] *= E;
283 }
Jean-Marc Valin5fa59952008-02-14 13:50:44 +1100284
285 encode_pulses(iy[0], N, K, enc);
286
Jean-Marc Valina4833ff2008-01-10 15:34:00 +1100287 /* Recompute the gain in one pass to reduce the encoder-decoder mismatch
Jean-Marc Valin636f5c82008-02-12 17:40:27 +1100288 due to the recursive computation used in quantisation.
289 Not quite sure whether we need that or not */
Jean-Marc Valina4833ff2008-01-10 15:34:00 +1100290 if (1) {
Jean-Marc Valin4a897682007-12-12 00:45:15 +1100291 float Ryp=0;
Jean-Marc Valin4a897682007-12-12 00:45:15 +1100292 float Ryy=0;
293 float g=0;
Jean-Marc Valin4a897682007-12-12 00:45:15 +1100294
295 for (i=0;i<N;i++)
296 Ryp += iy[0][i]*p[i];
297
298 for (i=0;i<N;i++)
299 y[0][i] = iy[0][i] - alpha*Ryp*p[i];
300
Jean-Marc Valin4a897682007-12-12 00:45:15 +1100301 Ryp = 0;
302 for (i=0;i<N;i++)
303 Ryp += y[0][i]*p[i];
304
305 for (i=0;i<N;i++)
306 Ryy += y[0][i]*y[0][i];
307
308 g = (sqrt(Ryp*Ryp + Ryy - Ryy*Rpp) - Ryp)/Ryy;
309
310 for (i=0;i<N;i++)
311 x[i] = p[i] + g*y[0][i];
312
313 }
Jean-Marc Valinb4dfce42008-02-25 17:41:30 +1100314 for (j=0;j<N;j++)
315 {
Jean-Marc Valin2fa8aff2008-02-26 11:38:00 +1100316 X[j] = x[j] * NORM_SCALING;
317 P[j] = p[j] * NORM_SCALING;
Jean-Marc Valinb4dfce42008-02-25 17:41:30 +1100318 }
Jean-Marc Valin4a897682007-12-12 00:45:15 +1100319
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100320}
321
Jean-Marc Valin879fbfd2008-02-20 17:17:13 +1100322/** Decode pulse vector and combine the result with the pitch vector to produce
323 the final normalised signal in the current band. */
Jean-Marc Valin2fa8aff2008-02-26 11:38:00 +1100324void alg_unquant(celt_norm_t *X, int N, int K, celt_norm_t *P, float alpha, ec_dec *dec)
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100325{
326 int i;
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100327 float Rpp=0, Ryp=0, Ryy=0;
328 float g;
Jean-Marc Valin9a0bba12008-02-20 14:08:50 +1100329 VARDECL(int *iy);
330 VARDECL(float *y);
Jean-Marc Valin2fa8aff2008-02-26 11:38:00 +1100331 VARDECL(float *x);
332 VARDECL(float *p);
Jean-Marc Valin9a0bba12008-02-20 14:08:50 +1100333
334 ALLOC(iy, N, int);
335 ALLOC(y, N, float);
Jean-Marc Valin2fa8aff2008-02-26 11:38:00 +1100336 ALLOC(x, N, float);
337 ALLOC(p, N, float);
Jean-Marc Valin25298f22007-12-03 15:24:11 +1100338
Jean-Marc Valin5fa59952008-02-14 13:50:44 +1100339 decode_pulses(iy, N, K, dec);
Jean-Marc Valinb4dfce42008-02-25 17:41:30 +1100340 for (i=0;i<N;i++)
341 {
Jean-Marc Valin2fa8aff2008-02-26 11:38:00 +1100342 x[i] = X[i]*NORM_SCALING_1;
343 p[i] = P[i]*NORM_SCALING_1;
Jean-Marc Valinb4dfce42008-02-25 17:41:30 +1100344 }
Jean-Marc Valin5fa59952008-02-14 13:50:44 +1100345
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100346 /*for (i=0;i<N;i++)
347 printf ("%d ", iy[i]);*/
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100348 for (i=0;i<N;i++)
349 Rpp += p[i]*p[i];
350
351 for (i=0;i<N;i++)
352 Ryp += iy[i]*p[i];
353
354 for (i=0;i<N;i++)
355 y[i] = iy[i] - alpha*Ryp*p[i];
356
357 /* Recompute after the projection (I think it's right) */
358 Ryp = 0;
359 for (i=0;i<N;i++)
360 Ryp += y[i]*p[i];
361
362 for (i=0;i<N;i++)
363 Ryy += y[i]*y[i];
364
365 g = (sqrt(Ryp*Ryp + Ryy - Ryy*Rpp) - Ryp)/Ryy;
366
367 for (i=0;i<N;i++)
368 x[i] = p[i] + g*y[i];
Jean-Marc Valinb4dfce42008-02-25 17:41:30 +1100369 for (i=0;i<N;i++)
370 {
Jean-Marc Valin2fa8aff2008-02-26 11:38:00 +1100371 X[i] = x[i] * NORM_SCALING;
372 P[i] = p[i] * NORM_SCALING;
Jean-Marc Valinb4dfce42008-02-25 17:41:30 +1100373 }
374
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100375}
376
377
378static const float pg[11] = {1.f, .75f, .65f, 0.6f, 0.6f, .6f, .55f, .55f, .5f, .5f, .5f};
379
Jean-Marc Valin18ddc022008-02-22 14:24:50 +1100380void intra_prediction(celt_norm_t *x, float *W, int N, int K, celt_norm_t *Y, celt_norm_t *P, int B, int N0, ec_enc *enc)
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100381{
382 int i,j;
383 int best=0;
Jean-Marc Valin50d11162007-12-03 14:34:52 +1100384 float best_score=0;
385 float s = 1;
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100386 int sign;
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100387 float E;
Jean-Marc Valin9a0bba12008-02-20 14:08:50 +1100388 float pred_gain;
Jean-Marc Valin8f0f4b92008-02-11 13:52:44 +1100389 int max_pos = N0-N/B;
390 if (max_pos > 32)
391 max_pos = 32;
392
393 for (i=0;i<max_pos*B;i+=B)
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100394 {
395 int j;
396 float xy=0, yy=0;
397 float score;
398 for (j=0;j<N;j++)
399 {
Jean-Marc Valinb4dfce42008-02-25 17:41:30 +1100400 xy += 1.f*x[j]*Y[i+N-j-1];
401 yy += 1.f*Y[i+N-j-1]*Y[i+N-j-1];
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100402 }
Jean-Marc Valin50d11162007-12-03 14:34:52 +1100403 score = xy*xy/(.001+yy);
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100404 if (score > best_score)
405 {
406 best_score = score;
407 best = i;
Jean-Marc Valin50d11162007-12-03 14:34:52 +1100408 if (xy>0)
409 s = 1;
410 else
411 s = -1;
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100412 }
413 }
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100414 if (s<0)
415 sign = 1;
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100416 else
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100417 sign = 0;
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100418 /*printf ("%d %d ", sign, best);*/
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100419 ec_enc_uint(enc,sign,2);
Jean-Marc Valin8f0f4b92008-02-11 13:52:44 +1100420 ec_enc_uint(enc,best/B,max_pos);
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100421 /*printf ("%d %f\n", best, best_score);*/
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100422
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100423 if (K>10)
424 pred_gain = pg[10];
425 else
426 pred_gain = pg[K];
427 E = 1e-10;
428 for (j=0;j<N;j++)
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100429 {
Jean-Marc Valind501f612008-02-21 12:16:57 +1100430 P[j] = s*Y[best+N-j-1];
Jean-Marc Valinb4dfce42008-02-25 17:41:30 +1100431 E += NORM_SCALING_1*NORM_SCALING_1*P[j]*P[j];
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100432 }
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100433 E = pred_gain/sqrt(E);
434 for (j=0;j<N;j++)
435 P[j] *= E;
436 if (K>0)
437 {
438 for (j=0;j<N;j++)
439 x[j] -= P[j];
440 } else {
441 for (j=0;j<N;j++)
442 x[j] = P[j];
443 }
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100444 /*printf ("quant ");*/
445 /*for (j=0;j<N;j++) printf ("%f ", P[j]);*/
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100446
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100447}
Jean-Marc Valinfc08d0a2007-12-07 13:26:15 +1100448
Jean-Marc Valin18ddc022008-02-22 14:24:50 +1100449void intra_unquant(celt_norm_t *x, int N, int K, celt_norm_t *Y, celt_norm_t *P, int B, int N0, ec_dec *dec)
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100450{
Jean-Marc Valin11f01722007-12-09 01:19:36 +1100451 int j;
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100452 int sign;
453 float s;
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100454 int best;
455 float E;
Jean-Marc Valin9a0bba12008-02-20 14:08:50 +1100456 float pred_gain;
Jean-Marc Valin8f0f4b92008-02-11 13:52:44 +1100457 int max_pos = N0-N/B;
458 if (max_pos > 32)
459 max_pos = 32;
460
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100461 sign = ec_dec_uint(dec, 2);
462 if (sign == 0)
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100463 s = 1;
464 else
465 s = -1;
466
Jean-Marc Valin8f0f4b92008-02-11 13:52:44 +1100467 best = B*ec_dec_uint(dec, max_pos);
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100468 /*printf ("%d %d ", sign, best);*/
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100469
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100470 if (K>10)
471 pred_gain = pg[10];
472 else
473 pred_gain = pg[K];
474 E = 1e-10;
475 for (j=0;j<N;j++)
476 {
Jean-Marc Valind501f612008-02-21 12:16:57 +1100477 P[j] = s*Y[best+N-j-1];
Jean-Marc Valinb4dfce42008-02-25 17:41:30 +1100478 E += NORM_SCALING_1*NORM_SCALING_1*P[j]*P[j];
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100479 }
480 E = pred_gain/sqrt(E);
481 for (j=0;j<N;j++)
482 P[j] *= E;
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100483 if (K==0)
484 {
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100485 for (j=0;j<N;j++)
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100486 x[j] = P[j];
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100487 }
488}
Jean-Marc Valin0e20ca02008-02-11 15:33:53 +1100489
Jean-Marc Valin18ddc022008-02-22 14:24:50 +1100490void intra_fold(celt_norm_t *x, int N, celt_norm_t *Y, celt_norm_t *P, int B, int N0, int Nmax)
Jean-Marc Valin0e20ca02008-02-11 15:33:53 +1100491{
Jean-Marc Valin0df0eb42008-02-13 16:00:10 +1100492 int i, j;
Jean-Marc Valin0e20ca02008-02-11 15:33:53 +1100493 float E;
494
495 E = 1e-10;
Jean-Marc Valin0df0eb42008-02-13 16:00:10 +1100496 if (N0 >= Nmax/2)
Jean-Marc Valin0e20ca02008-02-11 15:33:53 +1100497 {
Jean-Marc Valin0df0eb42008-02-13 16:00:10 +1100498 for (i=0;i<B;i++)
499 {
500 for (j=0;j<N/B;j++)
501 {
502 P[j*B+i] = Y[(Nmax-N0-j-1)*B+i];
Jean-Marc Valinb4dfce42008-02-25 17:41:30 +1100503 E += NORM_SCALING_1*NORM_SCALING_1*P[j*B+i]*P[j*B+i];
Jean-Marc Valin0df0eb42008-02-13 16:00:10 +1100504 }
505 }
506 } else {
507 for (j=0;j<N;j++)
508 {
509 P[j] = Y[j];
Jean-Marc Valinb4dfce42008-02-25 17:41:30 +1100510 E += NORM_SCALING_1*NORM_SCALING_1*P[j]*P[j];
Jean-Marc Valin0df0eb42008-02-13 16:00:10 +1100511 }
Jean-Marc Valin0e20ca02008-02-11 15:33:53 +1100512 }
513 E = 1.f/sqrt(E);
514 for (j=0;j<N;j++)
515 P[j] *= E;
516 for (j=0;j<N;j++)
517 x[j] = P[j];
518}
519