blob: 388df6b22c18b4ce9790109b29719cf42f65d220 [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 Valin41af4212007-11-30 18:35:37 +110095 int L2 = L;
96 if (L>maxL)
97 {
98 L2 = maxL;
99 maxL *= N;
100 }
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100101 if (pulsesLeft > 5)
102 L2 = 1;
103
104 pulsesAtOnce = pulsesLeft/N;
105 if (pulsesAtOnce<1)
106 pulsesAtOnce = 1;
107
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100108 for (m=0;m<L;m++)
109 best_scores[m] = -1e10;
110
111 for (m=0;m<L2;m++)
112 {
113 for (j=0;j<N;j++)
114 {
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100115 int sign;
116 for (sign=-1;sign<=1;sign+=2)
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100117 {
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100118 /* All pulses at one location must have the same size */
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100119 if (iy[m][j]*sign < 0)
120 continue;
121 //fprintf (stderr, "%d/%d %d/%d %d/%d\n", i, K, m, L2, j, N);
122 float tmp_xy, tmp_yy, tmp_yp;
123 float score;
124 float g;
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100125 float s = sign*pulsesAtOnce;
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100126
127 /* Updating the sums the the new pulse(s) */
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100128 tmp_xy = xy[m] + s*x[j] - alpha*s*p[j]*Rxp;
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100129 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 +1100130 tmp_yp = yp[m] + s*p[j] *(1-alpha*Rpp);
131 g = (sqrt(tmp_yp*tmp_yp + tmp_yy - tmp_yy*Rpp) - tmp_yp)/tmp_yy;
132 score = 2*g*tmp_xy - g*g*tmp_yy;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100133
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100134 if (score>best_scores[L-1])
135 {
136 int k, n;
137 int id = L-1;
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100138 float *tmp_ny;
139 int *tmp_iny;
140
141 tmp_ny = ny[L-1];
142 tmp_iny = iny[L-1];
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100143 while (id > 0 && score > best_scores[id-1])
144 id--;
145
146 for (k=L-1;k>id;k--)
147 {
148 nxy[k] = nxy[k-1];
149 nyy[k] = nyy[k-1];
150 nyp[k] = nyp[k-1];
151 //fprintf(stderr, "%d %d \n", N, k);
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100152 ny[k] = ny[k-1];
153 iny[k] = iny[k-1];
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100154 gain[k] = gain[k-1];
155 best_scores[k] = best_scores[k-1];
156 }
157
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100158 ny[id] = tmp_ny;
159 iny[id] = tmp_iny;
160
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100161 nxy[id] = tmp_xy;
162 nyy[id] = tmp_yy;
163 nyp[id] = tmp_yp;
164 gain[id] = g;
165 for (n=0;n<N;n++)
166 ny[id][n] = y[m][n];
167 ny[id][j] += s;
168 for (n=0;n<N;n++)
169 ny[id][n] -= alpha*s*p[j]*p[n];
170
171 for (n=0;n<N;n++)
172 iny[id][n] = iy[m][n];
173 if (s>0)
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100174 iny[id][j] += pulsesAtOnce;
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100175 else
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100176 iny[id][j] -= pulsesAtOnce;
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100177 best_scores[id] = score;
178 }
179 }
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100180 }
181
182 }
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100183 int k;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100184 for (k=0;k<L;k++)
185 {
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100186 float *tmp_ny;
187 int *tmp_iny;
188
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100189 xy[k] = nxy[k];
190 yy[k] = nyy[k];
191 yp[k] = nyp[k];
Jean-Marc Valinfe419832008-02-12 15:05:01 +1100192
193 tmp_ny = ny[k];
194 ny[k] = y[k];
195 y[k] = tmp_ny;
196 tmp_iny = iny[k];
197 iny[k] = iy[k];
198 iy[k] = tmp_iny;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100199 }
Jean-Marc Valin846d4e22008-02-12 13:48:48 +1100200 pulsesLeft -= pulsesAtOnce;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100201 }
202
203 for (i=0;i<N;i++)
204 x[i] = p[i]+gain[0]*y[0][i];
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100205 if (0) {
206 float E=1e-15;
207 int ABS = 0;
208 for (i=0;i<N;i++)
209 ABS += abs(iy[0][i]);
210 //if (K != ABS)
211 // printf ("%d %d\n", K, ABS);
212 for (i=0;i<N;i++)
213 E += x[i]*x[i];
214 //printf ("%f\n", E);
215 E = 1/sqrt(E);
216 for (i=0;i<N;i++)
217 x[i] *= E;
218 }
Jean-Marc Valin29ccab82007-12-06 15:39:38 +1100219 int comb[K];
220 int signs[K];
Jean-Marc Valin70c8ffd2007-12-07 14:20:01 +1100221 //for (i=0;i<N;i++)
222 // printf ("%d ", iy[0][i]);
Jean-Marc Valin29ccab82007-12-06 15:39:38 +1100223 pulse2comb(N, K, comb, signs, iy[0]);
Jean-Marc Valinf8db8002007-12-11 14:52:56 +1100224 ec_enc_uint64(enc,icwrs64(N, K, comb, signs),ncwrs64(N, K));
Jean-Marc Valina76a0b22008-01-17 22:43:05 +1100225 //printf ("%llu ", icwrs64(N, K, comb, signs));
Jean-Marc Valina4833ff2008-01-10 15:34:00 +1100226 /* Recompute the gain in one pass to reduce the encoder-decoder mismatch
227 due to the recursive computation used in quantisation */
228 if (1) {
Jean-Marc Valin4a897682007-12-12 00:45:15 +1100229 float Ryp=0;
230 float Rpp=0;
231 float Ryy=0;
232 float g=0;
233 for (i=0;i<N;i++)
234 Rpp += p[i]*p[i];
235
236 for (i=0;i<N;i++)
237 Ryp += iy[0][i]*p[i];
238
239 for (i=0;i<N;i++)
240 y[0][i] = iy[0][i] - alpha*Ryp*p[i];
241
Jean-Marc Valin4a897682007-12-12 00:45:15 +1100242 Ryp = 0;
243 for (i=0;i<N;i++)
244 Ryp += y[0][i]*p[i];
245
246 for (i=0;i<N;i++)
247 Ryy += y[0][i]*y[0][i];
248
249 g = (sqrt(Ryp*Ryp + Ryy - Ryy*Rpp) - Ryp)/Ryy;
250
251 for (i=0;i<N;i++)
252 x[i] = p[i] + g*y[0][i];
253
254 }
255
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100256}
257
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100258void alg_unquant(float *x, int N, int K, float *p, float alpha, ec_dec *dec)
259{
260 int i;
261 celt_uint64_t id;
262 int comb[K];
263 int signs[K];
264 int iy[N];
265 float y[N];
266 float Rpp=0, Ryp=0, Ryy=0;
267 float g;
Jean-Marc Valin25298f22007-12-03 15:24:11 +1100268
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100269 id = ec_dec_uint64(dec, ncwrs64(N, K));
Jean-Marc Valina76a0b22008-01-17 22:43:05 +1100270 //printf ("%llu ", id);
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100271 cwrsi64(N, K, id, comb, signs);
272 comb2pulse(N, K, iy, comb, signs);
273 //for (i=0;i<N;i++)
274 // printf ("%d ", iy[i]);
275 for (i=0;i<N;i++)
276 Rpp += p[i]*p[i];
277
278 for (i=0;i<N;i++)
279 Ryp += iy[i]*p[i];
280
281 for (i=0;i<N;i++)
282 y[i] = iy[i] - alpha*Ryp*p[i];
283
284 /* Recompute after the projection (I think it's right) */
285 Ryp = 0;
286 for (i=0;i<N;i++)
287 Ryp += y[i]*p[i];
288
289 for (i=0;i<N;i++)
290 Ryy += y[i]*y[i];
291
292 g = (sqrt(Ryp*Ryp + Ryy - Ryy*Rpp) - Ryp)/Ryy;
293
294 for (i=0;i<N;i++)
295 x[i] = p[i] + g*y[i];
296}
297
298
299static const float pg[11] = {1.f, .75f, .65f, 0.6f, 0.6f, .6f, .55f, .55f, .5f, .5f, .5f};
300
301void 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 +1100302{
303 int i,j;
304 int best=0;
Jean-Marc Valin50d11162007-12-03 14:34:52 +1100305 float best_score=0;
306 float s = 1;
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100307 int sign;
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100308 float E;
Jean-Marc Valin8f0f4b92008-02-11 13:52:44 +1100309 int max_pos = N0-N/B;
310 if (max_pos > 32)
311 max_pos = 32;
312
313 for (i=0;i<max_pos*B;i+=B)
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100314 {
315 int j;
316 float xy=0, yy=0;
317 float score;
318 for (j=0;j<N;j++)
319 {
320 xy += x[j]*Y[i+j];
321 yy += Y[i+j]*Y[i+j];
322 }
Jean-Marc Valin50d11162007-12-03 14:34:52 +1100323 score = xy*xy/(.001+yy);
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100324 if (score > best_score)
325 {
326 best_score = score;
327 best = i;
Jean-Marc Valin50d11162007-12-03 14:34:52 +1100328 if (xy>0)
329 s = 1;
330 else
331 s = -1;
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100332 }
333 }
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100334 if (s<0)
335 sign = 1;
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100336 else
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100337 sign = 0;
338 //printf ("%d %d ", sign, best);
339 ec_enc_uint(enc,sign,2);
Jean-Marc Valin8f0f4b92008-02-11 13:52:44 +1100340 ec_enc_uint(enc,best/B,max_pos);
Jean-Marc Valin50d11162007-12-03 14:34:52 +1100341 //printf ("%d %f\n", best, best_score);
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100342
343 float pred_gain;
344 if (K>10)
345 pred_gain = pg[10];
346 else
347 pred_gain = pg[K];
348 E = 1e-10;
349 for (j=0;j<N;j++)
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100350 {
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100351 P[j] = s*Y[best+j];
352 E += P[j]*P[j];
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100353 }
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100354 E = pred_gain/sqrt(E);
355 for (j=0;j<N;j++)
356 P[j] *= E;
357 if (K>0)
358 {
359 for (j=0;j<N;j++)
360 x[j] -= P[j];
361 } else {
362 for (j=0;j<N;j++)
363 x[j] = P[j];
364 }
365 //printf ("quant ");
366 //for (j=0;j<N;j++) printf ("%f ", P[j]);
367
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100368}
Jean-Marc Valinfc08d0a2007-12-07 13:26:15 +1100369
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100370void 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 +1100371{
Jean-Marc Valin11f01722007-12-09 01:19:36 +1100372 int j;
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100373 int sign;
374 float s;
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100375 int best;
376 float E;
Jean-Marc Valin8f0f4b92008-02-11 13:52:44 +1100377 int max_pos = N0-N/B;
378 if (max_pos > 32)
379 max_pos = 32;
380
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100381 sign = ec_dec_uint(dec, 2);
382 if (sign == 0)
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100383 s = 1;
384 else
385 s = -1;
386
Jean-Marc Valin8f0f4b92008-02-11 13:52:44 +1100387 best = B*ec_dec_uint(dec, max_pos);
Jean-Marc Valin0aa39032007-12-07 15:09:58 +1100388 //printf ("%d %d ", sign, best);
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100389
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100390 float pred_gain;
391 if (K>10)
392 pred_gain = pg[10];
393 else
394 pred_gain = pg[K];
395 E = 1e-10;
396 for (j=0;j<N;j++)
397 {
398 P[j] = s*Y[best+j];
399 E += P[j]*P[j];
400 }
401 E = pred_gain/sqrt(E);
402 for (j=0;j<N;j++)
403 P[j] *= E;
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100404 if (K==0)
405 {
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100406 for (j=0;j<N;j++)
Jean-Marc Valin0d227d82007-12-31 16:12:12 +1100407 x[j] = P[j];
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +1100408 }
409}
Jean-Marc Valin0e20ca02008-02-11 15:33:53 +1100410
411void intra_fold(float *x, int N, int K, float *Y, float *P, int B, int N0)
412{
413 int j;
414 float E;
415
416 E = 1e-10;
417 for (j=0;j<N;j++)
418 {
419 P[j] = Y[j];
420 E += P[j]*P[j];
421 }
422 E = 1.f/sqrt(E);
423 for (j=0;j<N;j++)
424 P[j] *= E;
425 for (j=0;j<N;j++)
426 x[j] = P[j];
427}
428