blob: 5ae7f545d237efbd1d962c9f89b8e32dc5c61b7a [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 Valin3b277dc2008-02-14 16:46:50 +110037struct NBest {
38 float score;
39 float gain;
40 int sign;
41 int pos;
42 int orig;
43 float xy;
44 float yy;
45 float yp;
46};
Jean-Marc Valin41af4212007-11-30 18:35:37 +110047
48/* Improved algebraic pulse-base quantiser. The signal x is replaced by the sum of the pitch
49 a combination of pulses such that its norm is still equal to 1. The only difference with
50 the quantiser above is that the search is more complete. */
Jean-Marc Valin46014ca2007-12-14 13:47:04 +110051void 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 +110052{
Jean-Marc Valin4a897682007-12-12 00:45:15 +110053 int L = 3;
Jean-Marc Valin41af4212007-11-30 18:35:37 +110054 //float tata[200];
Jean-Marc Valinfe419832008-02-12 15:05:01 +110055 float _y[L][N];
56 int _iy[L][N];
Jean-Marc Valin41af4212007-11-30 18:35:37 +110057 //float tata2[200];
Jean-Marc Valinfe419832008-02-12 15:05:01 +110058 float _ny[L][N];
59 int _iny[L][N];
60 float *(ny[L]), *(y[L]);
61 int *(iny[L]), *(iy[L]);
Jean-Marc Valin41af4212007-11-30 18:35:37 +110062 int i, j, m;
Jean-Marc Valin846d4e22008-02-12 13:48:48 +110063 int pulsesLeft;
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +110064 float xy[L];
65 float yy[L];
66 float yp[L];
67 struct NBest _nbest[L];
68 struct NBest *(nbest[L]);
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +110069 float Rpp=0, Rxp=0;
Jean-Marc Valin41af4212007-11-30 18:35:37 +110070 int maxL = 1;
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +110071
Jean-Marc Valinfe419832008-02-12 15:05:01 +110072 for (m=0;m<L;m++)
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +110073 nbest[m] = &_nbest[m];
74
75 for (m=0;m<L;m++)
Jean-Marc Valinfe419832008-02-12 15:05:01 +110076 {
77 ny[m] = _ny[m];
78 iny[m] = _iny[m];
79 y[m] = _y[m];
80 iy[m] = _iy[m];
81 }
82
Jean-Marc Valin41af4212007-11-30 18:35:37 +110083 for (j=0;j<N;j++)
84 Rpp += p[j]*p[j];
Jean-Marc Valinfc08d0a2007-12-07 13:26:15 +110085 //if (Rpp>.01)
86 // alpha = (1-sqrt(1-Rpp))/Rpp;
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +110087 for (j=0;j<N;j++)
88 Rxp += x[j]*p[j];
Jean-Marc Valin41af4212007-11-30 18:35:37 +110089 for (m=0;m<L;m++)
90 for (i=0;i<N;i++)
91 y[m][i] = 0;
92
93 for (m=0;m<L;m++)
94 for (i=0;i<N;i++)
95 ny[m][i] = 0;
96
97 for (m=0;m<L;m++)
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +110098 for (i=0;i<N;i++)
99 iy[m][i] = iny[m][i] = 0;
100
101 for (m=0;m<L;m++)
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100102 xy[m] = yy[m] = yp[m] = 0;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100103
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100104 pulsesLeft = K;
105 while (pulsesLeft > 0)
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100106 {
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100107 int pulsesAtOnce=1;
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100108 int Lupdate = L;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100109 int L2 = L;
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100110 pulsesAtOnce = pulsesLeft/N;
111 if (pulsesAtOnce<1)
112 pulsesAtOnce = 1;
113 if (pulsesLeft-pulsesAtOnce > 3 || N > 30)
114 Lupdate = 1;
115 //printf ("%d %d %d/%d %d\n", Lupdate, pulsesAtOnce, pulsesLeft, K, N);
116 L2 = Lupdate;
117 if (L2>maxL)
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100118 {
119 L2 = maxL;
120 maxL *= N;
121 }
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100122
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100123 for (m=0;m<L;m++)
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100124 nbest[m]->score = -1e10;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100125
126 for (m=0;m<L2;m++)
127 {
128 for (j=0;j<N;j++)
129 {
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100130 int sign;
Jean-Marc Valinac1e03d2008-02-12 23:00:18 +1100131 //if (x[j]>0) sign=1; else sign=-1;
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100132 for (sign=-1;sign<=1;sign+=2)
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100133 {
Jean-Marc Valinc9cc6d32008-02-13 11:37:41 +1100134 /* All pulses at one location must have the same sign. Also,
135 only consider sign in the same direction as x[j], except for the
136 last pulses */
Jean-Marc Valinac1e03d2008-02-12 23:00:18 +1100137 if (iy[m][j]*sign < 0 || (x[j]*sign<0 && pulsesLeft>((K+1)>>1)))
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100138 continue;
139 //fprintf (stderr, "%d/%d %d/%d %d/%d\n", i, K, m, L2, j, N);
140 float tmp_xy, tmp_yy, tmp_yp;
141 float score;
142 float g;
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100143 float s = sign*pulsesAtOnce;
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100144
145 /* Updating the sums the the new pulse(s) */
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100146 tmp_xy = xy[m] + s*x[j] - alpha*s*p[j]*Rxp;
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100147 tmp_yy = yy[m] + 2*s*y[m][j] + s*s +s*s*alpha*alpha*p[j]*p[j]*Rpp - 2*alpha*s*p[j]*yp[m] - 2*s*s*alpha*p[j]*p[j];
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100148 tmp_yp = yp[m] + s*p[j] *(1-alpha*Rpp);
149 g = (sqrt(tmp_yp*tmp_yp + tmp_yy - tmp_yy*Rpp) - tmp_yp)/tmp_yy;
150 score = 2*g*tmp_xy - g*g*tmp_yy;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100151
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100152 if (score>nbest[Lupdate-1]->score)
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100153 {
154 int k, n;
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100155 int id = Lupdate-1;
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100156 struct NBest *tmp_best;
157
158 /* Save some pointers that would be deleted and use them for the current entry*/
159 tmp_best = nbest[Lupdate-1];
160 while (id > 0 && score > nbest[id-1]->score)
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100161 id--;
162
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100163 for (k=Lupdate-1;k>id;k--)
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100164 nbest[k] = nbest[k-1];
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100165
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100166 nbest[id] = tmp_best;
167 nbest[id]->score = score;
168 nbest[id]->pos = j;
169 nbest[id]->orig = m;
170 nbest[id]->sign = sign;
171 nbest[id]->gain = g;
172 nbest[id]->xy = tmp_xy;
173 nbest[id]->yy = tmp_yy;
174 nbest[id]->yp = tmp_yp;
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100175 }
Jean-Marc Valin636f5c82008-02-12 17:40:27 +1100176 }
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100177 }
Jean-Marc Valin636f5c82008-02-12 17:40:27 +1100178
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100179 }
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100180 int k;
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100181 for (k=0;k<Lupdate;k++)
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100182 {
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100183 int n;
184 int is;
185 float s;
186 is = nbest[k]->sign*pulsesAtOnce;
187 s = is;
188 for (n=0;n<N;n++)
189 ny[k][n] = y[nbest[k]->orig][n] - alpha*s*p[nbest[k]->pos]*p[n];
190 ny[k][nbest[k]->pos] += s;
191
192 for (n=0;n<N;n++)
193 iny[k][n] = iy[nbest[k]->orig][n];
194 iny[k][nbest[k]->pos] += is;
195
196 xy[k] = nbest[k]->xy;
197 yy[k] = nbest[k]->yy;
198 yp[k] = nbest[k]->yp;
199 }
200
201 for (k=0;k<Lupdate;k++)
202 {
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100203 float *tmp_ny;
204 int *tmp_iny;
205
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100206 tmp_ny = ny[k];
207 ny[k] = y[k];
208 y[k] = tmp_ny;
209 tmp_iny = iny[k];
210 iny[k] = iy[k];
211 iy[k] = tmp_iny;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100212 }
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100213 pulsesLeft -= pulsesAtOnce;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100214 }
215
Jean-Marc Valinac1e03d2008-02-12 23:00:18 +1100216 if (0) {
217 float err=0;
218 for (i=0;i<N;i++)
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100219 err += (x[i]-nbest[0]->gain*y[0][i])*(x[i]-nbest[0]->gain*y[0][i]);
Jean-Marc Valinac1e03d2008-02-12 23:00:18 +1100220 //if (N<=10)
221 //printf ("%f %d %d\n", err, K, N);
222 }
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100223 for (i=0;i<N;i++)
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100224 x[i] = p[i]+nbest[0]->gain*y[0][i];
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100225 if (0) {
226 float E=1e-15;
227 int ABS = 0;
228 for (i=0;i<N;i++)
229 ABS += abs(iy[0][i]);
230 //if (K != ABS)
231 // printf ("%d %d\n", K, ABS);
232 for (i=0;i<N;i++)
233 E += x[i]*x[i];
234 //printf ("%f\n", E);
235 E = 1/sqrt(E);
236 for (i=0;i<N;i++)
237 x[i] *= E;
238 }
Jean-Marc Valin5fa59952008-02-14 13:50:44 +1100239
240 encode_pulses(iy[0], N, K, enc);
241
Jean-Marc Valina76a0b22008-01-17 22:43:05 +1100242 //printf ("%llu ", icwrs64(N, K, comb, signs));
Jean-Marc Valina4833ff2008-01-10 15:34:00 +1100243 /* Recompute the gain in one pass to reduce the encoder-decoder mismatch
Jean-Marc Valin636f5c82008-02-12 17:40:27 +1100244 due to the recursive computation used in quantisation.
245 Not quite sure whether we need that or not */
Jean-Marc Valina4833ff2008-01-10 15:34:00 +1100246 if (1) {
Jean-Marc Valin4a897682007-12-12 00:45:15 +1100247 float Ryp=0;
248 float Rpp=0;
249 float Ryy=0;
250 float g=0;
251 for (i=0;i<N;i++)
252 Rpp += p[i]*p[i];
253
254 for (i=0;i<N;i++)
255 Ryp += iy[0][i]*p[i];
256
257 for (i=0;i<N;i++)
258 y[0][i] = iy[0][i] - alpha*Ryp*p[i];
259
Jean-Marc Valin4a897682007-12-12 00:45:15 +1100260 Ryp = 0;
261 for (i=0;i<N;i++)
262 Ryp += y[0][i]*p[i];
263
264 for (i=0;i<N;i++)
265 Ryy += y[0][i]*y[0][i];
266
267 g = (sqrt(Ryp*Ryp + Ryy - Ryy*Rpp) - Ryp)/Ryy;
268
269 for (i=0;i<N;i++)
270 x[i] = p[i] + g*y[0][i];
271
272 }
273
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100274}
275
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100276void alg_unquant(float *x, int N, int K, float *p, float alpha, ec_dec *dec)
277{
278 int i;
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100279 int iy[N];
280 float y[N];
281 float Rpp=0, Ryp=0, Ryy=0;
282 float g;
Jean-Marc Valin25298f22007-12-03 15:24:11 +1100283
Jean-Marc Valin5fa59952008-02-14 13:50:44 +1100284 decode_pulses(iy, N, K, dec);
285
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100286 //for (i=0;i<N;i++)
287 // printf ("%d ", iy[i]);
288 for (i=0;i<N;i++)
289 Rpp += p[i]*p[i];
290
291 for (i=0;i<N;i++)
292 Ryp += iy[i]*p[i];
293
294 for (i=0;i<N;i++)
295 y[i] = iy[i] - alpha*Ryp*p[i];
296
297 /* Recompute after the projection (I think it's right) */
298 Ryp = 0;
299 for (i=0;i<N;i++)
300 Ryp += y[i]*p[i];
301
302 for (i=0;i<N;i++)
303 Ryy += y[i]*y[i];
304
305 g = (sqrt(Ryp*Ryp + Ryy - Ryy*Rpp) - Ryp)/Ryy;
306
307 for (i=0;i<N;i++)
308 x[i] = p[i] + g*y[i];
309}
310
311
312static const float pg[11] = {1.f, .75f, .65f, 0.6f, 0.6f, .6f, .55f, .55f, .5f, .5f, .5f};
313
314void 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 +1100315{
316 int i,j;
317 int best=0;
Jean-Marc Valin50d11162007-12-03 14:34:52 +1100318 float best_score=0;
319 float s = 1;
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100320 int sign;
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100321 float E;
Jean-Marc Valin8f0f4b92008-02-11 13:52:44 +1100322 int max_pos = N0-N/B;
323 if (max_pos > 32)
324 max_pos = 32;
325
326 for (i=0;i<max_pos*B;i+=B)
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100327 {
328 int j;
329 float xy=0, yy=0;
330 float score;
331 for (j=0;j<N;j++)
332 {
333 xy += x[j]*Y[i+j];
334 yy += Y[i+j]*Y[i+j];
335 }
Jean-Marc Valin50d11162007-12-03 14:34:52 +1100336 score = xy*xy/(.001+yy);
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100337 if (score > best_score)
338 {
339 best_score = score;
340 best = i;
Jean-Marc Valin50d11162007-12-03 14:34:52 +1100341 if (xy>0)
342 s = 1;
343 else
344 s = -1;
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100345 }
346 }
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100347 if (s<0)
348 sign = 1;
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100349 else
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100350 sign = 0;
351 //printf ("%d %d ", sign, best);
352 ec_enc_uint(enc,sign,2);
Jean-Marc Valin8f0f4b92008-02-11 13:52:44 +1100353 ec_enc_uint(enc,best/B,max_pos);
Jean-Marc Valin50d11162007-12-03 14:34:52 +1100354 //printf ("%d %f\n", best, best_score);
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100355
356 float pred_gain;
357 if (K>10)
358 pred_gain = pg[10];
359 else
360 pred_gain = pg[K];
361 E = 1e-10;
362 for (j=0;j<N;j++)
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100363 {
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100364 P[j] = s*Y[best+j];
365 E += P[j]*P[j];
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100366 }
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100367 E = pred_gain/sqrt(E);
368 for (j=0;j<N;j++)
369 P[j] *= E;
370 if (K>0)
371 {
372 for (j=0;j<N;j++)
373 x[j] -= P[j];
374 } else {
375 for (j=0;j<N;j++)
376 x[j] = P[j];
377 }
378 //printf ("quant ");
379 //for (j=0;j<N;j++) printf ("%f ", P[j]);
380
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100381}
Jean-Marc Valinfc08d0a2007-12-07 13:26:15 +1100382
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100383void 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 +1100384{
Jean-Marc Valin11f01722007-12-09 01:19:36 +1100385 int j;
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100386 int sign;
387 float s;
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100388 int best;
389 float E;
Jean-Marc Valin8f0f4b92008-02-11 13:52:44 +1100390 int max_pos = N0-N/B;
391 if (max_pos > 32)
392 max_pos = 32;
393
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100394 sign = ec_dec_uint(dec, 2);
395 if (sign == 0)
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100396 s = 1;
397 else
398 s = -1;
399
Jean-Marc Valin8f0f4b92008-02-11 13:52:44 +1100400 best = B*ec_dec_uint(dec, max_pos);
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100401 //printf ("%d %d ", sign, best);
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100402
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100403 float pred_gain;
404 if (K>10)
405 pred_gain = pg[10];
406 else
407 pred_gain = pg[K];
408 E = 1e-10;
409 for (j=0;j<N;j++)
410 {
411 P[j] = s*Y[best+j];
412 E += P[j]*P[j];
413 }
414 E = pred_gain/sqrt(E);
415 for (j=0;j<N;j++)
416 P[j] *= E;
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100417 if (K==0)
418 {
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100419 for (j=0;j<N;j++)
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100420 x[j] = P[j];
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100421 }
422}
Jean-Marc Valin0e20ca02008-02-11 15:33:53 +1100423
Jean-Marc Valin0df0eb42008-02-13 16:00:10 +1100424void intra_fold(float *x, int N, float *Y, float *P, int B, int N0, int Nmax)
Jean-Marc Valin0e20ca02008-02-11 15:33:53 +1100425{
Jean-Marc Valin0df0eb42008-02-13 16:00:10 +1100426 int i, j;
Jean-Marc Valin0e20ca02008-02-11 15:33:53 +1100427 float E;
428
429 E = 1e-10;
Jean-Marc Valin0df0eb42008-02-13 16:00:10 +1100430 if (N0 >= Nmax/2)
Jean-Marc Valin0e20ca02008-02-11 15:33:53 +1100431 {
Jean-Marc Valin0df0eb42008-02-13 16:00:10 +1100432 for (i=0;i<B;i++)
433 {
434 for (j=0;j<N/B;j++)
435 {
436 P[j*B+i] = Y[(Nmax-N0-j-1)*B+i];
437 E += P[j*B+i]*P[j*B+i];
438 }
439 }
440 } else {
441 for (j=0;j<N;j++)
442 {
443 P[j] = Y[j];
444 E += P[j]*P[j];
445 }
Jean-Marc Valin0e20ca02008-02-11 15:33:53 +1100446 }
447 E = 1.f/sqrt(E);
448 for (j=0;j<N;j++)
449 P[j] *= E;
450 for (j=0;j<N;j++)
451 x[j] = P[j];
452}
453