blob: db965eba0e043ae8f8cd0f88aa9bcd07332c36cc [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 Valin0d587d82008-02-14 21:29:50 +110062 int i, j, k, 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++)
Jean-Marc Valin0d587d82008-02-14 21:29:50 +110084 {
Jean-Marc Valin41af4212007-11-30 18:35:37 +110085 Rpp += p[j]*p[j];
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +110086 Rxp += x[j]*p[j];
Jean-Marc Valin0d587d82008-02-14 21:29:50 +110087 }
Jean-Marc Valin41af4212007-11-30 18:35:37 +110088
Jean-Marc Valin0d587d82008-02-14 21:29:50 +110089 /* We only need to initialise the zero because the first iteration only uses that */
90 for (i=0;i<N;i++)
91 y[0][i] = 0;
92 for (i=0;i<N;i++)
93 iy[0][i] = 0;
94 xy[0] = yy[0] = yp[0] = 0;
95
Jean-Marc Valin846d4e22008-02-12 13:48:48 +110096 pulsesLeft = K;
97 while (pulsesLeft > 0)
Jean-Marc Valin41af4212007-11-30 18:35:37 +110098 {
Jean-Marc Valin846d4e22008-02-12 13:48:48 +110099 int pulsesAtOnce=1;
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100100 int Lupdate = L;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100101 int L2 = L;
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100102
103 /* Decide on complexity strategy */
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100104 pulsesAtOnce = pulsesLeft/N;
105 if (pulsesAtOnce<1)
106 pulsesAtOnce = 1;
107 if (pulsesLeft-pulsesAtOnce > 3 || N > 30)
108 Lupdate = 1;
109 //printf ("%d %d %d/%d %d\n", Lupdate, pulsesAtOnce, pulsesLeft, K, N);
110 L2 = Lupdate;
111 if (L2>maxL)
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100112 {
113 L2 = maxL;
114 maxL *= N;
115 }
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100116
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100117 for (m=0;m<Lupdate;m++)
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100118 nbest[m]->score = -1e10;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100119
120 for (m=0;m<L2;m++)
121 {
122 for (j=0;j<N;j++)
123 {
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100124 int sign;
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100125 /*if (x[j]>0) sign=1; else sign=-1;*/
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100126 for (sign=-1;sign<=1;sign+=2)
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100127 {
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100128 /* All pulses at one location must have the same sign. */
129 if (iy[m][j]*sign < 0)
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100130 continue;
131 //fprintf (stderr, "%d/%d %d/%d %d/%d\n", i, K, m, L2, j, N);
132 float tmp_xy, tmp_yy, tmp_yp;
133 float score;
134 float g;
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100135 float s = sign*pulsesAtOnce;
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100136
Jean-Marc Valina073c7b2008-02-14 16:58:04 +1100137 /* Updating the sums of the new pulse(s) */
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100138 tmp_xy = xy[m] + s*x[j] - alpha*s*p[j]*Rxp;
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100139 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 +1100140 tmp_yp = yp[m] + s*p[j] *(1-alpha*Rpp);
Jean-Marc Valina073c7b2008-02-14 16:58:04 +1100141
142 /* Compute the gain such that ||p + g*y|| = 1 */
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100143 g = (sqrt(tmp_yp*tmp_yp + tmp_yy - tmp_yy*Rpp) - tmp_yp)/tmp_yy;
Jean-Marc Valina073c7b2008-02-14 16:58:04 +1100144 /* Knowing that gain, what the error: (x-g*y)^2
145 (result is negated and we discard x^2 because it's constant) */
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100146 score = 2*g*tmp_xy - g*g*tmp_yy;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100147
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100148 if (score>nbest[Lupdate-1]->score)
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100149 {
150 int k, n;
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100151 int id = Lupdate-1;
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100152 struct NBest *tmp_best;
153
154 /* Save some pointers that would be deleted and use them for the current entry*/
155 tmp_best = nbest[Lupdate-1];
156 while (id > 0 && score > nbest[id-1]->score)
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100157 id--;
158
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100159 for (k=Lupdate-1;k>id;k--)
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100160 nbest[k] = nbest[k-1];
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100161
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100162 nbest[id] = tmp_best;
163 nbest[id]->score = score;
164 nbest[id]->pos = j;
165 nbest[id]->orig = m;
166 nbest[id]->sign = sign;
167 nbest[id]->gain = g;
168 nbest[id]->xy = tmp_xy;
169 nbest[id]->yy = tmp_yy;
170 nbest[id]->yp = tmp_yp;
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100171 }
Jean-Marc Valin636f5c82008-02-12 17:40:27 +1100172 }
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100173 }
Jean-Marc Valin636f5c82008-02-12 17:40:27 +1100174
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100175 }
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100176 /* Only now that we've made the final choice, update ny/iny and others */
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100177 for (k=0;k<Lupdate;k++)
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100178 {
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100179 int n;
180 int is;
181 float s;
182 is = nbest[k]->sign*pulsesAtOnce;
183 s = is;
184 for (n=0;n<N;n++)
185 ny[k][n] = y[nbest[k]->orig][n] - alpha*s*p[nbest[k]->pos]*p[n];
186 ny[k][nbest[k]->pos] += s;
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100187
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100188 for (n=0;n<N;n++)
189 iny[k][n] = iy[nbest[k]->orig][n];
190 iny[k][nbest[k]->pos] += is;
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100191
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100192 xy[k] = nbest[k]->xy;
193 yy[k] = nbest[k]->yy;
194 yp[k] = nbest[k]->yp;
195 }
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100196 /* Swap ny/iny with y/iy */
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100197 for (k=0;k<Lupdate;k++)
198 {
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100199 float *tmp_ny;
200 int *tmp_iny;
201
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100202 tmp_ny = ny[k];
203 ny[k] = y[k];
204 y[k] = tmp_ny;
205 tmp_iny = iny[k];
206 iny[k] = iy[k];
207 iy[k] = tmp_iny;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100208 }
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100209 pulsesLeft -= pulsesAtOnce;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100210 }
211
Jean-Marc Valinac1e03d2008-02-12 23:00:18 +1100212 if (0) {
213 float err=0;
214 for (i=0;i<N;i++)
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100215 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 +1100216 //if (N<=10)
217 //printf ("%f %d %d\n", err, K, N);
218 }
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100219 for (i=0;i<N;i++)
Jean-Marc Valin3b277dc2008-02-14 16:46:50 +1100220 x[i] = p[i]+nbest[0]->gain*y[0][i];
Jean-Marc Valin0d587d82008-02-14 21:29:50 +1100221 /* Sanity checks, don't bother */
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100222 if (0) {
223 float E=1e-15;
224 int ABS = 0;
225 for (i=0;i<N;i++)
226 ABS += abs(iy[0][i]);
227 //if (K != ABS)
228 // printf ("%d %d\n", K, ABS);
229 for (i=0;i<N;i++)
230 E += x[i]*x[i];
231 //printf ("%f\n", E);
232 E = 1/sqrt(E);
233 for (i=0;i<N;i++)
234 x[i] *= E;
235 }
Jean-Marc Valin5fa59952008-02-14 13:50:44 +1100236
237 encode_pulses(iy[0], N, K, enc);
238
Jean-Marc Valina4833ff2008-01-10 15:34:00 +1100239 /* Recompute the gain in one pass to reduce the encoder-decoder mismatch
Jean-Marc Valin636f5c82008-02-12 17:40:27 +1100240 due to the recursive computation used in quantisation.
241 Not quite sure whether we need that or not */
Jean-Marc Valina4833ff2008-01-10 15:34:00 +1100242 if (1) {
Jean-Marc Valin4a897682007-12-12 00:45:15 +1100243 float Ryp=0;
Jean-Marc Valin4a897682007-12-12 00:45:15 +1100244 float Ryy=0;
245 float g=0;
Jean-Marc Valin4a897682007-12-12 00:45:15 +1100246
247 for (i=0;i<N;i++)
248 Ryp += iy[0][i]*p[i];
249
250 for (i=0;i<N;i++)
251 y[0][i] = iy[0][i] - alpha*Ryp*p[i];
252
Jean-Marc Valin4a897682007-12-12 00:45:15 +1100253 Ryp = 0;
254 for (i=0;i<N;i++)
255 Ryp += y[0][i]*p[i];
256
257 for (i=0;i<N;i++)
258 Ryy += y[0][i]*y[0][i];
259
260 g = (sqrt(Ryp*Ryp + Ryy - Ryy*Rpp) - Ryp)/Ryy;
261
262 for (i=0;i<N;i++)
263 x[i] = p[i] + g*y[0][i];
264
265 }
266
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100267}
268
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100269void alg_unquant(float *x, int N, int K, float *p, float alpha, ec_dec *dec)
270{
271 int i;
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100272 int iy[N];
273 float y[N];
274 float Rpp=0, Ryp=0, Ryy=0;
275 float g;
Jean-Marc Valin25298f22007-12-03 15:24:11 +1100276
Jean-Marc Valin5fa59952008-02-14 13:50:44 +1100277 decode_pulses(iy, N, K, dec);
278
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100279 //for (i=0;i<N;i++)
280 // printf ("%d ", iy[i]);
281 for (i=0;i<N;i++)
282 Rpp += p[i]*p[i];
283
284 for (i=0;i<N;i++)
285 Ryp += iy[i]*p[i];
286
287 for (i=0;i<N;i++)
288 y[i] = iy[i] - alpha*Ryp*p[i];
289
290 /* Recompute after the projection (I think it's right) */
291 Ryp = 0;
292 for (i=0;i<N;i++)
293 Ryp += y[i]*p[i];
294
295 for (i=0;i<N;i++)
296 Ryy += y[i]*y[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[i];
302}
303
304
305static const float pg[11] = {1.f, .75f, .65f, 0.6f, 0.6f, .6f, .55f, .55f, .5f, .5f, .5f};
306
307void 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 +1100308{
309 int i,j;
310 int best=0;
Jean-Marc Valin50d11162007-12-03 14:34:52 +1100311 float best_score=0;
312 float s = 1;
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100313 int sign;
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100314 float E;
Jean-Marc Valin8f0f4b92008-02-11 13:52:44 +1100315 int max_pos = N0-N/B;
316 if (max_pos > 32)
317 max_pos = 32;
318
319 for (i=0;i<max_pos*B;i+=B)
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100320 {
321 int j;
322 float xy=0, yy=0;
323 float score;
324 for (j=0;j<N;j++)
325 {
326 xy += x[j]*Y[i+j];
327 yy += Y[i+j]*Y[i+j];
328 }
Jean-Marc Valin50d11162007-12-03 14:34:52 +1100329 score = xy*xy/(.001+yy);
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100330 if (score > best_score)
331 {
332 best_score = score;
333 best = i;
Jean-Marc Valin50d11162007-12-03 14:34:52 +1100334 if (xy>0)
335 s = 1;
336 else
337 s = -1;
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100338 }
339 }
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100340 if (s<0)
341 sign = 1;
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100342 else
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100343 sign = 0;
344 //printf ("%d %d ", sign, best);
345 ec_enc_uint(enc,sign,2);
Jean-Marc Valin8f0f4b92008-02-11 13:52:44 +1100346 ec_enc_uint(enc,best/B,max_pos);
Jean-Marc Valin50d11162007-12-03 14:34:52 +1100347 //printf ("%d %f\n", best, best_score);
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100348
349 float pred_gain;
350 if (K>10)
351 pred_gain = pg[10];
352 else
353 pred_gain = pg[K];
354 E = 1e-10;
355 for (j=0;j<N;j++)
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100356 {
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100357 P[j] = s*Y[best+j];
358 E += P[j]*P[j];
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100359 }
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100360 E = pred_gain/sqrt(E);
361 for (j=0;j<N;j++)
362 P[j] *= E;
363 if (K>0)
364 {
365 for (j=0;j<N;j++)
366 x[j] -= P[j];
367 } else {
368 for (j=0;j<N;j++)
369 x[j] = P[j];
370 }
371 //printf ("quant ");
372 //for (j=0;j<N;j++) printf ("%f ", P[j]);
373
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100374}
Jean-Marc Valinfc08d0a2007-12-07 13:26:15 +1100375
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100376void 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 +1100377{
Jean-Marc Valin11f01722007-12-09 01:19:36 +1100378 int j;
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100379 int sign;
380 float s;
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100381 int best;
382 float E;
Jean-Marc Valin8f0f4b92008-02-11 13:52:44 +1100383 int max_pos = N0-N/B;
384 if (max_pos > 32)
385 max_pos = 32;
386
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100387 sign = ec_dec_uint(dec, 2);
388 if (sign == 0)
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100389 s = 1;
390 else
391 s = -1;
392
Jean-Marc Valin8f0f4b92008-02-11 13:52:44 +1100393 best = B*ec_dec_uint(dec, max_pos);
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100394 //printf ("%d %d ", sign, best);
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100395
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100396 float pred_gain;
397 if (K>10)
398 pred_gain = pg[10];
399 else
400 pred_gain = pg[K];
401 E = 1e-10;
402 for (j=0;j<N;j++)
403 {
404 P[j] = s*Y[best+j];
405 E += P[j]*P[j];
406 }
407 E = pred_gain/sqrt(E);
408 for (j=0;j<N;j++)
409 P[j] *= E;
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100410 if (K==0)
411 {
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100412 for (j=0;j<N;j++)
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100413 x[j] = P[j];
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100414 }
415}
Jean-Marc Valin0e20ca02008-02-11 15:33:53 +1100416
Jean-Marc Valin0df0eb42008-02-13 16:00:10 +1100417void intra_fold(float *x, int N, float *Y, float *P, int B, int N0, int Nmax)
Jean-Marc Valin0e20ca02008-02-11 15:33:53 +1100418{
Jean-Marc Valin0df0eb42008-02-13 16:00:10 +1100419 int i, j;
Jean-Marc Valin0e20ca02008-02-11 15:33:53 +1100420 float E;
421
422 E = 1e-10;
Jean-Marc Valin0df0eb42008-02-13 16:00:10 +1100423 if (N0 >= Nmax/2)
Jean-Marc Valin0e20ca02008-02-11 15:33:53 +1100424 {
Jean-Marc Valin0df0eb42008-02-13 16:00:10 +1100425 for (i=0;i<B;i++)
426 {
427 for (j=0;j<N/B;j++)
428 {
429 P[j*B+i] = Y[(Nmax-N0-j-1)*B+i];
430 E += P[j*B+i]*P[j*B+i];
431 }
432 }
433 } else {
434 for (j=0;j<N;j++)
435 {
436 P[j] = Y[j];
437 E += P[j]*P[j];
438 }
Jean-Marc Valin0e20ca02008-02-11 15:33:53 +1100439 }
440 E = 1.f/sqrt(E);
441 for (j=0;j<N;j++)
442 P[j] *= E;
443 for (j=0;j<N;j++)
444 x[j] = P[j];
445}
446