~ubuntu-branches/ubuntu/vivid/linphone/vivid

« back to all changes in this revision

Viewing changes to speex/libspeex/cb_search.c

  • Committer: Bazaar Package Importer
  • Author(s): Samuel Mimram
  • Date: 2006-11-15 10:34:50 UTC
  • mfrom: (1.2.1 upstream) (2.1.8 feisty)
  • Revision ID: james.westby@ubuntu.com-20061115103450-qgafwcks2lkhctlj
* New upstream release.
* Enable video support.
* Fix mismatched #endif in mscommon.h, closes: #398307.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2002 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
 
 
33
 
#include "cb_search.h"
34
 
#include "filters.h"
35
 
#include "stack_alloc.h"
36
 
#include "vq.h"
37
 
#include "misc.h"
38
 
#include <stdio.h>
39
 
 
40
 
#ifdef _USE_SSE
41
 
#include "cb_search_sse.h"
42
 
#else
43
 
 
44
 
static void compute_weighted_codebook(const signed char *shape_cb, const spx_sig_t *r, spx_word16_t *resp, float *resp2, spx_word32_t *E, int shape_cb_size, int subvect_size, char *stack)
45
 
{
46
 
   int i, j, k;
47
 
   for (i=0;i<shape_cb_size;i++)
48
 
   {
49
 
      spx_word16_t *res;
50
 
      const signed char *shape;
51
 
 
52
 
      res = resp+i*subvect_size;
53
 
      shape = shape_cb+i*subvect_size;
54
 
 
55
 
      /* Compute codeword response using convolution with impulse response */
56
 
      for(j=0;j<subvect_size;j++)
57
 
      {
58
 
         spx_word32_t resj=0;
59
 
         for (k=0;k<=j;k++)
60
 
            resj = MAC16_16_Q11(resj,shape[k],r[j-k]);
61
 
#ifndef FIXED_POINT
62
 
         resj *= 0.03125;
63
 
#endif
64
 
         res[j] = resj;
65
 
         /*printf ("%d\n", (int)res[j]);*/
66
 
      }
67
 
      
68
 
      /* Compute codeword energy */
69
 
      E[i]=0;
70
 
      for(j=0;j<subvect_size;j++)
71
 
         E[i]=ADD32(E[i],MULT16_16(res[j],res[j]));
72
 
   }
73
 
 
74
 
}
75
 
 
76
 
#endif
77
 
 
78
 
 
79
 
void split_cb_search_shape_sign(
80
 
spx_sig_t target[],                     /* target vector */
81
 
spx_coef_t ak[],                        /* LPCs for this subframe */
82
 
spx_coef_t awk1[],                      /* Weighted LPCs for this subframe */
83
 
spx_coef_t awk2[],                      /* Weighted LPCs for this subframe */
84
 
const void *par,                      /* Codebook/search parameters*/
85
 
int   p,                        /* number of LPC coeffs */
86
 
int   nsf,                      /* number of samples in subframe */
87
 
spx_sig_t *exc,
88
 
spx_sig_t *r,
89
 
SpeexBits *bits,
90
 
char *stack,
91
 
int   complexity
92
 
)
93
 
{
94
 
   int i,j,k,m,n,q;
95
 
   spx_word16_t *resp;
96
 
#ifdef _USE_SSE
97
 
   __m128 *resp2;
98
 
   __m128 *E;
99
 
#else
100
 
   spx_word16_t *resp2;
101
 
   spx_word32_t *E;
102
 
#endif
103
 
   spx_word16_t *t;
104
 
   spx_sig_t *e, *r2;
105
 
   spx_word16_t *tmp;
106
 
   spx_word32_t *ndist, *odist;
107
 
   int *itmp;
108
 
   spx_word16_t **ot, **nt;
109
 
   int **nind, **oind;
110
 
   int *ind;
111
 
   const signed char *shape_cb;
112
 
   int shape_cb_size, subvect_size, nb_subvect;
113
 
   split_cb_params *params;
114
 
   int N=2;
115
 
   int *best_index;
116
 
   spx_word32_t *best_dist;
117
 
   int have_sign;
118
 
   N=complexity;
119
 
   if (N>10)
120
 
      N=10;
121
 
 
122
 
   ot=PUSH(stack, N, spx_word16_t*);
123
 
   nt=PUSH(stack, N, spx_word16_t*);
124
 
   oind=PUSH(stack, N, int*);
125
 
   nind=PUSH(stack, N, int*);
126
 
 
127
 
   params = (split_cb_params *) par;
128
 
   subvect_size = params->subvect_size;
129
 
   nb_subvect = params->nb_subvect;
130
 
   shape_cb_size = 1<<params->shape_bits;
131
 
   shape_cb = params->shape_cb;
132
 
   have_sign = params->have_sign;
133
 
   resp = PUSH(stack, shape_cb_size*subvect_size, spx_word16_t);
134
 
#ifdef _USE_SSE
135
 
   resp2 = PUSH(stack, (shape_cb_size*subvect_size)>>2, __m128);
136
 
   E = PUSH(stack, shape_cb_size>>2, __m128);
137
 
#else
138
 
   resp2 = resp;
139
 
   E = PUSH(stack, shape_cb_size, spx_word32_t);
140
 
#endif
141
 
   t = PUSH(stack, nsf, spx_word16_t);
142
 
   e = PUSH(stack, nsf, spx_sig_t);
143
 
   r2 = PUSH(stack, nsf, spx_sig_t);
144
 
   ind = PUSH(stack, nb_subvect, int);
145
 
 
146
 
   tmp = PUSH(stack, 2*N*nsf, spx_word16_t);
147
 
   for (i=0;i<N;i++)
148
 
   {
149
 
      ot[i]=tmp;
150
 
      tmp += nsf;
151
 
      nt[i]=tmp;
152
 
      tmp += nsf;
153
 
   }
154
 
   best_index = PUSH(stack, N, int);
155
 
   best_dist = PUSH(stack, N, spx_word32_t);
156
 
   ndist = PUSH(stack, N, spx_word32_t);
157
 
   odist = PUSH(stack, N, spx_word32_t);
158
 
   
159
 
   itmp = PUSH(stack, 2*N*nb_subvect, int);
160
 
   for (i=0;i<N;i++)
161
 
   {
162
 
      nind[i]=itmp;
163
 
      itmp+=nb_subvect;
164
 
      oind[i]=itmp;
165
 
      itmp+=nb_subvect;
166
 
      for (j=0;j<nb_subvect;j++)
167
 
         nind[i][j]=oind[i][j]=-1;
168
 
   }
169
 
   
170
 
   /* FIXME: make that adaptive? */
171
 
   for (i=0;i<nsf;i++)
172
 
      t[i]=SHR(target[i],6);
173
 
 
174
 
   for (j=0;j<N;j++)
175
 
      for (i=0;i<nsf;i++)
176
 
         ot[j][i]=t[i];
177
 
 
178
 
   /*for (i=0;i<nsf;i++)
179
 
     printf ("%d\n", (int)t[i]);*/
180
 
 
181
 
   /* Pre-compute codewords response and energy */
182
 
   compute_weighted_codebook(shape_cb, r, resp, resp2, E, shape_cb_size, subvect_size, stack);
183
 
 
184
 
   for (j=0;j<N;j++)
185
 
      odist[j]=0;
186
 
   /*For all subvectors*/
187
 
   for (i=0;i<nb_subvect;i++)
188
 
   {
189
 
      /*"erase" nbest list*/
190
 
      for (j=0;j<N;j++)
191
 
         ndist[j]=-2;
192
 
 
193
 
      /*For all n-bests of previous subvector*/
194
 
      for (j=0;j<N;j++)
195
 
      {
196
 
         spx_word16_t *x=ot[j]+subvect_size*i;
197
 
         /*Find new n-best based on previous n-best j*/
198
 
         if (have_sign)
199
 
            vq_nbest_sign(x, resp2, subvect_size, shape_cb_size, E, N, best_index, best_dist, stack);
200
 
         else
201
 
            vq_nbest(x, resp2, subvect_size, shape_cb_size, E, N, best_index, best_dist, stack);
202
 
 
203
 
         /*For all new n-bests*/
204
 
         for (k=0;k<N;k++)
205
 
         {
206
 
            spx_word16_t *ct;
207
 
            spx_word32_t err=0;
208
 
            ct = ot[j];
209
 
            /*update target*/
210
 
 
211
 
            /*previous target*/
212
 
            for (m=i*subvect_size;m<(i+1)*subvect_size;m++)
213
 
               t[m]=ct[m];
214
 
 
215
 
            /* New code: update only enough of the target to calculate error*/
216
 
            {
217
 
               int rind;
218
 
               spx_word16_t *res;
219
 
               spx_word16_t sign=1;
220
 
               rind = best_index[k];
221
 
               if (rind>=shape_cb_size)
222
 
               {
223
 
                  sign=-1;
224
 
                  rind-=shape_cb_size;
225
 
               }
226
 
               res = resp+rind*subvect_size;
227
 
               if (sign>0)
228
 
                  for (m=0;m<subvect_size;m++)
229
 
                     t[subvect_size*i+m] -= res[m];
230
 
               else
231
 
                  for (m=0;m<subvect_size;m++)
232
 
                     t[subvect_size*i+m] += res[m];
233
 
            }
234
 
            
235
 
            /*compute error (distance)*/
236
 
            err=odist[j];
237
 
            for (m=i*subvect_size;m<(i+1)*subvect_size;m++)
238
 
               err += t[m]*t[m];
239
 
            /*update n-best list*/
240
 
            if (err<ndist[N-1] || ndist[N-1]<-1)
241
 
            {
242
 
 
243
 
               /*previous target (we don't care what happened before*/
244
 
               for (m=(i+1)*subvect_size;m<nsf;m++)
245
 
                  t[m]=ct[m];
246
 
               /* New code: update the rest of the target only if it's worth it */
247
 
               for (m=0;m<subvect_size;m++)
248
 
               {
249
 
                  spx_word16_t g;
250
 
                  int rind;
251
 
                  spx_word16_t sign=1;
252
 
                  rind = best_index[k];
253
 
                  if (rind>=shape_cb_size)
254
 
                  {
255
 
                     sign=-1;
256
 
                     rind-=shape_cb_size;
257
 
                  }
258
 
 
259
 
                  q=subvect_size-m;
260
 
#ifdef FIXED_POINT
261
 
                  g=sign*shape_cb[rind*subvect_size+m];
262
 
                  for (n=subvect_size*(i+1);n<nsf;n++,q++)
263
 
                     t[n] = SUB32(t[n],MULT16_16_Q11(g,r[q]));
264
 
#else
265
 
                  g=sign*0.03125*shape_cb[rind*subvect_size+m];
266
 
                  for (n=subvect_size*(i+1);n<nsf;n++,q++)
267
 
                     t[n] = SUB32(t[n],g*r[q]);
268
 
#endif
269
 
               }
270
 
 
271
 
 
272
 
               for (m=0;m<N;m++)
273
 
               {
274
 
                  if (err < ndist[m] || ndist[m]<-1)
275
 
                  {
276
 
                     for (n=N-1;n>m;n--)
277
 
                     {
278
 
                        for (q=(i+1)*subvect_size;q<nsf;q++)
279
 
                           nt[n][q]=nt[n-1][q];
280
 
                        for (q=0;q<nb_subvect;q++)
281
 
                           nind[n][q]=nind[n-1][q];
282
 
                        ndist[n]=ndist[n-1];
283
 
                     }
284
 
                     for (q=(i+1)*subvect_size;q<nsf;q++)
285
 
                        nt[m][q]=t[q];
286
 
                     for (q=0;q<nb_subvect;q++)
287
 
                        nind[m][q]=oind[j][q];
288
 
                     nind[m][i]=best_index[k];
289
 
                     ndist[m]=err;
290
 
                     break;
291
 
                  }
292
 
               }
293
 
            }
294
 
         }
295
 
         if (i==0)
296
 
           break;
297
 
      }
298
 
 
299
 
      /*update old-new data*/
300
 
      /* just swap pointers instead of a long copy */
301
 
      {
302
 
         spx_word16_t **tmp2;
303
 
         tmp2=ot;
304
 
         ot=nt;
305
 
         nt=tmp2;
306
 
      }
307
 
      for (j=0;j<N;j++)
308
 
         for (m=0;m<nb_subvect;m++)
309
 
            oind[j][m]=nind[j][m];
310
 
      for (j=0;j<N;j++)
311
 
         odist[j]=ndist[j];
312
 
   }
313
 
 
314
 
   /*save indices*/
315
 
   for (i=0;i<nb_subvect;i++)
316
 
   {
317
 
      ind[i]=nind[0][i];
318
 
      speex_bits_pack(bits,ind[i],params->shape_bits+have_sign);
319
 
   }
320
 
   
321
 
   /* Put everything back together */
322
 
   for (i=0;i<nb_subvect;i++)
323
 
   {
324
 
      int rind;
325
 
      spx_word16_t sign=1;
326
 
      rind = ind[i];
327
 
      if (rind>=shape_cb_size)
328
 
      {
329
 
         sign=-1;
330
 
         rind-=shape_cb_size;
331
 
      }
332
 
#ifdef FIXED_POINT
333
 
      if (sign==1)
334
 
      {
335
 
         for (j=0;j<subvect_size;j++)
336
 
            e[subvect_size*i+j]=SHL((spx_word32_t)shape_cb[rind*subvect_size+j],SIG_SHIFT-5);
337
 
      } else {
338
 
         for (j=0;j<subvect_size;j++)
339
 
            e[subvect_size*i+j]=-SHL((spx_word32_t)shape_cb[rind*subvect_size+j],SIG_SHIFT-5);
340
 
      }
341
 
#else
342
 
      for (j=0;j<subvect_size;j++)
343
 
         e[subvect_size*i+j]=sign*0.03125*shape_cb[rind*subvect_size+j];
344
 
#endif
345
 
   }   
346
 
   /* Update excitation */
347
 
   for (j=0;j<nsf;j++)
348
 
      exc[j]+=e[j];
349
 
   
350
 
   /* Update target */
351
 
   syn_percep_zero(e, ak, awk1, awk2, r2, nsf,p, stack);
352
 
   for (j=0;j<nsf;j++)
353
 
      target[j]-=r2[j];
354
 
 
355
 
}
356
 
 
357
 
 
358
 
void split_cb_shape_sign_unquant(
359
 
spx_sig_t *exc,
360
 
const void *par,                      /* non-overlapping codebook */
361
 
int   nsf,                      /* number of samples in subframe */
362
 
SpeexBits *bits,
363
 
char *stack
364
 
)
365
 
{
366
 
   int i,j;
367
 
   int *ind, *signs;
368
 
   const signed char *shape_cb;
369
 
   int shape_cb_size, subvect_size, nb_subvect;
370
 
   split_cb_params *params;
371
 
   int have_sign;
372
 
 
373
 
   params = (split_cb_params *) par;
374
 
   subvect_size = params->subvect_size;
375
 
   nb_subvect = params->nb_subvect;
376
 
   shape_cb_size = 1<<params->shape_bits;
377
 
   shape_cb = params->shape_cb;
378
 
   have_sign = params->have_sign;
379
 
 
380
 
   ind = PUSH(stack, nb_subvect, int);
381
 
   signs = PUSH(stack, nb_subvect, int);
382
 
 
383
 
   /* Decode codewords and gains */
384
 
   for (i=0;i<nb_subvect;i++)
385
 
   {
386
 
      if (have_sign)
387
 
         signs[i] = speex_bits_unpack_unsigned(bits, 1);
388
 
      else
389
 
         signs[i] = 0;
390
 
      ind[i] = speex_bits_unpack_unsigned(bits, params->shape_bits);
391
 
   }
392
 
   /* Compute decoded excitation */
393
 
   for (i=0;i<nb_subvect;i++)
394
 
   {
395
 
      spx_word16_t s=1;
396
 
      if (signs[i])
397
 
         s=-1;
398
 
#ifdef FIXED_POINT
399
 
      if (s==1)
400
 
      {
401
 
         for (j=0;j<subvect_size;j++)
402
 
            exc[subvect_size*i+j]=SHL((spx_word32_t)shape_cb[ind[i]*subvect_size+j],SIG_SHIFT-5);
403
 
      } else {
404
 
         for (j=0;j<subvect_size;j++)
405
 
            exc[subvect_size*i+j]=-SHL((spx_word32_t)shape_cb[ind[i]*subvect_size+j],SIG_SHIFT-5);
406
 
      }
407
 
#else
408
 
      for (j=0;j<subvect_size;j++)
409
 
         exc[subvect_size*i+j]+=s*0.03125*shape_cb[ind[i]*subvect_size+j];      
410
 
#endif
411
 
   }
412
 
}
413
 
 
414
 
void noise_codebook_quant(
415
 
spx_sig_t target[],                     /* target vector */
416
 
spx_coef_t ak[],                        /* LPCs for this subframe */
417
 
spx_coef_t awk1[],                      /* Weighted LPCs for this subframe */
418
 
spx_coef_t awk2[],                      /* Weighted LPCs for this subframe */
419
 
const void *par,                      /* Codebook/search parameters*/
420
 
int   p,                        /* number of LPC coeffs */
421
 
int   nsf,                      /* number of samples in subframe */
422
 
spx_sig_t *exc,
423
 
spx_sig_t *r,
424
 
SpeexBits *bits,
425
 
char *stack,
426
 
int   complexity
427
 
)
428
 
{
429
 
   int i;
430
 
   spx_sig_t *tmp=PUSH(stack, nsf, spx_sig_t);
431
 
   residue_percep_zero(target, ak, awk1, awk2, tmp, nsf, p, stack);
432
 
 
433
 
   for (i=0;i<nsf;i++)
434
 
      exc[i]+=tmp[i];
435
 
   for (i=0;i<nsf;i++)
436
 
      target[i]=0;
437
 
 
438
 
}
439
 
 
440
 
 
441
 
void noise_codebook_unquant(
442
 
spx_sig_t *exc,
443
 
const void *par,                      /* non-overlapping codebook */
444
 
int   nsf,                      /* number of samples in subframe */
445
 
SpeexBits *bits,
446
 
char *stack
447
 
)
448
 
{
449
 
   speex_rand_vec(1, exc, nsf);
450
 
}