cb_search.c 17.8 KB
Newer Older
Tristan Matthews's avatar
Tristan Matthews committed
1
/* Copyright (C) 2002-2006 Jean-Marc Valin
2
   File: cb_search.c
3

jm's avatar
jm committed
4
5
6
   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions
   are met:
Tristan Matthews's avatar
Tristan Matthews committed
7

jm's avatar
jm committed
8
9
   - Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.
Tristan Matthews's avatar
Tristan Matthews committed
10

jm's avatar
jm committed
11
12
13
   - Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.
Tristan Matthews's avatar
Tristan Matthews committed
14

jm's avatar
jm committed
15
16
17
   - Neither the name of the Xiph.org Foundation nor the names of its
   contributors may be used to endorse or promote products derived from
   this software without specific prior written permission.
Tristan Matthews's avatar
Tristan Matthews committed
18

jm's avatar
jm committed
19
20
21
22
23
24
25
26
27
28
29
   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31
*/

32
33
34
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
35

36
#include "cb_search.h"
37
#include "filters.h"
jmvalin's avatar
jmvalin committed
38
39
#include "stack_alloc.h"
#include "vq.h"
jm's avatar
jm committed
40
#include "arch.h"
41
42
#include "math_approx.h"
#include "os_support.h"
43

44
45
#ifdef _USE_SSE
#include "cb_search_sse.h"
jm's avatar
jm committed
46
47
#elif defined(ARM4_ASM) || defined(ARM5E_ASM)
#include "cb_search_arm4.h"
48
49
#elif defined(BFIN_ASM)
#include "cb_search_bfin.h"
jm's avatar
jm committed
50
#endif
51

52
53
#ifndef DISABLE_ENCODER

jm's avatar
jm committed
54
#ifndef OVERRIDE_COMPUTE_WEIGHTED_CODEBOOK
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
59
   VARDECL(spx_word16_t *shape);
   ALLOC(shape, subvect_size, spx_word16_t);
60
61
62
   for (i=0;i<shape_cb_size;i++)
   {
      spx_word16_t *res;
Tristan Matthews's avatar
Tristan Matthews committed
63

64
      res = resp+i*subvect_size;
65
66
      for (k=0;k<subvect_size;k++)
         shape[k] = (spx_word16_t)shape_cb[i*subvect_size+k];
jm's avatar
jm committed
67
      E[i]=0;
68
69
70
71
72

      /* Compute codeword response using convolution with impulse response */
      for(j=0;j<subvect_size;j++)
      {
         spx_word32_t resj=0;
jm's avatar
jm committed
73
         spx_word16_t res16;
74
         for (k=0;k<=j;k++)
jm's avatar
jm committed
75
76
            resj = MAC16_16(resj,shape[k],r[j-k]);
#ifdef FIXED_POINT
77
         res16 = EXTRACT16(SHR32(resj, 13));
jm's avatar
jm committed
78
#else
jm's avatar
jm committed
79
         res16 = 0.03125f*resj;
80
#endif
jm's avatar
jm committed
81
         /* Compute codeword energy */
jm's avatar
jm committed
82
83
         E[i]=MAC16_16(E[i],res16,res16);
         res[j] = res16;
84
85
86
87
88
89
90
         /*printf ("%d\n", (int)res[j]);*/
      }
   }

}
#endif

91
92
93
94
#ifndef OVERRIDE_TARGET_UPDATE
static inline void target_update(spx_word16_t *t, spx_word16_t g, spx_word16_t *r, int len)
{
   int n;
jm's avatar
jm committed
95
   for (n=0;n<len;n++)
96
      t[n] = SUB16(t[n],PSHR32(MULT16_16(g,r[n]),13));
97
98
99
}
#endif

100

101

102
static void split_cb_search_shape_sign_N1(
103
spx_word16_t target[],			/* target vector */
104
105
106
107
108
109
110
spx_coef_t ak[],			/* LPCs for this subframe */
spx_coef_t awk1[],			/* Weighted LPCs for this subframe */
spx_coef_t awk2[],			/* Weighted LPCs for this subframe */
const void *par,                      /* Codebook/search parameters*/
int   p,                        /* number of LPC coeffs */
int   nsf,                      /* number of samples in subframe */
spx_sig_t *exc,
111
spx_word16_t *r,
112
113
114
SpeexBits *bits,
char *stack,
int   update_target
jm's avatar
jm committed
115
)
116
{
117
   int i,j,m,q;
118
   VARDECL(spx_word16_t *resp);
119
#ifdef _USE_SSE
120
121
   VARDECL(__m128 *resp2);
   VARDECL(__m128 *E);
122
123
#else
   spx_word16_t *resp2;
124
   VARDECL(spx_word32_t *E);
125
#endif
126
127
   VARDECL(spx_word16_t *t);
   VARDECL(spx_sig_t *e);
128
129
   const signed char *shape_cb;
   int shape_cb_size, subvect_size, nb_subvect;
130
   const split_cb_params *params;
131
132
133
   int best_index;
   spx_word32_t best_dist;
   int have_sign;
Tristan Matthews's avatar
Tristan Matthews committed
134

135
   params = (const split_cb_params *) par;
136
137
138
139
140
   subvect_size = params->subvect_size;
   nb_subvect = params->nb_subvect;
   shape_cb_size = 1<<params->shape_bits;
   shape_cb = params->shape_cb;
   have_sign = params->have_sign;
141
   ALLOC(resp, shape_cb_size*subvect_size, spx_word16_t);
142
#ifdef _USE_SSE
143
144
   ALLOC(resp2, (shape_cb_size*subvect_size)>>2, __m128);
   ALLOC(E, shape_cb_size>>2, __m128);
145
146
#else
   resp2 = resp;
147
   ALLOC(E, shape_cb_size, spx_word32_t);
148
#endif
149
150
   ALLOC(t, nsf, spx_word16_t);
   ALLOC(e, nsf, spx_sig_t);
Tristan Matthews's avatar
Tristan Matthews committed
151

jm's avatar
jm committed
152
   /* FIXME: Do we still need to copy the target? */
153
   SPEEX_COPY(t, target, nsf);
154
155
156
157
158
159
160

   compute_weighted_codebook(shape_cb, r, resp, resp2, E, shape_cb_size, subvect_size, stack);

   for (i=0;i<nb_subvect;i++)
   {
      spx_word16_t *x=t+subvect_size*i;
      /*Find new n-best based on previous n-best j*/
161
#ifndef DISABLE_WIDEBAND
162
163
164
      if (have_sign)
         vq_nbest_sign(x, resp2, subvect_size, shape_cb_size, E, 1, &best_index, &best_dist, stack);
      else
165
#endif /* DISABLE_WIDEBAND */
166
         vq_nbest(x, resp2, subvect_size, shape_cb_size, E, 1, &best_index, &best_dist, stack);
Tristan Matthews's avatar
Tristan Matthews committed
167

168
      speex_bits_pack(bits,best_index,params->shape_bits+have_sign);
Tristan Matthews's avatar
Tristan Matthews committed
169

170
171
172
173
174
175
176
177
178
179
180
181
182
      {
         int rind;
         spx_word16_t *res;
         spx_word16_t sign=1;
         rind = best_index;
         if (rind>=shape_cb_size)
         {
            sign=-1;
            rind-=shape_cb_size;
         }
         res = resp+rind*subvect_size;
         if (sign>0)
            for (m=0;m<subvect_size;m++)
183
               t[subvect_size*i+m] = SUB16(t[subvect_size*i+m], res[m]);
184
185
         else
            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++)
jm's avatar
jm committed
192
               e[subvect_size*i+j]=SHL32(EXTEND32(shape_cb[rind*subvect_size+j]),SIG_SHIFT-5);
193
194
         } else {
            for (j=0;j<subvect_size;j++)
jm's avatar
jm committed
195
               e[subvect_size*i+j]=NEG32(SHL32(EXTEND32(shape_cb[rind*subvect_size+j]),SIG_SHIFT-5));
196
197
198
199
200
         }
#else
         for (j=0;j<subvect_size;j++)
            e[subvect_size*i+j]=sign*0.03125*shape_cb[rind*subvect_size+j];
#endif
Tristan Matthews's avatar
Tristan Matthews committed
201

202
      }
Tristan Matthews's avatar
Tristan Matthews committed
203

204
205
206
207
208
209
210
211
212
213
214
      for (m=0;m<subvect_size;m++)
      {
         spx_word16_t g;
         int rind;
         spx_word16_t sign=1;
         rind = best_index;
         if (rind>=shape_cb_size)
         {
            sign=-1;
            rind-=shape_cb_size;
         }
Tristan Matthews's avatar
Tristan Matthews committed
215

216
217
218
219
220
221
         q=subvect_size-m;
#ifdef FIXED_POINT
         g=sign*shape_cb[rind*subvect_size+m];
#else
         g=sign*0.03125*shape_cb[rind*subvect_size+m];
#endif
jm's avatar
jm committed
222
         target_update(t+subvect_size*(i+1), g, r+q, nsf-subvect_size*(i+1));
223
224
225
226
      }
   }

   /* Update excitation */
jm's avatar
Comment    
jm committed
227
   /* FIXME: We could update the excitation directly above */
228
   for (j=0;j<nsf;j++)
229
      exc[j]=ADD32(exc[j],e[j]);
Tristan Matthews's avatar
Tristan Matthews committed
230

231
232
233
   /* Update target: only update target if necessary */
   if (update_target)
   {
234
235
      VARDECL(spx_word16_t *r2);
      ALLOC(r2, nsf, spx_word16_t);
236
      for (j=0;j<nsf;j++)
237
238
239
240
         r2[j] = EXTRACT16(PSHR32(e[j] ,6));
      syn_percep_zero16(r2, ak, awk1, awk2, r2, nsf,p, stack);
      for (j=0;j<nsf;j++)
         target[j]=SUB16(target[j],PSHR16(r2[j],2));
241
242
243
   }
}

jm's avatar
jm committed
244

245

246
void split_cb_search_shape_sign(
247
spx_word16_t target[],			/* target vector */
248
249
250
spx_coef_t ak[],			/* LPCs for this subframe */
spx_coef_t awk1[],			/* Weighted LPCs for this subframe */
spx_coef_t awk2[],			/* Weighted LPCs for this subframe */
jm's avatar
jm committed
251
const void *par,                      /* Codebook/search parameters*/
252
253
int   p,                        /* number of LPC coeffs */
int   nsf,                      /* number of samples in subframe */
254
spx_sig_t *exc,
255
spx_word16_t *r,
256
SpeexBits *bits,
257
char *stack,
258
259
int   complexity,
int   update_target
260
261
262
)
{
   int i,j,k,m,n,q;
263
   VARDECL(spx_word16_t *resp);
264
#ifdef _USE_SSE
265
266
   VARDECL(__m128 *resp2);
   VARDECL(__m128 *E);
267
268
#else
   spx_word16_t *resp2;
269
   VARDECL(spx_word32_t *E);
270
#endif
271
272
273
274
275
276
277
278
   VARDECL(spx_word16_t *t);
   VARDECL(spx_sig_t *e);
   VARDECL(spx_word16_t *tmp);
   VARDECL(spx_word32_t *ndist);
   VARDECL(spx_word32_t *odist);
   VARDECL(int *itmp);
   VARDECL(spx_word16_t **ot2);
   VARDECL(spx_word16_t **nt2);
279
   spx_word16_t **ot, **nt;
280
281
282
   VARDECL(int **nind);
   VARDECL(int **oind);
   VARDECL(int *ind);
jm's avatar
jm committed
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
288
   VARDECL(int *best_index);
   VARDECL(spx_word32_t *best_dist);
289
290
   VARDECL(int *best_nind);
   VARDECL(int *best_ntarget);
291
   int have_sign;
292
293
294
   N=complexity;
   if (N>10)
      N=10;
295
296
   /* Complexity isn't as important for the codebooks as it is for the pitch */
   N=(2*N)/3;
297
298
   if (N<1)
      N=1;
jm's avatar
jm committed
299
300
   if (N==1)
   {
301
      split_cb_search_shape_sign_N1(target,ak,awk1,awk2,par,p,nsf,exc,r,bits,stack,update_target);
jm's avatar
jm committed
302
303
      return;
   }
304
305
306
307
   ALLOC(ot2, N, spx_word16_t*);
   ALLOC(nt2, N, spx_word16_t*);
   ALLOC(oind, N, int*);
   ALLOC(nind, N, int*);
308

309
   params = (const split_cb_params *) par;
310
311
312
313
   subvect_size = params->subvect_size;
   nb_subvect = params->nb_subvect;
   shape_cb_size = 1<<params->shape_bits;
   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
318
   ALLOC(resp2, (shape_cb_size*subvect_size)>>2, __m128);
   ALLOC(E, shape_cb_size>>2, __m128);
319
320
#else
   resp2 = resp;
321
   ALLOC(E, shape_cb_size, spx_word32_t);
322
#endif
323
324
325
   ALLOC(t, nsf, spx_word16_t);
   ALLOC(e, nsf, spx_sig_t);
   ALLOC(ind, nb_subvect, int);
jm's avatar
jm committed
326

327
   ALLOC(tmp, 2*N*nsf, spx_word16_t);
328
329
   for (i=0;i<N;i++)
   {
330
331
      ot2[i]=tmp+2*i*nsf;
      nt2[i]=tmp+(2*i+1)*nsf;
332
   }
333
334
335
336
   ot=ot2;
   nt=nt2;
   ALLOC(best_index, N, int);
   ALLOC(best_dist, N, spx_word32_t);
337
338
   ALLOC(best_nind, N, int);
   ALLOC(best_ntarget, N, int);
339
340
   ALLOC(ndist, N, spx_word32_t);
   ALLOC(odist, N, spx_word32_t);
Tristan Matthews's avatar
Tristan Matthews committed
341

342
   ALLOC(itmp, 2*N*nb_subvect, int);
343
344
   for (i=0;i<N;i++)
   {
345
346
      nind[i]=itmp+2*i*nb_subvect;
      oind[i]=itmp+(2*i+1)*nb_subvect;
347
   }
Tristan Matthews's avatar
Tristan Matthews committed
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
358

   for (j=0;j<N;j++)
      odist[j]=0;
Tristan Matthews's avatar
Tristan Matthews committed
359

360
361
362
363
364
   /*For all subvectors*/
   for (i=0;i<nb_subvect;i++)
   {
      /*"erase" nbest list*/
      for (j=0;j<N;j++)
jm's avatar
jm committed
365
         ndist[j]=VERY_LARGE32;
Tristan Matthews's avatar
Tristan Matthews committed
366
      /* This is not strictly necessary, but it provides an additonal safety
367
368
369
370
         to prevent crashes in case something goes wrong in the previous
         steps (e.g. NaNs) */
      for (j=0;j<N;j++)
         best_nind[j] = best_ntarget[j] = 0;
371
372
373
      /*For all n-bests of previous subvector*/
      for (j=0;j<N;j++)
      {
374
         spx_word16_t *x=ot[j]+subvect_size*i;
jm's avatar
jm committed
375
376
377
         spx_word32_t tener = 0;
         for (m=0;m<subvect_size;m++)
            tener = MAC16_16(tener, x[m],x[m]);
378
#ifdef FIXED_POINT
jm's avatar
jm committed
379
         tener = SHR32(tener,1);
380
381
382
#else
         tener *= .5;
#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
392
393

         /*For all new n-bests*/
         for (k=0;k<N;k++)
         {
jm's avatar
jm committed
394
            /* Compute total distance (including previous sub-vectors */
395
            spx_word32_t err = ADD32(ADD32(odist[j],best_dist[k]),tener);
Tristan Matthews's avatar
Tristan Matthews committed
396

397
            /*update n-best list*/
jm's avatar
jm committed
398
            if (err<ndist[N-1])
399
400
401
            {
               for (m=0;m<N;m++)
               {
jm's avatar
jm committed
402
                  if (err < ndist[m])
403
404
405
                  {
                     for (n=N-1;n>m;n--)
                     {
406
407
408
                        ndist[n] = ndist[n-1];
                        best_nind[n] = best_nind[n-1];
                        best_ntarget[n] = best_ntarget[n-1];
409
                     }
410
                     /* n is equal to m here, so they're interchangeable */
411
412
413
                     ndist[m] = err;
                     best_nind[n] = best_index[k];
                     best_ntarget[n] = j;
414
415
416
417
418
419
                     break;
                  }
               }
            }
         }
         if (i==0)
420
421
422
423
424
425
            break;
      }
      for (j=0;j<N;j++)
      {
         /*previous target (we don't care what happened before*/
         for (m=(i+1)*subvect_size;m<nsf;m++)
426
            nt[j][m]=ot[best_ntarget[j]][m];
Tristan Matthews's avatar
Tristan Matthews committed
427

428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
         /* New code: update the rest of the target only if it's worth it */
         for (m=0;m<subvect_size;m++)
         {
            spx_word16_t g;
            int rind;
            spx_word16_t sign=1;
            rind = best_nind[j];
            if (rind>=shape_cb_size)
            {
               sign=-1;
               rind-=shape_cb_size;
            }

            q=subvect_size-m;
#ifdef FIXED_POINT
            g=sign*shape_cb[rind*subvect_size+m];
#else
            g=sign*0.03125*shape_cb[rind*subvect_size+m];
#endif
jm's avatar
jm committed
447
            target_update(nt[j]+subvect_size*(i+1), g, r+q, nsf-subvect_size*(i+1));
448
449
450
451
452
         }

         for (q=0;q<nb_subvect;q++)
            nind[j][q]=oind[best_ntarget[j]][q];
         nind[j][i]=best_nind[j];
453
454
455
456
457
      }

      /*update old-new data*/
      /* just swap pointers instead of a long copy */
      {
458
         spx_word16_t **tmp2;
jm's avatar
jm committed
459
         tmp2=ot;
460
         ot=nt;
jm's avatar
jm committed
461
         nt=tmp2;
462
463
464
465
466
467
468
469
470
471
472
473
      }
      for (j=0;j<N;j++)
         for (m=0;m<nb_subvect;m++)
            oind[j][m]=nind[j][m];
      for (j=0;j<N;j++)
         odist[j]=ndist[j];
   }

   /*save indices*/
   for (i=0;i<nb_subvect;i++)
   {
      ind[i]=nind[0][i];
474
      speex_bits_pack(bits,ind[i],params->shape_bits+have_sign);
475
   }
Tristan Matthews's avatar
Tristan Matthews committed
476

477
478
479
480
   /* Put everything back together */
   for (i=0;i<nb_subvect;i++)
   {
      int rind;
481
      spx_word16_t sign=1;
482
      rind = ind[i];
jm's avatar
jm committed
483
      if (rind>=shape_cb_size)
484
485
486
487
      {
         sign=-1;
         rind-=shape_cb_size;
      }
488
489
490
491
#ifdef FIXED_POINT
      if (sign==1)
      {
         for (j=0;j<subvect_size;j++)
jm's avatar
jm committed
492
            e[subvect_size*i+j]=SHL32(EXTEND32(shape_cb[rind*subvect_size+j]),SIG_SHIFT-5);
493
494
      } else {
         for (j=0;j<subvect_size;j++)
jm's avatar
jm committed
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
Tristan Matthews's avatar
Tristan Matthews committed
501
   }
502
503
   /* Update excitation */
   for (j=0;j<nsf;j++)
504
      exc[j]=ADD32(exc[j],e[j]);
Tristan Matthews's avatar
Tristan Matthews committed
505

506
507
508
   /* Update target: only update target if necessary */
   if (update_target)
   {
509
510
511
512
513
      VARDECL(spx_word16_t *r2);
      ALLOC(r2, nsf, spx_word16_t);
      for (j=0;j<nsf;j++)
         r2[j] = EXTRACT16(PSHR32(e[j] ,6));
      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 */
jm's avatar
jm committed
519

520
#ifndef DISABLE_DECODER
521
void split_cb_shape_sign_unquant(
522
spx_sig_t *exc,
jm's avatar
jm committed
523
const void *par,                      /* non-overlapping codebook */
524
525
int   nsf,                      /* number of samples in subframe */
SpeexBits *bits,
526
527
char *stack,
spx_int32_t *seed
528
529
530
)
{
   int i,j;
531
532
   VARDECL(int *ind);
   VARDECL(int *signs);
jm's avatar
jm committed
533
   const signed char *shape_cb;
534
   int shape_cb_size, subvect_size, nb_subvect;
535
   const split_cb_params *params;
536
   int have_sign;
537

538
   params = (const split_cb_params *) par;
539
540
541
542
   subvect_size = params->subvect_size;
   nb_subvect = params->nb_subvect;
   shape_cb_size = 1<<params->shape_bits;
   shape_cb = params->shape_cb;
543
544
   have_sign = params->have_sign;

545
546
   ALLOC(ind, nb_subvect, int);
   ALLOC(signs, nb_subvect, int);
547
548
549
550

   /* Decode codewords and gains */
   for (i=0;i<nb_subvect;i++)
   {
551
552
553
554
      if (have_sign)
         signs[i] = speex_bits_unpack_unsigned(bits, 1);
      else
         signs[i] = 0;
555
556
557
558
559
      ind[i] = speex_bits_unpack_unsigned(bits, params->shape_bits);
   }
   /* Compute decoded excitation */
   for (i=0;i<nb_subvect;i++)
   {
560
      spx_word16_t s=1;
561
562
      if (signs[i])
         s=-1;
jm's avatar
jm committed
563
#ifdef FIXED_POINT
564
565
566
      if (s==1)
      {
         for (j=0;j<subvect_size;j++)
jm's avatar
jm committed
567
            exc[subvect_size*i+j]=SHL32(EXTEND32(shape_cb[ind[i]*subvect_size+j]),SIG_SHIFT-5);
568
569
      } else {
         for (j=0;j<subvect_size;j++)
jm's avatar
jm committed
570
            exc[subvect_size*i+j]=NEG32(SHL32(EXTEND32(shape_cb[ind[i]*subvect_size+j]),SIG_SHIFT-5));
571
      }
jm's avatar
jm committed
572
573
#else
      for (j=0;j<subvect_size;j++)
Tristan Matthews's avatar
Tristan Matthews committed
574
         exc[subvect_size*i+j]+=s*0.03125*shape_cb[ind[i]*subvect_size+j];
jm's avatar
jm committed
575
#endif
576
577
   }
}
578
#endif /* DISABLE_DECODER */
jmvalin's avatar
jmvalin committed
579

580
#ifndef DISABLE_ENCODER
jmvalin's avatar
jmvalin committed
581
void noise_codebook_quant(
582
spx_word16_t target[],			/* target vector */
583
584
585
spx_coef_t ak[],			/* LPCs for this subframe */
spx_coef_t awk1[],			/* Weighted LPCs for this subframe */
spx_coef_t awk2[],			/* Weighted LPCs for this subframe */
jm's avatar
jm committed
586
const void *par,                      /* Codebook/search parameters*/
jmvalin's avatar
jmvalin committed
587
588
int   p,                        /* number of LPC coeffs */
int   nsf,                      /* number of samples in subframe */
589
spx_sig_t *exc,
590
spx_word16_t *r,
jmvalin's avatar
jmvalin committed
591
SpeexBits *bits,
592
char *stack,
593
594
int   complexity,
int   update_target
jmvalin's avatar
jmvalin committed
595
596
597
)
{
   int i;
598
599
600
   VARDECL(spx_word16_t *tmp);
   ALLOC(tmp, nsf, spx_word16_t);
   residue_percep_zero16(target, ak, awk1, awk2, tmp, nsf, p, stack);
jmvalin's avatar
jmvalin committed
601
602

   for (i=0;i<nsf;i++)
603
      exc[i]+=SHL32(EXTEND32(tmp[i]),8);
604
   SPEEX_MEMSET(target, 0, nsf);
jmvalin's avatar
jmvalin committed
605
}
606
#endif /* DISABLE_ENCODER */
jmvalin's avatar
jmvalin committed
607

608
#ifndef DISABLE_DECODER
jmvalin's avatar
jmvalin committed
609
void noise_codebook_unquant(
610
spx_sig_t *exc,
jm's avatar
jm committed
611
const void *par,                      /* non-overlapping codebook */
jmvalin's avatar
jmvalin committed
612
613
int   nsf,                      /* number of samples in subframe */
SpeexBits *bits,
614
615
char *stack,
spx_int32_t *seed
jmvalin's avatar
jmvalin committed
616
617
)
{
618
619
620
   int i;
   /* FIXME: This is bad, but I don't think the function ever gets called anyway */
   for (i=0;i<nsf;i++)
621
      exc[i]=SHL32(EXTEND32(speex_rand(1, seed)),SIG_SHIFT);
jmvalin's avatar
jmvalin committed
622
}
623
#endif /* DISABLE_DECODER */