1 /* Original copyright */
2 /*-----------------------------------------------------------------------*\
4 FILE........: GAINSHAPE.C
6 AUTHOR......: David Rowe
7 COMPANY.....: Voicetronix
10 General gain-shape codebook search.
12 \*-----------------------------------------------------------------------*/
15 /* Modified by Jean-Marc Valin 2002
17 This library is free software; you can redistribute it and/or
18 modify it under the terms of the GNU Lesser General Public
19 License as published by the Free Software Foundation; either
20 version 2.1 of the License, or (at your option) any later version.
22 This library is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 Lesser General Public License for more details.
27 You should have received a copy of the GNU Lesser General Public
28 License along with this library; if not, write to the Free Software
29 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
35 #include <cb_search.h>
39 #include "stack_alloc.h"
43 static float scal_gains4[16] = {
55 /*---------------------------------------------------------------------------*\
57 void overlap_cb_search()
59 Searches a gain/shape codebook consisting of overlapping entries for the
60 closest vector to the target. Gives identical results to search() above
61 buts uses fast end correction algorithm for the synthesis of response
64 \*---------------------------------------------------------------------------*/
66 float overlap_cb_search(
67 float target[], /* target vector */
68 float ak[], /* LPCs for this subframe */
69 float awk1[], /* Weighted LPCs for this subframe */
70 float awk2[], /* Weighted LPCs for this subframe */
71 float codebook[], /* overlapping codebook */
72 int entries, /* number of overlapping entries to search */
73 float *gain, /* gain of optimum entry */
74 int *index, /* index of optimum entry */
75 int p, /* number of LPC coeffs */
76 int nsf, /* number of samples in subframe */
80 float *resp; /* zero state response to current entry */
81 float *h; /* impulse response of synthesis filter */
82 float *impulse; /* excitation vector containing one impulse */
83 float d,e,g,score; /* codebook searching variables */
84 float bscore; /* score of "best" vector so far */
85 int i,k; /* loop variables */
89 /*resp = (float*)malloc(sizeof(float)*nsf);
90 h = (float*)malloc(sizeof(float)*nsf);
91 impulse = (float*)malloc(sizeof(float)*nsf);
93 resp=PUSH(stack, nsf);
95 impulse=PUSH(stack, nsf);
105 /* Calculate impulse response of A(z/g1) / ( A(z)*(z/g2) ) */
106 residue_zero(impulse, awk1, h, nsf, p);
107 syn_filt_zero(h, ak, h, nsf, p);
108 syn_filt_zero(h, awk2, h, nsf,p);
110 /* Calculate codebook zero-response */
111 residue_zero(&codebook[entries-1],awk1,resp,nsf,p);
112 syn_filt_zero(resp,ak,resp,nsf,p);
113 syn_filt_zero(resp,awk2,resp,nsf,p);
115 /* Search codebook backwards using end correction for synthesis */
117 for(k=entries-1; k>=0; k--) {
120 for(i=0; i<nsf; i++) {
121 d += target[i]*resp[i];
122 e += resp[i]*resp[i];
126 /*printf ("score: %f %f %f %f\n", target[0],d,e,score);*/
127 if (score >= bscore) {
133 /* Synthesise next entry */
136 for(i=nsf-1; i>=1; i--)
137 resp[i] = resp[i-1] + codebook[k-1]*h[i];
138 resp[0] = codebook[k-1]*h[0];
153 void split_cb_search(
154 float target[], /* target vector */
155 float ak[], /* LPCs for this subframe */
156 float awk1[], /* Weighted LPCs for this subframe */
157 float awk2[], /* Weighted LPCs for this subframe */
158 void *par, /* Codebook/search parameters*/
159 int p, /* number of LPC coeffs */
160 int nsf, /* number of samples in subframe */
172 int shape_cb_size, subvect_size, nb_subvect;
174 split_cb_params *params;
176 params = (split_cb_params *) par;
177 subvect_size = params->subvect_size;
178 nb_subvect = params->nb_subvect;
179 shape_cb_size = 1<<params->shape_bits;
180 shape_cb = params->shape_cb;
181 resp = PUSH(stack, shape_cb_size*subvect_size);
182 E = PUSH(stack, shape_cb_size);
183 t = PUSH(stack, nsf);
184 r = PUSH(stack, nsf);
185 e = PUSH(stack, nsf);
186 gains = PUSH(stack, nb_subvect);
187 ind = (int*)PUSH(stack, nb_subvect);
189 /* Compute energy of the "real excitation" */
190 syn_filt_zero(target, awk1, e, nsf, p);
191 residue_zero(e, ak, e, nsf, p);
192 residue_zero(e, awk2, e, nsf, p);
194 exc_energy += e[i]*e[i];
195 exc_energy=sqrt(exc_energy/nb_subvect);
197 /* Quantize global ("average") gain */
198 q=log(exc_energy+.1);
205 frame_bits_pack(bits, id, 4);
206 exc_energy=exp(.5*q+2);
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);
219 /* Pre-compute codewords response and energy */
220 for (i=0;i<shape_cb_size;i++)
222 float *res = resp+i*subvect_size;
224 /* Compute codeword response */
226 for(j=0;j<subvect_size;j++)
228 for(j=0;j<subvect_size;j++)
230 for (k=j;k<subvect_size;k++)
231 res[k]+=shape_cb[i*subvect_size+j]*r[k-j];
233 /* Compute energy of codeword response */
235 for(j=0;j<subvect_size;j++)
240 for (i=0;i<nb_subvect;i++)
242 int best_index=0, k, m;
243 float g, corr, best_gain=0, score, best_score=-1;
244 /* Find best codeword for current sub-vector */
245 for (j=0;j<shape_cb_size;j++)
247 corr=xcorr(resp+j*subvect_size,t+subvect_size*i,subvect_size);
248 score=corr*corr*E[j];
250 if (score>best_score)
257 frame_bits_pack(bits,best_index,params->shape_bits);
262 best_gain /= .01+exc_energy;
265 best_gain=-best_gain;
269 /* Find gain index (it's a scalar but we use the VQ code anyway)*/
270 best_id = vq_index(&best_gain, scal_gains4, 1, 8);
272 best_gain=scal_gains4[best_id];
273 /*printf ("gain_quant: %f %d %f\n", best_gain, best_id, scal_gains4[best_id]);*/
275 best_gain=-best_gain;
276 best_gain *= exc_energy;
277 frame_bits_pack(bits,s,1);
278 frame_bits_pack(bits,best_id,3);
282 /* Update target for next subvector */
283 for (j=0;j<subvect_size;j++)
285 g=best_gain*shape_cb[best_index*subvect_size+j];
286 for (k=subvect_size*i+j,m=0;k<nsf;k++,m++)
291 /* Put everything back together */
292 for (i=0;i<nb_subvect;i++)
293 for (j=0;j<subvect_size;j++)
294 e[subvect_size*i+j]=gains[i]*shape_cb[ind[i]*subvect_size+j];
296 /* Update excitation */
301 residue_zero(e, awk1, r, nsf, p);
302 syn_filt_zero(r, ak, r, nsf, p);
303 syn_filt_zero(r, awk2, r, nsf,p);
321 void split_cb_unquant(
323 void *par, /* non-overlapping codebook */
324 int nsf, /* number of samples in subframe */
333 float *shape_cb, exc_energy;
334 int shape_cb_size, subvect_size, nb_subvect;
335 split_cb_params *params;
337 params = (split_cb_params *) par;
338 subvect_size = params->subvect_size;
339 nb_subvect = params->nb_subvect;
340 shape_cb_size = 1<<params->shape_bits;
341 shape_cb = params->shape_cb;
343 ind = (int*)PUSH(stack, nb_subvect);
344 gains = PUSH(stack, nb_subvect);
345 sign = PUSH(stack, nb_subvect);
347 /* Decode global (average) gain */
350 id = frame_bits_unpack_unsigned(bits, 4);
351 exc_energy=exp(.5*id+2);
354 /* Decode codewords and gains */
355 for (i=0;i<nb_subvect;i++)
358 ind[i] = frame_bits_unpack_unsigned(bits, params->shape_bits);
359 if (frame_bits_unpack_unsigned(bits, 1))
364 gain_id = frame_bits_unpack_unsigned(bits, 3);
365 gains[i]=scal_gains4[gain_id];
367 gains[i] *= exc_energy;
372 /* Compute decoded excitation */
373 for (i=0;i<nb_subvect;i++)
374 for (j=0;j<subvect_size;j++)
375 exc[subvect_size*i+j]+=gains[i]*shape_cb[ind[i]*subvect_size+j];