1 /* Copyright (C) 2002-2006 Jean-Marc Valin
2    File: cb_search.c
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 #ifdef HAVE_CONFIG_H
33 #include "config.h"
34 #endif
35 
36 #include "cb_search.h"
37 #include "filters.h"
38 #include "stack_alloc.h"
39 #include "vq.h"
40 #include "arch.h"
41 #include "math_approx.h"
42 #include "os_support.h"
43 
44 #ifdef _USE_SSE
45 #include "cb_search_sse.h"
46 #elif defined(ARM4_ASM) || defined(ARM5E_ASM)
47 #include "cb_search_arm4.h"
48 #elif defined(BFIN_ASM)
49 #include "cb_search_bfin.h"
50 #endif
51 
52 #ifndef DISABLE_ENCODER
53 
54 #ifndef OVERRIDE_COMPUTE_WEIGHTED_CODEBOOK
compute_weighted_codebook(const signed char * shape_cb,const spx_word16_t * r,spx_word16_t * resp,spx_word16_t * resp2,spx_word32_t * E,int shape_cb_size,int subvect_size,char * stack)55 static void compute_weighted_codebook(const signed char *shape_cb, const spx_word16_t *r, spx_word16_t *resp, spx_word16_t *resp2, spx_word32_t *E, int shape_cb_size, int subvect_size, char *stack)
56 {
57    int i, j, k;
58    VARDECL(spx_word16_t *shape);
59    ALLOC(shape, subvect_size, spx_word16_t);
60    for (i=0;i<shape_cb_size;i++)
61    {
62       spx_word16_t *res;
63 
64       res = resp+i*subvect_size;
65       for (k=0;k<subvect_size;k++)
66          shape[k] = (spx_word16_t)shape_cb[i*subvect_size+k];
67       E[i]=0;
68 
69       /* Compute codeword response using convolution with impulse response */
70       for(j=0;j<subvect_size;j++)
71       {
72          spx_word32_t resj=0;
73          spx_word16_t res16;
74          for (k=0;k<=j;k++)
75             resj = MAC16_16(resj,shape[k],r[j-k]);
76 #ifdef FIXED_POINT
77          res16 = EXTRACT16(SHR32(resj, 13));
78 #else
79          res16 = 0.03125f*resj;
80 #endif
81          /* Compute codeword energy */
82          E[i]=MAC16_16(E[i],res16,res16);
83          res[j] = res16;
84          /*printf ("%d\n", (int)res[j]);*/
85       }
86    }
87 
88 }
89 #endif
90 
91 #ifndef OVERRIDE_TARGET_UPDATE
target_update(spx_word16_t * t,spx_word16_t g,spx_word16_t * r,int len)92 static inline void target_update(spx_word16_t *t, spx_word16_t g, spx_word16_t *r, int len)
93 {
94    int n;
95    for (n=0;n<len;n++)
96       t[n] = SUB16(t[n],PSHR32(MULT16_16(g,r[n]),13));
97 }
98 #endif
99 
100 
101 
split_cb_search_shape_sign_N1(spx_word16_t target[],spx_coef_t ak[],spx_coef_t awk1[],spx_coef_t awk2[],const void * par,int p,int nsf,spx_sig_t * exc,spx_word16_t * r,SpeexBits * bits,char * stack,int update_target)102 static void split_cb_search_shape_sign_N1(
103 spx_word16_t target[],			/* target vector */
104 spx_coef_t ak[],			/* LPCs for this subframe */
105 spx_coef_t awk1[],			/* Weighted LPCs for this subframe */
106 spx_coef_t awk2[],			/* Weighted LPCs for this subframe */
107 const void *par,                      /* Codebook/search parameters*/
108 int   p,                        /* number of LPC coeffs */
109 int   nsf,                      /* number of samples in subframe */
110 spx_sig_t *exc,
111 spx_word16_t *r,
112 SpeexBits *bits,
113 char *stack,
114 int   update_target
115 )
116 {
117    int i,j,m,q;
118    VARDECL(spx_word16_t *resp);
119 #ifdef _USE_SSE
120    VARDECL(__m128 *resp2);
121    VARDECL(__m128 *E);
122 #else
123    spx_word16_t *resp2;
124    VARDECL(spx_word32_t *E);
125 #endif
126    VARDECL(spx_word16_t *t);
127    VARDECL(spx_sig_t *e);
128    const signed char *shape_cb;
129    int shape_cb_size, subvect_size, nb_subvect;
130    const split_cb_params *params;
131    int best_index;
132    spx_word32_t best_dist;
133    int have_sign;
134 
135    params = (const split_cb_params *) par;
136    subvect_size = params->subvect_size;
137    nb_subvect = params->nb_subvect;
138    shape_cb_size = 1<<params->shape_bits;
139    shape_cb = params->shape_cb;
140    have_sign = params->have_sign;
141    ALLOC(resp, shape_cb_size*subvect_size, spx_word16_t);
142 #ifdef _USE_SSE
143    ALLOC(resp2, (shape_cb_size*subvect_size)>>2, __m128);
144    ALLOC(E, shape_cb_size>>2, __m128);
145 #else
146    resp2 = resp;
147    ALLOC(E, shape_cb_size, spx_word32_t);
148 #endif
149    ALLOC(t, nsf, spx_word16_t);
150    ALLOC(e, nsf, spx_sig_t);
151 
152    /* FIXME: Do we still need to copy the target? */
153    SPEEX_COPY(t, target, nsf);
154 
155    compute_weighted_codebook(shape_cb, r, resp, resp2, E, shape_cb_size, subvect_size, stack);
156 
157    for (i=0;i<nb_subvect;i++)
158    {
159       spx_word16_t *x=t+subvect_size*i;
160       /*Find new n-best based on previous n-best j*/
161 #ifndef DISABLE_WIDEBAND
162       if (have_sign)
163          vq_nbest_sign(x, resp2, subvect_size, shape_cb_size, E, 1, &best_index, &best_dist, stack);
164       else
165 #endif /* DISABLE_WIDEBAND */
166          vq_nbest(x, resp2, subvect_size, shape_cb_size, E, 1, &best_index, &best_dist, stack);
167 
168       speex_bits_pack(bits,best_index,params->shape_bits+have_sign);
169 
170       {
171          int rind;
172          spx_word16_t *res;
173          spx_word16_t sign=1;
174          rind = best_index;
175          if (rind>=shape_cb_size)
176          {
177             sign=-1;
178             rind-=shape_cb_size;
179          }
180          res = resp+rind*subvect_size;
181          if (sign>0)
182             for (m=0;m<subvect_size;m++)
183                t[subvect_size*i+m] = SUB16(t[subvect_size*i+m], res[m]);
184          else
185             for (m=0;m<subvect_size;m++)
186                t[subvect_size*i+m] = ADD16(t[subvect_size*i+m], res[m]);
187 
188 #ifdef FIXED_POINT
189          if (sign==1)
190          {
191             for (j=0;j<subvect_size;j++)
192                e[subvect_size*i+j]=SHL32(EXTEND32(shape_cb[rind*subvect_size+j]),SIG_SHIFT-5);
193          } else {
194             for (j=0;j<subvect_size;j++)
195                e[subvect_size*i+j]=NEG32(SHL32(EXTEND32(shape_cb[rind*subvect_size+j]),SIG_SHIFT-5));
196          }
197 #else
198          for (j=0;j<subvect_size;j++)
199             e[subvect_size*i+j]=sign*0.03125*shape_cb[rind*subvect_size+j];
200 #endif
201 
202       }
203 
204       for (m=0;m<subvect_size;m++)
205       {
206          spx_word16_t g;
207          int rind;
208          spx_word16_t sign=1;
209          rind = best_index;
210          if (rind>=shape_cb_size)
211          {
212             sign=-1;
213             rind-=shape_cb_size;
214          }
215 
216          q=subvect_size-m;
217 #ifdef FIXED_POINT
218          g=sign*shape_cb[rind*subvect_size+m];
219 #else
220          g=sign*0.03125*shape_cb[rind*subvect_size+m];
221 #endif
222          target_update(t+subvect_size*(i+1), g, r+q, nsf-subvect_size*(i+1));
223       }
224    }
225 
226    /* Update excitation */
227    /* FIXME: We could update the excitation directly above */
228    for (j=0;j<nsf;j++)
229       exc[j]=ADD32(exc[j],e[j]);
230 
231    /* Update target: only update target if necessary */
232    if (update_target)
233    {
234       VARDECL(spx_word16_t *r2);
235       ALLOC(r2, nsf, spx_word16_t);
236       for (j=0;j<nsf;j++)
237          r2[j] = EXTRACT16(PSHR32(e[j] ,6));
238       syn_percep_zero16(r2, ak, awk1, awk2, r2, nsf,p, stack);
239       for (j=0;j<nsf;j++)
240          target[j]=SUB16(target[j],PSHR16(r2[j],2));
241    }
242 }
243 
244 
245 
split_cb_search_shape_sign(spx_word16_t target[],spx_coef_t ak[],spx_coef_t awk1[],spx_coef_t awk2[],const void * par,int p,int nsf,spx_sig_t * exc,spx_word16_t * r,SpeexBits * bits,char * stack,int complexity,int update_target)246 void split_cb_search_shape_sign(
247 spx_word16_t target[],			/* target vector */
248 spx_coef_t ak[],			/* LPCs for this subframe */
249 spx_coef_t awk1[],			/* Weighted LPCs for this subframe */
250 spx_coef_t awk2[],			/* Weighted LPCs for this subframe */
251 const void *par,                      /* Codebook/search parameters*/
252 int   p,                        /* number of LPC coeffs */
253 int   nsf,                      /* number of samples in subframe */
254 spx_sig_t *exc,
255 spx_word16_t *r,
256 SpeexBits *bits,
257 char *stack,
258 int   complexity,
259 int   update_target
260 )
261 {
262    int i,j,k,m,n,q;
263    VARDECL(spx_word16_t *resp);
264 #ifdef _USE_SSE
265    VARDECL(__m128 *resp2);
266    VARDECL(__m128 *E);
267 #else
268    spx_word16_t *resp2;
269    VARDECL(spx_word32_t *E);
270 #endif
271    VARDECL(spx_word16_t *t);
272    VARDECL(spx_sig_t *e);
273    VARDECL(spx_word16_t *tmp);
274    VARDECL(spx_word32_t *ndist);
275    VARDECL(spx_word32_t *odist);
276    VARDECL(int *itmp);
277    VARDECL(spx_word16_t **ot2);
278    VARDECL(spx_word16_t **nt2);
279    spx_word16_t **ot, **nt;
280    VARDECL(int **nind);
281    VARDECL(int **oind);
282    VARDECL(int *ind);
283    const signed char *shape_cb;
284    int shape_cb_size, subvect_size, nb_subvect;
285    const split_cb_params *params;
286    int N=2;
287    VARDECL(int *best_index);
288    VARDECL(spx_word32_t *best_dist);
289    VARDECL(int *best_nind);
290    VARDECL(int *best_ntarget);
291    int have_sign;
292    N=complexity;
293    if (N>10)
294       N=10;
295    /* Complexity isn't as important for the codebooks as it is for the pitch */
296    N=(2*N)/3;
297    if (N<1)
298       N=1;
299    if (N==1)
300    {
301       split_cb_search_shape_sign_N1(target,ak,awk1,awk2,par,p,nsf,exc,r,bits,stack,update_target);
302       return;
303    }
304    ALLOC(ot2, N, spx_word16_t*);
305    ALLOC(nt2, N, spx_word16_t*);
306    ALLOC(oind, N, int*);
307    ALLOC(nind, N, int*);
308 
309    params = (const split_cb_params *) par;
310    subvect_size = params->subvect_size;
311    nb_subvect = params->nb_subvect;
312    shape_cb_size = 1<<params->shape_bits;
313    shape_cb = params->shape_cb;
314    have_sign = params->have_sign;
315    ALLOC(resp, shape_cb_size*subvect_size, spx_word16_t);
316 #ifdef _USE_SSE
317    ALLOC(resp2, (shape_cb_size*subvect_size)>>2, __m128);
318    ALLOC(E, shape_cb_size>>2, __m128);
319 #else
320    resp2 = resp;
321    ALLOC(E, shape_cb_size, spx_word32_t);
322 #endif
323    ALLOC(t, nsf, spx_word16_t);
324    ALLOC(e, nsf, spx_sig_t);
325    ALLOC(ind, nb_subvect, int);
326 
327    ALLOC(tmp, 2*N*nsf, spx_word16_t);
328    for (i=0;i<N;i++)
329    {
330       ot2[i]=tmp+2*i*nsf;
331       nt2[i]=tmp+(2*i+1)*nsf;
332    }
333    ot=ot2;
334    nt=nt2;
335    ALLOC(best_index, N, int);
336    ALLOC(best_dist, N, spx_word32_t);
337    ALLOC(best_nind, N, int);
338    ALLOC(best_ntarget, N, int);
339    ALLOC(ndist, N, spx_word32_t);
340    ALLOC(odist, N, spx_word32_t);
341 
342    ALLOC(itmp, 2*N*nb_subvect, int);
343    for (i=0;i<N;i++)
344    {
345       nind[i]=itmp+2*i*nb_subvect;
346       oind[i]=itmp+(2*i+1)*nb_subvect;
347    }
348 
349    SPEEX_COPY(t, target, nsf);
350 
351    for (j=0;j<N;j++)
352       SPEEX_COPY(&ot[j][0], t, nsf);
353 
354    /* Pre-compute codewords response and energy */
355    compute_weighted_codebook(shape_cb, r, resp, resp2, E, shape_cb_size, subvect_size, stack);
356 
357    for (j=0;j<N;j++)
358       odist[j]=0;
359 
360    /*For all subvectors*/
361    for (i=0;i<nb_subvect;i++)
362    {
363       /*"erase" nbest list*/
364       for (j=0;j<N;j++)
365          ndist[j]=VERY_LARGE32;
366       /* This is not strictly necessary, but it provides an additonal safety
367          to prevent crashes in case something goes wrong in the previous
368          steps (e.g. NaNs) */
369       for (j=0;j<N;j++)
370          best_nind[j] = best_ntarget[j] = 0;
371       /*For all n-bests of previous subvector*/
372       for (j=0;j<N;j++)
373       {
374          spx_word16_t *x=ot[j]+subvect_size*i;
375          spx_word32_t tener = 0;
376          for (m=0;m<subvect_size;m++)
377             tener = MAC16_16(tener, x[m],x[m]);
378 #ifdef FIXED_POINT
379          tener = SHR32(tener,1);
380 #else
381          tener *= .5;
382 #endif
383          /*Find new n-best based on previous n-best j*/
384 #ifndef DISABLE_WIDEBAND
385          if (have_sign)
386             vq_nbest_sign(x, resp2, subvect_size, shape_cb_size, E, N, best_index, best_dist, stack);
387          else
388 #endif /* DISABLE_WIDEBAND */
389             vq_nbest(x, resp2, subvect_size, shape_cb_size, E, N, best_index, best_dist, stack);
390 
391          /*For all new n-bests*/
392          for (k=0;k<N;k++)
393          {
394             /* Compute total distance (including previous sub-vectors */
395             spx_word32_t err = ADD32(ADD32(odist[j],best_dist[k]),tener);
396 
397             /*update n-best list*/
398             if (err<ndist[N-1])
399             {
400                for (m=0;m<N;m++)
401                {
402                   if (err < ndist[m])
403                   {
404                      for (n=N-1;n>m;n--)
405                      {
406                         ndist[n] = ndist[n-1];
407                         best_nind[n] = best_nind[n-1];
408                         best_ntarget[n] = best_ntarget[n-1];
409                      }
410                      /* n is equal to m here, so they're interchangeable */
411                      ndist[m] = err;
412                      best_nind[n] = best_index[k];
413                      best_ntarget[n] = j;
414                      break;
415                   }
416                }
417             }
418          }
419          if (i==0)
420             break;
421       }
422       for (j=0;j<N;j++)
423       {
424          /*previous target (we don't care what happened before*/
425          for (m=(i+1)*subvect_size;m<nsf;m++)
426             nt[j][m]=ot[best_ntarget[j]][m];
427 
428          /* New code: update the rest of the target only if it's worth it */
429          for (m=0;m<subvect_size;m++)
430          {
431             spx_word16_t g;
432             int rind;
433             spx_word16_t sign=1;
434             rind = best_nind[j];
435             if (rind>=shape_cb_size)
436             {
437                sign=-1;
438                rind-=shape_cb_size;
439             }
440 
441             q=subvect_size-m;
442 #ifdef FIXED_POINT
443             g=sign*shape_cb[rind*subvect_size+m];
444 #else
445             g=sign*0.03125*shape_cb[rind*subvect_size+m];
446 #endif
447             target_update(nt[j]+subvect_size*(i+1), g, r+q, nsf-subvect_size*(i+1));
448          }
449 
450          for (q=0;q<nb_subvect;q++)
451             nind[j][q]=oind[best_ntarget[j]][q];
452          nind[j][i]=best_nind[j];
453       }
454 
455       /*update old-new data*/
456       /* just swap pointers instead of a long copy */
457       {
458          spx_word16_t **tmp2;
459          tmp2=ot;
460          ot=nt;
461          nt=tmp2;
462       }
463       for (j=0;j<N;j++)
464          for (m=0;m<nb_subvect;m++)
465             oind[j][m]=nind[j][m];
466       for (j=0;j<N;j++)
467          odist[j]=ndist[j];
468    }
469 
470    /*save indices*/
471    for (i=0;i<nb_subvect;i++)
472    {
473       ind[i]=nind[0][i];
474       speex_bits_pack(bits,ind[i],params->shape_bits+have_sign);
475    }
476 
477    /* Put everything back together */
478    for (i=0;i<nb_subvect;i++)
479    {
480       int rind;
481       spx_word16_t sign=1;
482       rind = ind[i];
483       if (rind>=shape_cb_size)
484       {
485          sign=-1;
486          rind-=shape_cb_size;
487       }
488 #ifdef FIXED_POINT
489       if (sign==1)
490       {
491          for (j=0;j<subvect_size;j++)
492             e[subvect_size*i+j]=SHL32(EXTEND32(shape_cb[rind*subvect_size+j]),SIG_SHIFT-5);
493       } else {
494          for (j=0;j<subvect_size;j++)
495             e[subvect_size*i+j]=NEG32(SHL32(EXTEND32(shape_cb[rind*subvect_size+j]),SIG_SHIFT-5));
496       }
497 #else
498       for (j=0;j<subvect_size;j++)
499          e[subvect_size*i+j]=sign*0.03125*shape_cb[rind*subvect_size+j];
500 #endif
501    }
502    /* Update excitation */
503    for (j=0;j<nsf;j++)
504       exc[j]=ADD32(exc[j],e[j]);
505 
506    /* Update target: only update target if necessary */
507    if (update_target)
508    {
509       VARDECL(spx_word16_t *r2);
510       ALLOC(r2, nsf, spx_word16_t);
511       for (j=0;j<nsf;j++)
512          r2[j] = EXTRACT16(PSHR32(e[j] ,6));
513       syn_percep_zero16(r2, ak, awk1, awk2, r2, nsf,p, stack);
514       for (j=0;j<nsf;j++)
515          target[j]=SUB16(target[j],PSHR16(r2[j],2));
516    }
517 }
518 #endif /* DISABLE_ENCODER */
519 
520 #ifndef DISABLE_DECODER
split_cb_shape_sign_unquant(spx_sig_t * exc,const void * par,int nsf,SpeexBits * bits,char * stack,spx_int32_t * seed)521 void split_cb_shape_sign_unquant(
522 spx_sig_t *exc,
523 const void *par,                      /* non-overlapping codebook */
524 int   nsf,                      /* number of samples in subframe */
525 SpeexBits *bits,
526 char *stack,
527 spx_int32_t *seed
528 )
529 {
530    int i,j;
531    VARDECL(int *ind);
532    VARDECL(int *signs);
533    const signed char *shape_cb;
534    int subvect_size, nb_subvect;
535    const split_cb_params *params;
536    int have_sign;
537 
538    params = (const split_cb_params *) par;
539    subvect_size = params->subvect_size;
540    nb_subvect = params->nb_subvect;
541 
542    shape_cb = params->shape_cb;
543    have_sign = params->have_sign;
544 
545    ALLOC(ind, nb_subvect, int);
546    ALLOC(signs, nb_subvect, int);
547 
548    /* Decode codewords and gains */
549    for (i=0;i<nb_subvect;i++)
550    {
551       if (have_sign)
552          signs[i] = speex_bits_unpack_unsigned(bits, 1);
553       else
554          signs[i] = 0;
555       ind[i] = speex_bits_unpack_unsigned(bits, params->shape_bits);
556    }
557    /* Compute decoded excitation */
558    for (i=0;i<nb_subvect;i++)
559    {
560       spx_word16_t s=1;
561       if (signs[i])
562          s=-1;
563 #ifdef FIXED_POINT
564       if (s==1)
565       {
566          for (j=0;j<subvect_size;j++)
567             exc[subvect_size*i+j]=SHL32(EXTEND32(shape_cb[ind[i]*subvect_size+j]),SIG_SHIFT-5);
568       } else {
569          for (j=0;j<subvect_size;j++)
570             exc[subvect_size*i+j]=NEG32(SHL32(EXTEND32(shape_cb[ind[i]*subvect_size+j]),SIG_SHIFT-5));
571       }
572 #else
573       for (j=0;j<subvect_size;j++)
574          exc[subvect_size*i+j]+=s*0.03125*shape_cb[ind[i]*subvect_size+j];
575 #endif
576    }
577 }
578 #endif /* DISABLE_DECODER */
579 
580 #ifndef DISABLE_ENCODER
noise_codebook_quant(spx_word16_t target[],spx_coef_t ak[],spx_coef_t awk1[],spx_coef_t awk2[],const void * par,int p,int nsf,spx_sig_t * exc,spx_word16_t * r,SpeexBits * bits,char * stack,int complexity,int update_target)581 void noise_codebook_quant(
582 spx_word16_t target[],			/* target vector */
583 spx_coef_t ak[],			/* LPCs for this subframe */
584 spx_coef_t awk1[],			/* Weighted LPCs for this subframe */
585 spx_coef_t awk2[],			/* Weighted LPCs for this subframe */
586 const void *par,                      /* Codebook/search parameters*/
587 int   p,                        /* number of LPC coeffs */
588 int   nsf,                      /* number of samples in subframe */
589 spx_sig_t *exc,
590 spx_word16_t *r,
591 SpeexBits *bits,
592 char *stack,
593 int   complexity,
594 int   update_target
595 )
596 {
597    int i;
598    VARDECL(spx_word16_t *tmp);
599    ALLOC(tmp, nsf, spx_word16_t);
600    residue_percep_zero16(target, ak, awk1, awk2, tmp, nsf, p, stack);
601 
602    for (i=0;i<nsf;i++)
603       exc[i]+=SHL32(EXTEND32(tmp[i]),8);
604    SPEEX_MEMSET(target, 0, nsf);
605 }
606 #endif /* DISABLE_ENCODER */
607 
608 #ifndef DISABLE_DECODER
noise_codebook_unquant(spx_sig_t * exc,const void * par,int nsf,SpeexBits * bits,char * stack,spx_int32_t * seed)609 void noise_codebook_unquant(
610 spx_sig_t *exc,
611 const void *par,                      /* non-overlapping codebook */
612 int   nsf,                      /* number of samples in subframe */
613 SpeexBits *bits,
614 char *stack,
615 spx_int32_t *seed
616 )
617 {
618    int i;
619    /* FIXME: This is bad, but I don't think the function ever gets called anyway */
620    for (i=0;i<nsf;i++)
621       exc[i]=SHL32(EXTEND32(speex_rand(1, seed)),SIG_SHIFT);
622 }
623 #endif /* DISABLE_DECODER */
624