107577d0e3e6102ee8bf7a4a3bccd488ef23b9d7
[speexdsp.git] / libspeex / ltp.c
1 /* Copyright (C) 2002 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 #include <math.h>
34 #include "ltp.h"
35 #include "stack_alloc.h"
36 #include "filters.h"
37 #include "speex_bits.h"
38 #include "math_approx.h"
39
40 #include <stdio.h>
41
42 #ifdef _USE_SSE
43 #include "ltp_sse.h"
44 #else
45 static spx_word32_t inner_prod(spx_word16_t *x, spx_word16_t *y, int len)
46 {
47    int i;
48    spx_word32_t sum=0;
49    for (i=0;i<len;i+=4)
50    {
51       spx_word32_t part=0;
52       part = MAC16_16(part,x[i],y[i]);
53       part = MAC16_16(part,x[i+1],y[i+1]);
54       part = MAC16_16(part,x[i+2],y[i+2]);
55       part = MAC16_16(part,x[i+3],y[i+3]);
56       sum = ADD32(sum,SHR(part,6));
57    }
58    return sum;
59 }
60 #endif
61
62 void open_loop_nbest_pitch(spx_sig_t *sw, int start, int end, int len, int *pitch, spx_word16_t *gain, int N, char *stack)
63 {
64    int i,j,k;
65    spx_word32_t *best_score;
66    spx_word32_t e0;
67    spx_word32_t *corr, *energy;
68    spx_word32_t *score;
69    spx_word16_t *swn;
70
71    best_score = PUSH(stack,N, spx_word32_t);
72    corr = PUSH(stack,end-start+1, spx_word32_t);
73    energy = PUSH(stack,end-start+2, spx_word32_t);
74    score = PUSH(stack,end-start+1, spx_word32_t);
75
76 #ifdef FIXED_POINT
77    swn = PUSH(stack, end+len, spx_word16_t);
78    normalize16(sw-end, swn, 16384, end+len);
79    swn += end;
80 #else
81    swn = sw;
82 #endif
83
84    for (i=0;i<N;i++)
85    {
86         best_score[i]=-1;
87         gain[i]=0;
88         pitch[i]=start;
89    }
90
91
92    energy[0]=inner_prod(swn-start, swn-start, len);
93    e0=inner_prod(swn, swn, len);
94    for (i=start;i<=end;i++)
95    {
96       /* Update energy for next pitch*/
97       energy[i-start+1] = energy[i-start] + SHR(MULT16_16(swn[-i-1],swn[-i-1]),6) - SHR(MULT16_16(swn[-i+len-1],swn[-i+len-1]),6);
98    }
99    for (i=start;i<=end;i++)
100    {
101       corr[i-start]=0;
102       score[i-start]=0;
103    }
104
105    for (i=start;i<=end;i++)
106    {
107       /* Compute correlation*/
108       corr[i-start]=inner_prod(swn, swn-i, len);
109    }
110
111 #ifdef FIXED_POINT
112    {
113       spx_word16_t *corr16;
114       spx_word16_t *ener16;
115       corr16 = PUSH(stack, end-start+1, spx_word16_t);
116       ener16 = PUSH(stack, end-start+1, spx_word16_t);
117       normalize16(corr, corr16, 16384, end-start+1);
118       normalize16(energy, ener16, 16384, end-start+1);
119
120       for (i=start;i<=end;i++)
121       {
122          spx_word16_t g;
123          spx_word32_t tmp;
124          tmp = corr16[i-start];
125          if (SHR(corr16[i-start],4)>ener16[i-start])
126             tmp = SHL((spx_word32_t)ener16[i-start],14);
127          else if (-SHR(corr16[i-start],4)>ener16[i-start])
128             tmp = -SHL((spx_word32_t)ener16[i-start],14);
129          else
130             tmp = SHL(tmp,10);
131          g = DIV32_16(tmp, 8+ener16[i-start]);
132          score[i-start] = MULT16_16(corr16[i-start],g);
133       }
134    }
135 #else
136    for (i=start;i<=end;i++)
137    {
138       float g = corr[i-start]/(1+energy[i-start]);
139       if (g>16)
140          g = 16;
141       else if (g<-16)
142          g = -16;
143       score[i-start] = g*corr[i-start];
144    }
145 #endif
146
147    /* Extract best scores */
148    for (i=start;i<=end;i++)
149    {
150       if (score[i-start]>best_score[N-1])
151       {
152          for (j=0;j<N;j++)
153          {
154             if (score[i-start] > best_score[j])
155             {
156                for (k=N-1;k>j;k--)
157                {
158                   best_score[k]=best_score[k-1];
159                   pitch[k]=pitch[k-1];
160                }
161                best_score[j]=score[i-start];
162                pitch[j]=i;
163                break;
164             }
165          }
166       }
167    }
168
169    /* Compute open-loop gain */
170    for (j=0;j<N;j++)
171    {
172       spx_word16_t g;
173       i=pitch[j];
174       g = DIV32(corr[i-start], 10+SHR(MULT16_16(spx_sqrt(e0),spx_sqrt(energy[i-start])),6));
175       /* FIXME: g = max(g,corr/energy) */
176       if (g<0)
177          g = 0;
178       gain[j]=g;
179    }
180 }
181
182
183 /** Finds the best quantized 3-tap pitch predictor by analysis by synthesis */
184 static spx_word64_t pitch_gain_search_3tap(
185 spx_sig_t target[],                 /* Target vector */
186 spx_coef_t ak[],                     /* LPCs for this subframe */
187 spx_coef_t awk1[],                   /* Weighted LPCs #1 for this subframe */
188 spx_coef_t awk2[],                   /* Weighted LPCs #2 for this subframe */
189 spx_sig_t exc[],                    /* Excitation */
190 void *par,
191 int   pitch,                    /* Pitch value */
192 int   p,                        /* Number of LPC coeffs */
193 int   nsf,                      /* Number of samples in subframe */
194 SpeexBits *bits,
195 char *stack,
196 spx_sig_t *exc2,
197 spx_sig_t *r,
198 int  *cdbk_index,
199 int cdbk_offset
200 )
201 {
202    int i,j;
203    spx_sig_t *tmp, *tmp2;
204    spx_sig_t *x[3];
205    spx_sig_t *e[3];
206    spx_word32_t corr[3];
207    spx_word32_t A[3][3];
208    int   gain_cdbk_size;
209    signed char *gain_cdbk;
210    spx_word16_t gain[3];
211    spx_word64_t err;
212
213    ltp_params *params;
214    params = (ltp_params*) par;
215    gain_cdbk_size = 1<<params->gain_bits;
216    gain_cdbk = params->gain_cdbk + 3*gain_cdbk_size*cdbk_offset;
217    tmp = PUSH(stack, 3*nsf, spx_sig_t);
218    tmp2 = PUSH(stack, 3*nsf, spx_sig_t);
219
220    x[0]=tmp;
221    x[1]=tmp+nsf;
222    x[2]=tmp+2*nsf;
223
224    e[0]=tmp2;
225    e[1]=tmp2+nsf;
226    e[2]=tmp2+2*nsf;
227    for (i=2;i>=0;i--)
228    {
229       int pp=pitch+1-i;
230       for (j=0;j<nsf;j++)
231       {
232          if (j-pp<0)
233             e[i][j]=exc2[j-pp];
234          else if (j-pp-pitch<0)
235             e[i][j]=exc2[j-pp-pitch];
236          else
237             e[i][j]=0;
238       }
239
240       if (i==2)
241          syn_percep_zero(e[i], ak, awk1, awk2, x[i], nsf, p, stack);
242       else {
243          for (j=0;j<nsf-1;j++)
244             x[i][j+1]=x[i+1][j];
245          x[i][0]=0;
246          for (j=0;j<nsf;j++)
247          {
248             /* FIXME: Check for overflows */
249             /*x[i][j]+=e[i][0]*r[j]/SIG_SCALING;*/
250             x[i][j]+=SHL(MULT16_32_Q15(r[j], e[i][0]),1);
251             /*printf ("%d\n", (int)r[j]);*/
252          }
253       }
254    }
255
256 #ifdef FIXED_POINT
257    {
258       /* If using fixed-point, we need to normalize the signals first */
259       spx_word16_t *y[3];
260       spx_word16_t *t;
261
262       spx_sig_t max_val=1;
263       int sig_shift;
264       
265       y[0] = PUSH(stack, nsf, spx_word16_t);
266       y[1] = PUSH(stack, nsf, spx_word16_t);
267       y[2] = PUSH(stack, nsf, spx_word16_t);
268       t = PUSH(stack, nsf, spx_word16_t);
269       for (j=0;j<3;j++)
270       {
271          for (i=0;i<nsf;i++)
272          {
273             spx_sig_t tmp = x[j][i];
274             if (tmp<0)
275                tmp = -tmp;
276             if (tmp > max_val)
277                max_val = tmp;
278          }
279       }
280       for (i=0;i<nsf;i++)
281       {
282          spx_sig_t tmp = target[i];
283          if (tmp<0)
284             tmp = -tmp;
285          if (tmp > max_val)
286             max_val = tmp;
287       }
288
289       sig_shift=0;
290       while (max_val>16384)
291       {
292          sig_shift++;
293          max_val >>= 1;
294       }
295
296       for (j=0;j<3;j++)
297       {
298          for (i=0;i<nsf;i++)
299          {
300             y[j][i] = SHR(x[j][i],sig_shift);
301          }
302       }     
303       for (i=0;i<nsf;i++)
304       {
305          t[i] = SHR(target[i],sig_shift);
306       }
307
308       for (i=0;i<3;i++)
309          corr[i]=inner_prod(y[i],t,nsf);
310       
311       for (i=0;i<3;i++)
312          for (j=0;j<=i;j++)
313             A[i][j]=A[j][i]=inner_prod(y[i],y[j],nsf);
314    }
315 #else
316    {
317       for (i=0;i<3;i++)
318          corr[i]=inner_prod(x[i],target,nsf);
319       
320       for (i=0;i<3;i++)
321          for (j=0;j<=i;j++)
322             A[i][j]=A[j][i]=inner_prod(x[i],x[j],nsf);
323    }
324 #endif
325
326    {
327       spx_word32_t C[9];
328       signed char *ptr=gain_cdbk;
329       int best_cdbk=0;
330       spx_word32_t best_sum=0;
331       C[0]=corr[2];
332       C[1]=corr[1];
333       C[2]=corr[0];
334       C[3]=A[1][2];
335       C[4]=A[0][1];
336       C[5]=A[0][2];
337       C[6]=A[2][2];
338       C[7]=A[1][1];
339       C[8]=A[0][0];
340 #ifndef FIXED_POINT
341       C[6]*=.5;
342       C[7]*=.5;
343       C[8]*=.5;
344 #endif
345       for (i=0;i<gain_cdbk_size;i++)
346       {
347          spx_word32_t sum=0;
348          spx_word16_t g0,g1,g2;
349          ptr = gain_cdbk+3*i;
350          g0=ptr[0]+32;
351          g1=ptr[1]+32;
352          g2=ptr[2]+32;
353
354          /* FIXME: check for possible overflows on sum and MULT16_32 */
355          sum += MULT16_32_Q14(MULT16_16_16(g0,64),C[0]);
356          sum += MULT16_32_Q14(MULT16_16_16(g1,64),C[1]);
357          sum += MULT16_32_Q14(MULT16_16_16(g2,64),C[2]);
358          sum -= MULT16_32_Q14(MULT16_16_16(g0,g1),C[3]);
359          sum -= MULT16_32_Q14(MULT16_16_16(g2,g1),C[4]);
360          sum -= MULT16_32_Q14(MULT16_16_16(g2,g0),C[5]);
361          sum -= MULT16_32_Q15(MULT16_16_16(g0,g0),C[6]);
362          sum -= MULT16_32_Q15(MULT16_16_16(g1,g1),C[7]);
363          sum -= MULT16_32_Q15(MULT16_16_16(g2,g2),C[8]);
364
365          /* We could force "safe" pitch values to handle packet loss better */
366
367          if (sum>best_sum || i==0)
368          {
369             best_sum=sum;
370             best_cdbk=i;
371          }
372       }
373 #ifdef FIXED_POINT
374       gain[0] = 32+(spx_word16_t)gain_cdbk[best_cdbk*3];
375       gain[1] = 32+(spx_word16_t)gain_cdbk[best_cdbk*3+1];
376       gain[2] = 32+(spx_word16_t)gain_cdbk[best_cdbk*3+2];
377 #else
378       gain[0] = 0.015625*gain_cdbk[best_cdbk*3]  + .5;
379       gain[1] = 0.015625*gain_cdbk[best_cdbk*3+1]+ .5;
380       gain[2] = 0.015625*gain_cdbk[best_cdbk*3+2]+ .5;
381 #endif
382       *cdbk_index=best_cdbk;
383    }
384
385 #ifdef FIXED_POINT
386    for (i=0;i<nsf;i++)
387      exc[i]=SHL(MULT16_32_Q15(SHL(gain[0],7),e[2][i])+MULT16_32_Q15(SHL(gain[1],7),e[1][i])+MULT16_32_Q15(SHL(gain[2],7),e[0][i]),2);
388    
389    err=0;
390    for (i=0;i<nsf;i++)
391    {
392       spx_sig_t perr=target[i]-SHL((MULT16_32_Q15(SHL(gain[0],7),x[2][i])+MULT16_32_Q15(SHL(gain[1],7),x[1][i])+MULT16_32_Q15(SHL(gain[2],7),x[0][i])),2);
393       spx_word16_t perr2 = PSHR(perr,15);
394       err = ADD64(err,MULT16_16(perr2,perr2));
395       
396    }
397 #else
398    for (i=0;i<nsf;i++)
399       exc[i]=gain[0]*e[2][i]+gain[1]*e[1][i]+gain[2]*e[0][i];
400    
401    err=0;
402    for (i=0;i<nsf;i++)
403       err+=(target[i]-gain[2]*x[0][i]-gain[1]*x[1][i]-gain[0]*x[2][i])
404       * (target[i]-gain[2]*x[0][i]-gain[1]*x[1][i]-gain[0]*x[2][i]);
405 #endif
406
407    return err;
408 }
409
410
411 /** Finds the best quantized 3-tap pitch predictor by analysis by synthesis */
412 int pitch_search_3tap(
413 spx_sig_t target[],                 /* Target vector */
414 spx_sig_t *sw,
415 spx_coef_t ak[],                     /* LPCs for this subframe */
416 spx_coef_t awk1[],                   /* Weighted LPCs #1 for this subframe */
417 spx_coef_t awk2[],                   /* Weighted LPCs #2 for this subframe */
418 spx_sig_t exc[],                    /* Excitation */
419 void *par,
420 int   start,                    /* Smallest pitch value allowed */
421 int   end,                      /* Largest pitch value allowed */
422 spx_word16_t pitch_coef,               /* Voicing (pitch) coefficient */
423 int   p,                        /* Number of LPC coeffs */
424 int   nsf,                      /* Number of samples in subframe */
425 SpeexBits *bits,
426 char *stack,
427 spx_sig_t *exc2,
428 spx_sig_t *r,
429 int complexity,
430 int cdbk_offset
431 )
432 {
433    int i,j;
434    int cdbk_index, pitch=0, best_gain_index=0;
435    spx_sig_t *best_exc;
436    int best_pitch=0;
437    spx_word64_t err, best_err=-1;
438    int N;
439    ltp_params *params;
440    int *nbest;
441    spx_word16_t *gains;
442
443    N=complexity;
444    if (N>10)
445       N=10;
446
447    nbest=PUSH(stack, N, int);
448    gains = PUSH(stack, N, spx_word16_t);
449    params = (ltp_params*) par;
450
451    if (N==0 || end<start)
452    {
453       speex_bits_pack(bits, 0, params->pitch_bits);
454       speex_bits_pack(bits, 0, params->gain_bits);
455       for (i=0;i<nsf;i++)
456          exc[i]=0;
457       return start;
458    }
459    
460    best_exc=PUSH(stack,nsf, spx_sig_t);
461    
462    if (N>end-start+1)
463       N=end-start+1;
464    open_loop_nbest_pitch(sw, start, end, nsf, nbest, gains, N, stack);
465    for (i=0;i<N;i++)
466    {
467       pitch=nbest[i];
468       for (j=0;j<nsf;j++)
469          exc[j]=0;
470       err=pitch_gain_search_3tap(target, ak, awk1, awk2, exc, par, pitch, p, nsf,
471                                  bits, stack, exc2, r, &cdbk_index, cdbk_offset);
472       if (err<best_err || best_err<0)
473       {
474          for (j=0;j<nsf;j++)
475             best_exc[j]=exc[j];
476          best_err=err;
477          best_pitch=pitch;
478          best_gain_index=cdbk_index;
479       }
480    }
481    
482    /*printf ("pitch: %d %d\n", best_pitch, best_gain_index);*/
483    speex_bits_pack(bits, best_pitch-start, params->pitch_bits);
484    speex_bits_pack(bits, best_gain_index, params->gain_bits);
485    /*printf ("encode pitch: %d %d\n", best_pitch, best_gain_index);*/
486    for (i=0;i<nsf;i++)
487       exc[i]=best_exc[i];
488
489    return pitch;
490 }
491
492 void pitch_unquant_3tap(
493 spx_sig_t exc[],                    /* Excitation */
494 int   start,                    /* Smallest pitch value allowed */
495 int   end,                      /* Largest pitch value allowed */
496 spx_word16_t pitch_coef,               /* Voicing (pitch) coefficient */
497 void *par,
498 int   nsf,                      /* Number of samples in subframe */
499 int *pitch_val,
500 spx_word16_t *gain_val,
501 SpeexBits *bits,
502 char *stack,
503 int count_lost,
504 int subframe_offset,
505 spx_word16_t last_pitch_gain,
506 int cdbk_offset
507 )
508 {
509    int i;
510    int pitch;
511    int gain_index;
512    float gain[3];
513    signed char *gain_cdbk;
514    int gain_cdbk_size;
515    ltp_params *params;
516 #ifdef FIXED_POINT
517    spx_word16_t sgain[3];
518 #endif
519    params = (ltp_params*) par;
520    gain_cdbk_size = 1<<params->gain_bits;
521    gain_cdbk = params->gain_cdbk + 3*gain_cdbk_size*cdbk_offset;
522
523    pitch = speex_bits_unpack_unsigned(bits, params->pitch_bits);
524    pitch += start;
525    gain_index = speex_bits_unpack_unsigned(bits, params->gain_bits);
526    /*printf ("decode pitch: %d %d\n", pitch, gain_index);*/
527 #ifdef FIXED_POINT
528    sgain[0] = 32+(spx_word16_t)gain_cdbk[gain_index*3];
529    sgain[1] = 32+(spx_word16_t)gain_cdbk[gain_index*3+1];
530    sgain[2] = 32+(spx_word16_t)gain_cdbk[gain_index*3+2];
531 #else
532    gain[0] = 0.015625*gain_cdbk[gain_index*3]+.5;
533    gain[1] = 0.015625*gain_cdbk[gain_index*3+1]+.5;
534    gain[2] = 0.015625*gain_cdbk[gain_index*3+2]+.5;
535 #endif
536
537    if (count_lost && pitch > subframe_offset)
538    {
539       float gain_sum;
540 #ifdef FIXED_POINT
541       gain[0] = 0.015625*sgain[0];
542       gain[1] = 0.015625*sgain[1];
543       gain[2] = 0.015625*sgain[2];
544 #endif
545       if (1) {
546          float tmp = count_lost < 4 ? GAIN_SCALING_1*last_pitch_gain : 0.4 * GAIN_SCALING_1 * last_pitch_gain;
547          if (tmp>.95)
548             tmp=.95;
549          gain_sum = fabs(gain[1]);
550          if (gain[0]>0)
551             gain_sum += gain[0];
552          else
553             gain_sum -= .5*gain[0];
554          if (gain[2]>0)
555             gain_sum += gain[2];
556          else
557             gain_sum -= .5*gain[2];
558          if (gain_sum > tmp) {
559             float fact = tmp/gain_sum;
560             for (i=0;i<3;i++)
561                gain[i]*=fact;
562
563          }
564
565       }
566
567       if (0) {
568       gain_sum = fabs(gain[0])+fabs(gain[1])+fabs(gain[2]);
569          if (gain_sum>.95) {
570          float fact = .95/gain_sum;
571          for (i=0;i<3;i++)
572             gain[i]*=fact;
573       }
574    }
575    }
576
577    *pitch_val = pitch;
578    gain_val[0]=sgain[0];
579    gain_val[1]=sgain[1];
580    gain_val[2]=sgain[2];
581
582    {
583       spx_sig_t *e[3];
584       spx_sig_t *tmp2;
585       tmp2=PUSH(stack, 3*nsf, spx_sig_t);
586       e[0]=tmp2;
587       e[1]=tmp2+nsf;
588       e[2]=tmp2+2*nsf;
589       
590       for (i=0;i<3;i++)
591       {
592          int j;
593          int pp=pitch+1-i;
594 #if 0
595          for (j=0;j<nsf;j++)
596          {
597             if (j-pp<0)
598                e[i][j]=exc[j-pp];
599             else if (j-pp-pitch<0)
600                e[i][j]=exc[j-pp-pitch];
601             else
602                e[i][j]=0;
603          }
604 #else
605          {
606             int tmp1, tmp3;
607             tmp1=nsf;
608             if (tmp1>pp)
609                tmp1=pp;
610             for (j=0;j<tmp1;j++)
611                e[i][j]=exc[j-pp];
612             tmp3=nsf;
613             if (tmp3>pp+pitch)
614                tmp3=pp+pitch;
615             for (j=tmp1;j<tmp3;j++)
616                e[i][j]=exc[j-pp-pitch];
617             for (j=tmp3;j<nsf;j++)
618                e[i][j]=0;
619          }
620 #endif
621       }
622
623 #ifdef FIXED_POINT
624       {
625          for (i=0;i<nsf;i++)
626             exc[i]=SHL(MULT16_32_Q15(SHL(sgain[0],7),e[2][i])+MULT16_32_Q15(SHL(sgain[1],7),e[1][i])+MULT16_32_Q15(SHL(sgain[2],7),e[0][i]),2);
627       }
628 #else
629       for (i=0;i<nsf;i++)
630          exc[i]=gain[0]*e[2][i]+gain[1]*e[1][i]+gain[2]*e[0][i];
631 #endif
632    }
633 }
634
635
636 /** Forced pitch delay and gain */
637 int forced_pitch_quant(
638 spx_sig_t target[],                 /* Target vector */
639 spx_sig_t *sw,
640 spx_coef_t ak[],                     /* LPCs for this subframe */
641 spx_coef_t awk1[],                   /* Weighted LPCs #1 for this subframe */
642 spx_coef_t awk2[],                   /* Weighted LPCs #2 for this subframe */
643 spx_sig_t exc[],                    /* Excitation */
644 void *par,
645 int   start,                    /* Smallest pitch value allowed */
646 int   end,                      /* Largest pitch value allowed */
647 spx_word16_t pitch_coef,               /* Voicing (pitch) coefficient */
648 int   p,                        /* Number of LPC coeffs */
649 int   nsf,                      /* Number of samples in subframe */
650 SpeexBits *bits,
651 char *stack,
652 spx_sig_t *exc2,
653 spx_sig_t *r,
654 int complexity,
655 int cdbk_offset
656 )
657 {
658    int i;
659    float coef = GAIN_SCALING_1*pitch_coef;
660    if (coef>.99)
661       coef=.99;
662    for (i=0;i<nsf;i++)
663    {
664       exc[i]=exc[i-start]*coef;
665    }
666    return start;
667 }
668
669 /** Unquantize forced pitch delay and gain */
670 void forced_pitch_unquant(
671 spx_sig_t exc[],                    /* Excitation */
672 int   start,                    /* Smallest pitch value allowed */
673 int   end,                      /* Largest pitch value allowed */
674 spx_word16_t pitch_coef,               /* Voicing (pitch) coefficient */
675 void *par,
676 int   nsf,                      /* Number of samples in subframe */
677 int *pitch_val,
678 spx_word16_t *gain_val,
679 SpeexBits *bits,
680 char *stack,
681 int count_lost,
682 int subframe_offset,
683 spx_word16_t last_pitch_gain,
684 int cdbk_offset
685 )
686 {
687    int i;
688    float coef = GAIN_SCALING_1*pitch_coef;
689    if (coef>.99)
690       coef=.99;
691    for (i=0;i<nsf;i++)
692    {
693       exc[i]=exc[i-start]*coef;
694    }
695    *pitch_val = start;
696    gain_val[0]=gain_val[2]=0;
697    gain_val[1] = pitch_coef;
698 }