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 #define min(a,b) ((a) < (b) ? (a) : (b))
44 #define max(a,b) ((a) > (b) ? (a) : (b))
47 static float scal_gains4[16] = {
59 /*---------------------------------------------------------------------------*\
61 void overlap_cb_search()
63 Searches a gain/shape codebook consisting of overlapping entries for the
64 closest vector to the target. Gives identical results to search() above
65 buts uses fast end correction algorithm for the synthesis of response
68 \*---------------------------------------------------------------------------*/
70 float overlap_cb_search(
71 float target[], /* target vector */
72 float ak[], /* LPCs for this subframe */
73 float awk1[], /* Weighted LPCs for this subframe */
74 float awk2[], /* Weighted LPCs for this subframe */
75 float codebook[], /* overlapping codebook */
76 int entries, /* number of overlapping entries to search */
77 float *gain, /* gain of optimum entry */
78 int *index, /* index of optimum entry */
79 int p, /* number of LPC coeffs */
80 int nsf, /* number of samples in subframe */
84 float *resp; /* zero state response to current entry */
85 float *h; /* impulse response of synthesis filter */
86 float *impulse; /* excitation vector containing one impulse */
87 float d,e,g,score; /* codebook searching variables */
88 float bscore; /* score of "best" vector so far */
89 int i,k; /* loop variables */
93 /*resp = (float*)malloc(sizeof(float)*nsf);
94 h = (float*)malloc(sizeof(float)*nsf);
95 impulse = (float*)malloc(sizeof(float)*nsf);
97 resp=PUSH(stack, nsf);
99 impulse=PUSH(stack, nsf);
109 /* Calculate impulse response of A(z/g1) / ( A(z)*(z/g2) ) */
110 residue_zero(impulse, awk1, h, nsf, p);
111 syn_filt_zero(h, ak, h, nsf, p);
112 syn_filt_zero(h, awk2, h, nsf,p);
114 /* Calculate codebook zero-response */
115 residue_zero(&codebook[entries-1],awk1,resp,nsf,p);
116 syn_filt_zero(resp,ak,resp,nsf,p);
117 syn_filt_zero(resp,awk2,resp,nsf,p);
119 /* Search codebook backwards using end correction for synthesis */
121 for(k=entries-1; k>=0; k--) {
124 for(i=0; i<nsf; i++) {
125 d += target[i]*resp[i];
126 e += resp[i]*resp[i];
130 /*printf ("score: %f %f %f %f\n", target[0],d,e,score);*/
131 if (score >= bscore) {
137 /* Synthesise next entry */
140 for(i=nsf-1; i>=1; i--)
141 resp[i] = resp[i-1] + codebook[k-1]*h[i];
142 resp[0] = codebook[k-1]*h[0];
157 void split_cb_search(
158 float target[], /* target vector */
159 float ak[], /* LPCs for this subframe */
160 float awk1[], /* Weighted LPCs for this subframe */
161 float awk2[], /* Weighted LPCs for this subframe */
162 void *par, /* Codebook/search parameters*/
163 int p, /* number of LPC coeffs */
164 int nsf, /* number of samples in subframe */
176 int shape_cb_size, subvect_size, nb_subvect;
178 split_cb_params *params;
180 params = (split_cb_params *) par;
181 subvect_size = params->subvect_size;
182 nb_subvect = params->nb_subvect;
183 shape_cb_size = 1<<params->shape_bits;
184 shape_cb = params->shape_cb;
185 resp = PUSH(stack, shape_cb_size*subvect_size);
186 E = PUSH(stack, shape_cb_size);
187 t = PUSH(stack, nsf);
188 r = PUSH(stack, nsf);
189 e = PUSH(stack, nsf);
190 gains = PUSH(stack, nb_subvect);
191 ind = (int*)PUSH(stack, nb_subvect);
193 /* Compute energy of the "real excitation" */
194 syn_filt_zero(target, awk1, e, nsf, p);
195 residue_zero(e, ak, e, nsf, p);
196 residue_zero(e, awk2, e, nsf, p);
198 exc_energy += e[i]*e[i];
199 exc_energy=sqrt(exc_energy/nb_subvect);
201 /* Quantize global ("average") gain */
202 q=log(exc_energy+.1);
209 frame_bits_pack(bits, id, 4);
210 exc_energy=exp(.5*q+2);
219 residue_zero(e, awk1, r, nsf, p);
220 syn_filt_zero(r, ak, r, nsf, p);
221 syn_filt_zero(r, awk2, r, nsf,p);
223 /* Pre-compute codewords response and energy */
224 for (i=0;i<shape_cb_size;i++)
226 float *res = resp+i*subvect_size;
228 /* Compute codeword response */
230 for(j=0;j<subvect_size;j++)
232 for(j=0;j<subvect_size;j++)
234 for (k=j;k<subvect_size;k++)
235 res[k]+=shape_cb[i*subvect_size+j]*r[k-j];
237 /* Compute energy of codeword response */
239 for(j=0;j<subvect_size;j++)
244 for (i=0;i<nb_subvect;i++)
246 int best_index=0, k, m;
247 float g, corr, best_gain=0, score, best_score=-1;
248 /* Find best codeword for current sub-vector */
249 for (j=0;j<shape_cb_size;j++)
251 corr=xcorr(resp+j*subvect_size,t+subvect_size*i,subvect_size);
252 score=corr*corr*E[j];
254 if (score>best_score)
261 frame_bits_pack(bits,best_index,params->shape_bits);
266 best_gain /= .01+exc_energy;
269 best_gain=-best_gain;
273 /* Find gain index (it's a scalar but we use the VQ code anyway)*/
274 best_id = vq_index(&best_gain, scal_gains4, 1, 8);
276 best_gain=scal_gains4[best_id];
277 /*printf ("gain_quant: %f %d %f\n", best_gain, best_id, scal_gains4[best_id]);*/
279 best_gain=-best_gain;
280 best_gain *= exc_energy;
281 frame_bits_pack(bits,s,1);
282 frame_bits_pack(bits,best_id,3);
286 /* Update target for next subvector */
287 for (j=0;j<subvect_size;j++)
289 g=best_gain*shape_cb[best_index*subvect_size+j];
290 for (k=subvect_size*i+j,m=0;k<nsf;k++,m++)
295 /* Put everything back together */
296 for (i=0;i<nb_subvect;i++)
297 for (j=0;j<subvect_size;j++)
298 e[subvect_size*i+j]=gains[i]*shape_cb[ind[i]*subvect_size+j];
300 /* Update excitation */
305 residue_zero(e, awk1, r, nsf, p);
306 syn_filt_zero(r, ak, r, nsf, p);
307 syn_filt_zero(r, awk2, r, nsf,p);
322 void split_cb_search_nogain(
323 float target[], /* target vector */
324 float ak[], /* LPCs for this subframe */
325 float awk1[], /* Weighted LPCs for this subframe */
326 float awk2[], /* Weighted LPCs for this subframe */
327 void *par, /* Codebook/search parameters*/
328 int p, /* number of LPC coeffs */
329 int nsf, /* number of samples in subframe */
340 int shape_cb_size, subvect_size, nb_subvect;
341 split_cb_params *params;
343 params = (split_cb_params *) par;
344 subvect_size = params->subvect_size;
345 nb_subvect = params->nb_subvect;
346 shape_cb_size = 1<<params->shape_bits;
347 shape_cb = params->shape_cb;
348 resp = PUSH(stack, shape_cb_size*subvect_size);
349 t = PUSH(stack, nsf);
350 r = PUSH(stack, nsf);
351 e = PUSH(stack, nsf);
352 ind = (int*)PUSH(stack, nb_subvect);
360 residue_zero(e, awk1, r, nsf, p);
361 syn_filt_zero(r, ak, r, nsf, p);
362 syn_filt_zero(r, awk2, r, nsf,p);
364 /* Pre-compute codewords response and energy */
365 for (i=0;i<shape_cb_size;i++)
367 float *res = resp+i*subvect_size;
369 /* Compute codeword response */
371 for(j=0;j<subvect_size;j++)
373 for(j=0;j<subvect_size;j++)
375 for (k=j;k<subvect_size;k++)
376 res[k]+=shape_cb[i*subvect_size+j]*r[k-j];
380 for (i=0;i<nb_subvect;i++)
382 int best_index=0, k, m;
383 float g, dist, best_dist=-1;
385 /* Find best codeword for current sub-vector */
386 for (j=0;j<shape_cb_size;j++)
389 a=resp+j*subvect_size;
391 for (k=0;k<subvect_size;k++)
392 dist += (a[k]-b[k])*(a[k]-b[k]);
393 if (dist<best_dist || j==0)
399 /*printf ("best index: %d/%d\n", best_index, shape_cb_size);*/
400 frame_bits_pack(bits,best_index,params->shape_bits);
403 /* Update target for next subvector */
404 for (j=0;j<subvect_size;j++)
406 g=shape_cb[best_index*subvect_size+j];
407 for (k=subvect_size*i+j,m=0;k<nsf;k++,m++)
412 /* Put everything back together */
413 for (i=0;i<nb_subvect;i++)
414 for (j=0;j<subvect_size;j++)
415 e[subvect_size*i+j]=shape_cb[ind[i]*subvect_size+j];
417 /* Update excitation */
422 residue_zero(e, awk1, r, nsf, p);
423 syn_filt_zero(r, ak, r, nsf, p);
424 syn_filt_zero(r, awk2, r, nsf,p);
440 void split_cb_search2(
441 float target[], /* target vector */
442 float ak[], /* LPCs for this subframe */
443 float awk1[], /* Weighted LPCs for this subframe */
444 float awk2[], /* Weighted LPCs for this subframe */
445 void *par, /* Codebook/search parameters*/
446 int p, /* number of LPC coeffs */
447 int nsf, /* number of samples in subframe */
459 int shape_cb_size, subvect_size, nb_subvect;
461 split_cb_params *params;
463 params = (split_cb_params *) par;
464 subvect_size = params->subvect_size;
465 nb_subvect = params->nb_subvect;
466 shape_cb_size = 1<<params->shape_bits;
467 shape_cb = params->shape_cb;
468 resp = PUSH(stack, shape_cb_size*subvect_size);
469 E = PUSH(stack, shape_cb_size);
470 t = PUSH(stack, nsf);
471 r = PUSH(stack, nsf);
472 e = PUSH(stack, nsf);
473 gains = PUSH(stack, nb_subvect);
474 ind = (int*)PUSH(stack, nb_subvect);
476 /* Compute energy of the "real excitation" */
477 syn_filt_zero(target, awk1, e, nsf, p);
478 residue_zero(e, ak, e, nsf, p);
479 residue_zero(e, awk2, e, nsf, p);
481 exc_energy += e[i]*e[i];
482 exc_energy=sqrt(exc_energy/nb_subvect);
484 /* Quantize global ("average") gain */
485 q=log(exc_energy+.1);
492 frame_bits_pack(bits, id, 4);
493 exc_energy=exp(.5*q+2);
502 residue_zero(e, awk1, r, nsf, p);
503 syn_filt_zero(r, ak, r, nsf, p);
504 syn_filt_zero(r, awk2, r, nsf,p);
506 /* Pre-compute codewords response and energy */
507 for (i=0;i<shape_cb_size;i++)
509 float *res = resp+i*subvect_size;
511 /* Compute codeword response */
513 for(j=0;j<subvect_size;j++)
515 for(j=0;j<subvect_size;j++)
517 for (k=j;k<subvect_size;k++)
518 res[k]+=shape_cb[i*subvect_size+j]*r[k-j];
520 /* Compute energy of codeword response */
522 for(j=0;j<subvect_size;j++)
527 for (i=0;i<nb_subvect;i++)
529 int best_index[2]={0,0}, k, m;
530 float g, corr, best_gain[2]={0,0}, score, best_score[2]={-1,-1};
531 /* Find best codeword for current sub-vector */
532 for (j=0;j<shape_cb_size;j++)
534 corr=xcorr(resp+j*subvect_size,t+subvect_size*i,subvect_size);
535 score=corr*corr*E[j];
537 if (score>best_score[0])
539 best_index[1]=best_index[0];
540 best_score[1]=best_score[0];
541 best_gain[1]=best_gain[0];
546 } else if (score>best_score[1]) {
556 best_gain[k] /= .01+exc_energy;
559 best_gain[k]=-best_gain[k];
563 /* Find gain index (it's a scalar but we use the VQ code anyway)*/
564 best_id = vq_index(&best_gain[k], scal_gains4, 1, 8);
566 best_gain[k]=scal_gains4[best_id];
567 /*printf ("gain_quant: %f %d %f\n", best_gain, best_id, scal_gains4[best_id]);*/
569 best_gain[k]=-best_gain[k];
570 best_gain[k] *= exc_energy;
575 if (i<nb_subvect-1) {
577 float best_score2=-1, best_gain2=0;
580 float *tt=PUSH(stack,nsf);
581 for (nbest=0;nbest<2;nbest++)
585 for (j=0;j<subvect_size;j++)
587 g=best_gain[nbest]*shape_cb[best_index[nbest]*subvect_size+j];
588 for (k=subvect_size*i+j,m=0;k<nsf;k++,m++)
593 for (j=0;j<shape_cb_size;j++)
595 corr=xcorr(resp+j*subvect_size,tt+subvect_size*(i+1),subvect_size);
596 score=corr*corr*E[j];
598 if (score>best_score2)
608 best_gain2 /= .01+exc_energy;
611 best_gain2=-best_gain2;
614 best_id = vq_index(&best_gain2, scal_gains4, 1, 8);
615 best_gain2=scal_gains4[best_id];
617 best_gain2=-best_gain2;
618 best_gain2 *= exc_energy;
621 for (j=0;j<subvect_size;j++)
623 g=best_gain2*shape_cb[best_index2*subvect_size+j];
624 for (k=subvect_size*(i+1)+j,m=0;k<nsf;k++,m++)
627 for (j=subvect_size*i;j<subvect_size*(i+2);j++)
628 err[nbest]-=tt[j]*tt[j];
630 best_score[nbest]=err[nbest];
633 if (best_score[1]>best_score[0])
635 best_index[0]=best_index[1];
636 best_score[0]=best_score[1];
637 best_gain[0]=best_gain[1];
646 ind[i]=best_index[0];
647 gains[i]=best_gain[0];
648 /* Update target for next subvector */
649 for (j=0;j<subvect_size;j++)
651 g=best_gain[0]*shape_cb[best_index[0]*subvect_size+j];
652 for (k=subvect_size*i+j,m=0;k<nsf;k++,m++)
657 /* Put everything back together */
658 for (i=0;i<nb_subvect;i++)
659 for (j=0;j<subvect_size;j++)
660 e[subvect_size*i+j]=gains[i]*shape_cb[ind[i]*subvect_size+j];
662 /* Update excitation */
667 residue_zero(e, awk1, r, nsf, p);
668 syn_filt_zero(r, ak, r, nsf, p);
669 syn_filt_zero(r, awk2, r, nsf,p);
687 void split_cb_unquant(
689 void *par, /* non-overlapping codebook */
690 int nsf, /* number of samples in subframe */
699 float *shape_cb, exc_energy;
700 int shape_cb_size, subvect_size, nb_subvect;
701 split_cb_params *params;
703 params = (split_cb_params *) par;
704 subvect_size = params->subvect_size;
705 nb_subvect = params->nb_subvect;
706 shape_cb_size = 1<<params->shape_bits;
707 shape_cb = params->shape_cb;
709 ind = (int*)PUSH(stack, nb_subvect);
710 gains = PUSH(stack, nb_subvect);
711 sign = PUSH(stack, nb_subvect);
713 /* Decode global (average) gain */
716 id = frame_bits_unpack_unsigned(bits, 4);
717 exc_energy=exp(.5*id+2);
720 /* Decode codewords and gains */
721 for (i=0;i<nb_subvect;i++)
724 ind[i] = frame_bits_unpack_unsigned(bits, params->shape_bits);
725 if (frame_bits_unpack_unsigned(bits, 1))
730 gain_id = frame_bits_unpack_unsigned(bits, 3);
731 gains[i]=scal_gains4[gain_id];
733 gains[i] *= exc_energy;
738 /* Compute decoded excitation */
739 for (i=0;i<nb_subvect;i++)
740 for (j=0;j<subvect_size;j++)
741 exc[subvect_size*i+j]+=gains[i]*shape_cb[ind[i]*subvect_size+j];