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