Decoder back in sync with the encoder
[speexdsp.git] / libspeex / cb_search.c
1 /* Original copyright */
2 /*-----------------------------------------------------------------------*\
3
4     FILE........: GAINSHAPE.C
5     TYPE........: C Module
6     AUTHOR......: David Rowe
7     COMPANY.....: Voicetronix
8     DATE CREATED: 19/2/02
9
10     General gain-shape codebook search.
11
12 \*-----------------------------------------------------------------------*/
13
14
15 /* Modified by Jean-Marc Valin 2002
16
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.
21    
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.
26    
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
30 */
31
32
33
34 #include <stdlib.h>
35 #include <cb_search.h>
36 #include "filters.h"
37 #include <math.h>
38 #include <stdio.h>
39 #include "stack_alloc.h"
40 #include "vq.h"
41 #include "matrix.h"
42
43 #define min(a,b) ((a) < (b) ? (a) : (b))
44 #define max(a,b) ((a) > (b) ? (a) : (b))
45
46
47 static float scal_gains4[16] = {
48    0.27713,
49    0.49282,
50    0.69570,
51    0.90786,
52    1.14235,
53    1.42798,
54    1.80756,
55    2.42801
56 };
57
58
59 /*---------------------------------------------------------------------------*\
60                                                                              
61  void overlap_cb_search()                                                             
62                                                                               
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       
66  vectors.                                                                     
67                                                                              
68 \*---------------------------------------------------------------------------*/
69
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 */
81 float *stack
82 )
83 {
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 */
90
91   /* Initialise */
92   
93   /*resp = (float*)malloc(sizeof(float)*nsf);
94   h = (float*)malloc(sizeof(float)*nsf);
95   impulse = (float*)malloc(sizeof(float)*nsf);
96   */
97   resp=PUSH(stack, nsf);
98   h=PUSH(stack, nsf);
99   impulse=PUSH(stack, nsf);
100
101   for(i=0; i<nsf; i++)
102     impulse[i] = 0.0;
103    
104   *gain = 0.0;
105   *index = 0;
106   bscore = 0.0;
107   impulse[0] = 1.0;
108
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);
113   
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);
118     
119   /* Search codebook backwards using end correction for synthesis */
120   
121   for(k=entries-1; k>=0; k--) {
122
123     d = 0.0; e = 0.0;
124     for(i=0; i<nsf; i++) {
125       d += target[i]*resp[i];
126       e += resp[i]*resp[i];
127     }
128     g = d/(e+.0001);
129     score = g*d;
130     /*printf ("score: %f %f %f %f\n", target[0],d,e,score);*/
131     if (score >= bscore) {
132       bscore = score;
133       *gain = g;
134       *index = k;
135     }
136     
137     /* Synthesise next entry */
138     
139     if (k) {
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];
143     }
144   }
145
146   /*free(resp);
147   free(h);
148   free(impulse);*/
149   POP(stack);
150   POP(stack);
151   POP(stack);
152   return bscore;
153 }
154
155
156
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 */
165 float *exc,
166 FrameBits *bits,
167 float *stack
168 )
169 {
170    int i,j, id;
171    float *resp, *E, q;
172    float *t, *r, *e;
173    float *gains;
174    int *ind;
175    float *shape_cb;
176    int shape_cb_size, subvect_size, nb_subvect;
177    float exc_energy=0;
178    split_cb_params *params;
179
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);
192
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);
197    for (i=0;i<nsf;i++)
198       exc_energy += e[i]*e[i];
199    exc_energy=sqrt(exc_energy/nb_subvect);
200
201    /* Quantize global ("average") gain */
202    q=log(exc_energy+.1);
203    q=floor(.5+2*(q-2));
204    if (q<0)
205       q=0;
206    if (q>15)
207       q=15;
208    id = (int)q;
209    frame_bits_pack(bits, id, 4);
210    exc_energy=exp(.5*q+2);
211
212
213    for (i=0;i<nsf;i++)
214       t[i]=target[i];
215
216    e[0]=1;
217    for (i=1;i<nsf;i++)
218       e[i]=0;
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);
222    
223    /* Pre-compute codewords response and energy */
224    for (i=0;i<shape_cb_size;i++)
225    {
226       float *res = resp+i*subvect_size;
227
228       /* Compute codeword response */
229       int k;
230       for(j=0;j<subvect_size;j++)
231          res[j]=0;
232       for(j=0;j<subvect_size;j++)
233       {
234          for (k=j;k<subvect_size;k++)
235             res[k]+=shape_cb[i*subvect_size+j]*r[k-j];
236       }
237       /* Compute energy of codeword response */
238       E[i]=0;
239       for(j=0;j<subvect_size;j++)
240          E[i]+=res[j]*res[j];
241       E[i]=1/(.001+E[i]);
242    }
243
244    for (i=0;i<nb_subvect;i++)
245    {
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++)
250       {
251          corr=xcorr(resp+j*subvect_size,t+subvect_size*i,subvect_size);
252          score=corr*corr*E[j];
253          g = corr*E[j];
254          if (score>best_score)
255          {
256             best_index=j;
257             best_score=score;
258             best_gain=g;
259          }
260       }
261       frame_bits_pack(bits,best_index,params->shape_bits);
262       
263       /* Quantize gain */
264       {
265          int s=0, best_id;
266          best_gain /= .01+exc_energy;
267          if (best_gain<0)
268          {
269             best_gain=-best_gain;
270             s=1;
271          }
272
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);
275
276          best_gain=scal_gains4[best_id];
277          /*printf ("gain_quant: %f %d %f\n", best_gain, best_id, scal_gains4[best_id]);*/
278          if (s)
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);
283       }
284       ind[i]=best_index;
285       gains[i]=best_gain;
286       /* Update target for next subvector */
287       for (j=0;j<subvect_size;j++)
288       {
289          g=best_gain*shape_cb[best_index*subvect_size+j];
290          for (k=subvect_size*i+j,m=0;k<nsf;k++,m++)
291             t[k] -= g*r[m];
292       }
293    }
294    
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];
299
300    /* Update excitation */
301    for (j=0;j<nsf;j++)
302       exc[j]+=e[j];
303    
304    /* Update target */
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);
308    for (j=0;j<nsf;j++)
309       target[j]-=r[j];
310
311    
312
313
314    POP(stack);
315    POP(stack);
316    POP(stack);
317    POP(stack);
318    POP(stack);
319    POP(stack);
320 }
321
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 */
330 float *exc,
331 FrameBits *bits,
332 float *stack
333 )
334 {
335    int i,j;
336    float *resp;
337    float *t, *r, *e;
338    int *ind;
339    float *shape_cb;
340    int shape_cb_size, subvect_size, nb_subvect;
341    split_cb_params *params;
342
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);
353
354    for (i=0;i<nsf;i++)
355       t[i]=target[i];
356
357    e[0]=1;
358    for (i=1;i<nsf;i++)
359       e[i]=0;
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);
363    
364    /* Pre-compute codewords response and energy */
365    for (i=0;i<shape_cb_size;i++)
366    {
367       float *res = resp+i*subvect_size;
368
369       /* Compute codeword response */
370       int k;
371       for(j=0;j<subvect_size;j++)
372          res[j]=0;
373       for(j=0;j<subvect_size;j++)
374       {
375          for (k=j;k<subvect_size;k++)
376             res[k]+=shape_cb[i*subvect_size+j]*r[k-j];
377       }
378    }
379
380    for (i=0;i<nb_subvect;i++)
381    {
382       int best_index=0, k, m;
383       float g, dist, best_dist=-1;
384       float *a, *b;
385       /* Find best codeword for current sub-vector */
386       for (j=0;j<shape_cb_size;j++)
387       {
388          dist=0;
389          a=resp+j*subvect_size;
390          b=t+subvect_size*i;
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)
394          {
395             best_dist=dist;
396             best_index=j;
397          }
398       }
399       /*printf ("best index: %d/%d\n", best_index, shape_cb_size);*/
400       frame_bits_pack(bits,best_index,params->shape_bits);
401
402       ind[i]=best_index;
403       /* Update target for next subvector */
404       for (j=0;j<subvect_size;j++)
405       {
406          g=shape_cb[best_index*subvect_size+j];
407          for (k=subvect_size*i+j,m=0;k<nsf;k++,m++)
408             t[k] -= g*r[m];
409       }
410    }
411    
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];
416
417    /* Update excitation */
418    for (j=0;j<nsf;j++)
419       exc[j]+=e[j];
420    
421    /* Update target */
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);
425    for (j=0;j<nsf;j++)
426       target[j]-=r[j];
427
428    
429
430
431    POP(stack);
432    POP(stack);
433    POP(stack);
434    POP(stack);
435 }
436
437
438
439
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 */
448 float *exc,
449 FrameBits *bits,
450 float *stack
451 )
452 {
453    int i,j, id;
454    float *resp, *E, q;
455    float *t, *r, *e;
456    float *gains;
457    int *ind, *gain_ind;
458    float *shape_cb;
459    int shape_cb_size, subvect_size, nb_subvect;
460    float exc_energy=0;
461    split_cb_params *params;
462
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);
475    gain_ind = (int*)PUSH(stack, nb_subvect);
476
477    /* Compute energy of the "real excitation" */
478    syn_filt_zero(target, awk1, e, nsf, p);
479    residue_zero(e, ak, e, nsf, p);
480    residue_zero(e, awk2, e, nsf, p);
481    for (i=0;i<nsf;i++)
482       exc_energy += e[i]*e[i];
483    exc_energy=sqrt(exc_energy/nb_subvect);
484
485    /* Quantize global ("average") gain */
486    q=log(exc_energy+.1);
487    q=floor(.5+2*(q-2));
488    if (q<0)
489       q=0;
490    if (q>15)
491       q=15;
492    id = (int)q;
493    frame_bits_pack(bits, id, 4);
494    exc_energy=exp(.5*q+2);
495
496
497    for (i=0;i<nsf;i++)
498       t[i]=target[i];
499
500    e[0]=1;
501    for (i=1;i<nsf;i++)
502       e[i]=0;
503    residue_zero(e, awk1, r, nsf, p);
504    syn_filt_zero(r, ak, r, nsf, p);
505    syn_filt_zero(r, awk2, r, nsf,p);
506    
507    /* Pre-compute codewords response and energy */
508    for (i=0;i<shape_cb_size;i++)
509    {
510       float *res = resp+i*subvect_size;
511
512       /* Compute codeword response */
513       int k;
514       for(j=0;j<subvect_size;j++)
515          res[j]=0;
516       for(j=0;j<subvect_size;j++)
517       {
518          for (k=j;k<subvect_size;k++)
519             res[k]+=shape_cb[i*subvect_size+j]*r[k-j];
520       }
521       /* Compute energy of codeword response */
522       E[i]=0;
523       for(j=0;j<subvect_size;j++)
524          E[i]+=res[j]*res[j];
525       E[i]=1/(.001+E[i]);
526    }
527
528    for (i=0;i<nb_subvect;i++)
529    {
530       int best_index[2]={0,0}, k, m, best_gain_ind[2]={0,0};
531       float g, corr, best_gain[2]={0,0}, score, best_score[2]={-1,-1};
532       /* Find best codeword for current sub-vector */
533       for (j=0;j<shape_cb_size;j++)
534       {
535          corr=xcorr(resp+j*subvect_size,t+subvect_size*i,subvect_size);
536          score=corr*corr*E[j];
537          g = corr*E[j];
538          if (score>best_score[0])
539          {
540             best_index[1]=best_index[0];
541             best_score[1]=best_score[0];
542             best_gain[1]=best_gain[0];
543
544             best_index[0]=j;
545             best_score[0]=score;
546             best_gain[0]=g;
547          } else if (score>best_score[1]) {
548             best_index[1]=j;
549             best_score[1]=score;
550             best_gain[1]=g;            
551          }
552       }
553       
554       /* Quantize gain */
555       for (k=0;k<2;k++) {
556          int s=0, best_id;
557          best_gain[k] /= .01+exc_energy;
558          if (best_gain[k]<0)
559          {
560             best_gain[k]=-best_gain[k];
561             s=1;
562          }
563
564          /* Find gain index (it's a scalar but we use the VQ code anyway)*/
565          best_id = vq_index(&best_gain[k], scal_gains4, 1, 8);
566
567          best_gain_ind[k]=best_id;
568          best_gain[k]=scal_gains4[best_id];
569          /*printf ("gain_quant: %f %d %f\n", best_gain, best_id, scal_gains4[best_id]);*/
570          if (s)
571             best_gain[k]=-best_gain[k];
572          best_gain[k] *= exc_energy;
573       }
574
575
576
577       if (i<nb_subvect-1) {
578          int best_index2=0;
579          float best_score2=-1, best_gain2=0;
580          int nbest;
581          float err[2]={0,0};
582          float *tt=PUSH(stack,nsf);
583          for (nbest=0;nbest<2;nbest++)
584          {
585             for (j=0;j<nsf;j++)
586                tt[j]=t[j];
587             for (j=0;j<subvect_size;j++)
588             {
589                g=best_gain[nbest]*shape_cb[best_index[nbest]*subvect_size+j];
590                for (k=subvect_size*i+j,m=0;k<nsf;k++,m++)
591                   tt[k] -= g*r[m];
592             }
593             
594
595             for (j=0;j<shape_cb_size;j++)
596             {
597                corr=xcorr(resp+j*subvect_size,tt+subvect_size*(i+1),subvect_size);
598                score=corr*corr*E[j];
599                g = corr*E[j];
600                if (score>best_score2)
601                {
602                   best_index2=j;
603                   best_score2=score;
604                   best_gain2=g;
605                }
606             }
607
608             {
609                int s=0, best_id;
610                best_gain2 /= .01+exc_energy;
611                if (best_gain2<0)
612                {
613                   best_gain2=-best_gain2;
614                   s=1;
615                }
616                best_id = vq_index(&best_gain2, scal_gains4, 1, 8);
617                best_gain2=scal_gains4[best_id];
618                if (s)
619                   best_gain2=-best_gain2;
620                best_gain2 *= exc_energy;
621             }
622
623             for (j=0;j<subvect_size;j++)
624             {
625                g=best_gain2*shape_cb[best_index2*subvect_size+j];
626                for (k=subvect_size*(i+1)+j,m=0;k<nsf;k++,m++)
627                   tt[k] -= g*r[m];
628             }
629             for (j=subvect_size*i;j<subvect_size*(i+2);j++)
630                err[nbest]-=tt[j]*tt[j];
631             
632             best_score[nbest]=err[nbest];
633          }
634
635          if (best_score[1]>best_score[0])
636          {
637             best_index[0]=best_index[1];
638             best_score[0]=best_score[1];
639             best_gain[0]=best_gain[1];
640             best_gain_ind[0]=best_gain_ind[1];
641          }
642          POP(stack);
643       }
644
645
646       
647
648       ind[i]=best_index[0];
649       gain_ind[i]=best_gain_ind[0];
650       gains[i]=best_gain[0];
651       /* Update target for next subvector */
652       for (j=0;j<subvect_size;j++)
653       {
654          g=best_gain[0]*shape_cb[best_index[0]*subvect_size+j];
655          for (k=subvect_size*i+j,m=0;k<nsf;k++,m++)
656             t[k] -= g*r[m];
657       }
658    }
659    for (i=0;i<nb_subvect;i++)
660    {
661       frame_bits_pack(bits, ind[i], params->shape_bits);
662       if (gains[i]<0)
663          frame_bits_pack(bits, 1, 1);
664       else
665          frame_bits_pack(bits, 0, 1);
666       frame_bits_pack(bits, gain_ind[i], 3);
667       printf ("encode split: %d %d %f\n", i, ind[i], gains[i]);
668
669    }
670    /* Put everything back together */
671    for (i=0;i<nb_subvect;i++)
672       for (j=0;j<subvect_size;j++)
673          e[subvect_size*i+j]=gains[i]*shape_cb[ind[i]*subvect_size+j];
674
675    /* Update excitation */
676    for (j=0;j<nsf;j++)
677       exc[j]+=e[j];
678    
679    /* Update target */
680    residue_zero(e, awk1, r, nsf, p);
681    syn_filt_zero(r, ak, r, nsf, p);
682    syn_filt_zero(r, awk2, r, nsf,p);
683    for (j=0;j<nsf;j++)
684       target[j]-=r[j];
685
686    
687
688
689    POP(stack);
690    POP(stack);
691    POP(stack);
692    POP(stack);
693    POP(stack);
694    POP(stack);
695    POP(stack);
696 }
697
698
699
700
701 void split_cb_unquant(
702 float *exc,
703 void *par,                      /* non-overlapping codebook */
704 int   nsf,                      /* number of samples in subframe */
705 FrameBits *bits,
706 float *stack
707 )
708 {
709    int i,j;
710    int *ind;
711    float *gains;
712    float *sign;
713    float *shape_cb, exc_energy;
714    int shape_cb_size, subvect_size, nb_subvect;
715    split_cb_params *params;
716
717    params = (split_cb_params *) par;
718    subvect_size = params->subvect_size;
719    nb_subvect = params->nb_subvect;
720    shape_cb_size = 1<<params->shape_bits;
721    shape_cb = params->shape_cb;
722    
723    ind = (int*)PUSH(stack, nb_subvect);
724    gains = PUSH(stack, nb_subvect);
725    sign = PUSH(stack, nb_subvect);
726
727    /* Decode global (average) gain */
728    {
729       int id;
730       id = frame_bits_unpack_unsigned(bits, 4);
731       exc_energy=exp(.5*id+2);
732    }
733
734    /* Decode codewords and gains */
735    for (i=0;i<nb_subvect;i++)
736    {
737       int gain_id;
738       ind[i] = frame_bits_unpack_unsigned(bits, params->shape_bits);
739       if (frame_bits_unpack_unsigned(bits, 1))
740          sign[i]=-1;
741       else
742          sign[i]=1;
743       
744       gain_id = frame_bits_unpack_unsigned(bits, 3);
745       gains[i]=scal_gains4[gain_id];
746       gains[i] *= sign[i];
747       gains[i] *= exc_energy;
748
749       printf ("decode split: %d %d %f\n", i, ind[i], gains[i]);
750    }
751
752    /* Compute decoded excitation */
753    for (i=0;i<nb_subvect;i++)
754       for (j=0;j<subvect_size;j++)
755          exc[subvect_size*i+j]+=gains[i]*shape_cb[ind[i]*subvect_size+j];
756
757    POP(stack);
758    POP(stack);
759    POP(stack);
760 }
761
762
763
764 void split_cb_nogain_unquant(
765 float *exc,
766 void *par,                      /* non-overlapping codebook */
767 int   nsf,                      /* number of samples in subframe */
768 float gain,
769 FrameBits *bits,
770 float *stack
771 )
772 {
773    int i,j;
774    int *ind;
775    float *shape_cb;
776    int shape_cb_size, subvect_size, nb_subvect;
777    split_cb_params *params;
778
779    params = (split_cb_params *) par;
780    subvect_size = params->subvect_size;
781    nb_subvect = params->nb_subvect;
782    shape_cb_size = 1<<params->shape_bits;
783    shape_cb = params->shape_cb;
784    
785    ind = (int*)PUSH(stack, nb_subvect);
786
787    /* Decode codewords and gains */
788    for (i=0;i<nb_subvect;i++)
789    {
790       int gain_id;
791       ind[i] = frame_bits_unpack_unsigned(bits, params->shape_bits);
792    }
793
794    /* Compute decoded excitation */
795    for (i=0;i<nb_subvect;i++)
796       for (j=0;j<subvect_size;j++)
797          exc[subvect_size*i+j]+=gain*shape_cb[ind[i]*subvect_size+j];
798
799    POP(stack);
800 }