Coverage Report

Created: 2023-09-25 07:07

/src/speex/libspeex/ltp.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2002-2006 Jean-Marc Valin
2
   File: ltp.c
3
   Long-Term Prediction functions
4
5
   Redistribution and use in source and binary forms, with or without
6
   modification, are permitted provided that the following conditions
7
   are met:
8
9
   - Redistributions of source code must retain the above copyright
10
   notice, this list of conditions and the following disclaimer.
11
12
   - Redistributions in binary form must reproduce the above copyright
13
   notice, this list of conditions and the following disclaimer in the
14
   documentation and/or other materials provided with the distribution.
15
16
   - Neither the name of the Xiph.org Foundation nor the names of its
17
   contributors may be used to endorse or promote products derived from
18
   this software without specific prior written permission.
19
20
   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21
   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23
   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
24
   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25
   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26
   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27
   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28
   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29
   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30
   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
*/
32
33
#ifdef HAVE_CONFIG_H
34
#include "config.h"
35
#endif
36
37
#include <math.h>
38
#include "ltp.h"
39
#include "stack_alloc.h"
40
#include "filters.h"
41
#include "math_approx.h"
42
#include "os_support.h"
43
44
#ifndef NULL
45
#define NULL 0
46
#endif
47
48
49
#ifdef _USE_SSE
50
#include "ltp_sse.h"
51
#elif defined (ARM4_ASM) || defined(ARM5E_ASM)
52
#include "ltp_arm4.h"
53
#elif defined (BFIN_ASM)
54
#include "ltp_bfin.h"
55
#endif
56
57
#ifndef OVERRIDE_INNER_PROD
58
spx_word32_t inner_prod(const spx_word16_t *x, const spx_word16_t *y, int len)
59
{
60
   spx_word32_t sum=0;
61
   len >>= 2;
62
   while(len--)
63
   {
64
      spx_word32_t part=0;
65
      part = MAC16_16(part,*x++,*y++);
66
      part = MAC16_16(part,*x++,*y++);
67
      part = MAC16_16(part,*x++,*y++);
68
      part = MAC16_16(part,*x++,*y++);
69
      /* HINT: If you had a 40-bit accumulator, you could shift only at the end */
70
      sum = ADD32(sum,SHR32(part,6));
71
   }
72
   return sum;
73
}
74
#endif
75
76
#ifndef DISABLE_ENCODER
77
78
#ifndef OVERRIDE_PITCH_XCORR
79
#if 0 /* HINT: Enable this for machines with enough registers (i.e. not x86) */
80
static void pitch_xcorr(const spx_word16_t *_x, const spx_word16_t *_y, spx_word32_t *corr, int len, int nb_pitch, char *stack)
81
{
82
   int i,j;
83
   for (i=0;i<nb_pitch;i+=4)
84
   {
85
      /* Compute correlation*/
86
      /*corr[nb_pitch-1-i]=inner_prod(x, _y+i, len);*/
87
      spx_word32_t sum1=0;
88
      spx_word32_t sum2=0;
89
      spx_word32_t sum3=0;
90
      spx_word32_t sum4=0;
91
      const spx_word16_t *y = _y+i;
92
      const spx_word16_t *x = _x;
93
      spx_word16_t y0, y1, y2, y3;
94
      /*y0=y[0];y1=y[1];y2=y[2];y3=y[3];*/
95
      y0=*y++;
96
      y1=*y++;
97
      y2=*y++;
98
      y3=*y++;
99
      for (j=0;j<len;j+=4)
100
      {
101
         spx_word32_t part1;
102
         spx_word32_t part2;
103
         spx_word32_t part3;
104
         spx_word32_t part4;
105
         part1 = MULT16_16(*x,y0);
106
         part2 = MULT16_16(*x,y1);
107
         part3 = MULT16_16(*x,y2);
108
         part4 = MULT16_16(*x,y3);
109
         x++;
110
         y0=*y++;
111
         part1 = MAC16_16(part1,*x,y1);
112
         part2 = MAC16_16(part2,*x,y2);
113
         part3 = MAC16_16(part3,*x,y3);
114
         part4 = MAC16_16(part4,*x,y0);
115
         x++;
116
         y1=*y++;
117
         part1 = MAC16_16(part1,*x,y2);
118
         part2 = MAC16_16(part2,*x,y3);
119
         part3 = MAC16_16(part3,*x,y0);
120
         part4 = MAC16_16(part4,*x,y1);
121
         x++;
122
         y2=*y++;
123
         part1 = MAC16_16(part1,*x,y3);
124
         part2 = MAC16_16(part2,*x,y0);
125
         part3 = MAC16_16(part3,*x,y1);
126
         part4 = MAC16_16(part4,*x,y2);
127
         x++;
128
         y3=*y++;
129
130
         sum1 = ADD32(sum1,SHR32(part1,6));
131
         sum2 = ADD32(sum2,SHR32(part2,6));
132
         sum3 = ADD32(sum3,SHR32(part3,6));
133
         sum4 = ADD32(sum4,SHR32(part4,6));
134
      }
135
      corr[nb_pitch-1-i]=sum1;
136
      corr[nb_pitch-2-i]=sum2;
137
      corr[nb_pitch-3-i]=sum3;
138
      corr[nb_pitch-4-i]=sum4;
139
   }
140
141
}
142
#else
143
static void pitch_xcorr(const spx_word16_t *_x, const spx_word16_t *_y, spx_word32_t *corr, int len, int nb_pitch, char *stack)
144
{
145
   int i;
146
   for (i=0;i<nb_pitch;i++)
147
   {
148
      /* Compute correlation*/
149
      corr[nb_pitch-1-i]=inner_prod(_x, _y+i, len);
150
   }
151
152
}
153
#endif
154
#endif
155
156
#ifndef OVERRIDE_COMPUTE_PITCH_ERROR
157
static inline spx_word32_t compute_pitch_error(spx_word16_t *C, spx_word16_t *g, spx_word16_t pitch_control)
158
0
{
159
0
   spx_word32_t sum = 0;
160
0
   sum = ADD32(sum,MULT16_16(MULT16_16_16(g[0],pitch_control),C[0]));
161
0
   sum = ADD32(sum,MULT16_16(MULT16_16_16(g[1],pitch_control),C[1]));
162
0
   sum = ADD32(sum,MULT16_16(MULT16_16_16(g[2],pitch_control),C[2]));
163
0
   sum = SUB32(sum,MULT16_16(MULT16_16_16(g[0],g[1]),C[3]));
164
0
   sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[1]),C[4]));
165
0
   sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[0]),C[5]));
166
0
   sum = SUB32(sum,MULT16_16(MULT16_16_16(g[0],g[0]),C[6]));
167
0
   sum = SUB32(sum,MULT16_16(MULT16_16_16(g[1],g[1]),C[7]));
168
0
   sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[2]),C[8]));
169
0
   return sum;
170
0
}
171
#endif
172
173
#ifndef OVERRIDE_OPEN_LOOP_NBEST_PITCH
174
void open_loop_nbest_pitch(spx_word16_t *sw, int start, int end, int len, int *pitch, spx_word16_t *gain, int N, char *stack)
175
0
{
176
0
   int i,j,k;
177
0
   VARDECL(spx_word32_t *best_score);
178
0
   VARDECL(spx_word32_t *best_ener);
179
0
   spx_word32_t e0;
180
0
   VARDECL(spx_word32_t *corr);
181
#ifdef FIXED_POINT
182
   /* In fixed-point, we need only one (temporary) array of 32-bit values and two (corr16, ener16)
183
      arrays for (normalized) 16-bit values */
184
   VARDECL(spx_word16_t *corr16);
185
   VARDECL(spx_word16_t *ener16);
186
   spx_word32_t *energy;
187
   int cshift=0, eshift=0;
188
   int scaledown = 0;
189
   ALLOC(corr16, end-start+1, spx_word16_t);
190
   ALLOC(ener16, end-start+1, spx_word16_t);
191
   ALLOC(corr, end-start+1, spx_word32_t);
192
   energy = corr;
193
#else
194
   /* In floating-point, we need to float arrays and no normalized copies */
195
0
   VARDECL(spx_word32_t *energy);
196
0
   spx_word16_t *corr16;
197
0
   spx_word16_t *ener16;
198
0
   ALLOC(energy, end-start+2, spx_word32_t);
199
0
   ALLOC(corr, end-start+1, spx_word32_t);
200
0
   corr16 = corr;
201
0
   ener16 = energy;
202
0
#endif
203
204
0
   ALLOC(best_score, N, spx_word32_t);
205
0
   ALLOC(best_ener, N, spx_word32_t);
206
0
   for (i=0;i<N;i++)
207
0
   {
208
0
        best_score[i]=-1;
209
0
        best_ener[i]=0;
210
0
        pitch[i]=start;
211
0
   }
212
213
#ifdef FIXED_POINT
214
   for (i=-end;i<len;i++)
215
   {
216
      if (ABS16(sw[i])>16383)
217
      {
218
         scaledown=1;
219
         break;
220
      }
221
   }
222
   /* If the weighted input is close to saturation, then we scale it down */
223
   if (scaledown)
224
   {
225
      for (i=-end;i<len;i++)
226
      {
227
         sw[i]=SHR16(sw[i],1);
228
      }
229
   }
230
#endif
231
0
   energy[0]=inner_prod(sw-start, sw-start, len);
232
0
   e0=inner_prod(sw, sw, len);
233
0
   for (i=start;i<end;i++)
234
0
   {
235
      /* Update energy for next pitch*/
236
0
      energy[i-start+1] = SUB32(ADD32(energy[i-start],SHR32(MULT16_16(sw[-i-1],sw[-i-1]),6)), SHR32(MULT16_16(sw[-i+len-1],sw[-i+len-1]),6));
237
0
      if (energy[i-start+1] < 0)
238
0
         energy[i-start+1] = 0;
239
0
   }
240
241
#ifdef FIXED_POINT
242
   eshift = normalize16(energy, ener16, 32766, end-start+1);
243
#endif
244
245
   /* In fixed-point, this actually overrites the energy array (aliased to corr) */
246
0
   pitch_xcorr(sw, sw-end, corr, len, end-start+1, stack);
247
248
#ifdef FIXED_POINT
249
   /* Normalize to 180 so we can square it and it still fits in 16 bits */
250
   cshift = normalize16(corr, corr16, 180, end-start+1);
251
   /* If we scaled weighted input down, we need to scale it up again (OK, so we've just lost the LSB, who cares?) */
252
   if (scaledown)
253
   {
254
      for (i=-end;i<len;i++)
255
      {
256
         sw[i]=SHL16(sw[i],1);
257
      }
258
   }
259
#endif
260
261
   /* Search for the best pitch prediction gain */
262
0
   for (i=start;i<=end;i++)
263
0
   {
264
0
      spx_word16_t tmp = MULT16_16_16(corr16[i-start],corr16[i-start]);
265
      /* Instead of dividing the tmp by the energy, we multiply on the other side */
266
0
      if (MULT16_16(tmp,best_ener[N-1])>MULT16_16(best_score[N-1],ADD16(1,ener16[i-start])))
267
0
      {
268
         /* We can safely put it last and then check */
269
0
         best_score[N-1]=tmp;
270
0
         best_ener[N-1]=ener16[i-start]+1;
271
0
         pitch[N-1]=i;
272
         /* Check if it comes in front of others */
273
0
         for (j=0;j<N-1;j++)
274
0
         {
275
0
            if (MULT16_16(tmp,best_ener[j])>MULT16_16(best_score[j],ADD16(1,ener16[i-start])))
276
0
            {
277
0
               for (k=N-1;k>j;k--)
278
0
               {
279
0
                  best_score[k]=best_score[k-1];
280
0
                  best_ener[k]=best_ener[k-1];
281
0
                  pitch[k]=pitch[k-1];
282
0
               }
283
0
               best_score[j]=tmp;
284
0
               best_ener[j]=ener16[i-start]+1;
285
0
               pitch[j]=i;
286
0
               break;
287
0
            }
288
0
         }
289
0
      }
290
0
   }
291
292
   /* Compute open-loop gain if necessary */
293
0
   if (gain)
294
0
   {
295
0
      for (j=0;j<N;j++)
296
0
      {
297
0
         spx_word16_t g;
298
0
         i=pitch[j];
299
0
         g = DIV32(SHL32(EXTEND32(corr16[i-start]),cshift), 10+SHR32(MULT16_16(spx_sqrt(e0),spx_sqrt(SHL32(EXTEND32(ener16[i-start]),eshift))),6));
300
         /* FIXME: g = max(g,corr/energy) */
301
0
         if (g<0)
302
0
            g = 0;
303
0
         gain[j]=g;
304
0
      }
305
0
   }
306
307
308
0
}
309
#endif
310
311
#ifndef OVERRIDE_PITCH_GAIN_SEARCH_3TAP_VQ
312
static int pitch_gain_search_3tap_vq(
313
  const signed char *gain_cdbk,
314
  int                gain_cdbk_size,
315
  spx_word16_t      *C16,
316
  spx_word16_t       max_gain
317
)
318
0
{
319
0
  const signed char *ptr=gain_cdbk;
320
0
  int                best_cdbk=0;
321
0
  spx_word32_t       best_sum=-VERY_LARGE32;
322
0
  spx_word32_t       sum=0;
323
0
  spx_word16_t       g[3];
324
0
  spx_word16_t       pitch_control=64;
325
0
  spx_word16_t       gain_sum;
326
0
  int                i;
327
328
0
  for (i=0;i<gain_cdbk_size;i++) {
329
330
0
    ptr = gain_cdbk+4*i;
331
0
    g[0]=ADD16((spx_word16_t)ptr[0],32);
332
0
    g[1]=ADD16((spx_word16_t)ptr[1],32);
333
0
    g[2]=ADD16((spx_word16_t)ptr[2],32);
334
0
    gain_sum = (spx_word16_t)ptr[3];
335
336
0
    sum = compute_pitch_error(C16, g, pitch_control);
337
338
0
    if (sum>best_sum && gain_sum<=max_gain) {
339
0
      best_sum=sum;
340
0
      best_cdbk=i;
341
0
    }
342
0
  }
343
344
0
  return best_cdbk;
345
0
}
346
#endif
347
348
/** Finds the best quantized 3-tap pitch predictor by analysis by synthesis */
349
static spx_word32_t pitch_gain_search_3tap(
350
const spx_word16_t target[],       /* Target vector */
351
const spx_coef_t ak[],          /* LPCs for this subframe */
352
const spx_coef_t awk1[],        /* Weighted LPCs #1 for this subframe */
353
const spx_coef_t awk2[],        /* Weighted LPCs #2 for this subframe */
354
spx_sig_t exc[],                /* Excitation */
355
const signed char *gain_cdbk,
356
int gain_cdbk_size,
357
int   pitch,                    /* Pitch value */
358
int   p,                        /* Number of LPC coeffs */
359
int   nsf,                      /* Number of samples in subframe */
360
SpeexBits *bits,
361
char *stack,
362
const spx_word16_t *exc2,
363
const spx_word16_t *r,
364
spx_word16_t *new_target,
365
int  *cdbk_index,
366
int plc_tuning,
367
spx_word32_t cumul_gain,
368
int scaledown
369
)
370
0
{
371
0
   int i,j;
372
0
   VARDECL(spx_word16_t *tmp1);
373
0
   VARDECL(spx_word16_t *e);
374
0
   spx_word16_t *x[3];
375
0
   spx_word32_t corr[3];
376
0
   spx_word32_t A[3][3];
377
0
   spx_word16_t gain[3];
378
0
   spx_word32_t err;
379
0
   spx_word16_t max_gain=128;
380
0
   int          best_cdbk=0;
381
382
0
   ALLOC(tmp1, 3*nsf, spx_word16_t);
383
0
   ALLOC(e, nsf, spx_word16_t);
384
385
0
   if (cumul_gain > 262144)
386
0
      max_gain = 31;
387
388
0
   x[0]=tmp1;
389
0
   x[1]=tmp1+nsf;
390
0
   x[2]=tmp1+2*nsf;
391
392
0
   for (j=0;j<nsf;j++)
393
0
      new_target[j] = target[j];
394
395
0
   {
396
0
      int bound;
397
0
      VARDECL(spx_mem_t *mm);
398
0
      int pp=pitch-1;
399
0
      ALLOC(mm, p, spx_mem_t);
400
0
      bound = nsf;
401
0
      if (nsf-pp>0)
402
0
         bound = pp;
403
0
      for (j=0;j<bound;j++)
404
0
         e[j]=exc2[j-pp];
405
0
      bound = nsf;
406
0
      if (nsf-pp-pitch>0)
407
0
         bound = pp+pitch;
408
0
      for (;j<bound;j++)
409
0
         e[j]=exc2[j-pp-pitch];
410
0
      for (;j<nsf;j++)
411
0
         e[j]=0;
412
#ifdef FIXED_POINT
413
      /* Scale target and excitation down if needed (avoiding overflow) */
414
      if (scaledown)
415
      {
416
         for (j=0;j<nsf;j++)
417
            e[j] = SHR16(e[j],1);
418
         for (j=0;j<nsf;j++)
419
            new_target[j] = SHR16(new_target[j],1);
420
      }
421
#endif
422
0
      for (j=0;j<p;j++)
423
0
         mm[j] = 0;
424
0
      iir_mem16(e, ak, e, nsf, p, mm, stack);
425
0
      for (j=0;j<p;j++)
426
0
         mm[j] = 0;
427
0
      filter10(e, awk1, awk2, e, nsf, mm, stack);
428
0
      for (j=0;j<nsf;j++)
429
0
         x[2][j] = e[j];
430
0
   }
431
0
   for (i=1;i>=0;i--)
432
0
   {
433
0
      spx_word16_t e0=exc2[-pitch-1+i];
434
#ifdef FIXED_POINT
435
      /* Scale excitation down if needed (avoiding overflow) */
436
      if (scaledown)
437
         e0 = SHR16(e0,1);
438
#endif
439
0
      x[i][0]=MULT16_16_Q14(r[0], e0);
440
0
      for (j=0;j<nsf-1;j++)
441
0
         x[i][j+1]=ADD32(x[i+1][j],MULT16_16_P14(r[j+1], e0));
442
0
   }
443
444
0
   for (i=0;i<3;i++)
445
0
      corr[i]=inner_prod(x[i],new_target,nsf);
446
0
   for (i=0;i<3;i++)
447
0
      for (j=0;j<=i;j++)
448
0
         A[i][j]=A[j][i]=inner_prod(x[i],x[j],nsf);
449
450
0
   {
451
0
      spx_word32_t C[9];
452
#ifdef FIXED_POINT
453
      spx_word16_t C16[9];
454
#else
455
0
      spx_word16_t *C16=C;
456
0
#endif
457
0
      C[0]=corr[2];
458
0
      C[1]=corr[1];
459
0
      C[2]=corr[0];
460
0
      C[3]=A[1][2];
461
0
      C[4]=A[0][1];
462
0
      C[5]=A[0][2];
463
0
      C[6]=A[2][2];
464
0
      C[7]=A[1][1];
465
0
      C[8]=A[0][0];
466
467
      /*plc_tuning *= 2;*/
468
0
      if (plc_tuning<2)
469
0
         plc_tuning=2;
470
0
      if (plc_tuning>30)
471
0
         plc_tuning=30;
472
#ifdef FIXED_POINT
473
      C[0] = SHL32(C[0],1);
474
      C[1] = SHL32(C[1],1);
475
      C[2] = SHL32(C[2],1);
476
      C[3] = SHL32(C[3],1);
477
      C[4] = SHL32(C[4],1);
478
      C[5] = SHL32(C[5],1);
479
      C[6] = MAC16_32_Q15(C[6],MULT16_16_16(plc_tuning,655),C[6]);
480
      C[7] = MAC16_32_Q15(C[7],MULT16_16_16(plc_tuning,655),C[7]);
481
      C[8] = MAC16_32_Q15(C[8],MULT16_16_16(plc_tuning,655),C[8]);
482
      normalize16(C, C16, 32767, 9);
483
#else
484
0
      C[6]*=.5*(1+.02*plc_tuning);
485
0
      C[7]*=.5*(1+.02*plc_tuning);
486
0
      C[8]*=.5*(1+.02*plc_tuning);
487
0
#endif
488
489
0
      best_cdbk = pitch_gain_search_3tap_vq(gain_cdbk, gain_cdbk_size, C16, max_gain);
490
491
#ifdef FIXED_POINT
492
      gain[0] = ADD16(32,(spx_word16_t)gain_cdbk[best_cdbk*4]);
493
      gain[1] = ADD16(32,(spx_word16_t)gain_cdbk[best_cdbk*4+1]);
494
      gain[2] = ADD16(32,(spx_word16_t)gain_cdbk[best_cdbk*4+2]);
495
      /*printf ("%d %d %d %d\n",gain[0],gain[1],gain[2], best_cdbk);*/
496
#else
497
0
      gain[0] = 0.015625*gain_cdbk[best_cdbk*4]  + .5;
498
0
      gain[1] = 0.015625*gain_cdbk[best_cdbk*4+1]+ .5;
499
0
      gain[2] = 0.015625*gain_cdbk[best_cdbk*4+2]+ .5;
500
0
#endif
501
0
      *cdbk_index=best_cdbk;
502
0
   }
503
504
0
   SPEEX_MEMSET(exc, 0, nsf);
505
0
   for (i=0;i<3;i++)
506
0
   {
507
0
      int j;
508
0
      int tmp1, tmp3;
509
0
      int pp=pitch+1-i;
510
0
      tmp1=nsf;
511
0
      if (tmp1>pp)
512
0
         tmp1=pp;
513
0
      for (j=0;j<tmp1;j++)
514
0
         exc[j]=MAC16_16(exc[j],SHL16(gain[2-i],7),exc2[j-pp]);
515
0
      tmp3=nsf;
516
0
      if (tmp3>pp+pitch)
517
0
         tmp3=pp+pitch;
518
0
      for (j=tmp1;j<tmp3;j++)
519
0
         exc[j]=MAC16_16(exc[j],SHL16(gain[2-i],7),exc2[j-pp-pitch]);
520
0
   }
521
0
   for (i=0;i<nsf;i++)
522
0
   {
523
0
      spx_word32_t tmp = ADD32(ADD32(MULT16_16(gain[0],x[2][i]),MULT16_16(gain[1],x[1][i])),
524
0
                            MULT16_16(gain[2],x[0][i]));
525
0
      new_target[i] = SUB16(new_target[i], EXTRACT16(PSHR32(tmp,6)));
526
0
   }
527
0
   err = inner_prod(new_target, new_target, nsf);
528
529
0
   return err;
530
0
}
531
532
/** Finds the best quantized 3-tap pitch predictor by analysis by synthesis */
533
int pitch_search_3tap(
534
spx_word16_t target[],                 /* Target vector */
535
spx_word16_t *sw,
536
spx_coef_t ak[],                     /* LPCs for this subframe */
537
spx_coef_t awk1[],                   /* Weighted LPCs #1 for this subframe */
538
spx_coef_t awk2[],                   /* Weighted LPCs #2 for this subframe */
539
spx_sig_t exc[],                    /* Excitation */
540
const void *par,
541
int   start,                    /* Smallest pitch value allowed */
542
int   end,                      /* Largest pitch value allowed */
543
spx_word16_t pitch_coef,               /* Voicing (pitch) coefficient */
544
int   p,                        /* Number of LPC coeffs */
545
int   nsf,                      /* Number of samples in subframe */
546
SpeexBits *bits,
547
char *stack,
548
spx_word16_t *exc2,
549
spx_word16_t *r,
550
int complexity,
551
int cdbk_offset,
552
int plc_tuning,
553
spx_word32_t *cumul_gain
554
)
555
0
{
556
0
   int i;
557
0
   int cdbk_index, pitch=0, best_gain_index=0;
558
0
   VARDECL(spx_sig_t *best_exc);
559
0
   VARDECL(spx_word16_t *new_target);
560
0
   VARDECL(spx_word16_t *best_target);
561
0
   int best_pitch=0;
562
0
   spx_word32_t err, best_err=-1;
563
0
   int N;
564
0
   const ltp_params *params;
565
0
   const signed char *gain_cdbk;
566
0
   int   gain_cdbk_size;
567
0
   int scaledown=0;
568
569
0
   VARDECL(int *nbest);
570
571
0
   params = (const ltp_params*) par;
572
0
   gain_cdbk_size = 1<<params->gain_bits;
573
0
   gain_cdbk = params->gain_cdbk + 4*gain_cdbk_size*cdbk_offset;
574
575
0
   N=complexity;
576
0
   if (N>10)
577
0
      N=10;
578
0
   if (N<1)
579
0
      N=1;
580
581
0
   ALLOC(nbest, N, int);
582
0
   params = (const ltp_params*) par;
583
584
0
   if (end<start)
585
0
   {
586
0
      speex_bits_pack(bits, 0, params->pitch_bits);
587
0
      speex_bits_pack(bits, 0, params->gain_bits);
588
0
      SPEEX_MEMSET(exc, 0, nsf);
589
0
      return start;
590
0
   }
591
592
#ifdef FIXED_POINT
593
   /* Check if we need to scale everything down in the pitch search to avoid overflows */
594
   for (i=0;i<nsf;i++)
595
   {
596
      if (ABS16(target[i])>16383)
597
      {
598
         scaledown=1;
599
         break;
600
      }
601
   }
602
   for (i=-end;i<0;i++)
603
   {
604
      if (ABS16(exc2[i])>16383)
605
      {
606
         scaledown=1;
607
         break;
608
      }
609
   }
610
#endif
611
0
   if (N>end-start+1)
612
0
      N=end-start+1;
613
0
   if (end != start)
614
0
      open_loop_nbest_pitch(sw, start, end, nsf, nbest, NULL, N, stack);
615
0
   else
616
0
      nbest[0] = start;
617
618
0
   ALLOC(best_exc, nsf, spx_sig_t);
619
0
   ALLOC(new_target, nsf, spx_word16_t);
620
0
   ALLOC(best_target, nsf, spx_word16_t);
621
622
0
   for (i=0;i<N;i++)
623
0
   {
624
0
      pitch=nbest[i];
625
0
      SPEEX_MEMSET(exc, 0, nsf);
626
0
      err=pitch_gain_search_3tap(target, ak, awk1, awk2, exc, gain_cdbk, gain_cdbk_size, pitch, p, nsf,
627
0
                                 bits, stack, exc2, r, new_target, &cdbk_index, plc_tuning, *cumul_gain, scaledown);
628
0
      if (err<best_err || best_err<0)
629
0
      {
630
0
         SPEEX_COPY(best_exc, exc, nsf);
631
0
         SPEEX_COPY(best_target, new_target, nsf);
632
0
         best_err=err;
633
0
         best_pitch=pitch;
634
0
         best_gain_index=cdbk_index;
635
0
      }
636
0
   }
637
   /*printf ("pitch: %d %d\n", best_pitch, best_gain_index);*/
638
0
   speex_bits_pack(bits, best_pitch-start, params->pitch_bits);
639
0
   speex_bits_pack(bits, best_gain_index, params->gain_bits);
640
#ifdef FIXED_POINT
641
   *cumul_gain = MULT16_32_Q13(SHL16(params->gain_cdbk[4*best_gain_index+3],8), MAX32(1024,*cumul_gain));
642
#else
643
0
   *cumul_gain = 0.03125*MAX32(1024,*cumul_gain)*params->gain_cdbk[4*best_gain_index+3];
644
0
#endif
645
   /*printf ("%f\n", cumul_gain);*/
646
   /*printf ("encode pitch: %d %d\n", best_pitch, best_gain_index);*/
647
0
   SPEEX_COPY(exc, best_exc, nsf);
648
0
   SPEEX_COPY(target, best_target, nsf);
649
#ifdef FIXED_POINT
650
   /* Scale target back up if needed */
651
   if (scaledown)
652
   {
653
      for (i=0;i<nsf;i++)
654
         target[i]=SHL16(target[i],1);
655
   }
656
#endif
657
0
   return pitch;
658
0
}
659
#endif /* DISABLE_ENCODER */
660
661
#ifndef DISABLE_DECODER
662
void pitch_unquant_3tap(
663
spx_word16_t exc[],             /* Input excitation */
664
spx_word32_t exc_out[],         /* Output excitation */
665
int   start,                    /* Smallest pitch value allowed */
666
int   end,                      /* Largest pitch value allowed */
667
spx_word16_t pitch_coef,        /* Voicing (pitch) coefficient */
668
const void *par,
669
int   nsf,                      /* Number of samples in subframe */
670
int *pitch_val,
671
spx_word16_t *gain_val,
672
SpeexBits *bits,
673
char *stack,
674
int count_lost,
675
int subframe_offset,
676
spx_word16_t last_pitch_gain,
677
int cdbk_offset
678
)
679
59.4k
{
680
59.4k
   int i;
681
59.4k
   int pitch;
682
59.4k
   int gain_index;
683
59.4k
   spx_word16_t gain[3];
684
59.4k
   const signed char *gain_cdbk;
685
59.4k
   int gain_cdbk_size;
686
59.4k
   const ltp_params *params;
687
688
59.4k
   params = (const ltp_params*) par;
689
59.4k
   gain_cdbk_size = 1<<params->gain_bits;
690
59.4k
   gain_cdbk = params->gain_cdbk + 4*gain_cdbk_size*cdbk_offset;
691
692
59.4k
   pitch = speex_bits_unpack_unsigned(bits, params->pitch_bits);
693
59.4k
   pitch += start;
694
59.4k
   gain_index = speex_bits_unpack_unsigned(bits, params->gain_bits);
695
   /*printf ("decode pitch: %d %d\n", pitch, gain_index);*/
696
#ifdef FIXED_POINT
697
   gain[0] = ADD16(32,(spx_word16_t)gain_cdbk[gain_index*4]);
698
   gain[1] = ADD16(32,(spx_word16_t)gain_cdbk[gain_index*4+1]);
699
   gain[2] = ADD16(32,(spx_word16_t)gain_cdbk[gain_index*4+2]);
700
#else
701
59.4k
   gain[0] = 0.015625*gain_cdbk[gain_index*4]+.5;
702
59.4k
   gain[1] = 0.015625*gain_cdbk[gain_index*4+1]+.5;
703
59.4k
   gain[2] = 0.015625*gain_cdbk[gain_index*4+2]+.5;
704
59.4k
#endif
705
706
59.4k
   if (count_lost && pitch > subframe_offset)
707
0
   {
708
0
      spx_word16_t gain_sum;
709
0
      if (1) {
710
#ifdef FIXED_POINT
711
         spx_word16_t tmp = count_lost < 4 ? last_pitch_gain : SHR16(last_pitch_gain,1);
712
         if (tmp>62)
713
            tmp=62;
714
#else
715
0
         spx_word16_t tmp = count_lost < 4 ? last_pitch_gain : 0.5 * last_pitch_gain;
716
0
         if (tmp>.95)
717
0
            tmp=.95;
718
0
#endif
719
0
         gain_sum = gain_3tap_to_1tap(gain);
720
721
0
         if (gain_sum > tmp)
722
0
         {
723
0
            spx_word16_t fact = DIV32_16(SHL32(EXTEND32(tmp),14),gain_sum);
724
0
            for (i=0;i<3;i++)
725
0
               gain[i]=MULT16_16_Q14(fact,gain[i]);
726
0
         }
727
728
0
      }
729
730
0
   }
731
732
59.4k
   *pitch_val = pitch;
733
59.4k
   gain_val[0]=gain[0];
734
59.4k
   gain_val[1]=gain[1];
735
59.4k
   gain_val[2]=gain[2];
736
59.4k
   gain[0] = SHL16(gain[0],7);
737
59.4k
   gain[1] = SHL16(gain[1],7);
738
59.4k
   gain[2] = SHL16(gain[2],7);
739
59.4k
   SPEEX_MEMSET(exc_out, 0, nsf);
740
237k
   for (i=0;i<3;i++)
741
178k
   {
742
178k
      int j;
743
178k
      int tmp1, tmp3;
744
178k
      int pp=pitch+1-i;
745
178k
      tmp1=nsf;
746
178k
      if (tmp1>pp)
747
148k
         tmp1=pp;
748
3.99M
      for (j=0;j<tmp1;j++)
749
3.81M
         exc_out[j]=MAC16_16(exc_out[j],gain[2-i],exc[j-pp]);
750
178k
      tmp3=nsf;
751
178k
      if (tmp3>pp+pitch)
752
139k
         tmp3=pp+pitch;
753
2.66M
      for (j=tmp1;j<tmp3;j++)
754
2.48M
         exc_out[j]=MAC16_16(exc_out[j],gain[2-i],exc[j-pp-pitch]);
755
178k
   }
756
   /*for (i=0;i<nsf;i++)
757
   exc[i]=PSHR32(exc32[i],13);*/
758
59.4k
}
759
#endif /* DISABLE_DECODER */
760
761
#ifndef DISABLE_ENCODER
762
/** Forced pitch delay and gain */
763
int forced_pitch_quant(
764
spx_word16_t target[],                 /* Target vector */
765
spx_word16_t *sw,
766
spx_coef_t ak[],                     /* LPCs for this subframe */
767
spx_coef_t awk1[],                   /* Weighted LPCs #1 for this subframe */
768
spx_coef_t awk2[],                   /* Weighted LPCs #2 for this subframe */
769
spx_sig_t exc[],                    /* Excitation */
770
const void *par,
771
int   start,                    /* Smallest pitch value allowed */
772
int   end,                      /* Largest pitch value allowed */
773
spx_word16_t pitch_coef,               /* Voicing (pitch) coefficient */
774
int   p,                        /* Number of LPC coeffs */
775
int   nsf,                      /* Number of samples in subframe */
776
SpeexBits *bits,
777
char *stack,
778
spx_word16_t *exc2,
779
spx_word16_t *r,
780
int complexity,
781
int cdbk_offset,
782
int plc_tuning,
783
spx_word32_t *cumul_gain
784
)
785
0
{
786
0
   int i;
787
0
   VARDECL(spx_word16_t *res);
788
0
   ALLOC(res, nsf, spx_word16_t);
789
#ifdef FIXED_POINT
790
   if (pitch_coef>63)
791
      pitch_coef=63;
792
#else
793
0
   if (pitch_coef>.99)
794
0
      pitch_coef=.99;
795
0
#endif
796
0
   for (i=0;i<nsf&&i<start;i++)
797
0
   {
798
0
      exc[i]=MULT16_16(SHL16(pitch_coef, 7),exc2[i-start]);
799
0
   }
800
0
   for (;i<nsf;i++)
801
0
   {
802
0
      exc[i]=MULT16_32_Q15(SHL16(pitch_coef, 9),exc[i-start]);
803
0
   }
804
0
   for (i=0;i<nsf;i++)
805
0
      res[i] = EXTRACT16(PSHR32(exc[i], SIG_SHIFT-1));
806
0
   syn_percep_zero16(res, ak, awk1, awk2, res, nsf, p, stack);
807
0
   for (i=0;i<nsf;i++)
808
0
      target[i]=EXTRACT16(SATURATE(SUB32(EXTEND32(target[i]),EXTEND32(res[i])),32700));
809
0
   return start;
810
0
}
811
#endif /* DISABLE_ENCODER */
812
813
#ifndef DISABLE_DECODER
814
/** Unquantize forced pitch delay and gain */
815
void forced_pitch_unquant(
816
spx_word16_t exc[],             /* Input excitation */
817
spx_word32_t exc_out[],         /* Output excitation */
818
int   start,                    /* Smallest pitch value allowed */
819
int   end,                      /* Largest pitch value allowed */
820
spx_word16_t pitch_coef,        /* Voicing (pitch) coefficient */
821
const void *par,
822
int   nsf,                      /* Number of samples in subframe */
823
int *pitch_val,
824
spx_word16_t *gain_val,
825
SpeexBits *bits,
826
char *stack,
827
int count_lost,
828
int subframe_offset,
829
spx_word16_t last_pitch_gain,
830
int cdbk_offset
831
)
832
25.2k
{
833
25.2k
   int i;
834
#ifdef FIXED_POINT
835
   if (pitch_coef>63)
836
      pitch_coef=63;
837
#else
838
25.2k
   if (pitch_coef>.99)
839
2.17k
      pitch_coef=.99;
840
25.2k
#endif
841
1.03M
   for (i=0;i<nsf;i++)
842
1.01M
   {
843
1.01M
      exc_out[i]=MULT16_16(exc[i-start],SHL16(pitch_coef,7));
844
1.01M
      exc[i] = EXTRACT16(PSHR32(exc_out[i],13));
845
1.01M
   }
846
25.2k
   *pitch_val = start;
847
25.2k
   gain_val[0]=gain_val[2]=0;
848
25.2k
   gain_val[1] = pitch_coef;
849
25.2k
}
850
#endif /* DISABLE_DECODER */