1 /*-----------------------------------------------------------------------*\
3 FILE........: GAINSHAPE.C
5 AUTHOR......: David Rowe
6 COMPANY.....: Voicetronix
9 General gain-shape codebook search.
11 \*-----------------------------------------------------------------------*/
13 /* Modified by Jean-Marc Valin 2002
15 This library is free software; you can redistribute it and/or
16 modify it under the terms of the GNU Lesser General Public
17 License as published by the Free Software Foundation; either
18 version 2.1 of the License, or (at your option) any later version.
20 This library is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 Lesser General Public License for more details.
25 You should have received a copy of the GNU Lesser General Public
26 License along with this library; if not, write to the Free Software
27 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33 #include <cb_search.h>
37 #include "stack_alloc.h"
41 /*---------------------------------------------------------------------------*\
43 void overlap_cb_search()
45 Searches a gain/shape codebook consisting of overlapping entries for the
46 closest vector to the target. Gives identical results to search() above
47 buts uses fast end correction algorithm for the synthesis of response
50 \*---------------------------------------------------------------------------*/
52 float overlap_cb_search(
53 float target[], /* target vector */
54 float ak[], /* LPCs for this subframe */
55 float awk1[], /* Weighted LPCs for this subframe */
56 float awk2[], /* Weighted LPCs for this subframe */
57 float codebook[], /* overlapping codebook */
58 int entries, /* number of overlapping entries to search */
59 float *gain, /* gain of optimum entry */
60 int *index, /* index of optimum entry */
61 int p, /* number of LPC coeffs */
62 int nsf /* number of samples in subframe */
65 float *resp; /* zero state response to current entry */
66 float *h; /* impulse response of synthesis filter */
67 float *impulse; /* excitation vector containing one impulse */
68 float d,e,g,score; /* codebook searching variables */
69 float bscore; /* score of "best" vector so far */
70 int i,k; /* loop variables */
74 resp = (float*)malloc(sizeof(float)*nsf);
75 h = (float*)malloc(sizeof(float)*nsf);
76 impulse = (float*)malloc(sizeof(float)*nsf);
86 /* Calculate impulse response of A(z/g2) / ( A(z)*(z/g1) ) */
87 residue_zero(impulse, awk1, h, nsf, p);
88 syn_filt_zero(h, ak, h, nsf, p);
89 syn_filt_zero(h, awk2, h, nsf,p);
91 /* Calculate codebook zero-response */
92 residue_zero(&codebook[entries-1],awk1,resp,nsf,p);
93 syn_filt_zero(resp,ak,resp,nsf,p);
94 syn_filt_zero(resp,awk2,resp,nsf,p);
96 /* Search codebook backwards using end correction for synthesis */
98 for(k=entries-1; k>=0; k--) {
101 for(i=0; i<nsf; i++) {
102 d += target[i]*resp[i];
103 e += resp[i]*resp[i];
107 /*printf ("score: %f %f %f %f\n", target[0],d,e,score);*/
108 if (score >= bscore) {
114 /* Synthesise next entry */
117 for(i=nsf-1; i>=1; i--)
118 resp[i] = resp[i-1] + codebook[k-1]*h[i];
119 resp[0] = codebook[k-1]*h[0];
132 void split_cb_search(
133 float target[], /* target vector */
134 float ak[], /* LPCs for this subframe */
135 float awk1[], /* Weighted LPCs for this subframe */
136 float awk2[], /* Weighted LPCs for this subframe */
137 void *par, /* Codebook/search parameters*/
138 int p, /* number of LPC coeffs */
139 int nsf, /* number of samples in subframe */
146 float *resp, *E, *Ee;
150 float *shape_cb, *gain_cb;
151 int shape_cb_size, gain_cb_size, subvect_size, nb_subvect;
152 split_cb_params *params;
154 params = (split_cb_params *) par;
155 subvect_size = params->subvect_size;
156 nb_subvect = params->nb_subvect;
157 shape_cb_size = 1<<params->shape_bits;
158 shape_cb = params->shape_cb;
159 gain_cb_size = 1<<params->gain_bits;
160 gain_cb = params->gain_cb;
161 resp = PUSH(stack, shape_cb_size*subvect_size);
162 E = PUSH(stack, shape_cb_size);
163 Ee = PUSH(stack, shape_cb_size);
164 t = PUSH(stack, nsf);
165 r = PUSH(stack, nsf);
166 e = PUSH(stack, nsf);
167 gains = PUSH(stack, nb_subvect);
168 ind = (int*)PUSH(stack, nb_subvect);
173 for (i=0;i<shape_cb_size;i++)
175 float *res = resp+i*subvect_size;
176 residue_zero(shape_cb+i*subvect_size, awk1, res, subvect_size, p);
177 syn_filt_zero(res, ak, res, subvect_size, p);
178 syn_filt_zero(res, awk2, res, subvect_size,p);
180 for(j=0;j<subvect_size;j++)
183 for(j=0;j<subvect_size;j++)
184 Ee[i]+=shape_cb[i*subvect_size+j]*shape_cb[i*subvect_size+j];
187 for (i=0;i<nb_subvect;i++)
190 float g, corr, best_gain=0, score, best_score=-1;
191 for (j=0;j<shape_cb_size;j++)
193 corr=xcorr(resp+j*subvect_size,t+subvect_size*i,subvect_size);
194 score=corr*corr/(.001+E[j]);
195 g = corr/(.001+E[j]);
196 if (score>best_score)
200 best_gain=corr/(.001+E[j]);
203 frame_bits_pack(bits,best_index,params->shape_bits);
205 frame_bits_pack(bits,0,1);
207 frame_bits_pack(bits,1,1);
209 gains[i]=best_gain*Ee[ind[i]];
213 for (j=0;j<subvect_size;j++)
214 e[subvect_size*i+j]=best_gain*shape_cb[best_index*subvect_size+j];
215 residue_zero(e, awk1, r, nsf, p);
216 syn_filt_zero(r, ak, r, nsf, p);
217 syn_filt_zero(r, awk2, r, nsf,p);
223 int best_vq_index=0, max_index;
224 float max_gain=0, log_max, min_dist=0, *sign;
226 if (gain_cb) /*If no gain codebook, do not quantize (for testing/debugging) */
228 sign = PUSH(stack, nb_subvect);
229 for (i=0;i<nb_subvect;i++)
239 for (i=0;i<nb_subvect;i++)
240 if (gains[i]>max_gain)
242 log_max=log(max_gain+1);
243 max_index = (int)(floor(.5+log_max-3));
248 max_gain=1/exp(max_index+3.0);
249 for (i=0;i<nb_subvect;i++)
251 frame_bits_pack(bits,max_index,3);
253 /*Vector quantize gains[i]*/
255 best_vq_index = vq_index(gains, gain_cb, nb_subvect, gain_cb_size);
256 frame_bits_pack(bits,best_vq_index,params->gain_bits);
257 printf ("best_gains_vq_index %d %f %d\n", best_vq_index, min_dist, max_index);
258 for (i=0;i<nb_subvect;i++)
259 gains[i]= sign[i]*gain_cb[best_vq_index*nb_subvect+i]/max_gain/(Ee[ind[i]]+.001);
261 best_vq_index = vq_index(gains, gain_cb, nb_subvect/2, gain_cb_size);
262 frame_bits_pack(bits,best_vq_index,params->gain_bits);
263 printf ("best_gains_vq_index %d %f %d\n", best_vq_index, min_dist, max_index);
264 for (i=0;i<nb_subvect/2;i++)
265 gains[i]= sign[i]*gain_cb[best_vq_index*nb_subvect+i]/max_gain/(Ee[ind[i]]+.001);
267 best_vq_index = vq_index(gains+5, gain_cb, nb_subvect/2, gain_cb_size);
268 frame_bits_pack(bits,best_vq_index,params->gain_bits);
269 printf ("best_gains_vq_index %d %f %d\n", best_vq_index, min_dist, max_index);
270 for (i=0;i<nb_subvect/2;i++)
271 gains[i+5]= sign[i+5]*gain_cb[best_vq_index*nb_subvect+i]/max_gain/(Ee[ind[i+5]]+.001);
278 for (i=0;i<nb_subvect;i++)
279 printf ("%f ", gains[i]);
281 for (i=0;i<nb_subvect;i++)
282 gains[i]= gains[i]/(Ee[ind[i]]+.001);
285 for (i=0;i<nb_subvect;i++)
286 for (j=0;j<subvect_size;j++)
287 exc[subvect_size*i+j]+=gains[i]*shape_cb[ind[i]*subvect_size+j];
291 /*TODO: Perform joint optimization of gains*/
306 void split_cb_unquant(
308 void *par, /* non-overlapping codebook */
309 int nsf, /* number of samples in subframe */
318 int max_gain_ind, vq_gain_ind;
320 float *shape_cb, *gain_cb;
321 int shape_cb_size, gain_cb_size, subvect_size, nb_subvect;
322 split_cb_params *params;
324 params = (split_cb_params *) par;
325 subvect_size = params->subvect_size;
326 nb_subvect = params->nb_subvect;
327 shape_cb_size = 1<<params->shape_bits;
328 shape_cb = params->shape_cb;
329 gain_cb_size = 1<<params->gain_bits;
330 gain_cb = params->gain_cb;
332 ind = (int*)PUSH(stack, nb_subvect);
333 gains = PUSH(stack, nb_subvect);
334 sign = PUSH(stack, nb_subvect);
335 Ee=PUSH(stack, nb_subvect);
337 for (i=0;i<nb_subvect;i++)
339 ind[i] = frame_bits_unpack_unsigned(bits, params->shape_bits);
340 if (frame_bits_unpack_unsigned(bits, 1))
345 for (j=0;j<subvect_size;j++)
346 Ee[i]+=shape_cb[ind[i]*subvect_size+j]*shape_cb[ind[i]*subvect_size+j];
348 max_gain_ind = frame_bits_unpack_unsigned(bits, 3);
349 vq_gain_ind = frame_bits_unpack_unsigned(bits, params->gain_bits);
350 printf ("unquant gains ind: %d %d\n", max_gain_ind, vq_gain_ind);
352 max_gain=exp(max_gain_ind+3.0);
353 for (i=0;i<nb_subvect;i++)
354 gains[i] = sign[i]*gain_cb[vq_gain_ind*nb_subvect+i]*max_gain/Ee[i];
356 printf ("unquant gains: ");
357 for (i=0;i<nb_subvect;i++)
358 printf ("%f ", gains[i]);
361 for (i=0;i<nb_subvect;i++)
362 for (j=0;j<subvect_size;j++)
363 exc[subvect_size*i+j]+=gains[i]*shape_cb[ind[i]*subvect_size+j];