...
[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             x[i][j]=ADD32(x[i][j],SHL(MULT16_32_Q15(r[j], e[i][0]),1));
249          }
250       }
251    }
252
253 #ifdef FIXED_POINT
254    {
255       /* If using fixed-point, we need to normalize the signals first */
256       spx_word16_t *y[3];
257       spx_word16_t *t;
258
259       spx_sig_t max_val=1;
260       int sig_shift;
261       
262       y[0] = PUSH(stack, nsf, spx_word16_t);
263       y[1] = PUSH(stack, nsf, spx_word16_t);
264       y[2] = PUSH(stack, nsf, spx_word16_t);
265       t = PUSH(stack, nsf, spx_word16_t);
266       for (j=0;j<3;j++)
267       {
268          for (i=0;i<nsf;i++)
269          {
270             spx_sig_t tmp = x[j][i];
271             if (tmp<0)
272                tmp = -tmp;
273             if (tmp > max_val)
274                max_val = tmp;
275          }
276       }
277       for (i=0;i<nsf;i++)
278       {
279          spx_sig_t tmp = target[i];
280          if (tmp<0)
281             tmp = -tmp;
282          if (tmp > max_val)
283             max_val = tmp;
284       }
285
286       sig_shift=0;
287       while (max_val>16384)
288       {
289          sig_shift++;
290          max_val >>= 1;
291       }
292
293       for (j=0;j<3;j++)
294       {
295          for (i=0;i<nsf;i++)
296          {
297             y[j][i] = SHR(x[j][i],sig_shift);
298          }
299       }     
300       for (i=0;i<nsf;i++)
301       {
302          t[i] = SHR(target[i],sig_shift);
303       }
304
305       for (i=0;i<3;i++)
306          corr[i]=inner_prod(y[i],t,nsf);
307       
308       for (i=0;i<3;i++)
309          for (j=0;j<=i;j++)
310             A[i][j]=A[j][i]=inner_prod(y[i],y[j],nsf);
311    }
312 #else
313    {
314       for (i=0;i<3;i++)
315          corr[i]=inner_prod(x[i],target,nsf);
316       
317       for (i=0;i<3;i++)
318          for (j=0;j<=i;j++)
319             A[i][j]=A[j][i]=inner_prod(x[i],x[j],nsf);
320    }
321 #endif
322
323    {
324       spx_word32_t C[9];
325       signed char *ptr=gain_cdbk;
326       int best_cdbk=0;
327       spx_word32_t best_sum=0;
328       C[0]=corr[2];
329       C[1]=corr[1];
330       C[2]=corr[0];
331       C[3]=A[1][2];
332       C[4]=A[0][1];
333       C[5]=A[0][2];
334       C[6]=A[2][2];
335       C[7]=A[1][1];
336       C[8]=A[0][0];
337 #ifndef FIXED_POINT
338       C[6]*=.5;
339       C[7]*=.5;
340       C[8]*=.5;
341 #endif
342       for (i=0;i<gain_cdbk_size;i++)
343       {
344          spx_word32_t sum=0;
345          spx_word16_t g0,g1,g2;
346          ptr = gain_cdbk+3*i;
347          g0=ptr[0]+32;
348          g1=ptr[1]+32;
349          g2=ptr[2]+32;
350
351          sum = ADD32(sum,MULT16_32_Q14(MULT16_16_16(g0,64),C[0]));
352          sum = ADD32(sum,MULT16_32_Q14(MULT16_16_16(g1,64),C[1]));
353          sum = ADD32(sum,MULT16_32_Q14(MULT16_16_16(g2,64),C[2]));
354          sum = SUB32(sum,MULT16_32_Q14(MULT16_16_16(g0,g1),C[3]));
355          sum = SUB32(sum,MULT16_32_Q14(MULT16_16_16(g2,g1),C[4]));
356          sum = SUB32(sum,MULT16_32_Q14(MULT16_16_16(g2,g0),C[5]));
357          sum = SUB32(sum,MULT16_32_Q15(MULT16_16_16(g0,g0),C[6]));
358          sum = SUB32(sum,MULT16_32_Q15(MULT16_16_16(g1,g1),C[7]));
359          sum = SUB32(sum,MULT16_32_Q15(MULT16_16_16(g2,g2),C[8]));
360
361          /* We could force "safe" pitch values to handle packet loss better */
362
363          if (sum>best_sum || i==0)
364          {
365             best_sum=sum;
366             best_cdbk=i;
367          }
368       }
369 #ifdef FIXED_POINT
370       gain[0] = 32+(spx_word16_t)gain_cdbk[best_cdbk*3];
371       gain[1] = 32+(spx_word16_t)gain_cdbk[best_cdbk*3+1];
372       gain[2] = 32+(spx_word16_t)gain_cdbk[best_cdbk*3+2];
373 #else
374       gain[0] = 0.015625*gain_cdbk[best_cdbk*3]  + .5;
375       gain[1] = 0.015625*gain_cdbk[best_cdbk*3+1]+ .5;
376       gain[2] = 0.015625*gain_cdbk[best_cdbk*3+2]+ .5;
377 #endif
378       *cdbk_index=best_cdbk;
379    }
380
381 #ifdef FIXED_POINT
382    for (i=0;i<nsf;i++)
383      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);
384    
385    err=0;
386    for (i=0;i<nsf;i++)
387    {
388       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);
389       spx_word16_t perr2 = PSHR(perr,15);
390       err = ADD64(err,MULT16_16(perr2,perr2));
391       
392    }
393 #else
394    for (i=0;i<nsf;i++)
395       exc[i]=gain[0]*e[2][i]+gain[1]*e[1][i]+gain[2]*e[0][i];
396    
397    err=0;
398    for (i=0;i<nsf;i++)
399       err+=(target[i]-gain[2]*x[0][i]-gain[1]*x[1][i]-gain[0]*x[2][i])
400       * (target[i]-gain[2]*x[0][i]-gain[1]*x[1][i]-gain[0]*x[2][i]);
401 #endif
402
403    return err;
404 }
405
406
407 /** Finds the best quantized 3-tap pitch predictor by analysis by synthesis */
408 int pitch_search_3tap(
409 spx_sig_t target[],                 /* Target vector */
410 spx_sig_t *sw,
411 spx_coef_t ak[],                     /* LPCs for this subframe */
412 spx_coef_t awk1[],                   /* Weighted LPCs #1 for this subframe */
413 spx_coef_t awk2[],                   /* Weighted LPCs #2 for this subframe */
414 spx_sig_t exc[],                    /* Excitation */
415 void *par,
416 int   start,                    /* Smallest pitch value allowed */
417 int   end,                      /* Largest pitch value allowed */
418 spx_word16_t pitch_coef,               /* Voicing (pitch) coefficient */
419 int   p,                        /* Number of LPC coeffs */
420 int   nsf,                      /* Number of samples in subframe */
421 SpeexBits *bits,
422 char *stack,
423 spx_sig_t *exc2,
424 spx_sig_t *r,
425 int complexity,
426 int cdbk_offset
427 )
428 {
429    int i,j;
430    int cdbk_index, pitch=0, best_gain_index=0;
431    spx_sig_t *best_exc;
432    int best_pitch=0;
433    spx_word64_t err, best_err=-1;
434    int N;
435    ltp_params *params;
436    int *nbest;
437    spx_word16_t *gains;
438
439    N=complexity;
440    if (N>10)
441       N=10;
442
443    nbest=PUSH(stack, N, int);
444    gains = PUSH(stack, N, spx_word16_t);
445    params = (ltp_params*) par;
446
447    if (N==0 || end<start)
448    {
449       speex_bits_pack(bits, 0, params->pitch_bits);
450       speex_bits_pack(bits, 0, params->gain_bits);
451       for (i=0;i<nsf;i++)
452          exc[i]=0;
453       return start;
454    }
455    
456    best_exc=PUSH(stack,nsf, spx_sig_t);
457    
458    if (N>end-start+1)
459       N=end-start+1;
460    open_loop_nbest_pitch(sw, start, end, nsf, nbest, gains, N, stack);
461    for (i=0;i<N;i++)
462    {
463       pitch=nbest[i];
464       for (j=0;j<nsf;j++)
465          exc[j]=0;
466       err=pitch_gain_search_3tap(target, ak, awk1, awk2, exc, par, pitch, p, nsf,
467                                  bits, stack, exc2, r, &cdbk_index, cdbk_offset);
468       if (err<best_err || best_err<0)
469       {
470          for (j=0;j<nsf;j++)
471             best_exc[j]=exc[j];
472          best_err=err;
473          best_pitch=pitch;
474          best_gain_index=cdbk_index;
475       }
476    }
477    
478    /*printf ("pitch: %d %d\n", best_pitch, best_gain_index);*/
479    speex_bits_pack(bits, best_pitch-start, params->pitch_bits);
480    speex_bits_pack(bits, best_gain_index, params->gain_bits);
481    /*printf ("encode pitch: %d %d\n", best_pitch, best_gain_index);*/
482    for (i=0;i<nsf;i++)
483       exc[i]=best_exc[i];
484
485    return pitch;
486 }
487
488 void pitch_unquant_3tap(
489 spx_sig_t exc[],                    /* Excitation */
490 int   start,                    /* Smallest pitch value allowed */
491 int   end,                      /* Largest pitch value allowed */
492 spx_word16_t pitch_coef,               /* Voicing (pitch) coefficient */
493 void *par,
494 int   nsf,                      /* Number of samples in subframe */
495 int *pitch_val,
496 spx_word16_t *gain_val,
497 SpeexBits *bits,
498 char *stack,
499 int count_lost,
500 int subframe_offset,
501 spx_word16_t last_pitch_gain,
502 int cdbk_offset
503 )
504 {
505    int i;
506    int pitch;
507    int gain_index;
508    float gain[3];
509    signed char *gain_cdbk;
510    int gain_cdbk_size;
511    ltp_params *params;
512 #ifdef FIXED_POINT
513    spx_word16_t sgain[3];
514 #endif
515    params = (ltp_params*) par;
516    gain_cdbk_size = 1<<params->gain_bits;
517    gain_cdbk = params->gain_cdbk + 3*gain_cdbk_size*cdbk_offset;
518
519    pitch = speex_bits_unpack_unsigned(bits, params->pitch_bits);
520    pitch += start;
521    gain_index = speex_bits_unpack_unsigned(bits, params->gain_bits);
522    /*printf ("decode pitch: %d %d\n", pitch, gain_index);*/
523 #ifdef FIXED_POINT
524    sgain[0] = 32+(spx_word16_t)gain_cdbk[gain_index*3];
525    sgain[1] = 32+(spx_word16_t)gain_cdbk[gain_index*3+1];
526    sgain[2] = 32+(spx_word16_t)gain_cdbk[gain_index*3+2];
527 #else
528    gain[0] = 0.015625*gain_cdbk[gain_index*3]+.5;
529    gain[1] = 0.015625*gain_cdbk[gain_index*3+1]+.5;
530    gain[2] = 0.015625*gain_cdbk[gain_index*3+2]+.5;
531 #endif
532
533    if (count_lost && pitch > subframe_offset)
534    {
535       float gain_sum;
536 #ifdef FIXED_POINT
537       gain[0] = 0.015625*sgain[0];
538       gain[1] = 0.015625*sgain[1];
539       gain[2] = 0.015625*sgain[2];
540 #endif
541       if (1) {
542          float tmp = count_lost < 4 ? GAIN_SCALING_1*last_pitch_gain : 0.4 * GAIN_SCALING_1 * last_pitch_gain;
543          if (tmp>.95)
544             tmp=.95;
545          gain_sum = fabs(gain[1]);
546          if (gain[0]>0)
547             gain_sum += gain[0];
548          else
549             gain_sum -= .5*gain[0];
550          if (gain[2]>0)
551             gain_sum += gain[2];
552          else
553             gain_sum -= .5*gain[2];
554          if (gain_sum > tmp) {
555             float fact = tmp/gain_sum;
556             for (i=0;i<3;i++)
557                gain[i]*=fact;
558
559          }
560
561       }
562
563       if (0) {
564       gain_sum = fabs(gain[0])+fabs(gain[1])+fabs(gain[2]);
565          if (gain_sum>.95) {
566          float fact = .95/gain_sum;
567          for (i=0;i<3;i++)
568             gain[i]*=fact;
569       }
570    }
571    }
572
573    *pitch_val = pitch;
574    gain_val[0]=sgain[0];
575    gain_val[1]=sgain[1];
576    gain_val[2]=sgain[2];
577
578    {
579       spx_sig_t *e[3];
580       spx_sig_t *tmp2;
581       tmp2=PUSH(stack, 3*nsf, spx_sig_t);
582       e[0]=tmp2;
583       e[1]=tmp2+nsf;
584       e[2]=tmp2+2*nsf;
585       
586       for (i=0;i<3;i++)
587       {
588          int j;
589          int pp=pitch+1-i;
590 #if 0
591          for (j=0;j<nsf;j++)
592          {
593             if (j-pp<0)
594                e[i][j]=exc[j-pp];
595             else if (j-pp-pitch<0)
596                e[i][j]=exc[j-pp-pitch];
597             else
598                e[i][j]=0;
599          }
600 #else
601          {
602             int tmp1, tmp3;
603             tmp1=nsf;
604             if (tmp1>pp)
605                tmp1=pp;
606             for (j=0;j<tmp1;j++)
607                e[i][j]=exc[j-pp];
608             tmp3=nsf;
609             if (tmp3>pp+pitch)
610                tmp3=pp+pitch;
611             for (j=tmp1;j<tmp3;j++)
612                e[i][j]=exc[j-pp-pitch];
613             for (j=tmp3;j<nsf;j++)
614                e[i][j]=0;
615          }
616 #endif
617       }
618
619 #ifdef FIXED_POINT
620       {
621          for (i=0;i<nsf;i++)
622             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);
623       }
624 #else
625       for (i=0;i<nsf;i++)
626          exc[i]=gain[0]*e[2][i]+gain[1]*e[1][i]+gain[2]*e[0][i];
627 #endif
628    }
629 }
630
631
632 /** Forced pitch delay and gain */
633 int forced_pitch_quant(
634 spx_sig_t target[],                 /* Target vector */
635 spx_sig_t *sw,
636 spx_coef_t ak[],                     /* LPCs for this subframe */
637 spx_coef_t awk1[],                   /* Weighted LPCs #1 for this subframe */
638 spx_coef_t awk2[],                   /* Weighted LPCs #2 for this subframe */
639 spx_sig_t exc[],                    /* Excitation */
640 void *par,
641 int   start,                    /* Smallest pitch value allowed */
642 int   end,                      /* Largest pitch value allowed */
643 spx_word16_t pitch_coef,               /* Voicing (pitch) coefficient */
644 int   p,                        /* Number of LPC coeffs */
645 int   nsf,                      /* Number of samples in subframe */
646 SpeexBits *bits,
647 char *stack,
648 spx_sig_t *exc2,
649 spx_sig_t *r,
650 int complexity,
651 int cdbk_offset
652 )
653 {
654    int i;
655    float coef = GAIN_SCALING_1*pitch_coef;
656    if (coef>.99)
657       coef=.99;
658    for (i=0;i<nsf;i++)
659    {
660       exc[i]=exc[i-start]*coef;
661    }
662    return start;
663 }
664
665 /** Unquantize forced pitch delay and gain */
666 void forced_pitch_unquant(
667 spx_sig_t exc[],                    /* Excitation */
668 int   start,                    /* Smallest pitch value allowed */
669 int   end,                      /* Largest pitch value allowed */
670 spx_word16_t pitch_coef,               /* Voicing (pitch) coefficient */
671 void *par,
672 int   nsf,                      /* Number of samples in subframe */
673 int *pitch_val,
674 spx_word16_t *gain_val,
675 SpeexBits *bits,
676 char *stack,
677 int count_lost,
678 int subframe_offset,
679 spx_word16_t last_pitch_gain,
680 int cdbk_offset
681 )
682 {
683    int i;
684    float coef = GAIN_SCALING_1*pitch_coef;
685    if (coef>.99)
686       coef=.99;
687    for (i=0;i<nsf;i++)
688    {
689       exc[i]=exc[i-start]*coef;
690    }
691    *pitch_val = start;
692    gain_val[0]=gain_val[2]=0;
693    gain_val[1] = pitch_coef;
694 }