Coverage Report

Created: 2026-07-30 07:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/pjsip/third_party/speex/libspeex/ltp.c
Line
Count
Source
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
904k
{
60
904k
   spx_word32_t sum=0;
61
904k
   len >>= 2;
62
15.6M
   while(len--)
63
14.7M
   {
64
14.7M
      spx_word32_t part=0;
65
14.7M
      part = MAC16_16(part,*x++,*y++);
66
14.7M
      part = MAC16_16(part,*x++,*y++);
67
14.7M
      part = MAC16_16(part,*x++,*y++);
68
14.7M
      part = MAC16_16(part,*x++,*y++);
69
      /* HINT: If you had a 40-bit accumulator, you could shift only at the end */
70
14.7M
      sum = ADD32(sum,SHR32(part,6));
71
14.7M
   }
72
904k
   return sum;
73
904k
}
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
6.32k
{
145
6.32k
   int i;
146
800k
   for (i=0;i<nb_pitch;i++)
147
794k
   {
148
      /* Compute correlation*/
149
794k
      corr[nb_pitch-1-i]=inner_prod(_x, _y+i, len);
150
794k
   }
151
152
6.32k
}
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
1.24M
{
159
1.24M
   spx_word32_t sum = 0;
160
1.24M
   sum = ADD32(sum,MULT16_16(MULT16_16_16(g[0],pitch_control),C[0]));
161
1.24M
   sum = ADD32(sum,MULT16_16(MULT16_16_16(g[1],pitch_control),C[1]));
162
1.24M
   sum = ADD32(sum,MULT16_16(MULT16_16_16(g[2],pitch_control),C[2]));
163
1.24M
   sum = SUB32(sum,MULT16_16(MULT16_16_16(g[0],g[1]),C[3]));
164
1.24M
   sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[1]),C[4]));
165
1.24M
   sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[0]),C[5]));
166
1.24M
   sum = SUB32(sum,MULT16_16(MULT16_16_16(g[0],g[0]),C[6]));
167
1.24M
   sum = SUB32(sum,MULT16_16(MULT16_16_16(g[1],g[1]),C[7]));
168
1.24M
   sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[2]),C[8]));
169
1.24M
   return sum;
170
1.24M
}
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
6.32k
{
176
6.32k
   int i,j,k;
177
6.32k
   VARDECL(spx_word32_t *best_score);
178
6.32k
   VARDECL(spx_word32_t *best_ener);
179
6.32k
   spx_word32_t e0;
180
6.32k
   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
6.32k
   VARDECL(spx_word32_t *energy);
196
6.32k
   spx_word16_t *corr16;
197
6.32k
   spx_word16_t *ener16;
198
6.32k
   ALLOC(energy, end-start+2, spx_word32_t);
199
6.32k
   ALLOC(corr, end-start+1, spx_word32_t);
200
6.32k
   corr16 = corr;
201
6.32k
   ener16 = energy;
202
6.32k
#endif
203
204
6.32k
   ALLOC(best_score, N, spx_word32_t);
205
6.32k
   ALLOC(best_ener, N, spx_word32_t);
206
24.7k
   for (i=0;i<N;i++)
207
18.4k
   {
208
18.4k
        best_score[i]=-1;
209
18.4k
        best_ener[i]=0;
210
18.4k
        pitch[i]=start;
211
18.4k
   }
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
6.32k
   energy[0]=inner_prod(sw-start, sw-start, len);
232
6.32k
   e0=inner_prod(sw, sw, len);
233
794k
   for (i=start;i<end;i++)
234
787k
   {
235
      /* Update energy for next pitch*/
236
787k
      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
787k
      if (energy[i-start+1] < 0)
238
1.33k
         energy[i-start+1] = 0;
239
787k
   }
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
6.32k
   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
800k
   for (i=start;i<=end;i++)
263
794k
   {
264
794k
      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
794k
      if (MULT16_16(tmp,best_ener[N-1])>MULT16_16(best_score[N-1],ADD16(1,ener16[i-start])))
267
96.7k
      {
268
         /* We can safely put it last and then check */
269
96.7k
         best_score[N-1]=tmp;
270
96.7k
         best_ener[N-1]=ener16[i-start]+1;
271
96.7k
         pitch[N-1]=i;
272
         /* Check if it comes in front of others */
273
165k
         for (j=0;j<N-1;j++)
274
142k
         {
275
142k
            if (MULT16_16(tmp,best_ener[j])>MULT16_16(best_score[j],ADD16(1,ener16[i-start])))
276
74.0k
            {
277
224k
               for (k=N-1;k>j;k--)
278
150k
               {
279
150k
                  best_score[k]=best_score[k-1];
280
150k
                  best_ener[k]=best_ener[k-1];
281
150k
                  pitch[k]=pitch[k-1];
282
150k
               }
283
74.0k
               best_score[j]=tmp;
284
74.0k
               best_ener[j]=ener16[i-start]+1;
285
74.0k
               pitch[j]=i;
286
74.0k
               break;
287
74.0k
            }
288
142k
         }
289
96.7k
      }
290
794k
   }
291
292
   /* Compute open-loop gain if necessary */
293
6.32k
   if (gain)
294
1.45k
   {
295
10.1k
      for (j=0;j<N;j++)
296
8.70k
      {
297
8.70k
         spx_word16_t g;
298
8.70k
         i=pitch[j];
299
8.70k
         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
8.70k
         if (g<0)
302
4.53k
            g = 0;
303
8.70k
         gain[j]=g;
304
8.70k
      }
305
1.45k
   }
306
307
308
6.32k
}
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
9.75k
{
319
9.75k
  const signed char *ptr=gain_cdbk;
320
9.75k
  int                best_cdbk=0;
321
9.75k
  spx_word32_t       best_sum=-VERY_LARGE32;
322
9.75k
  spx_word32_t       sum=0;
323
9.75k
  spx_word16_t       g[3];
324
9.75k
  spx_word16_t       pitch_control=64;
325
9.75k
  spx_word16_t       gain_sum;
326
9.75k
  int                i;
327
328
1.25M
  for (i=0;i<gain_cdbk_size;i++) {
329
330
1.24M
    ptr = gain_cdbk+4*i;
331
1.24M
    g[0]=ADD16((spx_word16_t)ptr[0],32);
332
1.24M
    g[1]=ADD16((spx_word16_t)ptr[1],32);
333
1.24M
    g[2]=ADD16((spx_word16_t)ptr[2],32);
334
1.24M
    gain_sum = (spx_word16_t)ptr[3];
335
336
1.24M
    sum = compute_pitch_error(C16, g, pitch_control);
337
338
1.24M
    if (sum>best_sum && gain_sum<=max_gain) {
339
34.9k
      best_sum=sum;
340
34.9k
      best_cdbk=i;
341
34.9k
    }
342
1.24M
  }
343
344
9.75k
  return best_cdbk;
345
9.75k
}
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
9.75k
{
371
9.75k
   int i,j;
372
9.75k
   VARDECL(spx_word16_t *tmp1);
373
9.75k
   VARDECL(spx_word16_t *e);
374
9.75k
   spx_word16_t *x[3];
375
9.75k
   spx_word32_t corr[3];
376
9.75k
   spx_word32_t A[3][3];
377
9.75k
   spx_word16_t gain[3];
378
9.75k
   spx_word32_t err;
379
9.75k
   spx_word16_t max_gain=128;
380
9.75k
   int          best_cdbk=0;
381
382
9.75k
   ALLOC(tmp1, 3*nsf, spx_word16_t);
383
9.75k
   ALLOC(e, nsf, spx_word16_t);
384
385
9.75k
   if (cumul_gain > 262144)
386
6
      max_gain = 31;
387
388
9.75k
   x[0]=tmp1;
389
9.75k
   x[1]=tmp1+nsf;
390
9.75k
   x[2]=tmp1+2*nsf;
391
392
399k
   for (j=0;j<nsf;j++)
393
390k
      new_target[j] = target[j];
394
395
9.75k
   {
396
9.75k
      int bound;
397
9.75k
      VARDECL(spx_mem_t *mm);
398
9.75k
      int pp=pitch-1;
399
9.75k
      ALLOC(mm, p, spx_mem_t);
400
9.75k
      bound = nsf;
401
9.75k
      if (nsf-pp>0)
402
3.50k
         bound = pp;
403
348k
      for (j=0;j<bound;j++)
404
338k
         e[j]=exc2[j-pp];
405
9.75k
      bound = nsf;
406
9.75k
      if (nsf-pp-pitch>0)
407
1.16k
         bound = pp+pitch;
408
56.2k
      for (;j<bound;j++)
409
46.5k
         e[j]=exc2[j-pp-pitch];
410
14.7k
      for (;j<nsf;j++)
411
5.02k
         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
107k
      for (j=0;j<p;j++)
423
97.5k
         mm[j] = 0;
424
9.75k
      iir_mem16(e, ak, e, nsf, p, mm, stack);
425
107k
      for (j=0;j<p;j++)
426
97.5k
         mm[j] = 0;
427
9.75k
      filter10(e, awk1, awk2, e, nsf, mm, stack);
428
399k
      for (j=0;j<nsf;j++)
429
390k
         x[2][j] = e[j];
430
9.75k
   }
431
29.2k
   for (i=1;i>=0;i--)
432
19.5k
   {
433
19.5k
      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
19.5k
      x[i][0]=MULT16_16_Q14(r[0], e0);
440
780k
      for (j=0;j<nsf-1;j++)
441
760k
         x[i][j+1]=ADD32(x[i+1][j],MULT16_16_P14(r[j+1], e0));
442
19.5k
   }
443
444
39.0k
   for (i=0;i<3;i++)
445
29.2k
      corr[i]=inner_prod(x[i],new_target,nsf);
446
39.0k
   for (i=0;i<3;i++)
447
87.8k
      for (j=0;j<=i;j++)
448
58.5k
         A[i][j]=A[j][i]=inner_prod(x[i],x[j],nsf);
449
450
9.75k
   {
451
9.75k
      spx_word32_t C[9];
452
#ifdef FIXED_POINT
453
      spx_word16_t C16[9];
454
#else
455
9.75k
      spx_word16_t *C16=C;
456
9.75k
#endif
457
9.75k
      C[0]=corr[2];
458
9.75k
      C[1]=corr[1];
459
9.75k
      C[2]=corr[0];
460
9.75k
      C[3]=A[1][2];
461
9.75k
      C[4]=A[0][1];
462
9.75k
      C[5]=A[0][2];
463
9.75k
      C[6]=A[2][2];
464
9.75k
      C[7]=A[1][1];
465
9.75k
      C[8]=A[0][0];
466
467
      /*plc_tuning *= 2;*/
468
9.75k
      if (plc_tuning<2)
469
0
         plc_tuning=2;
470
9.75k
      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
9.75k
      C[6]*=.5*(1+.02*plc_tuning);
485
9.75k
      C[7]*=.5*(1+.02*plc_tuning);
486
9.75k
      C[8]*=.5*(1+.02*plc_tuning);
487
9.75k
#endif
488
489
9.75k
      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
9.75k
      gain[0] = 0.015625*gain_cdbk[best_cdbk*4]  + .5;
498
9.75k
      gain[1] = 0.015625*gain_cdbk[best_cdbk*4+1]+ .5;
499
9.75k
      gain[2] = 0.015625*gain_cdbk[best_cdbk*4+2]+ .5;
500
9.75k
#endif
501
9.75k
      *cdbk_index=best_cdbk;
502
9.75k
   }
503
504
9.75k
   SPEEX_MEMSET(exc, 0, nsf);
505
39.0k
   for (i=0;i<3;i++)
506
29.2k
   {
507
29.2k
      int j;
508
29.2k
      int tmp1, tmp3;
509
29.2k
      int pp=pitch+1-i;
510
29.2k
      tmp1=nsf;
511
29.2k
      if (tmp1>pp)
512
9.95k
         tmp1=pp;
513
1.05M
      for (j=0;j<tmp1;j++)
514
1.02M
         exc[j]=MAC16_16(exc[j],SHL16(gain[2-i],7),exc2[j-pp]);
515
29.2k
      tmp3=nsf;
516
29.2k
      if (tmp3>pp+pitch)
517
2.95k
         tmp3=pp+pitch;
518
161k
      for (j=tmp1;j<tmp3;j++)
519
132k
         exc[j]=MAC16_16(exc[j],SHL16(gain[2-i],7),exc2[j-pp-pitch]);
520
29.2k
   }
521
399k
   for (i=0;i<nsf;i++)
522
390k
   {
523
390k
      spx_word32_t tmp = ADD32(ADD32(MULT16_16(gain[0],x[2][i]),MULT16_16(gain[1],x[1][i])),
524
390k
                            MULT16_16(gain[2],x[0][i]));
525
390k
      new_target[i] = SUB16(new_target[i], EXTRACT16(PSHR32(tmp,6)));
526
390k
   }
527
9.75k
   err = inner_prod(new_target, new_target, nsf);
528
529
9.75k
   return err;
530
9.75k
}
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
4.96k
{
556
4.96k
   int i;
557
4.96k
   int cdbk_index, pitch=0, best_gain_index=0;
558
4.96k
   VARDECL(spx_sig_t *best_exc);
559
4.96k
   VARDECL(spx_word16_t *new_target);
560
4.96k
   VARDECL(spx_word16_t *best_target);
561
4.96k
   int best_pitch=0;
562
4.96k
   spx_word32_t err, best_err=-1;
563
4.96k
   int N;
564
4.96k
   const ltp_params *params;
565
4.96k
   const signed char *gain_cdbk;
566
4.96k
   int   gain_cdbk_size;
567
4.96k
   int scaledown=0;
568
569
4.96k
   VARDECL(int *nbest);
570
571
4.96k
   params = (const ltp_params*) par;
572
4.96k
   gain_cdbk_size = 1<<params->gain_bits;
573
4.96k
   gain_cdbk = params->gain_cdbk + 4*gain_cdbk_size*cdbk_offset;
574
575
4.96k
   N=complexity;
576
4.96k
   if (N>10)
577
0
      N=10;
578
4.96k
   if (N<1)
579
0
      N=1;
580
581
4.96k
   ALLOC(nbest, N, int);
582
4.96k
   params = (const ltp_params*) par;
583
584
4.96k
   if (end<start)
585
82
   {
586
82
      speex_bits_pack(bits, 0, params->pitch_bits);
587
82
      speex_bits_pack(bits, 0, params->gain_bits);
588
82
      SPEEX_MEMSET(exc, 0, nsf);
589
82
      return start;
590
82
   }
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
4.87k
   if (N>end-start+1)
612
0
      N=end-start+1;
613
4.87k
   if (end != start)
614
4.87k
      open_loop_nbest_pitch(sw, start, end, nsf, nbest, NULL, N, stack);
615
0
   else
616
0
      nbest[0] = start;
617
618
4.87k
   ALLOC(best_exc, nsf, spx_sig_t);
619
4.87k
   ALLOC(new_target, nsf, spx_word16_t);
620
4.87k
   ALLOC(best_target, nsf, spx_word16_t);
621
622
14.6k
   for (i=0;i<N;i++)
623
9.75k
   {
624
9.75k
      pitch=nbest[i];
625
9.75k
      SPEEX_MEMSET(exc, 0, nsf);
626
9.75k
      err=pitch_gain_search_3tap(target, ak, awk1, awk2, exc, gain_cdbk, gain_cdbk_size, pitch, p, nsf,
627
9.75k
                                 bits, stack, exc2, r, new_target, &cdbk_index, plc_tuning, *cumul_gain, scaledown);
628
9.75k
      if (err<best_err || best_err<0)
629
6.37k
      {
630
6.37k
         SPEEX_COPY(best_exc, exc, nsf);
631
6.37k
         SPEEX_COPY(best_target, new_target, nsf);
632
6.37k
         best_err=err;
633
6.37k
         best_pitch=pitch;
634
6.37k
         best_gain_index=cdbk_index;
635
6.37k
      }
636
9.75k
   }
637
   /*printf ("pitch: %d %d\n", best_pitch, best_gain_index);*/
638
4.87k
   speex_bits_pack(bits, best_pitch-start, params->pitch_bits);
639
4.87k
   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
4.87k
   *cumul_gain = 0.03125*MAX32(1024,*cumul_gain)*params->gain_cdbk[4*best_gain_index+3];
644
4.87k
#endif
645
   /*printf ("%f\n", cumul_gain);*/
646
   /*printf ("encode pitch: %d %d\n", best_pitch, best_gain_index);*/
647
4.87k
   SPEEX_COPY(exc, best_exc, nsf);
648
4.87k
   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
4.87k
   return pitch;
658
4.96k
}
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
1.17k
{
680
1.17k
   int i;
681
1.17k
   int pitch;
682
1.17k
   int gain_index;
683
1.17k
   spx_word16_t gain[3];
684
1.17k
   const signed char *gain_cdbk;
685
1.17k
   int gain_cdbk_size;
686
1.17k
   const ltp_params *params;
687
688
1.17k
   params = (const ltp_params*) par;
689
1.17k
   gain_cdbk_size = 1<<params->gain_bits;
690
1.17k
   gain_cdbk = params->gain_cdbk + 4*gain_cdbk_size*cdbk_offset;
691
692
1.17k
   pitch = speex_bits_unpack_unsigned(bits, params->pitch_bits);
693
1.17k
   pitch += start;
694
1.17k
   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
1.17k
   gain[0] = 0.015625*gain_cdbk[gain_index*4]+.5;
702
1.17k
   gain[1] = 0.015625*gain_cdbk[gain_index*4+1]+.5;
703
1.17k
   gain[2] = 0.015625*gain_cdbk[gain_index*4+2]+.5;
704
1.17k
#endif
705
706
1.17k
   if (count_lost && pitch > subframe_offset)
707
421
   {
708
421
      spx_word16_t gain_sum;
709
421
      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
421
         spx_word16_t tmp = count_lost < 4 ? last_pitch_gain : 0.5 * last_pitch_gain;
716
421
         if (tmp>.95)
717
1
            tmp=.95;
718
421
#endif
719
421
         gain_sum = gain_3tap_to_1tap(gain);
720
721
421
         if (gain_sum > tmp)
722
340
         {
723
340
            spx_word16_t fact = DIV32_16(SHL32(EXTEND32(tmp),14),gain_sum);
724
1.36k
            for (i=0;i<3;i++)
725
1.02k
               gain[i]=MULT16_16_Q14(fact,gain[i]);
726
340
         }
727
728
421
      }
729
730
421
   }
731
732
1.17k
   *pitch_val = pitch;
733
1.17k
   gain_val[0]=gain[0];
734
1.17k
   gain_val[1]=gain[1];
735
1.17k
   gain_val[2]=gain[2];
736
1.17k
   gain[0] = SHL16(gain[0],7);
737
1.17k
   gain[1] = SHL16(gain[1],7);
738
1.17k
   gain[2] = SHL16(gain[2],7);
739
1.17k
   SPEEX_MEMSET(exc_out, 0, nsf);
740
4.70k
   for (i=0;i<3;i++)
741
3.52k
   {
742
3.52k
      int j;
743
3.52k
      int tmp1, tmp3;
744
3.52k
      int pp=pitch+1-i;
745
3.52k
      tmp1=nsf;
746
3.52k
      if (tmp1>pp)
747
2.45k
         tmp1=pp;
748
92.4k
      for (j=0;j<tmp1;j++)
749
88.8k
         exc_out[j]=MAC16_16(exc_out[j],gain[2-i],exc[j-pp]);
750
3.52k
      tmp3=nsf;
751
3.52k
      if (tmp3>pp+pitch)
752
2.16k
         tmp3=pp+pitch;
753
42.9k
      for (j=tmp1;j<tmp3;j++)
754
39.4k
         exc_out[j]=MAC16_16(exc_out[j],gain[2-i],exc[j-pp-pitch]);
755
3.52k
   }
756
   /*for (i=0;i<nsf;i++)
757
   exc[i]=PSHR32(exc32[i],13);*/
758
1.17k
}
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
524
{
786
524
   int i;
787
524
   VARDECL(spx_word16_t *res);
788
524
   ALLOC(res, nsf, spx_word16_t);
789
#ifdef FIXED_POINT
790
   if (pitch_coef>63)
791
      pitch_coef=63;
792
#else
793
524
   if (pitch_coef>.99)
794
0
      pitch_coef=.99;
795
524
#endif
796
18.5k
   for (i=0;i<nsf&&i<start;i++)
797
18.0k
   {
798
18.0k
      exc[i]=MULT16_16(SHL16(pitch_coef, 7),exc2[i-start]);
799
18.0k
   }
800
3.42k
   for (;i<nsf;i++)
801
2.89k
   {
802
2.89k
      exc[i]=MULT16_32_Q15(SHL16(pitch_coef, 9),exc[i-start]);
803
2.89k
   }
804
21.4k
   for (i=0;i<nsf;i++)
805
20.9k
      res[i] = EXTRACT16(PSHR32(exc[i], SIG_SHIFT-1));
806
524
   syn_percep_zero16(res, ak, awk1, awk2, res, nsf, p, stack);
807
21.4k
   for (i=0;i<nsf;i++)
808
20.9k
      target[i]=EXTRACT16(SATURATE(SUB32(EXTEND32(target[i]),EXTEND32(res[i])),32700));
809
524
   return start;
810
524
}
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
428
{
833
428
   int i;
834
#ifdef FIXED_POINT
835
   if (pitch_coef>63)
836
      pitch_coef=63;
837
#else
838
428
   if (pitch_coef>.99)
839
112
      pitch_coef=.99;
840
428
#endif
841
17.5k
   for (i=0;i<nsf;i++)
842
17.1k
   {
843
17.1k
      exc_out[i]=MULT16_16(exc[i-start],SHL16(pitch_coef,7));
844
17.1k
      exc[i] = EXTRACT16(PSHR32(exc_out[i],13));
845
17.1k
   }
846
428
   *pitch_val = start;
847
428
   gain_val[0]=gain_val[2]=0;
848
428
   gain_val[1] = pitch_coef;
849
428
}
850
#endif /* DISABLE_DECODER */