blob: fb2dd6ee1ef9283efc6900bb3b9b9923a82f706d [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 Valin41af4212007-11-30 18:35:37 +110037
38/* Improved algebraic pulse-base quantiser. The signal x is replaced by the sum of the pitch
39 a combination of pulses such that its norm is still equal to 1. The only difference with
40 the quantiser above is that the search is more complete. */
Jean-Marc Valin46014ca2007-12-14 13:47:04 +110041void 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 +110042{
Jean-Marc Valin4a897682007-12-12 00:45:15 +110043 int L = 3;
Jean-Marc Valin41af4212007-11-30 18:35:37 +110044 //float tata[200];
Jean-Marc Valinfe419832008-02-12 15:05:01 +110045 float _y[L][N];
46 int _iy[L][N];
Jean-Marc Valin41af4212007-11-30 18:35:37 +110047 //float tata2[200];
Jean-Marc Valinfe419832008-02-12 15:05:01 +110048 float _ny[L][N];
49 int _iny[L][N];
50 float *(ny[L]), *(y[L]);
51 int *(iny[L]), *(iy[L]);
Jean-Marc Valin41af4212007-11-30 18:35:37 +110052 int i, j, m;
Jean-Marc Valin846d4e22008-02-12 13:48:48 +110053 int pulsesLeft;
Jean-Marc Valin41af4212007-11-30 18:35:37 +110054 float xy[L], nxy[L];
55 float yy[L], nyy[L];
56 float yp[L], nyp[L];
57 float best_scores[L];
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +110058 float Rpp=0, Rxp=0;
Jean-Marc Valin41af4212007-11-30 18:35:37 +110059 float gain[L];
60 int maxL = 1;
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +110061
Jean-Marc Valinfe419832008-02-12 15:05:01 +110062 for (m=0;m<L;m++)
63 {
64 ny[m] = _ny[m];
65 iny[m] = _iny[m];
66 y[m] = _y[m];
67 iy[m] = _iy[m];
68 }
69
Jean-Marc Valin41af4212007-11-30 18:35:37 +110070 for (j=0;j<N;j++)
71 Rpp += p[j]*p[j];
Jean-Marc Valinfc08d0a2007-12-07 13:26:15 +110072 //if (Rpp>.01)
73 // alpha = (1-sqrt(1-Rpp))/Rpp;
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +110074 for (j=0;j<N;j++)
75 Rxp += x[j]*p[j];
Jean-Marc Valin41af4212007-11-30 18:35:37 +110076 for (m=0;m<L;m++)
77 for (i=0;i<N;i++)
78 y[m][i] = 0;
79
80 for (m=0;m<L;m++)
81 for (i=0;i<N;i++)
82 ny[m][i] = 0;
83
84 for (m=0;m<L;m++)
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +110085 for (i=0;i<N;i++)
86 iy[m][i] = iny[m][i] = 0;
87
88 for (m=0;m<L;m++)
Jean-Marc Valin41af4212007-11-30 18:35:37 +110089 xy[m] = yy[m] = yp[m] = gain[m] = 0;
90
Jean-Marc Valin846d4e22008-02-12 13:48:48 +110091 pulsesLeft = K;
92 while (pulsesLeft > 0)
Jean-Marc Valin41af4212007-11-30 18:35:37 +110093 {
Jean-Marc Valin846d4e22008-02-12 13:48:48 +110094 int pulsesAtOnce=1;
Jean-Marc Valincab576e2008-02-12 17:21:14 +110095 int Lupdate = L;
Jean-Marc Valin41af4212007-11-30 18:35:37 +110096 int L2 = L;
Jean-Marc Valincab576e2008-02-12 17:21:14 +110097 pulsesAtOnce = pulsesLeft/N;
98 if (pulsesAtOnce<1)
99 pulsesAtOnce = 1;
100 if (pulsesLeft-pulsesAtOnce > 3 || N > 30)
101 Lupdate = 1;
102 //printf ("%d %d %d/%d %d\n", Lupdate, pulsesAtOnce, pulsesLeft, K, N);
103 L2 = Lupdate;
104 if (L2>maxL)
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100105 {
106 L2 = maxL;
107 maxL *= N;
108 }
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100109
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100110 for (m=0;m<L;m++)
111 best_scores[m] = -1e10;
112
113 for (m=0;m<L2;m++)
114 {
115 for (j=0;j<N;j++)
116 {
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100117 int sign;
Jean-Marc Valinac1e03d2008-02-12 23:00:18 +1100118 //if (x[j]>0) sign=1; else sign=-1;
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100119 for (sign=-1;sign<=1;sign+=2)
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100120 {
Jean-Marc Valinc9cc6d32008-02-13 11:37:41 +1100121 /* All pulses at one location must have the same sign. Also,
122 only consider sign in the same direction as x[j], except for the
123 last pulses */
Jean-Marc Valinac1e03d2008-02-12 23:00:18 +1100124 if (iy[m][j]*sign < 0 || (x[j]*sign<0 && pulsesLeft>((K+1)>>1)))
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100125 continue;
126 //fprintf (stderr, "%d/%d %d/%d %d/%d\n", i, K, m, L2, j, N);
127 float tmp_xy, tmp_yy, tmp_yp;
128 float score;
129 float g;
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100130 float s = sign*pulsesAtOnce;
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100131
132 /* Updating the sums the the new pulse(s) */
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100133 tmp_xy = xy[m] + s*x[j] - alpha*s*p[j]*Rxp;
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100134 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 +1100135 tmp_yp = yp[m] + s*p[j] *(1-alpha*Rpp);
136 g = (sqrt(tmp_yp*tmp_yp + tmp_yy - tmp_yy*Rpp) - tmp_yp)/tmp_yy;
137 score = 2*g*tmp_xy - g*g*tmp_yy;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100138
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100139 if (score>best_scores[Lupdate-1])
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100140 {
141 int k, n;
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100142 int id = Lupdate-1;
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100143 float *tmp_ny;
144 int *tmp_iny;
145
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100146 tmp_ny = ny[Lupdate-1];
147 tmp_iny = iny[Lupdate-1];
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100148 while (id > 0 && score > best_scores[id-1])
149 id--;
150
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100151 for (k=Lupdate-1;k>id;k--)
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100152 {
153 nxy[k] = nxy[k-1];
154 nyy[k] = nyy[k-1];
155 nyp[k] = nyp[k-1];
156 //fprintf(stderr, "%d %d \n", N, k);
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100157 ny[k] = ny[k-1];
158 iny[k] = iny[k-1];
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100159 gain[k] = gain[k-1];
160 best_scores[k] = best_scores[k-1];
161 }
162
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100163 ny[id] = tmp_ny;
164 iny[id] = tmp_iny;
Jean-Marc Valin636f5c82008-02-12 17:40:27 +1100165
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100166 nxy[id] = tmp_xy;
167 nyy[id] = tmp_yy;
168 nyp[id] = tmp_yp;
169 gain[id] = g;
170 for (n=0;n<N;n++)
Jean-Marc Valin636f5c82008-02-12 17:40:27 +1100171 ny[id][n] = y[m][n] - alpha*s*p[j]*p[n];
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100172 ny[id][j] += s;
Jean-Marc Valin636f5c82008-02-12 17:40:27 +1100173
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100174 for (n=0;n<N;n++)
175 iny[id][n] = iy[m][n];
176 if (s>0)
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100177 iny[id][j] += pulsesAtOnce;
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100178 else
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100179 iny[id][j] -= pulsesAtOnce;
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100180 best_scores[id] = score;
181 }
Jean-Marc Valin636f5c82008-02-12 17:40:27 +1100182 }
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100183 }
Jean-Marc Valin636f5c82008-02-12 17:40:27 +1100184
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100185 }
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100186 int k;
Jean-Marc Valincab576e2008-02-12 17:21:14 +1100187 for (k=0;k<Lupdate;k++)
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100188 {
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100189 float *tmp_ny;
190 int *tmp_iny;
191
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100192 xy[k] = nxy[k];
193 yy[k] = nyy[k];
194 yp[k] = nyp[k];
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100195
196 tmp_ny = ny[k];
197 ny[k] = y[k];
198 y[k] = tmp_ny;
199 tmp_iny = iny[k];
200 iny[k] = iy[k];
201 iy[k] = tmp_iny;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100202 }
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100203 pulsesLeft -= pulsesAtOnce;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100204 }
205
Jean-Marc Valinac1e03d2008-02-12 23:00:18 +1100206 if (0) {
207 float err=0;
208 for (i=0;i<N;i++)
209 err += (x[i]-gain[0]*y[0][i])*(x[i]-gain[0]*y[0][i]);
210 //if (N<=10)
211 //printf ("%f %d %d\n", err, K, N);
212 }
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100213 for (i=0;i<N;i++)
214 x[i] = p[i]+gain[0]*y[0][i];
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100215 if (0) {
216 float E=1e-15;
217 int ABS = 0;
218 for (i=0;i<N;i++)
219 ABS += abs(iy[0][i]);
220 //if (K != ABS)
221 // printf ("%d %d\n", K, ABS);
222 for (i=0;i<N;i++)
223 E += x[i]*x[i];
224 //printf ("%f\n", E);
225 E = 1/sqrt(E);
226 for (i=0;i<N;i++)
227 x[i] *= E;
228 }
Jean-Marc Valin29ccab82007-12-06 15:39:38 +1100229 int comb[K];
230 int signs[K];
Jean-Marc Valin70c8ffd2007-12-07 14:20:01 +1100231 //for (i=0;i<N;i++)
232 // printf ("%d ", iy[0][i]);
Jean-Marc Valin29ccab82007-12-06 15:39:38 +1100233 pulse2comb(N, K, comb, signs, iy[0]);
Jean-Marc Valinf8db8002007-12-11 14:52:56 +1100234 ec_enc_uint64(enc,icwrs64(N, K, comb, signs),ncwrs64(N, K));
Jean-Marc Valina76a0b22008-01-17 22:43:05 +1100235 //printf ("%llu ", icwrs64(N, K, comb, signs));
Jean-Marc Valina4833ff2008-01-10 15:34:00 +1100236 /* Recompute the gain in one pass to reduce the encoder-decoder mismatch
Jean-Marc Valin636f5c82008-02-12 17:40:27 +1100237 due to the recursive computation used in quantisation.
238 Not quite sure whether we need that or not */
Jean-Marc Valina4833ff2008-01-10 15:34:00 +1100239 if (1) {
Jean-Marc Valin4a897682007-12-12 00:45:15 +1100240 float Ryp=0;
241 float Rpp=0;
242 float Ryy=0;
243 float g=0;
244 for (i=0;i<N;i++)
245 Rpp += p[i]*p[i];
246
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;
272 celt_uint64_t id;
273 int comb[K];
274 int signs[K];
275 int iy[N];
276 float y[N];
277 float Rpp=0, Ryp=0, Ryy=0;
278 float g;
Jean-Marc Valin25298f22007-12-03 15:24:11 +1100279
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100280 id = ec_dec_uint64(dec, ncwrs64(N, K));
Jean-Marc Valina76a0b22008-01-17 22:43:05 +1100281 //printf ("%llu ", id);
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100282 cwrsi64(N, K, id, comb, signs);
283 comb2pulse(N, K, iy, comb, signs);
284 //for (i=0;i<N;i++)
285 // printf ("%d ", iy[i]);
286 for (i=0;i<N;i++)
287 Rpp += p[i]*p[i];
288
289 for (i=0;i<N;i++)
290 Ryp += iy[i]*p[i];
291
292 for (i=0;i<N;i++)
293 y[i] = iy[i] - alpha*Ryp*p[i];
294
295 /* Recompute after the projection (I think it's right) */
296 Ryp = 0;
297 for (i=0;i<N;i++)
298 Ryp += y[i]*p[i];
299
300 for (i=0;i<N;i++)
301 Ryy += y[i]*y[i];
302
303 g = (sqrt(Ryp*Ryp + Ryy - Ryy*Rpp) - Ryp)/Ryy;
304
305 for (i=0;i<N;i++)
306 x[i] = p[i] + g*y[i];
307}
308
309
310static const float pg[11] = {1.f, .75f, .65f, 0.6f, 0.6f, .6f, .55f, .55f, .5f, .5f, .5f};
311
312void 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 +1100313{
314 int i,j;
315 int best=0;
Jean-Marc Valin50d11162007-12-03 14:34:52 +1100316 float best_score=0;
317 float s = 1;
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100318 int sign;
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100319 float E;
Jean-Marc Valin8f0f4b92008-02-11 13:52:44 +1100320 int max_pos = N0-N/B;
321 if (max_pos > 32)
322 max_pos = 32;
323
324 for (i=0;i<max_pos*B;i+=B)
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100325 {
326 int j;
327 float xy=0, yy=0;
328 float score;
329 for (j=0;j<N;j++)
330 {
331 xy += x[j]*Y[i+j];
332 yy += Y[i+j]*Y[i+j];
333 }
Jean-Marc Valin50d11162007-12-03 14:34:52 +1100334 score = xy*xy/(.001+yy);
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100335 if (score > best_score)
336 {
337 best_score = score;
338 best = i;
Jean-Marc Valin50d11162007-12-03 14:34:52 +1100339 if (xy>0)
340 s = 1;
341 else
342 s = -1;
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100343 }
344 }
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100345 if (s<0)
346 sign = 1;
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100347 else
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100348 sign = 0;
349 //printf ("%d %d ", sign, best);
350 ec_enc_uint(enc,sign,2);
Jean-Marc Valin8f0f4b92008-02-11 13:52:44 +1100351 ec_enc_uint(enc,best/B,max_pos);
Jean-Marc Valin50d11162007-12-03 14:34:52 +1100352 //printf ("%d %f\n", best, best_score);
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100353
354 float pred_gain;
355 if (K>10)
356 pred_gain = pg[10];
357 else
358 pred_gain = pg[K];
359 E = 1e-10;
360 for (j=0;j<N;j++)
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100361 {
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100362 P[j] = s*Y[best+j];
363 E += P[j]*P[j];
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100364 }
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100365 E = pred_gain/sqrt(E);
366 for (j=0;j<N;j++)
367 P[j] *= E;
368 if (K>0)
369 {
370 for (j=0;j<N;j++)
371 x[j] -= P[j];
372 } else {
373 for (j=0;j<N;j++)
374 x[j] = P[j];
375 }
376 //printf ("quant ");
377 //for (j=0;j<N;j++) printf ("%f ", P[j]);
378
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100379}
Jean-Marc Valinfc08d0a2007-12-07 13:26:15 +1100380
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100381void 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 +1100382{
Jean-Marc Valin11f01722007-12-09 01:19:36 +1100383 int j;
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100384 int sign;
385 float s;
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100386 int best;
387 float E;
Jean-Marc Valin8f0f4b92008-02-11 13:52:44 +1100388 int max_pos = N0-N/B;
389 if (max_pos > 32)
390 max_pos = 32;
391
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100392 sign = ec_dec_uint(dec, 2);
393 if (sign == 0)
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100394 s = 1;
395 else
396 s = -1;
397
Jean-Marc Valin8f0f4b92008-02-11 13:52:44 +1100398 best = B*ec_dec_uint(dec, max_pos);
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100399 //printf ("%d %d ", sign, best);
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100400
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100401 float pred_gain;
402 if (K>10)
403 pred_gain = pg[10];
404 else
405 pred_gain = pg[K];
406 E = 1e-10;
407 for (j=0;j<N;j++)
408 {
409 P[j] = s*Y[best+j];
410 E += P[j]*P[j];
411 }
412 E = pred_gain/sqrt(E);
413 for (j=0;j<N;j++)
414 P[j] *= E;
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100415 if (K==0)
416 {
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100417 for (j=0;j<N;j++)
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100418 x[j] = P[j];
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100419 }
420}
Jean-Marc Valin0e20ca02008-02-11 15:33:53 +1100421
Jean-Marc Valin0df0eb42008-02-13 16:00:10 +1100422void intra_fold(float *x, int N, float *Y, float *P, int B, int N0, int Nmax)
Jean-Marc Valin0e20ca02008-02-11 15:33:53 +1100423{
Jean-Marc Valin0df0eb42008-02-13 16:00:10 +1100424 int i, j;
Jean-Marc Valin0e20ca02008-02-11 15:33:53 +1100425 float E;
426
427 E = 1e-10;
Jean-Marc Valin0df0eb42008-02-13 16:00:10 +1100428 if (N0 >= Nmax/2)
Jean-Marc Valin0e20ca02008-02-11 15:33:53 +1100429 {
Jean-Marc Valin0df0eb42008-02-13 16:00:10 +1100430 for (i=0;i<B;i++)
431 {
432 for (j=0;j<N/B;j++)
433 {
434 P[j*B+i] = Y[(Nmax-N0-j-1)*B+i];
435 E += P[j*B+i]*P[j*B+i];
436 }
437 }
438 } else {
439 for (j=0;j<N;j++)
440 {
441 P[j] = Y[j];
442 E += P[j]*P[j];
443 }
Jean-Marc Valin0e20ca02008-02-11 15:33:53 +1100444 }
445 E = 1.f/sqrt(E);
446 for (j=0;j<N;j++)
447 P[j] *= E;
448 for (j=0;j<N;j++)
449 x[j] = P[j];
450}
451