blob: a896274ded575730f2697676bc77900f5ad05fc6 [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 Valinfc08d0a2007-12-07 13:26:15 +110041void alg_quant(float *x, int N, int K, float *p, ec_enc *enc)
Jean-Marc Valin41af4212007-11-30 18:35:37 +110042{
43 int L = 5;
44 //float tata[200];
45 float y[L][N];
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +110046 int iy[L][N];
Jean-Marc Valin41af4212007-11-30 18:35:37 +110047 //float tata2[200];
48 float ny[L][N];
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +110049 int iny[L][N];
Jean-Marc Valin41af4212007-11-30 18:35:37 +110050 int i, j, m;
51 float xy[L], nxy[L];
52 float yy[L], nyy[L];
53 float yp[L], nyp[L];
54 float best_scores[L];
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +110055 float Rpp=0, Rxp=0;
Jean-Marc Valin41af4212007-11-30 18:35:37 +110056 float gain[L];
57 int maxL = 1;
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +110058 float alpha = .9;
59
Jean-Marc Valin41af4212007-11-30 18:35:37 +110060 for (j=0;j<N;j++)
61 Rpp += p[j]*p[j];
Jean-Marc Valinfc08d0a2007-12-07 13:26:15 +110062 //if (Rpp>.01)
63 // alpha = (1-sqrt(1-Rpp))/Rpp;
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +110064 for (j=0;j<N;j++)
65 Rxp += x[j]*p[j];
Jean-Marc Valin41af4212007-11-30 18:35:37 +110066 for (m=0;m<L;m++)
67 for (i=0;i<N;i++)
68 y[m][i] = 0;
69
70 for (m=0;m<L;m++)
71 for (i=0;i<N;i++)
72 ny[m][i] = 0;
73
74 for (m=0;m<L;m++)
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +110075 for (i=0;i<N;i++)
76 iy[m][i] = iny[m][i] = 0;
77
78 for (m=0;m<L;m++)
Jean-Marc Valin41af4212007-11-30 18:35:37 +110079 xy[m] = yy[m] = yp[m] = gain[m] = 0;
80
81 for (i=0;i<K;i++)
82 {
83 int L2 = L;
84 if (L>maxL)
85 {
86 L2 = maxL;
87 maxL *= N;
88 }
89 for (m=0;m<L;m++)
90 best_scores[m] = -1e10;
91
92 for (m=0;m<L2;m++)
93 {
94 for (j=0;j<N;j++)
95 {
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +110096 int sign;
97 for (sign=-1;sign<=1;sign+=2)
Jean-Marc Valin41af4212007-11-30 18:35:37 +110098 {
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +110099 if (iy[m][j]*sign < 0)
100 continue;
101 //fprintf (stderr, "%d/%d %d/%d %d/%d\n", i, K, m, L2, j, N);
102 float tmp_xy, tmp_yy, tmp_yp;
103 float score;
104 float g;
105 float s = sign;
106 tmp_xy = xy[m] + s*x[j] - alpha*s*p[j]*Rxp;
107 tmp_yy = yy[m] + 2*s*y[m][j] + 1 +alpha*alpha*p[j]*p[j]*Rpp - 2*alpha*s*p[j]*yp[m] - 2*alpha*p[j]*p[j];
108 tmp_yp = yp[m] + s*p[j] *(1-alpha*Rpp);
109 g = (sqrt(tmp_yp*tmp_yp + tmp_yy - tmp_yy*Rpp) - tmp_yp)/tmp_yy;
110 score = 2*g*tmp_xy - g*g*tmp_yy;
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100111
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100112 if (score>best_scores[L-1])
113 {
114 int k, n;
115 int id = L-1;
116 while (id > 0 && score > best_scores[id-1])
117 id--;
118
119 for (k=L-1;k>id;k--)
120 {
121 nxy[k] = nxy[k-1];
122 nyy[k] = nyy[k-1];
123 nyp[k] = nyp[k-1];
124 //fprintf(stderr, "%d %d \n", N, k);
125 for (n=0;n<N;n++)
126 ny[k][n] = ny[k-1][n];
127 for (n=0;n<N;n++)
128 iny[k][n] = iny[k-1][n];
129 gain[k] = gain[k-1];
130 best_scores[k] = best_scores[k-1];
131 }
132
133 nxy[id] = tmp_xy;
134 nyy[id] = tmp_yy;
135 nyp[id] = tmp_yp;
136 gain[id] = g;
137 for (n=0;n<N;n++)
138 ny[id][n] = y[m][n];
139 ny[id][j] += s;
140 for (n=0;n<N;n++)
141 ny[id][n] -= alpha*s*p[j]*p[n];
142
143 for (n=0;n<N;n++)
144 iny[id][n] = iy[m][n];
145 if (s>0)
146 iny[id][j] += 1;
147 else
148 iny[id][j] -= 1;
149 best_scores[id] = score;
150 }
151 }
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100152 }
153
154 }
155 int k,n;
156 for (k=0;k<L;k++)
157 {
158 xy[k] = nxy[k];
159 yy[k] = nyy[k];
160 yp[k] = nyp[k];
161 for (n=0;n<N;n++)
162 y[k][n] = ny[k][n];
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100163 for (n=0;n<N;n++)
164 iy[k][n] = iny[k][n];
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100165 }
166
167 }
168
169 for (i=0;i<N;i++)
170 x[i] = p[i]+gain[0]*y[0][i];
Jean-Marc Valin1e7087e2007-12-04 13:05:43 +1100171 if (0) {
172 float E=1e-15;
173 int ABS = 0;
174 for (i=0;i<N;i++)
175 ABS += abs(iy[0][i]);
176 //if (K != ABS)
177 // printf ("%d %d\n", K, ABS);
178 for (i=0;i<N;i++)
179 E += x[i]*x[i];
180 //printf ("%f\n", E);
181 E = 1/sqrt(E);
182 for (i=0;i<N;i++)
183 x[i] *= E;
184 }
Jean-Marc Valin29ccab82007-12-06 15:39:38 +1100185 int comb[K];
186 int signs[K];
187 pulse2comb(N, K, comb, signs, iy[0]);
Jean-Marc Valin9cace642007-12-06 17:44:09 +1100188 ec_enc_uint(enc,icwrs(N, K, comb, signs),ncwrs(N, K));
Jean-Marc Valin41af4212007-11-30 18:35:37 +1100189}
190
Jean-Marc Valin25298f22007-12-03 15:24:11 +1100191static const float pg[5] = {1.f, .82f, .75f, 0.7f, 0.6f};
192
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100193/* Finds the right offset into Y and copy it */
Jean-Marc Valin9cace642007-12-06 17:44:09 +1100194void copy_quant(float *x, int N, int K, float *Y, int B, int N0, ec_enc *enc)
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100195{
196 int i,j;
197 int best=0;
Jean-Marc Valin50d11162007-12-03 14:34:52 +1100198 float best_score=0;
199 float s = 1;
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100200 float E;
201 for (i=0;i<N0*B-N;i+=B)
202 {
203 int j;
204 float xy=0, yy=0;
205 float score;
206 for (j=0;j<N;j++)
207 {
208 xy += x[j]*Y[i+j];
209 yy += Y[i+j]*Y[i+j];
210 }
Jean-Marc Valin50d11162007-12-03 14:34:52 +1100211 score = xy*xy/(.001+yy);
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100212 if (score > best_score)
213 {
214 best_score = score;
215 best = i;
Jean-Marc Valin50d11162007-12-03 14:34:52 +1100216 if (xy>0)
217 s = 1;
218 else
219 s = -1;
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100220 }
221 }
Jean-Marc Valin9cace642007-12-06 17:44:09 +1100222 ec_enc_uint(enc,best/B,N0-N/B);
Jean-Marc Valin50d11162007-12-03 14:34:52 +1100223 //printf ("%d %f\n", best, best_score);
Jean-Marc Valin25298f22007-12-03 15:24:11 +1100224 if (K==0)
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100225 {
Jean-Marc Valin25298f22007-12-03 15:24:11 +1100226 E = 1e-10;
227 for (j=0;j<N;j++)
228 {
229 x[j] = s*Y[best+j];
230 E += x[j]*x[j];
231 }
232 E = 1/sqrt(E);
233 for (j=0;j<N;j++)
234 x[j] *= E;
235 } else {
236 float P[N];
237 float pred_gain;
238 if (K>4)
239 pred_gain = .5;
240 else
241 pred_gain = pg[K];
242 E = 1e-10;
243 for (j=0;j<N;j++)
244 {
245 P[j] = s*Y[best+j];
246 E += P[j]*P[j];
247 }
248 E = .8/sqrt(E);
249 for (j=0;j<N;j++)
250 P[j] *= E;
Jean-Marc Valinfc08d0a2007-12-07 13:26:15 +1100251 alg_quant(x, N, K, P, enc);
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100252 }
Jean-Marc Valin4841a0a2007-12-03 13:54:30 +1100253}
Jean-Marc Valinfc08d0a2007-12-07 13:26:15 +1100254
255void alg_unquant(float *x, int N, int K, float *p, ec_dec *dec)
256{
257 int i;
258 unsigned int id;
259 int comb[K];
260 int signs[K];
261 int iy[N];
262 float y[N];
263 float alpha = .9;
264 float Rpp=0, Ryp=0, Ryy=0;
265 float g;
266
267 id = ec_dec_uint(dec, ncwrs(N, K));
268 cwrsi(N, K, id, comb, signs);
269 comb2pulse(N, K, iy, comb, signs);
270
271 for (i=0;i<N;i++)
272 Rpp += p[i]*p[i];
273
274 for (i=0;i<N;i++)
275 Ryp += iy[i]*p[i];
276
277 for (i=0;i<N;i++)
278 y[i] = iy[i] - Ryp*p[i];
279
280 /* Recompute after the projection (I think it's right) */
281 Ryp = 0;
282 for (i=0;i<N;i++)
283 Ryp += y[i]*p[i];
284
285 for (i=0;i<N;i++)
286 Ryy += y[i]*y[i];
287
288 g = (sqrt(Ryp*Ryp + Ryy - Ryy*Rpp) - Ryp)/Ryy;
289
290 for (i=0;i<N;i++)
291 x[i] = p[i] + g*y[i];
292}
293