Coverage Report

Created: 2026-02-26 06:42

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/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
6.58M
{
60
6.58M
   spx_word32_t sum=0;
61
6.58M
   len >>= 2;
62
146M
   while(len--)
63
139M
   {
64
139M
      spx_word32_t part=0;
65
139M
      part = MAC16_16(part,*x++,*y++);
66
139M
      part = MAC16_16(part,*x++,*y++);
67
139M
      part = MAC16_16(part,*x++,*y++);
68
139M
      part = MAC16_16(part,*x++,*y++);
69
      /* HINT: If you had a 40-bit accumulator, you could shift only at the end */
70
139M
      sum = ADD32(sum,SHR32(part,6));
71
139M
   }
72
6.58M
   return sum;
73
6.58M
}
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
40.3k
{
145
40.3k
   int i;
146
4.93M
   for (i=0;i<nb_pitch;i++)
147
4.89M
   {
148
      /* Compute correlation*/
149
4.89M
      corr[nb_pitch-1-i]=inner_prod(_x, _y+i, len);
150
4.89M
   }
151
152
40.3k
}
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
27.9M
{
159
27.9M
   spx_word32_t sum = 0;
160
27.9M
   sum = ADD32(sum,MULT16_16(MULT16_16_16(g[0],pitch_control),C[0]));
161
27.9M
   sum = ADD32(sum,MULT16_16(MULT16_16_16(g[1],pitch_control),C[1]));
162
27.9M
   sum = ADD32(sum,MULT16_16(MULT16_16_16(g[2],pitch_control),C[2]));
163
27.9M
   sum = SUB32(sum,MULT16_16(MULT16_16_16(g[0],g[1]),C[3]));
164
27.9M
   sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[1]),C[4]));
165
27.9M
   sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[0]),C[5]));
166
27.9M
   sum = SUB32(sum,MULT16_16(MULT16_16_16(g[0],g[0]),C[6]));
167
27.9M
   sum = SUB32(sum,MULT16_16(MULT16_16_16(g[1],g[1]),C[7]));
168
27.9M
   sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[2]),C[8]));
169
27.9M
   return sum;
170
27.9M
}
ltp.c:compute_pitch_error
Line
Count
Source
158
13.9M
{
159
13.9M
   spx_word32_t sum = 0;
160
13.9M
   sum = ADD32(sum,MULT16_16(MULT16_16_16(g[0],pitch_control),C[0]));
161
13.9M
   sum = ADD32(sum,MULT16_16(MULT16_16_16(g[1],pitch_control),C[1]));
162
13.9M
   sum = ADD32(sum,MULT16_16(MULT16_16_16(g[2],pitch_control),C[2]));
163
13.9M
   sum = SUB32(sum,MULT16_16(MULT16_16_16(g[0],g[1]),C[3]));
164
13.9M
   sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[1]),C[4]));
165
13.9M
   sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[0]),C[5]));
166
13.9M
   sum = SUB32(sum,MULT16_16(MULT16_16_16(g[0],g[0]),C[6]));
167
13.9M
   sum = SUB32(sum,MULT16_16(MULT16_16_16(g[1],g[1]),C[7]));
168
13.9M
   sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[2]),C[8]));
169
13.9M
   return sum;
170
13.9M
}
ltp.c:compute_pitch_error
Line
Count
Source
158
13.9M
{
159
13.9M
   spx_word32_t sum = 0;
160
13.9M
   sum = ADD32(sum,MULT16_16(MULT16_16_16(g[0],pitch_control),C[0]));
161
13.9M
   sum = ADD32(sum,MULT16_16(MULT16_16_16(g[1],pitch_control),C[1]));
162
13.9M
   sum = ADD32(sum,MULT16_16(MULT16_16_16(g[2],pitch_control),C[2]));
163
13.9M
   sum = SUB32(sum,MULT16_16(MULT16_16_16(g[0],g[1]),C[3]));
164
13.9M
   sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[1]),C[4]));
165
13.9M
   sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[0]),C[5]));
166
13.9M
   sum = SUB32(sum,MULT16_16(MULT16_16_16(g[0],g[0]),C[6]));
167
13.9M
   sum = SUB32(sum,MULT16_16(MULT16_16_16(g[1],g[1]),C[7]));
168
13.9M
   sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[2]),C[8]));
169
13.9M
   return sum;
170
13.9M
}
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
56.6k
{
176
56.6k
   int i,j,k;
177
56.6k
   VARDECL(spx_word32_t *best_score);
178
56.6k
   VARDECL(spx_word32_t *best_ener);
179
56.6k
   spx_word32_t e0;
180
56.6k
   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
40.3k
   ALLOC(corr16, end-start+1, spx_word16_t);
190
40.3k
   ALLOC(ener16, end-start+1, spx_word16_t);
191
40.3k
   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
   VARDECL(spx_word32_t *energy);
196
   spx_word16_t *corr16;
197
   spx_word16_t *ener16;
198
16.2k
   ALLOC(energy, end-start+2, spx_word32_t);
199
16.2k
   ALLOC(corr, end-start+1, spx_word32_t);
200
   corr16 = corr;
201
   ener16 = energy;
202
#endif
203
204
56.6k
   ALLOC(best_score, N, spx_word32_t);
205
56.6k
   ALLOC(best_ener, N, spx_word32_t);
206
377k
   for (i=0;i<N;i++)
207
320k
   {
208
320k
        best_score[i]=-1;
209
320k
        best_ener[i]=0;
210
320k
        pitch[i]=start;
211
320k
   }
212
213
#ifdef FIXED_POINT
214
7.55M
   for (i=-end;i<len;i++)
215
7.52M
   {
216
7.52M
      if (ABS16(sw[i])>16383)
217
11.3k
      {
218
11.3k
         scaledown=1;
219
11.3k
         break;
220
11.3k
      }
221
7.52M
   }
222
   /* If the weighted input is close to saturation, then we scale it down */
223
40.3k
   if (scaledown)
224
11.3k
   {
225
2.64M
      for (i=-end;i<len;i++)
226
2.63M
      {
227
2.63M
         sw[i]=SHR16(sw[i],1);
228
2.63M
      }
229
11.3k
   }
230
#endif
231
56.6k
   energy[0]=inner_prod(sw-start, sw-start, len);
232
56.6k
   e0=inner_prod(sw, sw, len);
233
6.86M
   for (i=start;i<end;i++)
234
6.80M
   {
235
      /* Update energy for next pitch*/
236
6.80M
      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
6.80M
      if (energy[i-start+1] < 0)
238
6.79k
         energy[i-start+1] = 0;
239
6.80M
   }
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
56.6k
   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
40.3k
   if (scaledown)
253
11.3k
   {
254
2.64M
      for (i=-end;i<len;i++)
255
2.63M
      {
256
2.63M
         sw[i]=SHL16(sw[i],1);
257
2.63M
      }
258
11.3k
   }
259
#endif
260
261
   /* Search for the best pitch prediction gain */
262
6.91M
   for (i=start;i<=end;i++)
263
6.86M
   {
264
6.86M
      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
6.86M
      if (MULT16_16(tmp,best_ener[N-1])>MULT16_16(best_score[N-1],ADD16(1,ener16[i-start])))
267
1.11M
      {
268
         /* We can safely put it last and then check */
269
1.11M
         best_score[N-1]=tmp;
270
1.11M
         best_ener[N-1]=ener16[i-start]+1;
271
1.11M
         pitch[N-1]=i;
272
         /* Check if it comes in front of others */
273
3.41M
         for (j=0;j<N-1;j++)
274
3.25M
         {
275
3.25M
            if (MULT16_16(tmp,best_ener[j])>MULT16_16(best_score[j],ADD16(1,ener16[i-start])))
276
945k
            {
277
4.62M
               for (k=N-1;k>j;k--)
278
3.68M
               {
279
3.68M
                  best_score[k]=best_score[k-1];
280
3.68M
                  best_ener[k]=best_ener[k-1];
281
3.68M
                  pitch[k]=pitch[k-1];
282
3.68M
               }
283
945k
               best_score[j]=tmp;
284
945k
               best_ener[j]=ener16[i-start]+1;
285
945k
               pitch[j]=i;
286
945k
               break;
287
945k
            }
288
3.25M
         }
289
1.11M
      }
290
6.86M
   }
291
292
   /* Compute open-loop gain if necessary */
293
56.6k
   if (gain)
294
25.8k
   {
295
181k
      for (j=0;j<N;j++)
296
155k
      {
297
155k
         spx_word16_t g;
298
155k
         i=pitch[j];
299
155k
         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
155k
         if (g<0)
302
56.7k
            g = 0;
303
155k
         gain[j]=g;
304
155k
      }
305
25.8k
   }
306
307
308
56.6k
}
open_loop_nbest_pitch
Line
Count
Source
175
16.2k
{
176
16.2k
   int i,j,k;
177
16.2k
   VARDECL(spx_word32_t *best_score);
178
16.2k
   VARDECL(spx_word32_t *best_ener);
179
16.2k
   spx_word32_t e0;
180
16.2k
   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
16.2k
   VARDECL(spx_word32_t *energy);
196
16.2k
   spx_word16_t *corr16;
197
16.2k
   spx_word16_t *ener16;
198
16.2k
   ALLOC(energy, end-start+2, spx_word32_t);
199
16.2k
   ALLOC(corr, end-start+1, spx_word32_t);
200
16.2k
   corr16 = corr;
201
16.2k
   ener16 = energy;
202
16.2k
#endif
203
204
16.2k
   ALLOC(best_score, N, spx_word32_t);
205
16.2k
   ALLOC(best_ener, N, spx_word32_t);
206
111k
   for (i=0;i<N;i++)
207
95.3k
   {
208
95.3k
        best_score[i]=-1;
209
95.3k
        best_ener[i]=0;
210
95.3k
        pitch[i]=start;
211
95.3k
   }
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
16.2k
   energy[0]=inner_prod(sw-start, sw-start, len);
232
16.2k
   e0=inner_prod(sw, sw, len);
233
1.96M
   for (i=start;i<end;i++)
234
1.94M
   {
235
      /* Update energy for next pitch*/
236
1.94M
      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
1.94M
      if (energy[i-start+1] < 0)
238
6.79k
         energy[i-start+1] = 0;
239
1.94M
   }
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
16.2k
   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
1.98M
   for (i=start;i<=end;i++)
263
1.96M
   {
264
1.96M
      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
1.96M
      if (MULT16_16(tmp,best_ener[N-1])>MULT16_16(best_score[N-1],ADD16(1,ener16[i-start])))
267
352k
      {
268
         /* We can safely put it last and then check */
269
352k
         best_score[N-1]=tmp;
270
352k
         best_ener[N-1]=ener16[i-start]+1;
271
352k
         pitch[N-1]=i;
272
         /* Check if it comes in front of others */
273
949k
         for (j=0;j<N-1;j++)
274
904k
         {
275
904k
            if (MULT16_16(tmp,best_ener[j])>MULT16_16(best_score[j],ADD16(1,ener16[i-start])))
276
307k
            {
277
1.67M
               for (k=N-1;k>j;k--)
278
1.36M
               {
279
1.36M
                  best_score[k]=best_score[k-1];
280
1.36M
                  best_ener[k]=best_ener[k-1];
281
1.36M
                  pitch[k]=pitch[k-1];
282
1.36M
               }
283
307k
               best_score[j]=tmp;
284
307k
               best_ener[j]=ener16[i-start]+1;
285
307k
               pitch[j]=i;
286
307k
               break;
287
307k
            }
288
904k
         }
289
352k
      }
290
1.96M
   }
291
292
   /* Compute open-loop gain if necessary */
293
16.2k
   if (gain)
294
7.90k
   {
295
55.3k
      for (j=0;j<N;j++)
296
47.4k
      {
297
47.4k
         spx_word16_t g;
298
47.4k
         i=pitch[j];
299
47.4k
         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
47.4k
         if (g<0)
302
13.9k
            g = 0;
303
47.4k
         gain[j]=g;
304
47.4k
      }
305
7.90k
   }
306
307
308
16.2k
}
open_loop_nbest_pitch
Line
Count
Source
175
40.3k
{
176
40.3k
   int i,j,k;
177
40.3k
   VARDECL(spx_word32_t *best_score);
178
40.3k
   VARDECL(spx_word32_t *best_ener);
179
40.3k
   spx_word32_t e0;
180
40.3k
   VARDECL(spx_word32_t *corr);
181
40.3k
#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
40.3k
   VARDECL(spx_word16_t *corr16);
185
40.3k
   VARDECL(spx_word16_t *ener16);
186
40.3k
   spx_word32_t *energy;
187
40.3k
   int cshift=0, eshift=0;
188
40.3k
   int scaledown = 0;
189
40.3k
   ALLOC(corr16, end-start+1, spx_word16_t);
190
40.3k
   ALLOC(ener16, end-start+1, spx_word16_t);
191
40.3k
   ALLOC(corr, end-start+1, spx_word32_t);
192
40.3k
   energy = corr;
193
#else
194
   /* In floating-point, we need to float arrays and no normalized copies */
195
   VARDECL(spx_word32_t *energy);
196
   spx_word16_t *corr16;
197
   spx_word16_t *ener16;
198
   ALLOC(energy, end-start+2, spx_word32_t);
199
   ALLOC(corr, end-start+1, spx_word32_t);
200
   corr16 = corr;
201
   ener16 = energy;
202
#endif
203
204
40.3k
   ALLOC(best_score, N, spx_word32_t);
205
40.3k
   ALLOC(best_ener, N, spx_word32_t);
206
265k
   for (i=0;i<N;i++)
207
225k
   {
208
225k
        best_score[i]=-1;
209
225k
        best_ener[i]=0;
210
225k
        pitch[i]=start;
211
225k
   }
212
213
40.3k
#ifdef FIXED_POINT
214
7.55M
   for (i=-end;i<len;i++)
215
7.52M
   {
216
7.52M
      if (ABS16(sw[i])>16383)
217
11.3k
      {
218
11.3k
         scaledown=1;
219
11.3k
         break;
220
11.3k
      }
221
7.52M
   }
222
   /* If the weighted input is close to saturation, then we scale it down */
223
40.3k
   if (scaledown)
224
11.3k
   {
225
2.64M
      for (i=-end;i<len;i++)
226
2.63M
      {
227
2.63M
         sw[i]=SHR16(sw[i],1);
228
2.63M
      }
229
11.3k
   }
230
40.3k
#endif
231
40.3k
   energy[0]=inner_prod(sw-start, sw-start, len);
232
40.3k
   e0=inner_prod(sw, sw, len);
233
4.89M
   for (i=start;i<end;i++)
234
4.85M
   {
235
      /* Update energy for next pitch*/
236
4.85M
      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
4.85M
      if (energy[i-start+1] < 0)
238
0
         energy[i-start+1] = 0;
239
4.85M
   }
240
241
40.3k
#ifdef FIXED_POINT
242
40.3k
   eshift = normalize16(energy, ener16, 32766, end-start+1);
243
40.3k
#endif
244
245
   /* In fixed-point, this actually overrites the energy array (aliased to corr) */
246
40.3k
   pitch_xcorr(sw, sw-end, corr, len, end-start+1, stack);
247
248
40.3k
#ifdef FIXED_POINT
249
   /* Normalize to 180 so we can square it and it still fits in 16 bits */
250
40.3k
   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
40.3k
   if (scaledown)
253
11.3k
   {
254
2.64M
      for (i=-end;i<len;i++)
255
2.63M
      {
256
2.63M
         sw[i]=SHL16(sw[i],1);
257
2.63M
      }
258
11.3k
   }
259
40.3k
#endif
260
261
   /* Search for the best pitch prediction gain */
262
4.93M
   for (i=start;i<=end;i++)
263
4.89M
   {
264
4.89M
      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
4.89M
      if (MULT16_16(tmp,best_ener[N-1])>MULT16_16(best_score[N-1],ADD16(1,ener16[i-start])))
267
758k
      {
268
         /* We can safely put it last and then check */
269
758k
         best_score[N-1]=tmp;
270
758k
         best_ener[N-1]=ener16[i-start]+1;
271
758k
         pitch[N-1]=i;
272
         /* Check if it comes in front of others */
273
2.46M
         for (j=0;j<N-1;j++)
274
2.34M
         {
275
2.34M
            if (MULT16_16(tmp,best_ener[j])>MULT16_16(best_score[j],ADD16(1,ener16[i-start])))
276
637k
            {
277
2.95M
               for (k=N-1;k>j;k--)
278
2.31M
               {
279
2.31M
                  best_score[k]=best_score[k-1];
280
2.31M
                  best_ener[k]=best_ener[k-1];
281
2.31M
                  pitch[k]=pitch[k-1];
282
2.31M
               }
283
637k
               best_score[j]=tmp;
284
637k
               best_ener[j]=ener16[i-start]+1;
285
637k
               pitch[j]=i;
286
637k
               break;
287
637k
            }
288
2.34M
         }
289
758k
      }
290
4.89M
   }
291
292
   /* Compute open-loop gain if necessary */
293
40.3k
   if (gain)
294
17.9k
   {
295
125k
      for (j=0;j<N;j++)
296
107k
      {
297
107k
         spx_word16_t g;
298
107k
         i=pitch[j];
299
107k
         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
107k
         if (g<0)
302
42.7k
            g = 0;
303
107k
         gain[j]=g;
304
107k
      }
305
17.9k
   }
306
307
308
40.3k
}
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
342k
{
319
342k
  const signed char *ptr=gain_cdbk;
320
342k
  int                best_cdbk=0;
321
342k
  spx_word32_t       best_sum=-VERY_LARGE32;
322
342k
  spx_word32_t       sum=0;
323
342k
  spx_word16_t       g[3];
324
342k
  spx_word16_t       pitch_control=64;
325
342k
  spx_word16_t       gain_sum;
326
342k
  int                i;
327
328
28.2M
  for (i=0;i<gain_cdbk_size;i++) {
329
330
27.9M
    ptr = gain_cdbk+4*i;
331
27.9M
    g[0]=ADD16((spx_word16_t)ptr[0],32);
332
27.9M
    g[1]=ADD16((spx_word16_t)ptr[1],32);
333
27.9M
    g[2]=ADD16((spx_word16_t)ptr[2],32);
334
27.9M
    gain_sum = (spx_word16_t)ptr[3];
335
336
27.9M
    sum = compute_pitch_error(C16, g, pitch_control);
337
338
27.9M
    if (sum>best_sum && gain_sum<=max_gain) {
339
1.04M
      best_sum=sum;
340
1.04M
      best_cdbk=i;
341
1.04M
    }
342
27.9M
  }
343
344
342k
  return best_cdbk;
345
342k
}
ltp.c:pitch_gain_search_3tap_vq
Line
Count
Source
318
171k
{
319
171k
  const signed char *ptr=gain_cdbk;
320
171k
  int                best_cdbk=0;
321
171k
  spx_word32_t       best_sum=-VERY_LARGE32;
322
171k
  spx_word32_t       sum=0;
323
171k
  spx_word16_t       g[3];
324
171k
  spx_word16_t       pitch_control=64;
325
171k
  spx_word16_t       gain_sum;
326
171k
  int                i;
327
328
14.1M
  for (i=0;i<gain_cdbk_size;i++) {
329
330
13.9M
    ptr = gain_cdbk+4*i;
331
13.9M
    g[0]=ADD16((spx_word16_t)ptr[0],32);
332
13.9M
    g[1]=ADD16((spx_word16_t)ptr[1],32);
333
13.9M
    g[2]=ADD16((spx_word16_t)ptr[2],32);
334
13.9M
    gain_sum = (spx_word16_t)ptr[3];
335
336
13.9M
    sum = compute_pitch_error(C16, g, pitch_control);
337
338
13.9M
    if (sum>best_sum && gain_sum<=max_gain) {
339
522k
      best_sum=sum;
340
522k
      best_cdbk=i;
341
522k
    }
342
13.9M
  }
343
344
171k
  return best_cdbk;
345
171k
}
ltp.c:pitch_gain_search_3tap_vq
Line
Count
Source
318
171k
{
319
171k
  const signed char *ptr=gain_cdbk;
320
171k
  int                best_cdbk=0;
321
171k
  spx_word32_t       best_sum=-VERY_LARGE32;
322
171k
  spx_word32_t       sum=0;
323
171k
  spx_word16_t       g[3];
324
171k
  spx_word16_t       pitch_control=64;
325
171k
  spx_word16_t       gain_sum;
326
171k
  int                i;
327
328
14.1M
  for (i=0;i<gain_cdbk_size;i++) {
329
330
13.9M
    ptr = gain_cdbk+4*i;
331
13.9M
    g[0]=ADD16((spx_word16_t)ptr[0],32);
332
13.9M
    g[1]=ADD16((spx_word16_t)ptr[1],32);
333
13.9M
    g[2]=ADD16((spx_word16_t)ptr[2],32);
334
13.9M
    gain_sum = (spx_word16_t)ptr[3];
335
336
13.9M
    sum = compute_pitch_error(C16, g, pitch_control);
337
338
13.9M
    if (sum>best_sum && gain_sum<=max_gain) {
339
522k
      best_sum=sum;
340
522k
      best_cdbk=i;
341
522k
    }
342
13.9M
  }
343
344
171k
  return best_cdbk;
345
171k
}
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
171k
{
371
171k
   int i,j;
372
171k
   VARDECL(spx_word16_t *tmp1);
373
171k
   VARDECL(spx_word16_t *e);
374
171k
   spx_word16_t *x[3];
375
171k
   spx_word32_t corr[3];
376
171k
   spx_word32_t A[3][3];
377
171k
   spx_word16_t gain[3];
378
171k
   spx_word32_t err;
379
171k
   spx_word16_t max_gain=128;
380
171k
   int          best_cdbk=0;
381
382
171k
   ALLOC(tmp1, 3*nsf, spx_word16_t);
383
171k
   ALLOC(e, nsf, spx_word16_t);
384
385
171k
   if (cumul_gain > 262144)
386
694
      max_gain = 31;
387
388
171k
   x[0]=tmp1;
389
171k
   x[1]=tmp1+nsf;
390
171k
   x[2]=tmp1+2*nsf;
391
392
7.01M
   for (j=0;j<nsf;j++)
393
6.84M
      new_target[j] = target[j];
394
395
171k
   {
396
171k
      int bound;
397
171k
      VARDECL(spx_mem_t *mm);
398
171k
      int pp=pitch-1;
399
171k
      ALLOC(mm, p, spx_mem_t);
400
171k
      bound = nsf;
401
171k
      if (nsf-pp>0)
402
70.0k
         bound = pp;
403
5.91M
      for (j=0;j<bound;j++)
404
5.74M
         e[j]=exc2[j-pp];
405
171k
      bound = nsf;
406
171k
      if (nsf-pp-pitch>0)
407
23.7k
         bound = pp+pitch;
408
1.17M
      for (;j<bound;j++)
409
1.00M
         e[j]=exc2[j-pp-pitch];
410
274k
      for (;j<nsf;j++)
411
103k
         e[j]=0;
412
#ifdef FIXED_POINT
413
      /* Scale target and excitation down if needed (avoiding overflow) */
414
122k
      if (scaledown)
415
28.6k
      {
416
1.17M
         for (j=0;j<nsf;j++)
417
1.14M
            e[j] = SHR16(e[j],1);
418
1.17M
         for (j=0;j<nsf;j++)
419
1.14M
            new_target[j] = SHR16(new_target[j],1);
420
28.6k
      }
421
#endif
422
1.88M
      for (j=0;j<p;j++)
423
1.71M
         mm[j] = 0;
424
171k
      iir_mem16(e, ak, e, nsf, p, mm, stack);
425
1.88M
      for (j=0;j<p;j++)
426
1.71M
         mm[j] = 0;
427
171k
      filter10(e, awk1, awk2, e, nsf, mm, stack);
428
7.01M
      for (j=0;j<nsf;j++)
429
6.84M
         x[2][j] = e[j];
430
171k
   }
431
513k
   for (i=1;i>=0;i--)
432
342k
   {
433
342k
      spx_word16_t e0=exc2[-pitch-1+i];
434
#ifdef FIXED_POINT
435
      /* Scale excitation down if needed (avoiding overflow) */
436
244k
      if (scaledown)
437
57.2k
         e0 = SHR16(e0,1);
438
#endif
439
342k
      x[i][0]=MULT16_16_Q14(r[0], e0);
440
13.6M
      for (j=0;j<nsf-1;j++)
441
13.3M
         x[i][j+1]=ADD32(x[i+1][j],MULT16_16_P14(r[j+1], e0));
442
342k
   }
443
444
684k
   for (i=0;i<3;i++)
445
513k
      corr[i]=inner_prod(x[i],new_target,nsf);
446
684k
   for (i=0;i<3;i++)
447
1.54M
      for (j=0;j<=i;j++)
448
1.02M
         A[i][j]=A[j][i]=inner_prod(x[i],x[j],nsf);
449
450
171k
   {
451
171k
      spx_word32_t C[9];
452
#ifdef FIXED_POINT
453
      spx_word16_t C16[9];
454
#else
455
      spx_word16_t *C16=C;
456
#endif
457
171k
      C[0]=corr[2];
458
171k
      C[1]=corr[1];
459
171k
      C[2]=corr[0];
460
171k
      C[3]=A[1][2];
461
171k
      C[4]=A[0][1];
462
171k
      C[5]=A[0][2];
463
171k
      C[6]=A[2][2];
464
171k
      C[7]=A[1][1];
465
171k
      C[8]=A[0][0];
466
467
      /*plc_tuning *= 2;*/
468
171k
      if (plc_tuning<2)
469
0
         plc_tuning=2;
470
171k
      if (plc_tuning>30)
471
0
         plc_tuning=30;
472
#ifdef FIXED_POINT
473
122k
      C[0] = SHL32(C[0],1);
474
122k
      C[1] = SHL32(C[1],1);
475
122k
      C[2] = SHL32(C[2],1);
476
122k
      C[3] = SHL32(C[3],1);
477
122k
      C[4] = SHL32(C[4],1);
478
122k
      C[5] = SHL32(C[5],1);
479
122k
      C[6] = MAC16_32_Q15(C[6],MULT16_16_16(plc_tuning,655),C[6]);
480
122k
      C[7] = MAC16_32_Q15(C[7],MULT16_16_16(plc_tuning,655),C[7]);
481
122k
      C[8] = MAC16_32_Q15(C[8],MULT16_16_16(plc_tuning,655),C[8]);
482
      normalize16(C, C16, 32767, 9);
483
#else
484
      C[6]*=.5*(1+.02*plc_tuning);
485
      C[7]*=.5*(1+.02*plc_tuning);
486
      C[8]*=.5*(1+.02*plc_tuning);
487
#endif
488
489
171k
      best_cdbk = pitch_gain_search_3tap_vq(gain_cdbk, gain_cdbk_size, C16, max_gain);
490
491
#ifdef FIXED_POINT
492
122k
      gain[0] = ADD16(32,(spx_word16_t)gain_cdbk[best_cdbk*4]);
493
122k
      gain[1] = ADD16(32,(spx_word16_t)gain_cdbk[best_cdbk*4+1]);
494
122k
      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
      gain[0] = 0.015625*gain_cdbk[best_cdbk*4]  + .5;
498
      gain[1] = 0.015625*gain_cdbk[best_cdbk*4+1]+ .5;
499
      gain[2] = 0.015625*gain_cdbk[best_cdbk*4+2]+ .5;
500
#endif
501
171k
      *cdbk_index=best_cdbk;
502
171k
   }
503
504
171k
   SPEEX_MEMSET(exc, 0, nsf);
505
684k
   for (i=0;i<3;i++)
506
513k
   {
507
513k
      int j;
508
513k
      int tmp1, tmp3;
509
513k
      int pp=pitch+1-i;
510
513k
      tmp1=nsf;
511
513k
      if (tmp1>pp)
512
203k
         tmp1=pp;
513
17.9M
      for (j=0;j<tmp1;j++)
514
17.4M
         exc[j]=MAC16_16(exc[j],SHL16(gain[2-i],7),exc2[j-pp]);
515
513k
      tmp3=nsf;
516
513k
      if (tmp3>pp+pitch)
517
61.0k
         tmp3=pp+pitch;
518
3.37M
      for (j=tmp1;j<tmp3;j++)
519
2.86M
         exc[j]=MAC16_16(exc[j],SHL16(gain[2-i],7),exc2[j-pp-pitch]);
520
513k
   }
521
7.01M
   for (i=0;i<nsf;i++)
522
6.84M
   {
523
6.84M
      spx_word32_t tmp = ADD32(ADD32(MULT16_16(gain[0],x[2][i]),MULT16_16(gain[1],x[1][i])),
524
6.84M
                            MULT16_16(gain[2],x[0][i]));
525
6.84M
      new_target[i] = SUB16(new_target[i], EXTRACT16(PSHR32(tmp,6)));
526
6.84M
   }
527
171k
   err = inner_prod(new_target, new_target, nsf);
528
529
171k
   return err;
530
171k
}
ltp.c:pitch_gain_search_3tap
Line
Count
Source
370
49.1k
{
371
49.1k
   int i,j;
372
49.1k
   VARDECL(spx_word16_t *tmp1);
373
49.1k
   VARDECL(spx_word16_t *e);
374
49.1k
   spx_word16_t *x[3];
375
49.1k
   spx_word32_t corr[3];
376
49.1k
   spx_word32_t A[3][3];
377
49.1k
   spx_word16_t gain[3];
378
49.1k
   spx_word32_t err;
379
49.1k
   spx_word16_t max_gain=128;
380
49.1k
   int          best_cdbk=0;
381
382
49.1k
   ALLOC(tmp1, 3*nsf, spx_word16_t);
383
49.1k
   ALLOC(e, nsf, spx_word16_t);
384
385
49.1k
   if (cumul_gain > 262144)
386
330
      max_gain = 31;
387
388
49.1k
   x[0]=tmp1;
389
49.1k
   x[1]=tmp1+nsf;
390
49.1k
   x[2]=tmp1+2*nsf;
391
392
2.01M
   for (j=0;j<nsf;j++)
393
1.96M
      new_target[j] = target[j];
394
395
49.1k
   {
396
49.1k
      int bound;
397
49.1k
      VARDECL(spx_mem_t *mm);
398
49.1k
      int pp=pitch-1;
399
49.1k
      ALLOC(mm, p, spx_mem_t);
400
49.1k
      bound = nsf;
401
49.1k
      if (nsf-pp>0)
402
23.8k
         bound = pp;
403
1.62M
      for (j=0;j<bound;j++)
404
1.57M
         e[j]=exc2[j-pp];
405
49.1k
      bound = nsf;
406
49.1k
      if (nsf-pp-pitch>0)
407
8.20k
         bound = pp+pitch;
408
399k
      for (;j<bound;j++)
409
350k
         e[j]=exc2[j-pp-pitch];
410
87.1k
      for (;j<nsf;j++)
411
38.0k
         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
540k
      for (j=0;j<p;j++)
423
491k
         mm[j] = 0;
424
49.1k
      iir_mem16(e, ak, e, nsf, p, mm, stack);
425
540k
      for (j=0;j<p;j++)
426
491k
         mm[j] = 0;
427
49.1k
      filter10(e, awk1, awk2, e, nsf, mm, stack);
428
2.01M
      for (j=0;j<nsf;j++)
429
1.96M
         x[2][j] = e[j];
430
49.1k
   }
431
147k
   for (i=1;i>=0;i--)
432
98.2k
   {
433
98.2k
      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
98.2k
      x[i][0]=MULT16_16_Q14(r[0], e0);
440
3.93M
      for (j=0;j<nsf-1;j++)
441
3.83M
         x[i][j+1]=ADD32(x[i+1][j],MULT16_16_P14(r[j+1], e0));
442
98.2k
   }
443
444
196k
   for (i=0;i<3;i++)
445
147k
      corr[i]=inner_prod(x[i],new_target,nsf);
446
196k
   for (i=0;i<3;i++)
447
442k
      for (j=0;j<=i;j++)
448
294k
         A[i][j]=A[j][i]=inner_prod(x[i],x[j],nsf);
449
450
49.1k
   {
451
49.1k
      spx_word32_t C[9];
452
#ifdef FIXED_POINT
453
      spx_word16_t C16[9];
454
#else
455
49.1k
      spx_word16_t *C16=C;
456
49.1k
#endif
457
49.1k
      C[0]=corr[2];
458
49.1k
      C[1]=corr[1];
459
49.1k
      C[2]=corr[0];
460
49.1k
      C[3]=A[1][2];
461
49.1k
      C[4]=A[0][1];
462
49.1k
      C[5]=A[0][2];
463
49.1k
      C[6]=A[2][2];
464
49.1k
      C[7]=A[1][1];
465
49.1k
      C[8]=A[0][0];
466
467
      /*plc_tuning *= 2;*/
468
49.1k
      if (plc_tuning<2)
469
0
         plc_tuning=2;
470
49.1k
      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
49.1k
      C[6]*=.5*(1+.02*plc_tuning);
485
49.1k
      C[7]*=.5*(1+.02*plc_tuning);
486
49.1k
      C[8]*=.5*(1+.02*plc_tuning);
487
49.1k
#endif
488
489
49.1k
      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
49.1k
      gain[0] = 0.015625*gain_cdbk[best_cdbk*4]  + .5;
498
49.1k
      gain[1] = 0.015625*gain_cdbk[best_cdbk*4+1]+ .5;
499
49.1k
      gain[2] = 0.015625*gain_cdbk[best_cdbk*4+2]+ .5;
500
49.1k
#endif
501
49.1k
      *cdbk_index=best_cdbk;
502
49.1k
   }
503
504
49.1k
   SPEEX_MEMSET(exc, 0, nsf);
505
196k
   for (i=0;i<3;i++)
506
147k
   {
507
147k
      int j;
508
147k
      int tmp1, tmp3;
509
147k
      int pp=pitch+1-i;
510
147k
      tmp1=nsf;
511
147k
      if (tmp1>pp)
512
70.4k
         tmp1=pp;
513
4.95M
      for (j=0;j<tmp1;j++)
514
4.80M
         exc[j]=MAC16_16(exc[j],SHL16(gain[2-i],7),exc2[j-pp]);
515
147k
      tmp3=nsf;
516
147k
      if (tmp3>pp+pitch)
517
21.9k
         tmp3=pp+pitch;
518
1.15M
      for (j=tmp1;j<tmp3;j++)
519
1.00M
         exc[j]=MAC16_16(exc[j],SHL16(gain[2-i],7),exc2[j-pp-pitch]);
520
147k
   }
521
2.01M
   for (i=0;i<nsf;i++)
522
1.96M
   {
523
1.96M
      spx_word32_t tmp = ADD32(ADD32(MULT16_16(gain[0],x[2][i]),MULT16_16(gain[1],x[1][i])),
524
1.96M
                            MULT16_16(gain[2],x[0][i]));
525
1.96M
      new_target[i] = SUB16(new_target[i], EXTRACT16(PSHR32(tmp,6)));
526
1.96M
   }
527
49.1k
   err = inner_prod(new_target, new_target, nsf);
528
529
49.1k
   return err;
530
49.1k
}
ltp.c:pitch_gain_search_3tap
Line
Count
Source
370
122k
{
371
122k
   int i,j;
372
122k
   VARDECL(spx_word16_t *tmp1);
373
122k
   VARDECL(spx_word16_t *e);
374
122k
   spx_word16_t *x[3];
375
122k
   spx_word32_t corr[3];
376
122k
   spx_word32_t A[3][3];
377
122k
   spx_word16_t gain[3];
378
122k
   spx_word32_t err;
379
122k
   spx_word16_t max_gain=128;
380
122k
   int          best_cdbk=0;
381
382
122k
   ALLOC(tmp1, 3*nsf, spx_word16_t);
383
122k
   ALLOC(e, nsf, spx_word16_t);
384
385
122k
   if (cumul_gain > 262144)
386
364
      max_gain = 31;
387
388
122k
   x[0]=tmp1;
389
122k
   x[1]=tmp1+nsf;
390
122k
   x[2]=tmp1+2*nsf;
391
392
5.00M
   for (j=0;j<nsf;j++)
393
4.88M
      new_target[j] = target[j];
394
395
122k
   {
396
122k
      int bound;
397
122k
      VARDECL(spx_mem_t *mm);
398
122k
      int pp=pitch-1;
399
122k
      ALLOC(mm, p, spx_mem_t);
400
122k
      bound = nsf;
401
122k
      if (nsf-pp>0)
402
46.2k
         bound = pp;
403
4.28M
      for (j=0;j<bound;j++)
404
4.16M
         e[j]=exc2[j-pp];
405
122k
      bound = nsf;
406
122k
      if (nsf-pp-pitch>0)
407
15.5k
         bound = pp+pitch;
408
772k
      for (;j<bound;j++)
409
650k
         e[j]=exc2[j-pp-pitch];
410
187k
      for (;j<nsf;j++)
411
65.0k
         e[j]=0;
412
122k
#ifdef FIXED_POINT
413
      /* Scale target and excitation down if needed (avoiding overflow) */
414
122k
      if (scaledown)
415
28.6k
      {
416
1.17M
         for (j=0;j<nsf;j++)
417
1.14M
            e[j] = SHR16(e[j],1);
418
1.17M
         for (j=0;j<nsf;j++)
419
1.14M
            new_target[j] = SHR16(new_target[j],1);
420
28.6k
      }
421
122k
#endif
422
1.34M
      for (j=0;j<p;j++)
423
1.22M
         mm[j] = 0;
424
122k
      iir_mem16(e, ak, e, nsf, p, mm, stack);
425
1.34M
      for (j=0;j<p;j++)
426
1.22M
         mm[j] = 0;
427
122k
      filter10(e, awk1, awk2, e, nsf, mm, stack);
428
5.00M
      for (j=0;j<nsf;j++)
429
4.88M
         x[2][j] = e[j];
430
122k
   }
431
366k
   for (i=1;i>=0;i--)
432
244k
   {
433
244k
      spx_word16_t e0=exc2[-pitch-1+i];
434
244k
#ifdef FIXED_POINT
435
      /* Scale excitation down if needed (avoiding overflow) */
436
244k
      if (scaledown)
437
57.2k
         e0 = SHR16(e0,1);
438
244k
#endif
439
244k
      x[i][0]=MULT16_16_Q14(r[0], e0);
440
9.76M
      for (j=0;j<nsf-1;j++)
441
9.52M
         x[i][j+1]=ADD32(x[i+1][j],MULT16_16_P14(r[j+1], e0));
442
244k
   }
443
444
488k
   for (i=0;i<3;i++)
445
366k
      corr[i]=inner_prod(x[i],new_target,nsf);
446
488k
   for (i=0;i<3;i++)
447
1.09M
      for (j=0;j<=i;j++)
448
732k
         A[i][j]=A[j][i]=inner_prod(x[i],x[j],nsf);
449
450
122k
   {
451
122k
      spx_word32_t C[9];
452
122k
#ifdef FIXED_POINT
453
122k
      spx_word16_t C16[9];
454
#else
455
      spx_word16_t *C16=C;
456
#endif
457
122k
      C[0]=corr[2];
458
122k
      C[1]=corr[1];
459
122k
      C[2]=corr[0];
460
122k
      C[3]=A[1][2];
461
122k
      C[4]=A[0][1];
462
122k
      C[5]=A[0][2];
463
122k
      C[6]=A[2][2];
464
122k
      C[7]=A[1][1];
465
122k
      C[8]=A[0][0];
466
467
      /*plc_tuning *= 2;*/
468
122k
      if (plc_tuning<2)
469
0
         plc_tuning=2;
470
122k
      if (plc_tuning>30)
471
0
         plc_tuning=30;
472
122k
#ifdef FIXED_POINT
473
122k
      C[0] = SHL32(C[0],1);
474
122k
      C[1] = SHL32(C[1],1);
475
122k
      C[2] = SHL32(C[2],1);
476
122k
      C[3] = SHL32(C[3],1);
477
122k
      C[4] = SHL32(C[4],1);
478
122k
      C[5] = SHL32(C[5],1);
479
122k
      C[6] = MAC16_32_Q15(C[6],MULT16_16_16(plc_tuning,655),C[6]);
480
122k
      C[7] = MAC16_32_Q15(C[7],MULT16_16_16(plc_tuning,655),C[7]);
481
122k
      C[8] = MAC16_32_Q15(C[8],MULT16_16_16(plc_tuning,655),C[8]);
482
122k
      normalize16(C, C16, 32767, 9);
483
#else
484
      C[6]*=.5*(1+.02*plc_tuning);
485
      C[7]*=.5*(1+.02*plc_tuning);
486
      C[8]*=.5*(1+.02*plc_tuning);
487
#endif
488
489
122k
      best_cdbk = pitch_gain_search_3tap_vq(gain_cdbk, gain_cdbk_size, C16, max_gain);
490
491
122k
#ifdef FIXED_POINT
492
122k
      gain[0] = ADD16(32,(spx_word16_t)gain_cdbk[best_cdbk*4]);
493
122k
      gain[1] = ADD16(32,(spx_word16_t)gain_cdbk[best_cdbk*4+1]);
494
122k
      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
      gain[0] = 0.015625*gain_cdbk[best_cdbk*4]  + .5;
498
      gain[1] = 0.015625*gain_cdbk[best_cdbk*4+1]+ .5;
499
      gain[2] = 0.015625*gain_cdbk[best_cdbk*4+2]+ .5;
500
#endif
501
122k
      *cdbk_index=best_cdbk;
502
122k
   }
503
504
122k
   SPEEX_MEMSET(exc, 0, nsf);
505
488k
   for (i=0;i<3;i++)
506
366k
   {
507
366k
      int j;
508
366k
      int tmp1, tmp3;
509
366k
      int pp=pitch+1-i;
510
366k
      tmp1=nsf;
511
366k
      if (tmp1>pp)
512
133k
         tmp1=pp;
513
13.0M
      for (j=0;j<tmp1;j++)
514
12.6M
         exc[j]=MAC16_16(exc[j],SHL16(gain[2-i],7),exc2[j-pp]);
515
366k
      tmp3=nsf;
516
366k
      if (tmp3>pp+pitch)
517
39.1k
         tmp3=pp+pitch;
518
2.22M
      for (j=tmp1;j<tmp3;j++)
519
1.85M
         exc[j]=MAC16_16(exc[j],SHL16(gain[2-i],7),exc2[j-pp-pitch]);
520
366k
   }
521
5.00M
   for (i=0;i<nsf;i++)
522
4.88M
   {
523
4.88M
      spx_word32_t tmp = ADD32(ADD32(MULT16_16(gain[0],x[2][i]),MULT16_16(gain[1],x[1][i])),
524
4.88M
                            MULT16_16(gain[2],x[0][i]));
525
4.88M
      new_target[i] = SUB16(new_target[i], EXTRACT16(PSHR32(tmp,6)));
526
4.88M
   }
527
122k
   err = inner_prod(new_target, new_target, nsf);
528
529
122k
   return err;
530
122k
}
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
38.5k
{
556
38.5k
   int i;
557
38.5k
   int cdbk_index, pitch=0, best_gain_index=0;
558
38.5k
   VARDECL(spx_sig_t *best_exc);
559
38.5k
   VARDECL(spx_word16_t *new_target);
560
38.5k
   VARDECL(spx_word16_t *best_target);
561
38.5k
   int best_pitch=0;
562
38.5k
   spx_word32_t err, best_err=-1;
563
38.5k
   int N;
564
38.5k
   const ltp_params *params;
565
38.5k
   const signed char *gain_cdbk;
566
38.5k
   int   gain_cdbk_size;
567
38.5k
   int scaledown=0;
568
569
38.5k
   VARDECL(int *nbest);
570
571
38.5k
   params = (const ltp_params*) par;
572
38.5k
   gain_cdbk_size = 1<<params->gain_bits;
573
38.5k
   gain_cdbk = params->gain_cdbk + 4*gain_cdbk_size*cdbk_offset;
574
575
38.5k
   N=complexity;
576
38.5k
   if (N>10)
577
0
      N=10;
578
38.5k
   if (N<1)
579
5.99k
      N=1;
580
581
38.5k
   ALLOC(nbest, N, int);
582
38.5k
   params = (const ltp_params*) par;
583
584
38.5k
   if (end<start)
585
2.33k
   {
586
2.33k
      speex_bits_pack(bits, 0, params->pitch_bits);
587
2.33k
      speex_bits_pack(bits, 0, params->gain_bits);
588
2.33k
      SPEEX_MEMSET(exc, 0, nsf);
589
2.33k
      return start;
590
2.33k
   }
591
592
#ifdef FIXED_POINT
593
   /* Check if we need to scale everything down in the pitch search to avoid overflows */
594
937k
   for (i=0;i<nsf;i++)
595
916k
   {
596
916k
      if (ABS16(target[i])>16383)
597
5.03k
      {
598
5.03k
         scaledown=1;
599
5.03k
         break;
600
5.03k
      }
601
916k
   }
602
2.80M
   for (i=-end;i<0;i++)
603
2.77M
   {
604
2.77M
      if (ABS16(exc2[i])>16383)
605
4.26k
      {
606
4.26k
         scaledown=1;
607
4.26k
         break;
608
4.26k
      }
609
2.77M
   }
610
#endif
611
36.2k
   if (N>end-start+1)
612
3.98k
      N=end-start+1;
613
36.2k
   if (end != start)
614
30.7k
      open_loop_nbest_pitch(sw, start, end, nsf, nbest, NULL, N, stack);
615
5.47k
   else
616
5.47k
      nbest[0] = start;
617
618
36.2k
   ALLOC(best_exc, nsf, spx_sig_t);
619
36.2k
   ALLOC(new_target, nsf, spx_word16_t);
620
36.2k
   ALLOC(best_target, nsf, spx_word16_t);
621
622
207k
   for (i=0;i<N;i++)
623
171k
   {
624
171k
      pitch=nbest[i];
625
171k
      SPEEX_MEMSET(exc, 0, nsf);
626
171k
      err=pitch_gain_search_3tap(target, ak, awk1, awk2, exc, gain_cdbk, gain_cdbk_size, pitch, p, nsf,
627
171k
                                 bits, stack, exc2, r, new_target, &cdbk_index, plc_tuning, *cumul_gain, scaledown);
628
171k
      if (err<best_err || best_err<0)
629
48.3k
      {
630
48.3k
         SPEEX_COPY(best_exc, exc, nsf);
631
48.3k
         SPEEX_COPY(best_target, new_target, nsf);
632
48.3k
         best_err=err;
633
48.3k
         best_pitch=pitch;
634
48.3k
         best_gain_index=cdbk_index;
635
48.3k
      }
636
171k
   }
637
   /*printf ("pitch: %d %d\n", best_pitch, best_gain_index);*/
638
9.52k
   speex_bits_pack(bits, best_pitch-start, params->pitch_bits);
639
9.52k
   speex_bits_pack(bits, best_gain_index, params->gain_bits);
640
#ifdef FIXED_POINT
641
26.6k
   *cumul_gain = MULT16_32_Q13(SHL16(params->gain_cdbk[4*best_gain_index+3],8), MAX32(1024,*cumul_gain));
642
#else
643
9.52k
   *cumul_gain = 0.03125*MAX32(1024,*cumul_gain)*params->gain_cdbk[4*best_gain_index+3];
644
#endif
645
   /*printf ("%f\n", cumul_gain);*/
646
   /*printf ("encode pitch: %d %d\n", best_pitch, best_gain_index);*/
647
36.2k
   SPEEX_COPY(exc, best_exc, nsf);
648
36.2k
   SPEEX_COPY(target, best_target, nsf);
649
#ifdef FIXED_POINT
650
   /* Scale target back up if needed */
651
26.6k
   if (scaledown)
652
6.55k
   {
653
268k
      for (i=0;i<nsf;i++)
654
262k
         target[i]=SHL16(target[i],1);
655
6.55k
   }
656
#endif
657
9.52k
   return pitch;
658
38.5k
}
pitch_search_3tap
Line
Count
Source
555
10.2k
{
556
10.2k
   int i;
557
10.2k
   int cdbk_index, pitch=0, best_gain_index=0;
558
10.2k
   VARDECL(spx_sig_t *best_exc);
559
10.2k
   VARDECL(spx_word16_t *new_target);
560
10.2k
   VARDECL(spx_word16_t *best_target);
561
10.2k
   int best_pitch=0;
562
10.2k
   spx_word32_t err, best_err=-1;
563
10.2k
   int N;
564
10.2k
   const ltp_params *params;
565
10.2k
   const signed char *gain_cdbk;
566
10.2k
   int   gain_cdbk_size;
567
10.2k
   int scaledown=0;
568
569
10.2k
   VARDECL(int *nbest);
570
571
10.2k
   params = (const ltp_params*) par;
572
10.2k
   gain_cdbk_size = 1<<params->gain_bits;
573
10.2k
   gain_cdbk = params->gain_cdbk + 4*gain_cdbk_size*cdbk_offset;
574
575
10.2k
   N=complexity;
576
10.2k
   if (N>10)
577
0
      N=10;
578
10.2k
   if (N<1)
579
1.62k
      N=1;
580
581
10.2k
   ALLOC(nbest, N, int);
582
10.2k
   params = (const ltp_params*) par;
583
584
10.2k
   if (end<start)
585
735
   {
586
735
      speex_bits_pack(bits, 0, params->pitch_bits);
587
735
      speex_bits_pack(bits, 0, params->gain_bits);
588
735
      SPEEX_MEMSET(exc, 0, nsf);
589
735
      return start;
590
735
   }
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
9.52k
   if (N>end-start+1)
612
889
      N=end-start+1;
613
9.52k
   if (end != start)
614
8.35k
      open_loop_nbest_pitch(sw, start, end, nsf, nbest, NULL, N, stack);
615
1.17k
   else
616
1.17k
      nbest[0] = start;
617
618
9.52k
   ALLOC(best_exc, nsf, spx_sig_t);
619
9.52k
   ALLOC(new_target, nsf, spx_word16_t);
620
9.52k
   ALLOC(best_target, nsf, spx_word16_t);
621
622
58.6k
   for (i=0;i<N;i++)
623
49.1k
   {
624
49.1k
      pitch=nbest[i];
625
49.1k
      SPEEX_MEMSET(exc, 0, nsf);
626
49.1k
      err=pitch_gain_search_3tap(target, ak, awk1, awk2, exc, gain_cdbk, gain_cdbk_size, pitch, p, nsf,
627
49.1k
                                 bits, stack, exc2, r, new_target, &cdbk_index, plc_tuning, *cumul_gain, scaledown);
628
49.1k
      if (err<best_err || best_err<0)
629
11.8k
      {
630
11.8k
         SPEEX_COPY(best_exc, exc, nsf);
631
11.8k
         SPEEX_COPY(best_target, new_target, nsf);
632
11.8k
         best_err=err;
633
11.8k
         best_pitch=pitch;
634
11.8k
         best_gain_index=cdbk_index;
635
11.8k
      }
636
49.1k
   }
637
   /*printf ("pitch: %d %d\n", best_pitch, best_gain_index);*/
638
9.52k
   speex_bits_pack(bits, best_pitch-start, params->pitch_bits);
639
9.52k
   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
9.52k
   *cumul_gain = 0.03125*MAX32(1024,*cumul_gain)*params->gain_cdbk[4*best_gain_index+3];
644
9.52k
#endif
645
   /*printf ("%f\n", cumul_gain);*/
646
   /*printf ("encode pitch: %d %d\n", best_pitch, best_gain_index);*/
647
9.52k
   SPEEX_COPY(exc, best_exc, nsf);
648
9.52k
   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
9.52k
   return pitch;
658
10.2k
}
pitch_search_3tap
Line
Count
Source
555
28.2k
{
556
28.2k
   int i;
557
28.2k
   int cdbk_index, pitch=0, best_gain_index=0;
558
28.2k
   VARDECL(spx_sig_t *best_exc);
559
28.2k
   VARDECL(spx_word16_t *new_target);
560
28.2k
   VARDECL(spx_word16_t *best_target);
561
28.2k
   int best_pitch=0;
562
28.2k
   spx_word32_t err, best_err=-1;
563
28.2k
   int N;
564
28.2k
   const ltp_params *params;
565
28.2k
   const signed char *gain_cdbk;
566
28.2k
   int   gain_cdbk_size;
567
28.2k
   int scaledown=0;
568
569
28.2k
   VARDECL(int *nbest);
570
571
28.2k
   params = (const ltp_params*) par;
572
28.2k
   gain_cdbk_size = 1<<params->gain_bits;
573
28.2k
   gain_cdbk = params->gain_cdbk + 4*gain_cdbk_size*cdbk_offset;
574
575
28.2k
   N=complexity;
576
28.2k
   if (N>10)
577
0
      N=10;
578
28.2k
   if (N<1)
579
4.36k
      N=1;
580
581
28.2k
   ALLOC(nbest, N, int);
582
28.2k
   params = (const ltp_params*) par;
583
584
28.2k
   if (end<start)
585
1.60k
   {
586
1.60k
      speex_bits_pack(bits, 0, params->pitch_bits);
587
1.60k
      speex_bits_pack(bits, 0, params->gain_bits);
588
1.60k
      SPEEX_MEMSET(exc, 0, nsf);
589
1.60k
      return start;
590
1.60k
   }
591
592
26.6k
#ifdef FIXED_POINT
593
   /* Check if we need to scale everything down in the pitch search to avoid overflows */
594
937k
   for (i=0;i<nsf;i++)
595
916k
   {
596
916k
      if (ABS16(target[i])>16383)
597
5.03k
      {
598
5.03k
         scaledown=1;
599
5.03k
         break;
600
5.03k
      }
601
916k
   }
602
2.80M
   for (i=-end;i<0;i++)
603
2.77M
   {
604
2.77M
      if (ABS16(exc2[i])>16383)
605
4.26k
      {
606
4.26k
         scaledown=1;
607
4.26k
         break;
608
4.26k
      }
609
2.77M
   }
610
26.6k
#endif
611
26.6k
   if (N>end-start+1)
612
3.09k
      N=end-start+1;
613
26.6k
   if (end != start)
614
22.3k
      open_loop_nbest_pitch(sw, start, end, nsf, nbest, NULL, N, stack);
615
4.30k
   else
616
4.30k
      nbest[0] = start;
617
618
26.6k
   ALLOC(best_exc, nsf, spx_sig_t);
619
26.6k
   ALLOC(new_target, nsf, spx_word16_t);
620
26.6k
   ALLOC(best_target, nsf, spx_word16_t);
621
622
148k
   for (i=0;i<N;i++)
623
122k
   {
624
122k
      pitch=nbest[i];
625
122k
      SPEEX_MEMSET(exc, 0, nsf);
626
122k
      err=pitch_gain_search_3tap(target, ak, awk1, awk2, exc, gain_cdbk, gain_cdbk_size, pitch, p, nsf,
627
122k
                                 bits, stack, exc2, r, new_target, &cdbk_index, plc_tuning, *cumul_gain, scaledown);
628
122k
      if (err<best_err || best_err<0)
629
36.5k
      {
630
36.5k
         SPEEX_COPY(best_exc, exc, nsf);
631
36.5k
         SPEEX_COPY(best_target, new_target, nsf);
632
36.5k
         best_err=err;
633
36.5k
         best_pitch=pitch;
634
36.5k
         best_gain_index=cdbk_index;
635
36.5k
      }
636
122k
   }
637
   /*printf ("pitch: %d %d\n", best_pitch, best_gain_index);*/
638
26.6k
   speex_bits_pack(bits, best_pitch-start, params->pitch_bits);
639
26.6k
   speex_bits_pack(bits, best_gain_index, params->gain_bits);
640
26.6k
#ifdef FIXED_POINT
641
26.6k
   *cumul_gain = MULT16_32_Q13(SHL16(params->gain_cdbk[4*best_gain_index+3],8), MAX32(1024,*cumul_gain));
642
#else
643
   *cumul_gain = 0.03125*MAX32(1024,*cumul_gain)*params->gain_cdbk[4*best_gain_index+3];
644
#endif
645
   /*printf ("%f\n", cumul_gain);*/
646
   /*printf ("encode pitch: %d %d\n", best_pitch, best_gain_index);*/
647
26.6k
   SPEEX_COPY(exc, best_exc, nsf);
648
26.6k
   SPEEX_COPY(target, best_target, nsf);
649
26.6k
#ifdef FIXED_POINT
650
   /* Scale target back up if needed */
651
26.6k
   if (scaledown)
652
6.55k
   {
653
268k
      for (i=0;i<nsf;i++)
654
262k
         target[i]=SHL16(target[i],1);
655
6.55k
   }
656
26.6k
#endif
657
26.6k
   return pitch;
658
28.2k
}
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
125k
{
680
125k
   int i;
681
125k
   int pitch;
682
125k
   int gain_index;
683
125k
   spx_word16_t gain[3];
684
125k
   const signed char *gain_cdbk;
685
125k
   int gain_cdbk_size;
686
125k
   const ltp_params *params;
687
688
125k
   params = (const ltp_params*) par;
689
125k
   gain_cdbk_size = 1<<params->gain_bits;
690
125k
   gain_cdbk = params->gain_cdbk + 4*gain_cdbk_size*cdbk_offset;
691
692
125k
   pitch = speex_bits_unpack_unsigned(bits, params->pitch_bits);
693
125k
   pitch += start;
694
125k
   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
62.9k
   gain[0] = ADD16(32,(spx_word16_t)gain_cdbk[gain_index*4]);
698
62.9k
   gain[1] = ADD16(32,(spx_word16_t)gain_cdbk[gain_index*4+1]);
699
62.9k
   gain[2] = ADD16(32,(spx_word16_t)gain_cdbk[gain_index*4+2]);
700
#else
701
   gain[0] = 0.015625*gain_cdbk[gain_index*4]+.5;
702
   gain[1] = 0.015625*gain_cdbk[gain_index*4+1]+.5;
703
   gain[2] = 0.015625*gain_cdbk[gain_index*4+2]+.5;
704
#endif
705
706
125k
   if (count_lost && pitch > subframe_offset)
707
0
   {
708
0
      spx_word16_t gain_sum;
709
0
      if (1) {
710
#ifdef FIXED_POINT
711
0
         spx_word16_t tmp = count_lost < 4 ? last_pitch_gain : SHR16(last_pitch_gain,1);
712
0
         if (tmp>62)
713
0
            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
#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
125k
   *pitch_val = pitch;
733
125k
   gain_val[0]=gain[0];
734
125k
   gain_val[1]=gain[1];
735
125k
   gain_val[2]=gain[2];
736
125k
   gain[0] = SHL16(gain[0],7);
737
125k
   gain[1] = SHL16(gain[1],7);
738
125k
   gain[2] = SHL16(gain[2],7);
739
125k
   SPEEX_MEMSET(exc_out, 0, nsf);
740
503k
   for (i=0;i<3;i++)
741
377k
   {
742
377k
      int j;
743
377k
      int tmp1, tmp3;
744
377k
      int pp=pitch+1-i;
745
377k
      tmp1=nsf;
746
377k
      if (tmp1>pp)
747
313k
         tmp1=pp;
748
8.54M
      for (j=0;j<tmp1;j++)
749
8.17M
         exc_out[j]=MAC16_16(exc_out[j],gain[2-i],exc[j-pp]);
750
377k
      tmp3=nsf;
751
377k
      if (tmp3>pp+pitch)
752
286k
         tmp3=pp+pitch;
753
5.59M
      for (j=tmp1;j<tmp3;j++)
754
5.22M
         exc_out[j]=MAC16_16(exc_out[j],gain[2-i],exc[j-pp-pitch]);
755
377k
   }
756
   /*for (i=0;i<nsf;i++)
757
   exc[i]=PSHR32(exc32[i],13);*/
758
125k
}
pitch_unquant_3tap
Line
Count
Source
679
62.9k
{
680
62.9k
   int i;
681
62.9k
   int pitch;
682
62.9k
   int gain_index;
683
62.9k
   spx_word16_t gain[3];
684
62.9k
   const signed char *gain_cdbk;
685
62.9k
   int gain_cdbk_size;
686
62.9k
   const ltp_params *params;
687
688
62.9k
   params = (const ltp_params*) par;
689
62.9k
   gain_cdbk_size = 1<<params->gain_bits;
690
62.9k
   gain_cdbk = params->gain_cdbk + 4*gain_cdbk_size*cdbk_offset;
691
692
62.9k
   pitch = speex_bits_unpack_unsigned(bits, params->pitch_bits);
693
62.9k
   pitch += start;
694
62.9k
   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
62.9k
   gain[0] = 0.015625*gain_cdbk[gain_index*4]+.5;
702
62.9k
   gain[1] = 0.015625*gain_cdbk[gain_index*4+1]+.5;
703
62.9k
   gain[2] = 0.015625*gain_cdbk[gain_index*4+2]+.5;
704
62.9k
#endif
705
706
62.9k
   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
62.9k
   *pitch_val = pitch;
733
62.9k
   gain_val[0]=gain[0];
734
62.9k
   gain_val[1]=gain[1];
735
62.9k
   gain_val[2]=gain[2];
736
62.9k
   gain[0] = SHL16(gain[0],7);
737
62.9k
   gain[1] = SHL16(gain[1],7);
738
62.9k
   gain[2] = SHL16(gain[2],7);
739
62.9k
   SPEEX_MEMSET(exc_out, 0, nsf);
740
251k
   for (i=0;i<3;i++)
741
188k
   {
742
188k
      int j;
743
188k
      int tmp1, tmp3;
744
188k
      int pp=pitch+1-i;
745
188k
      tmp1=nsf;
746
188k
      if (tmp1>pp)
747
156k
         tmp1=pp;
748
4.27M
      for (j=0;j<tmp1;j++)
749
4.08M
         exc_out[j]=MAC16_16(exc_out[j],gain[2-i],exc[j-pp]);
750
188k
      tmp3=nsf;
751
188k
      if (tmp3>pp+pitch)
752
143k
         tmp3=pp+pitch;
753
2.79M
      for (j=tmp1;j<tmp3;j++)
754
2.61M
         exc_out[j]=MAC16_16(exc_out[j],gain[2-i],exc[j-pp-pitch]);
755
188k
   }
756
   /*for (i=0;i<nsf;i++)
757
   exc[i]=PSHR32(exc32[i],13);*/
758
62.9k
}
pitch_unquant_3tap
Line
Count
Source
679
62.9k
{
680
62.9k
   int i;
681
62.9k
   int pitch;
682
62.9k
   int gain_index;
683
62.9k
   spx_word16_t gain[3];
684
62.9k
   const signed char *gain_cdbk;
685
62.9k
   int gain_cdbk_size;
686
62.9k
   const ltp_params *params;
687
688
62.9k
   params = (const ltp_params*) par;
689
62.9k
   gain_cdbk_size = 1<<params->gain_bits;
690
62.9k
   gain_cdbk = params->gain_cdbk + 4*gain_cdbk_size*cdbk_offset;
691
692
62.9k
   pitch = speex_bits_unpack_unsigned(bits, params->pitch_bits);
693
62.9k
   pitch += start;
694
62.9k
   gain_index = speex_bits_unpack_unsigned(bits, params->gain_bits);
695
   /*printf ("decode pitch: %d %d\n", pitch, gain_index);*/
696
62.9k
#ifdef FIXED_POINT
697
62.9k
   gain[0] = ADD16(32,(spx_word16_t)gain_cdbk[gain_index*4]);
698
62.9k
   gain[1] = ADD16(32,(spx_word16_t)gain_cdbk[gain_index*4+1]);
699
62.9k
   gain[2] = ADD16(32,(spx_word16_t)gain_cdbk[gain_index*4+2]);
700
#else
701
   gain[0] = 0.015625*gain_cdbk[gain_index*4]+.5;
702
   gain[1] = 0.015625*gain_cdbk[gain_index*4+1]+.5;
703
   gain[2] = 0.015625*gain_cdbk[gain_index*4+2]+.5;
704
#endif
705
706
62.9k
   if (count_lost && pitch > subframe_offset)
707
0
   {
708
0
      spx_word16_t gain_sum;
709
0
      if (1) {
710
0
#ifdef FIXED_POINT
711
0
         spx_word16_t tmp = count_lost < 4 ? last_pitch_gain : SHR16(last_pitch_gain,1);
712
0
         if (tmp>62)
713
0
            tmp=62;
714
#else
715
         spx_word16_t tmp = count_lost < 4 ? last_pitch_gain : 0.5 * last_pitch_gain;
716
         if (tmp>.95)
717
            tmp=.95;
718
#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
62.9k
   *pitch_val = pitch;
733
62.9k
   gain_val[0]=gain[0];
734
62.9k
   gain_val[1]=gain[1];
735
62.9k
   gain_val[2]=gain[2];
736
62.9k
   gain[0] = SHL16(gain[0],7);
737
62.9k
   gain[1] = SHL16(gain[1],7);
738
62.9k
   gain[2] = SHL16(gain[2],7);
739
62.9k
   SPEEX_MEMSET(exc_out, 0, nsf);
740
251k
   for (i=0;i<3;i++)
741
188k
   {
742
188k
      int j;
743
188k
      int tmp1, tmp3;
744
188k
      int pp=pitch+1-i;
745
188k
      tmp1=nsf;
746
188k
      if (tmp1>pp)
747
156k
         tmp1=pp;
748
4.27M
      for (j=0;j<tmp1;j++)
749
4.08M
         exc_out[j]=MAC16_16(exc_out[j],gain[2-i],exc[j-pp]);
750
188k
      tmp3=nsf;
751
188k
      if (tmp3>pp+pitch)
752
143k
         tmp3=pp+pitch;
753
2.79M
      for (j=tmp1;j<tmp3;j++)
754
2.61M
         exc_out[j]=MAC16_16(exc_out[j],gain[2-i],exc[j-pp-pitch]);
755
188k
   }
756
   /*for (i=0;i<nsf;i++)
757
   exc[i]=PSHR32(exc32[i],13);*/
758
62.9k
}
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
63.0k
{
786
63.0k
   int i;
787
63.0k
   VARDECL(spx_word16_t *res);
788
63.0k
   ALLOC(res, nsf, spx_word16_t);
789
#ifdef FIXED_POINT
790
44.1k
   if (pitch_coef>63)
791
368
      pitch_coef=63;
792
#else
793
18.8k
   if (pitch_coef>.99)
794
140
      pitch_coef=.99;
795
#endif
796
1.99M
   for (i=0;i<nsf&&i<start;i++)
797
1.93M
   {
798
1.93M
      exc[i]=MULT16_16(SHL16(pitch_coef, 7),exc2[i-start]);
799
1.93M
   }
800
648k
   for (;i<nsf;i++)
801
585k
   {
802
585k
      exc[i]=MULT16_32_Q15(SHL16(pitch_coef, 9),exc[i-start]);
803
585k
   }
804
2.58M
   for (i=0;i<nsf;i++)
805
2.52M
      res[i] = EXTRACT16(PSHR32(exc[i], SIG_SHIFT-1));
806
63.0k
   syn_percep_zero16(res, ak, awk1, awk2, res, nsf, p, stack);
807
2.58M
   for (i=0;i<nsf;i++)
808
2.52M
      target[i]=EXTRACT16(SATURATE(SUB32(EXTEND32(target[i]),EXTEND32(res[i])),32700));
809
63.0k
   return start;
810
63.0k
}
forced_pitch_quant
Line
Count
Source
785
18.8k
{
786
18.8k
   int i;
787
18.8k
   VARDECL(spx_word16_t *res);
788
18.8k
   ALLOC(res, nsf, spx_word16_t);
789
#ifdef FIXED_POINT
790
   if (pitch_coef>63)
791
      pitch_coef=63;
792
#else
793
18.8k
   if (pitch_coef>.99)
794
140
      pitch_coef=.99;
795
18.8k
#endif
796
522k
   for (i=0;i<nsf&&i<start;i++)
797
503k
   {
798
503k
      exc[i]=MULT16_16(SHL16(pitch_coef, 7),exc2[i-start]);
799
503k
   }
800
270k
   for (;i<nsf;i++)
801
251k
   {
802
251k
      exc[i]=MULT16_32_Q15(SHL16(pitch_coef, 9),exc[i-start]);
803
251k
   }
804
773k
   for (i=0;i<nsf;i++)
805
754k
      res[i] = EXTRACT16(PSHR32(exc[i], SIG_SHIFT-1));
806
18.8k
   syn_percep_zero16(res, ak, awk1, awk2, res, nsf, p, stack);
807
773k
   for (i=0;i<nsf;i++)
808
754k
      target[i]=EXTRACT16(SATURATE(SUB32(EXTEND32(target[i]),EXTEND32(res[i])),32700));
809
18.8k
   return start;
810
18.8k
}
forced_pitch_quant
Line
Count
Source
785
44.1k
{
786
44.1k
   int i;
787
44.1k
   VARDECL(spx_word16_t *res);
788
44.1k
   ALLOC(res, nsf, spx_word16_t);
789
44.1k
#ifdef FIXED_POINT
790
44.1k
   if (pitch_coef>63)
791
368
      pitch_coef=63;
792
#else
793
   if (pitch_coef>.99)
794
      pitch_coef=.99;
795
#endif
796
1.47M
   for (i=0;i<nsf&&i<start;i++)
797
1.43M
   {
798
1.43M
      exc[i]=MULT16_16(SHL16(pitch_coef, 7),exc2[i-start]);
799
1.43M
   }
800
378k
   for (;i<nsf;i++)
801
334k
   {
802
334k
      exc[i]=MULT16_32_Q15(SHL16(pitch_coef, 9),exc[i-start]);
803
334k
   }
804
1.81M
   for (i=0;i<nsf;i++)
805
1.76M
      res[i] = EXTRACT16(PSHR32(exc[i], SIG_SHIFT-1));
806
44.1k
   syn_percep_zero16(res, ak, awk1, awk2, res, nsf, p, stack);
807
1.81M
   for (i=0;i<nsf;i++)
808
1.76M
      target[i]=EXTRACT16(SATURATE(SUB32(EXTEND32(target[i]),EXTEND32(res[i])),32700));
809
44.1k
   return start;
810
44.1k
}
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
67.3k
{
833
67.3k
   int i;
834
#ifdef FIXED_POINT
835
33.6k
   if (pitch_coef>63)
836
4.51k
      pitch_coef=63;
837
#else
838
33.6k
   if (pitch_coef>.99)
839
4.51k
      pitch_coef=.99;
840
#endif
841
2.76M
   for (i=0;i<nsf;i++)
842
2.69M
   {
843
2.69M
      exc_out[i]=MULT16_16(exc[i-start],SHL16(pitch_coef,7));
844
2.69M
      exc[i] = EXTRACT16(PSHR32(exc_out[i],13));
845
2.69M
   }
846
67.3k
   *pitch_val = start;
847
67.3k
   gain_val[0]=gain_val[2]=0;
848
67.3k
   gain_val[1] = pitch_coef;
849
67.3k
}
forced_pitch_unquant
Line
Count
Source
832
33.6k
{
833
33.6k
   int i;
834
#ifdef FIXED_POINT
835
   if (pitch_coef>63)
836
      pitch_coef=63;
837
#else
838
33.6k
   if (pitch_coef>.99)
839
4.51k
      pitch_coef=.99;
840
33.6k
#endif
841
1.38M
   for (i=0;i<nsf;i++)
842
1.34M
   {
843
1.34M
      exc_out[i]=MULT16_16(exc[i-start],SHL16(pitch_coef,7));
844
1.34M
      exc[i] = EXTRACT16(PSHR32(exc_out[i],13));
845
1.34M
   }
846
33.6k
   *pitch_val = start;
847
33.6k
   gain_val[0]=gain_val[2]=0;
848
33.6k
   gain_val[1] = pitch_coef;
849
33.6k
}
forced_pitch_unquant
Line
Count
Source
832
33.6k
{
833
33.6k
   int i;
834
33.6k
#ifdef FIXED_POINT
835
33.6k
   if (pitch_coef>63)
836
4.51k
      pitch_coef=63;
837
#else
838
   if (pitch_coef>.99)
839
      pitch_coef=.99;
840
#endif
841
1.38M
   for (i=0;i<nsf;i++)
842
1.34M
   {
843
1.34M
      exc_out[i]=MULT16_16(exc[i-start],SHL16(pitch_coef,7));
844
1.34M
      exc[i] = EXTRACT16(PSHR32(exc_out[i],13));
845
1.34M
   }
846
33.6k
   *pitch_val = start;
847
33.6k
   gain_val[0]=gain_val[2]=0;
848
33.6k
   gain_val[1] = pitch_coef;
849
33.6k
}
850
#endif /* DISABLE_DECODER */