blob: ff877bb02ce57f70665d3c45499aede91487e0fb [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 Valinb60340f2008-02-26 15:41:51 +110041#include "os_support.h"
Jean-Marc Valin41af4212007-11-30 18:35:37 +110042
Jean-Marc Valin883bd8e2008-02-15 00:34:01 +110043/* Enable this or define your own implementation if you want to speed up the
44 VQ search (used in inner loop only) */
45#if 0
46#include <xmmintrin.h>
47static inline float approx_sqrt(float x)
48{
49 _mm_store_ss(&x, _mm_sqrt_ss(_mm_set_ss(x)));
50 return x;
51}
52static inline float approx_inv(float x)
53{
54 _mm_store_ss(&x, _mm_rcp_ss(_mm_set_ss(x)));
55 return x;
56}
57#else
58#define approx_sqrt(x) (sqrt(x))
59#define approx_inv(x) (1.f/(x))
60#endif
61
Jean-Marc Valind4018c32008-02-27 10:09:48 +110062/** Takes the pitch vector and the decoded residual vector (non-compressed),
63 applies the compression in the pitch direction, computes the gain that will
64 give ||p+g*y||=1 and mixes the residual with the pitch. */
65static void mix_pitch_and_residual(int *iy, celt_norm_t *X, int N, celt_norm_t *P, float alpha)
66{
67 int i;
68 float Rpp=0, Ryp=0, Ryy=0;
69 float g;
70 VARDECL(float *y);
71 VARDECL(float *x);
72 VARDECL(float *p);
73
74 ALLOC(y, N, float);
75 ALLOC(x, N, float);
76 ALLOC(p, N, float);
77
78 for (i=0;i<N;i++)
79 p[i] = P[i]*NORM_SCALING_1;
80
81 /*for (i=0;i<N;i++)
82 printf ("%d ", iy[i]);*/
83 for (i=0;i<N;i++)
84 Rpp += p[i]*p[i];
85
86 for (i=0;i<N;i++)
87 Ryp += iy[i]*p[i];
88
89 for (i=0;i<N;i++)
90 y[i] = iy[i] - alpha*Ryp*p[i];
91
92 /* Recompute after the projection (I think it's right) */
93 Ryp = 0;
94 for (i=0;i<N;i++)
95 Ryp += y[i]*p[i];
96
97 for (i=0;i<N;i++)
98 Ryy += y[i]*y[i];
99
100 g = (sqrt(Ryp*Ryp + Ryy - Ryy*Rpp) - Ryp)/Ryy;
101
102 for (i=0;i<N;i++)
103 X[i] = P[i] + NORM_SCALING*g*y[i];
104}
105
Jean-Marc Valin879fbfd2008-02-20 17:17:13 +1100106/** All the info necessary to keep track of a hypothesis during the search */
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100107struct NBest {
108 float score;
109 float gain;
110 int sign;
111 int pos;
112 int orig;
113 float xy;
114 float yy;
115 float yp;
116};
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100117
Jean-Marc Valin5f09ea52008-02-26 16:43:04 +1100118void alg_quant(celt_norm_t *X, celt_mask_t *W, int N, int K, celt_norm_t *P, float alpha, ec_enc *enc)
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100119{
Jean-Marc Valin4a897682007-12-12 00:45:15 +1100120 int L = 3;
Jean-Marc Valin2fa8aff2008-02-26 11:38:00 +1100121 VARDECL(float *x);
122 VARDECL(float *p);
Jean-Marc Valin9a0bba12008-02-20 14:08:50 +1100123 VARDECL(float *_y);
124 VARDECL(float *_ny);
125 VARDECL(int *_iy);
126 VARDECL(int *_iny);
127 VARDECL(float **y);
128 VARDECL(float **ny);
129 VARDECL(int **iy);
130 VARDECL(int **iny);
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100131 int i, j, k, m;
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100132 int pulsesLeft;
Jean-Marc Valin9a0bba12008-02-20 14:08:50 +1100133 VARDECL(float *xy);
134 VARDECL(float *yy);
135 VARDECL(float *yp);
136 VARDECL(struct NBest *_nbest);
137 VARDECL(struct NBest **nbest);
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100138 float Rpp=0, Rxp=0;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100139 int maxL = 1;
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100140
Jean-Marc Valin2fa8aff2008-02-26 11:38:00 +1100141 ALLOC(x, N, float);
142 ALLOC(p, N, float);
Jean-Marc Valin9a0bba12008-02-20 14:08:50 +1100143 ALLOC(_y, L*N, float);
144 ALLOC(_ny, L*N, float);
145 ALLOC(_iy, L*N, int);
146 ALLOC(_iny, L*N, int);
147 ALLOC(y, L*N, float*);
148 ALLOC(ny, L*N, float*);
149 ALLOC(iy, L*N, int*);
150 ALLOC(iny, L*N, int*);
151
152 ALLOC(xy, L, float);
153 ALLOC(yy, L, float);
154 ALLOC(yp, L, float);
155 ALLOC(_nbest, L, struct NBest);
156 ALLOC(nbest, L, struct NBest *);
157
Jean-Marc Valinb4dfce42008-02-25 17:41:30 +1100158 for (j=0;j<N;j++)
159 {
Jean-Marc Valin2fa8aff2008-02-26 11:38:00 +1100160 x[j] = X[j]*NORM_SCALING_1;
161 p[j] = P[j]*NORM_SCALING_1;
Jean-Marc Valinb4dfce42008-02-25 17:41:30 +1100162 }
163
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100164 for (m=0;m<L;m++)
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100165 nbest[m] = &_nbest[m];
166
167 for (m=0;m<L;m++)
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100168 {
Jean-Marc Valin9a0bba12008-02-20 14:08:50 +1100169 ny[m] = &_ny[m*N];
170 iny[m] = &_iny[m*N];
171 y[m] = &_y[m*N];
172 iy[m] = &_iy[m*N];
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100173 }
174
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100175 for (j=0;j<N;j++)
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100176 {
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100177 Rpp += p[j]*p[j];
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100178 Rxp += x[j]*p[j];
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100179 }
Jean-Marc Valinb60340f2008-02-26 15:41:51 +1100180 if (Rpp>1)
181 celt_fatal("Rpp > 1");
182
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100183 /* We only need to initialise the zero because the first iteration only uses that */
184 for (i=0;i<N;i++)
185 y[0][i] = 0;
186 for (i=0;i<N;i++)
187 iy[0][i] = 0;
188 xy[0] = yy[0] = yp[0] = 0;
189
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100190 pulsesLeft = K;
191 while (pulsesLeft > 0)
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100192 {
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100193 int pulsesAtOnce=1;
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100194 int Lupdate = L;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100195 int L2 = L;
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100196
197 /* Decide on complexity strategy */
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100198 pulsesAtOnce = pulsesLeft/N;
199 if (pulsesAtOnce<1)
200 pulsesAtOnce = 1;
201 if (pulsesLeft-pulsesAtOnce > 3 || N > 30)
202 Lupdate = 1;
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100203 /*printf ("%d %d %d/%d %d\n", Lupdate, pulsesAtOnce, pulsesLeft, K, N);*/
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100204 L2 = Lupdate;
205 if (L2>maxL)
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100206 {
207 L2 = maxL;
208 maxL *= N;
209 }
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100210
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100211 for (m=0;m<Lupdate;m++)
Jean-Marc Valin883bd8e2008-02-15 00:34:01 +1100212 nbest[m]->score = -1e10f;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100213
214 for (m=0;m<L2;m++)
215 {
216 for (j=0;j<N;j++)
217 {
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100218 int sign;
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100219 /*if (x[j]>0) sign=1; else sign=-1;*/
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100220 for (sign=-1;sign<=1;sign+=2)
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100221 {
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100222 /*fprintf (stderr, "%d/%d %d/%d %d/%d\n", i, K, m, L2, j, N);*/
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100223 float tmp_xy, tmp_yy, tmp_yp;
224 float score;
225 float g;
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100226 float s = sign*pulsesAtOnce;
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100227
Jean-Marc Valin9a0bba12008-02-20 14:08:50 +1100228 /* All pulses at one location must have the same sign. */
229 if (iy[m][j]*sign < 0)
230 continue;
231
Jean-Marc Valina073c7b2008-02-14 16:58:04 +1100232 /* Updating the sums of the new pulse(s) */
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100233 tmp_xy = xy[m] + s*x[j] - alpha*s*p[j]*Rxp;
Jean-Marc Valin883bd8e2008-02-15 00:34:01 +1100234 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];
235 tmp_yp = yp[m] + s*p[j] *(1.f-alpha*Rpp);
Jean-Marc Valina073c7b2008-02-14 16:58:04 +1100236
237 /* Compute the gain such that ||p + g*y|| = 1 */
Jean-Marc Valin883bd8e2008-02-15 00:34:01 +1100238 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 +1100239 /* Knowing that gain, what the error: (x-g*y)^2
240 (result is negated and we discard x^2 because it's constant) */
Jean-Marc Valin883bd8e2008-02-15 00:34:01 +1100241 score = 2.f*g*tmp_xy - g*g*tmp_yy;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100242
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100243 if (score>nbest[Lupdate-1]->score)
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100244 {
Jean-Marc Valin472a5f02008-02-19 13:12:32 +1100245 int k;
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100246 int id = Lupdate-1;
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100247 struct NBest *tmp_best;
248
249 /* Save some pointers that would be deleted and use them for the current entry*/
250 tmp_best = nbest[Lupdate-1];
251 while (id > 0 && score > nbest[id-1]->score)
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100252 id--;
253
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100254 for (k=Lupdate-1;k>id;k--)
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100255 nbest[k] = nbest[k-1];
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100256
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100257 nbest[id] = tmp_best;
258 nbest[id]->score = score;
259 nbest[id]->pos = j;
260 nbest[id]->orig = m;
261 nbest[id]->sign = sign;
262 nbest[id]->gain = g;
263 nbest[id]->xy = tmp_xy;
264 nbest[id]->yy = tmp_yy;
265 nbest[id]->yp = tmp_yp;
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100266 }
Jean-Marc Valin636f5c82008-02-12 17:40:27 +1100267 }
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100268 }
Jean-Marc Valin636f5c82008-02-12 17:40:27 +1100269
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100270 }
Jean-Marc Valinb60340f2008-02-26 15:41:51 +1100271
272 if (!(nbest[0]->score > -1e10f))
273 celt_fatal("Could not find any match in VQ codebook. Something got corrupted somewhere.");
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100274 /* Only now that we've made the final choice, update ny/iny and others */
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100275 for (k=0;k<Lupdate;k++)
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100276 {
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100277 int n;
278 int is;
279 float s;
280 is = nbest[k]->sign*pulsesAtOnce;
281 s = is;
282 for (n=0;n<N;n++)
283 ny[k][n] = y[nbest[k]->orig][n] - alpha*s*p[nbest[k]->pos]*p[n];
284 ny[k][nbest[k]->pos] += s;
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100285
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100286 for (n=0;n<N;n++)
287 iny[k][n] = iy[nbest[k]->orig][n];
288 iny[k][nbest[k]->pos] += is;
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100289
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100290 xy[k] = nbest[k]->xy;
291 yy[k] = nbest[k]->yy;
292 yp[k] = nbest[k]->yp;
293 }
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100294 /* Swap ny/iny with y/iy */
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100295 for (k=0;k<Lupdate;k++)
296 {
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100297 float *tmp_ny;
298 int *tmp_iny;
299
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100300 tmp_ny = ny[k];
301 ny[k] = y[k];
302 y[k] = tmp_ny;
303 tmp_iny = iny[k];
304 iny[k] = iy[k];
305 iy[k] = tmp_iny;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100306 }
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100307 pulsesLeft -= pulsesAtOnce;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100308 }
309
Jean-Marc Valind4018c32008-02-27 10:09:48 +1100310#if 0
Jean-Marc Valinac1e03d2008-02-12 23:00:18 +1100311 if (0) {
312 float err=0;
313 for (i=0;i<N;i++)
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100314 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 +1100315 /*if (N<=10)
316 printf ("%f %d %d\n", err, K, N);*/
Jean-Marc Valinac1e03d2008-02-12 23:00:18 +1100317 }
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100318 /* Sanity checks, don't bother */
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100319 if (0) {
Jean-Marc Valind4018c32008-02-27 10:09:48 +1100320 for (i=0;i<N;i++)
321 x[i] = p[i]+nbest[0]->gain*y[0][i];
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100322 float E=1e-15;
323 int ABS = 0;
324 for (i=0;i<N;i++)
325 ABS += abs(iy[0][i]);
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100326 /*if (K != ABS)
327 printf ("%d %d\n", K, ABS);*/
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100328 for (i=0;i<N;i++)
329 E += x[i]*x[i];
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100330 /*printf ("%f\n", E);*/
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100331 E = 1/sqrt(E);
332 for (i=0;i<N;i++)
333 x[i] *= E;
334 }
Jean-Marc Valind4018c32008-02-27 10:09:48 +1100335#endif
Jean-Marc Valin5fa59952008-02-14 13:50:44 +1100336
337 encode_pulses(iy[0], N, K, enc);
338
Jean-Marc Valina4833ff2008-01-10 15:34:00 +1100339 /* Recompute the gain in one pass to reduce the encoder-decoder mismatch
Jean-Marc Valin636f5c82008-02-12 17:40:27 +1100340 due to the recursive computation used in quantisation.
341 Not quite sure whether we need that or not */
Jean-Marc Valind4018c32008-02-27 10:09:48 +1100342 mix_pitch_and_residual(iy[0], X, N, P, alpha);
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100343}
344
Jean-Marc Valin879fbfd2008-02-20 17:17:13 +1100345/** Decode pulse vector and combine the result with the pitch vector to produce
346 the final normalised signal in the current band. */
Jean-Marc Valin2fa8aff2008-02-26 11:38:00 +1100347void 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 +1100348{
Jean-Marc Valin9a0bba12008-02-20 14:08:50 +1100349 VARDECL(int *iy);
Jean-Marc Valin9a0bba12008-02-20 14:08:50 +1100350 ALLOC(iy, N, int);
Jean-Marc Valin5fa59952008-02-14 13:50:44 +1100351 decode_pulses(iy, N, K, dec);
Jean-Marc Valind4018c32008-02-27 10:09:48 +1100352 mix_pitch_and_residual(iy, X, N, P, alpha);
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100353}
354
355
356static const float pg[11] = {1.f, .75f, .65f, 0.6f, 0.6f, .6f, .55f, .55f, .5f, .5f, .5f};
357
Jean-Marc Valin5f09ea52008-02-26 16:43:04 +1100358void intra_prediction(celt_norm_t *x, celt_mask_t *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 +1100359{
360 int i,j;
361 int best=0;
Jean-Marc Valin50d11162007-12-03 14:34:52 +1100362 float best_score=0;
363 float s = 1;
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100364 int sign;
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100365 float E;
Jean-Marc Valin9a0bba12008-02-20 14:08:50 +1100366 float pred_gain;
Jean-Marc Valin8f0f4b92008-02-11 13:52:44 +1100367 int max_pos = N0-N/B;
368 if (max_pos > 32)
369 max_pos = 32;
370
371 for (i=0;i<max_pos*B;i+=B)
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100372 {
373 int j;
374 float xy=0, yy=0;
375 float score;
376 for (j=0;j<N;j++)
377 {
Jean-Marc Valinb4dfce42008-02-25 17:41:30 +1100378 xy += 1.f*x[j]*Y[i+N-j-1];
379 yy += 1.f*Y[i+N-j-1]*Y[i+N-j-1];
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100380 }
Jean-Marc Valin50d11162007-12-03 14:34:52 +1100381 score = xy*xy/(.001+yy);
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100382 if (score > best_score)
383 {
384 best_score = score;
385 best = i;
Jean-Marc Valin50d11162007-12-03 14:34:52 +1100386 if (xy>0)
387 s = 1;
388 else
389 s = -1;
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100390 }
391 }
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100392 if (s<0)
393 sign = 1;
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100394 else
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100395 sign = 0;
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100396 /*printf ("%d %d ", sign, best);*/
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100397 ec_enc_uint(enc,sign,2);
Jean-Marc Valin8f0f4b92008-02-11 13:52:44 +1100398 ec_enc_uint(enc,best/B,max_pos);
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100399 /*printf ("%d %f\n", best, best_score);*/
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100400
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100401 if (K>10)
402 pred_gain = pg[10];
403 else
404 pred_gain = pg[K];
405 E = 1e-10;
406 for (j=0;j<N;j++)
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100407 {
Jean-Marc Valind501f612008-02-21 12:16:57 +1100408 P[j] = s*Y[best+N-j-1];
Jean-Marc Valinb4dfce42008-02-25 17:41:30 +1100409 E += NORM_SCALING_1*NORM_SCALING_1*P[j]*P[j];
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100410 }
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100411 E = pred_gain/sqrt(E);
412 for (j=0;j<N;j++)
413 P[j] *= E;
414 if (K>0)
415 {
416 for (j=0;j<N;j++)
417 x[j] -= P[j];
418 } else {
419 for (j=0;j<N;j++)
420 x[j] = P[j];
421 }
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100422 /*printf ("quant ");*/
423 /*for (j=0;j<N;j++) printf ("%f ", P[j]);*/
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100424
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100425}
Jean-Marc Valinfc08d0a2007-12-07 13:26:15 +1100426
Jean-Marc Valin18ddc022008-02-22 14:24:50 +1100427void 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 +1100428{
Jean-Marc Valin11f01722007-12-09 01:19:36 +1100429 int j;
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100430 int sign;
431 float s;
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100432 int best;
433 float E;
Jean-Marc Valin9a0bba12008-02-20 14:08:50 +1100434 float pred_gain;
Jean-Marc Valin8f0f4b92008-02-11 13:52:44 +1100435 int max_pos = N0-N/B;
436 if (max_pos > 32)
437 max_pos = 32;
438
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100439 sign = ec_dec_uint(dec, 2);
440 if (sign == 0)
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100441 s = 1;
442 else
443 s = -1;
444
Jean-Marc Valin8f0f4b92008-02-11 13:52:44 +1100445 best = B*ec_dec_uint(dec, max_pos);
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100446 /*printf ("%d %d ", sign, best);*/
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100447
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100448 if (K>10)
449 pred_gain = pg[10];
450 else
451 pred_gain = pg[K];
452 E = 1e-10;
453 for (j=0;j<N;j++)
454 {
Jean-Marc Valind501f612008-02-21 12:16:57 +1100455 P[j] = s*Y[best+N-j-1];
Jean-Marc Valinb4dfce42008-02-25 17:41:30 +1100456 E += NORM_SCALING_1*NORM_SCALING_1*P[j]*P[j];
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100457 }
458 E = pred_gain/sqrt(E);
459 for (j=0;j<N;j++)
460 P[j] *= E;
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100461 if (K==0)
462 {
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100463 for (j=0;j<N;j++)
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100464 x[j] = P[j];
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100465 }
466}
Jean-Marc Valin0e20ca02008-02-11 15:33:53 +1100467
Jean-Marc Valin18ddc022008-02-22 14:24:50 +1100468void 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 +1100469{
Jean-Marc Valin0df0eb42008-02-13 16:00:10 +1100470 int i, j;
Jean-Marc Valin0e20ca02008-02-11 15:33:53 +1100471 float E;
472
473 E = 1e-10;
Jean-Marc Valin0df0eb42008-02-13 16:00:10 +1100474 if (N0 >= Nmax/2)
Jean-Marc Valin0e20ca02008-02-11 15:33:53 +1100475 {
Jean-Marc Valin0df0eb42008-02-13 16:00:10 +1100476 for (i=0;i<B;i++)
477 {
478 for (j=0;j<N/B;j++)
479 {
480 P[j*B+i] = Y[(Nmax-N0-j-1)*B+i];
Jean-Marc Valinb4dfce42008-02-25 17:41:30 +1100481 E += NORM_SCALING_1*NORM_SCALING_1*P[j*B+i]*P[j*B+i];
Jean-Marc Valin0df0eb42008-02-13 16:00:10 +1100482 }
483 }
484 } else {
485 for (j=0;j<N;j++)
486 {
487 P[j] = Y[j];
Jean-Marc Valinb4dfce42008-02-25 17:41:30 +1100488 E += NORM_SCALING_1*NORM_SCALING_1*P[j]*P[j];
Jean-Marc Valin0df0eb42008-02-13 16:00:10 +1100489 }
Jean-Marc Valin0e20ca02008-02-11 15:33:53 +1100490 }
491 E = 1.f/sqrt(E);
492 for (j=0;j<N;j++)
493 P[j] *= E;
494 for (j=0;j<N;j++)
495 x[j] = P[j];
496}
497