blob: 3827d875fb4ce26152bde8bdebfbab69f56f9c68 [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 Valin18ddc022008-02-22 14:24:50 +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 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 Valinb4dfce42008-02-25 17:41:30 +1100109 for (j=0;j<N;j++)
110 {
111 x[j] *= NORM_SCALING_1;
112 p[j] *= NORM_SCALING_1;
113 }
114
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100115 for (m=0;m<L;m++)
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100116 nbest[m] = &_nbest[m];
117
118 for (m=0;m<L;m++)
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100119 {
Jean-Marc Valin9a0bba12008-02-20 14:08:50 +1100120 ny[m] = &_ny[m*N];
121 iny[m] = &_iny[m*N];
122 y[m] = &_y[m*N];
123 iy[m] = &_iy[m*N];
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100124 }
125
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100126 for (j=0;j<N;j++)
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100127 {
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100128 Rpp += p[j]*p[j];
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100129 Rxp += x[j]*p[j];
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100130 }
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100131
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100132 /* We only need to initialise the zero because the first iteration only uses that */
133 for (i=0;i<N;i++)
134 y[0][i] = 0;
135 for (i=0;i<N;i++)
136 iy[0][i] = 0;
137 xy[0] = yy[0] = yp[0] = 0;
138
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100139 pulsesLeft = K;
140 while (pulsesLeft > 0)
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100141 {
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100142 int pulsesAtOnce=1;
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100143 int Lupdate = L;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100144 int L2 = L;
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100145
146 /* Decide on complexity strategy */
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100147 pulsesAtOnce = pulsesLeft/N;
148 if (pulsesAtOnce<1)
149 pulsesAtOnce = 1;
150 if (pulsesLeft-pulsesAtOnce > 3 || N > 30)
151 Lupdate = 1;
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100152 /*printf ("%d %d %d/%d %d\n", Lupdate, pulsesAtOnce, pulsesLeft, K, N);*/
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100153 L2 = Lupdate;
154 if (L2>maxL)
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100155 {
156 L2 = maxL;
157 maxL *= N;
158 }
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100159
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100160 for (m=0;m<Lupdate;m++)
Jean-Marc Valin883bd8e2008-02-15 00:34:01 +1100161 nbest[m]->score = -1e10f;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100162
163 for (m=0;m<L2;m++)
164 {
165 for (j=0;j<N;j++)
166 {
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100167 int sign;
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100168 /*if (x[j]>0) sign=1; else sign=-1;*/
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100169 for (sign=-1;sign<=1;sign+=2)
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100170 {
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100171 /*fprintf (stderr, "%d/%d %d/%d %d/%d\n", i, K, m, L2, j, N);*/
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100172 float tmp_xy, tmp_yy, tmp_yp;
173 float score;
174 float g;
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100175 float s = sign*pulsesAtOnce;
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100176
Jean-Marc Valin9a0bba12008-02-20 14:08:50 +1100177 /* All pulses at one location must have the same sign. */
178 if (iy[m][j]*sign < 0)
179 continue;
180
Jean-Marc Valina073c7b2008-02-14 16:58:04 +1100181 /* Updating the sums of the new pulse(s) */
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100182 tmp_xy = xy[m] + s*x[j] - alpha*s*p[j]*Rxp;
Jean-Marc Valin883bd8e2008-02-15 00:34:01 +1100183 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];
184 tmp_yp = yp[m] + s*p[j] *(1.f-alpha*Rpp);
Jean-Marc Valina073c7b2008-02-14 16:58:04 +1100185
186 /* Compute the gain such that ||p + g*y|| = 1 */
Jean-Marc Valin883bd8e2008-02-15 00:34:01 +1100187 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 +1100188 /* Knowing that gain, what the error: (x-g*y)^2
189 (result is negated and we discard x^2 because it's constant) */
Jean-Marc Valin883bd8e2008-02-15 00:34:01 +1100190 score = 2.f*g*tmp_xy - g*g*tmp_yy;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100191
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100192 if (score>nbest[Lupdate-1]->score)
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100193 {
Jean-Marc Valin472a5f02008-02-19 13:12:32 +1100194 int k;
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100195 int id = Lupdate-1;
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100196 struct NBest *tmp_best;
197
198 /* Save some pointers that would be deleted and use them for the current entry*/
199 tmp_best = nbest[Lupdate-1];
200 while (id > 0 && score > nbest[id-1]->score)
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100201 id--;
202
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100203 for (k=Lupdate-1;k>id;k--)
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100204 nbest[k] = nbest[k-1];
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100205
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100206 nbest[id] = tmp_best;
207 nbest[id]->score = score;
208 nbest[id]->pos = j;
209 nbest[id]->orig = m;
210 nbest[id]->sign = sign;
211 nbest[id]->gain = g;
212 nbest[id]->xy = tmp_xy;
213 nbest[id]->yy = tmp_yy;
214 nbest[id]->yp = tmp_yp;
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100215 }
Jean-Marc Valin636f5c82008-02-12 17:40:27 +1100216 }
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100217 }
Jean-Marc Valin636f5c82008-02-12 17:40:27 +1100218
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100219 }
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100220 /* Only now that we've made the final choice, update ny/iny and others */
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100221 for (k=0;k<Lupdate;k++)
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100222 {
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100223 int n;
224 int is;
225 float s;
226 is = nbest[k]->sign*pulsesAtOnce;
227 s = is;
228 for (n=0;n<N;n++)
229 ny[k][n] = y[nbest[k]->orig][n] - alpha*s*p[nbest[k]->pos]*p[n];
230 ny[k][nbest[k]->pos] += s;
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100231
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100232 for (n=0;n<N;n++)
233 iny[k][n] = iy[nbest[k]->orig][n];
234 iny[k][nbest[k]->pos] += is;
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100235
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100236 xy[k] = nbest[k]->xy;
237 yy[k] = nbest[k]->yy;
238 yp[k] = nbest[k]->yp;
239 }
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100240 /* Swap ny/iny with y/iy */
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100241 for (k=0;k<Lupdate;k++)
242 {
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100243 float *tmp_ny;
244 int *tmp_iny;
245
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100246 tmp_ny = ny[k];
247 ny[k] = y[k];
248 y[k] = tmp_ny;
249 tmp_iny = iny[k];
250 iny[k] = iy[k];
251 iy[k] = tmp_iny;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100252 }
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100253 pulsesLeft -= pulsesAtOnce;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100254 }
255
Jean-Marc Valinac1e03d2008-02-12 23:00:18 +1100256 if (0) {
257 float err=0;
258 for (i=0;i<N;i++)
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100259 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 +1100260 /*if (N<=10)
261 printf ("%f %d %d\n", err, K, N);*/
Jean-Marc Valinac1e03d2008-02-12 23:00:18 +1100262 }
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100263 for (i=0;i<N;i++)
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100264 x[i] = p[i]+nbest[0]->gain*y[0][i];
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100265 /* Sanity checks, don't bother */
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100266 if (0) {
267 float E=1e-15;
268 int ABS = 0;
269 for (i=0;i<N;i++)
270 ABS += abs(iy[0][i]);
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100271 /*if (K != ABS)
272 printf ("%d %d\n", K, ABS);*/
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100273 for (i=0;i<N;i++)
274 E += x[i]*x[i];
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100275 /*printf ("%f\n", E);*/
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100276 E = 1/sqrt(E);
277 for (i=0;i<N;i++)
278 x[i] *= E;
279 }
Jean-Marc Valin5fa59952008-02-14 13:50:44 +1100280
281 encode_pulses(iy[0], N, K, enc);
282
Jean-Marc Valina4833ff2008-01-10 15:34:00 +1100283 /* Recompute the gain in one pass to reduce the encoder-decoder mismatch
Jean-Marc Valin636f5c82008-02-12 17:40:27 +1100284 due to the recursive computation used in quantisation.
285 Not quite sure whether we need that or not */
Jean-Marc Valina4833ff2008-01-10 15:34:00 +1100286 if (1) {
Jean-Marc Valin4a897682007-12-12 00:45:15 +1100287 float Ryp=0;
Jean-Marc Valin4a897682007-12-12 00:45:15 +1100288 float Ryy=0;
289 float g=0;
Jean-Marc Valin4a897682007-12-12 00:45:15 +1100290
291 for (i=0;i<N;i++)
292 Ryp += iy[0][i]*p[i];
293
294 for (i=0;i<N;i++)
295 y[0][i] = iy[0][i] - alpha*Ryp*p[i];
296
Jean-Marc Valin4a897682007-12-12 00:45:15 +1100297 Ryp = 0;
298 for (i=0;i<N;i++)
299 Ryp += y[0][i]*p[i];
300
301 for (i=0;i<N;i++)
302 Ryy += y[0][i]*y[0][i];
303
304 g = (sqrt(Ryp*Ryp + Ryy - Ryy*Rpp) - Ryp)/Ryy;
305
306 for (i=0;i<N;i++)
307 x[i] = p[i] + g*y[0][i];
308
309 }
Jean-Marc Valinb4dfce42008-02-25 17:41:30 +1100310 for (j=0;j<N;j++)
311 {
312 x[j] *= NORM_SCALING;
313 p[j] *= NORM_SCALING;
314 }
Jean-Marc Valin4a897682007-12-12 00:45:15 +1100315
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100316}
317
Jean-Marc Valin879fbfd2008-02-20 17:17:13 +1100318/** Decode pulse vector and combine the result with the pitch vector to produce
319 the final normalised signal in the current band. */
Jean-Marc Valin18ddc022008-02-22 14:24:50 +1100320void 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 +1100321{
322 int i;
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100323 float Rpp=0, Ryp=0, Ryy=0;
324 float g;
Jean-Marc Valin9a0bba12008-02-20 14:08:50 +1100325 VARDECL(int *iy);
326 VARDECL(float *y);
327
328 ALLOC(iy, N, int);
329 ALLOC(y, N, float);
Jean-Marc Valin25298f22007-12-03 15:24:11 +1100330
Jean-Marc Valin5fa59952008-02-14 13:50:44 +1100331 decode_pulses(iy, N, K, dec);
Jean-Marc Valinb4dfce42008-02-25 17:41:30 +1100332 for (i=0;i<N;i++)
333 {
334 x[i] *= NORM_SCALING_1;
335 p[i] *= NORM_SCALING_1;
336 }
Jean-Marc Valin5fa59952008-02-14 13:50:44 +1100337
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100338 /*for (i=0;i<N;i++)
339 printf ("%d ", iy[i]);*/
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100340 for (i=0;i<N;i++)
341 Rpp += p[i]*p[i];
342
343 for (i=0;i<N;i++)
344 Ryp += iy[i]*p[i];
345
346 for (i=0;i<N;i++)
347 y[i] = iy[i] - alpha*Ryp*p[i];
348
349 /* Recompute after the projection (I think it's right) */
350 Ryp = 0;
351 for (i=0;i<N;i++)
352 Ryp += y[i]*p[i];
353
354 for (i=0;i<N;i++)
355 Ryy += y[i]*y[i];
356
357 g = (sqrt(Ryp*Ryp + Ryy - Ryy*Rpp) - Ryp)/Ryy;
358
359 for (i=0;i<N;i++)
360 x[i] = p[i] + g*y[i];
Jean-Marc Valinb4dfce42008-02-25 17:41:30 +1100361 for (i=0;i<N;i++)
362 {
363 x[i] *= NORM_SCALING;
364 p[i] *= NORM_SCALING;
365 }
366
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100367}
368
369
370static const float pg[11] = {1.f, .75f, .65f, 0.6f, 0.6f, .6f, .55f, .55f, .5f, .5f, .5f};
371
Jean-Marc Valin18ddc022008-02-22 14:24:50 +1100372void 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 +1100373{
374 int i,j;
375 int best=0;
Jean-Marc Valin50d11162007-12-03 14:34:52 +1100376 float best_score=0;
377 float s = 1;
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100378 int sign;
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100379 float E;
Jean-Marc Valin9a0bba12008-02-20 14:08:50 +1100380 float pred_gain;
Jean-Marc Valin8f0f4b92008-02-11 13:52:44 +1100381 int max_pos = N0-N/B;
382 if (max_pos > 32)
383 max_pos = 32;
384
385 for (i=0;i<max_pos*B;i+=B)
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100386 {
387 int j;
388 float xy=0, yy=0;
389 float score;
390 for (j=0;j<N;j++)
391 {
Jean-Marc Valinb4dfce42008-02-25 17:41:30 +1100392 xy += 1.f*x[j]*Y[i+N-j-1];
393 yy += 1.f*Y[i+N-j-1]*Y[i+N-j-1];
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100394 }
Jean-Marc Valin50d11162007-12-03 14:34:52 +1100395 score = xy*xy/(.001+yy);
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100396 if (score > best_score)
397 {
398 best_score = score;
399 best = i;
Jean-Marc Valin50d11162007-12-03 14:34:52 +1100400 if (xy>0)
401 s = 1;
402 else
403 s = -1;
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100404 }
405 }
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100406 if (s<0)
407 sign = 1;
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100408 else
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100409 sign = 0;
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100410 /*printf ("%d %d ", sign, best);*/
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100411 ec_enc_uint(enc,sign,2);
Jean-Marc Valin8f0f4b92008-02-11 13:52:44 +1100412 ec_enc_uint(enc,best/B,max_pos);
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100413 /*printf ("%d %f\n", best, best_score);*/
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100414
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100415 if (K>10)
416 pred_gain = pg[10];
417 else
418 pred_gain = pg[K];
419 E = 1e-10;
420 for (j=0;j<N;j++)
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100421 {
Jean-Marc Valind501f612008-02-21 12:16:57 +1100422 P[j] = s*Y[best+N-j-1];
Jean-Marc Valinb4dfce42008-02-25 17:41:30 +1100423 E += NORM_SCALING_1*NORM_SCALING_1*P[j]*P[j];
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100424 }
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100425 E = pred_gain/sqrt(E);
426 for (j=0;j<N;j++)
427 P[j] *= E;
428 if (K>0)
429 {
430 for (j=0;j<N;j++)
431 x[j] -= P[j];
432 } else {
433 for (j=0;j<N;j++)
434 x[j] = P[j];
435 }
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100436 /*printf ("quant ");*/
437 /*for (j=0;j<N;j++) printf ("%f ", P[j]);*/
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100438
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100439}
Jean-Marc Valinfc08d0a2007-12-07 13:26:15 +1100440
Jean-Marc Valin18ddc022008-02-22 14:24:50 +1100441void 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 +1100442{
Jean-Marc Valin11f01722007-12-09 01:19:36 +1100443 int j;
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100444 int sign;
445 float s;
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100446 int best;
447 float E;
Jean-Marc Valin9a0bba12008-02-20 14:08:50 +1100448 float pred_gain;
Jean-Marc Valin8f0f4b92008-02-11 13:52:44 +1100449 int max_pos = N0-N/B;
450 if (max_pos > 32)
451 max_pos = 32;
452
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100453 sign = ec_dec_uint(dec, 2);
454 if (sign == 0)
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100455 s = 1;
456 else
457 s = -1;
458
Jean-Marc Valin8f0f4b92008-02-11 13:52:44 +1100459 best = B*ec_dec_uint(dec, max_pos);
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100460 /*printf ("%d %d ", sign, best);*/
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100461
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100462 if (K>10)
463 pred_gain = pg[10];
464 else
465 pred_gain = pg[K];
466 E = 1e-10;
467 for (j=0;j<N;j++)
468 {
Jean-Marc Valind501f612008-02-21 12:16:57 +1100469 P[j] = s*Y[best+N-j-1];
Jean-Marc Valinb4dfce42008-02-25 17:41:30 +1100470 E += NORM_SCALING_1*NORM_SCALING_1*P[j]*P[j];
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100471 }
472 E = pred_gain/sqrt(E);
473 for (j=0;j<N;j++)
474 P[j] *= E;
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100475 if (K==0)
476 {
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100477 for (j=0;j<N;j++)
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100478 x[j] = P[j];
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100479 }
480}
Jean-Marc Valin0e20ca02008-02-11 15:33:53 +1100481
Jean-Marc Valin18ddc022008-02-22 14:24:50 +1100482void 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 +1100483{
Jean-Marc Valin0df0eb42008-02-13 16:00:10 +1100484 int i, j;
Jean-Marc Valin0e20ca02008-02-11 15:33:53 +1100485 float E;
486
487 E = 1e-10;
Jean-Marc Valin0df0eb42008-02-13 16:00:10 +1100488 if (N0 >= Nmax/2)
Jean-Marc Valin0e20ca02008-02-11 15:33:53 +1100489 {
Jean-Marc Valin0df0eb42008-02-13 16:00:10 +1100490 for (i=0;i<B;i++)
491 {
492 for (j=0;j<N/B;j++)
493 {
494 P[j*B+i] = Y[(Nmax-N0-j-1)*B+i];
Jean-Marc Valinb4dfce42008-02-25 17:41:30 +1100495 E += NORM_SCALING_1*NORM_SCALING_1*P[j*B+i]*P[j*B+i];
Jean-Marc Valin0df0eb42008-02-13 16:00:10 +1100496 }
497 }
498 } else {
499 for (j=0;j<N;j++)
500 {
501 P[j] = Y[j];
Jean-Marc Valinb4dfce42008-02-25 17:41:30 +1100502 E += NORM_SCALING_1*NORM_SCALING_1*P[j]*P[j];
Jean-Marc Valin0df0eb42008-02-13 16:00:10 +1100503 }
Jean-Marc Valin0e20ca02008-02-11 15:33:53 +1100504 }
505 E = 1.f/sqrt(E);
506 for (j=0;j<N;j++)
507 P[j] *= E;
508 for (j=0;j<N;j++)
509 x[j] = P[j];
510}
511