1 /* ------------------------------------------------------------------
2  * Copyright (C) 1998-2009 PacketVideo
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13  * express or implied.
14  * See the License for the specific language governing permissions
15  * and limitations under the License.
16  * -------------------------------------------------------------------
17  */
18 /****************************************************************************************
19 Portions of this file are derived from the following 3GPP standard:
20 
21     3GPP TS 26.073
22     ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
23     Available from http://www.3gpp.org
24 
25 (C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
26 Permission to distribute, modify and use this file under the standard license
27 terms listed above has been obtained from the copyright holder.
28 ****************************************************************************************/
29 /*
30 ------------------------------------------------------------------------------
31 
32 
33 
34 
35  Pathname: ./audio/gsm-amr/c/src/ec_gain.c
36  Funtions:
37 
38      Date: 01/28/2002
39 
40 ------------------------------------------------------------------------------
41  REVISION HISTORY
42 
43  Description: Removed the functions ec_gain_code_init, ec_gain_pitch_init,
44  ech_gain_code_exit, and ec_gain_pitch_exit.
45 
46  The ec_gains related structures are no longer dynamically allocated.
47 
48  Description: Updated include files and input/output sections.
49 
50  Description:  Replaced OSCL mem type functions and eliminated include
51                files that now are chosen by OSCL definitions
52 
53  Description:  Replaced "int" and/or "char" with OSCL defined types.
54 
55  Description: Added #ifdef __cplusplus around extern'ed table.
56 
57  Description:
58 
59 ------------------------------------------------------------------------------
60  MODULE DESCRIPTION
61 
62  These modules execute the code book gains for error concealment. This module
63  contains the init, reset, exit, and "main" functions in this process.
64 
65 ------------------------------------------------------------------------------
66 */
67 
68 
69 /*----------------------------------------------------------------------------
70 ; INCLUDES
71 ----------------------------------------------------------------------------*/
72 #include "ec_gains.h"
73 #include "typedef.h"
74 #include "cnst.h"
75 #include "gmed_n.h"
76 #include "gc_pred.h"
77 #include "basic_op.h"
78 
79 
80 /*--------------------------------------------------------------------------*/
81 #ifdef __cplusplus
82 extern "C"
83 {
84 #endif
85 
86     /*----------------------------------------------------------------------------
87     ; MACROS
88     ; Define module specific macros here
89     ----------------------------------------------------------------------------*/
90 
91 
92     /*----------------------------------------------------------------------------
93     ; DEFINES
94     ; Include all pre-processor statements here. Include conditional
95     ; compile variables also.
96     ----------------------------------------------------------------------------*/
97 
98 
99     /*----------------------------------------------------------------------------
100     ; LOCAL FUNCTION DEFINITIONS
101     ; Function Prototype declaration
102     ----------------------------------------------------------------------------*/
103 
104 
105     /*----------------------------------------------------------------------------
106     ; LOCAL VARIABLE DEFINITIONS
107     ; Variable declaration - defined here and used outside this module
108     ----------------------------------------------------------------------------*/
109 
110     extern const Word16 qua_gain_pitch[];
111     extern const Word16 qua_gain_code[];
112 
113 
114     /*--------------------------------------------------------------------------*/
115 #ifdef __cplusplus
116 }
117 #endif
118 
119 /*
120 ------------------------------------------------------------------------------
121  FUNCTION NAME: ec_gain_code_reset
122 ------------------------------------------------------------------------------
123  INPUT AND OUTPUT DEFINITIONS
124 
125  Inputs:
126   state = pointer to a pointer to a structure containing code state data of
127           stucture type ec_gain_codeState
128 
129  Outputs:
130     None.
131 
132  Returns:
133     None
134 
135  Global Variables Used:
136     None.
137 
138  Local Variables Needed:
139     None.
140 
141 ------------------------------------------------------------------------------
142  FUNCTION DESCRIPTION
143 
144  This function resets the state data for the ec_gain module.
145 
146 ------------------------------------------------------------------------------
147  REQUIREMENTS
148 
149  None
150 
151 ------------------------------------------------------------------------------
152  REFERENCES
153 
154  None
155 
156 ------------------------------------------------------------------------------
157  PSEUDO-CODE
158 
159 int ec_gain_code_reset (ec_gain_codeState *state)
160 {
161   Word16 i;
162 
163   if (state == (ec_gain_codeState *) NULL){
164       // fprintf(stderr, "ec_gain_code_reset: invalid parameter\n");
165       return -1;
166   }
167 
168   for ( i = 0; i < 5; i++)
169       state->gbuf[i] = 1;
170   state->past_gain_code = 0;
171   state->prev_gc = 1;
172 
173   return 0;
174 }
175 
176 ------------------------------------------------------------------------------
177  RESOURCES USED [optional]
178 
179  When the code is written for a specific target processor the
180  the resources used should be documented below.
181 
182  HEAP MEMORY USED: x bytes
183 
184  STACK MEMORY USED: x bytes
185 
186  CLOCK CYCLES: (cycle count equation for this function) + (variable
187                 used to represent cycle count for each subroutine
188                 called)
189      where: (cycle count variable) = cycle count for [subroutine
190                                      name]
191 
192 ------------------------------------------------------------------------------
193  CAUTION [optional]
194  [State any special notes, constraints or cautions for users of this function]
195 
196 ------------------------------------------------------------------------------
197 */
198 
ec_gain_code_reset(ec_gain_codeState * state)199 Word16 ec_gain_code_reset(ec_gain_codeState *state)
200 {
201     Word16 i;
202 
203     if (state == (ec_gain_codeState *) NULL)
204     {
205         /* fprintf(stderr, "ec_gain_code_reset: invalid parameter\n"); */
206         return -1;
207     }
208 
209     for (i = 0; i < 5; i++)
210         state->gbuf[i] = 1;
211     state->past_gain_code = 0;
212     state->prev_gc = 1;
213 
214     return 0;
215 }
216 
217 /*
218 ------------------------------------------------------------------------------
219  FUNCTION NAME: ec_gain_code
220 ------------------------------------------------------------------------------
221  INPUT AND OUTPUT DEFINITIONS
222 
223  Inputs:
224   st = pointer to a pointer to a structure containing code state data of
225        stucture type ec_gain_codeState
226   pred_state = pointer to MA predictor state of type gc_predState
227   state  = state of the state machine of type Word16
228   gain_code = pointer to decoded innovation gain of type Word16
229   pOverflow = pointer to overflow indicator of type Flag
230 
231  Outputs:
232   st = pointer to a pointer to a structure containing code state data of
233        stucture type ec_gain_codeState
234   pred_state = pointer to MA predictor state of type gc_predState
235   pOverflow = 1 if there is an overflow else it is zero.
236 
237  Returns:
238     None.
239 
240  Global Variables Used:
241     None.
242 
243  Local Variables Needed:
244     None.
245 
246 ------------------------------------------------------------------------------
247  FUNCTION DESCRIPTION
248 
249 This function does error concealment using the codebook. Call this function
250 only in BFI (instead of normal gain decoding function).
251 
252 ------------------------------------------------------------------------------
253  REQUIREMENTS
254 
255  None.
256 
257 ------------------------------------------------------------------------------
258  REFERENCES
259 
260  ec_gain.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
261 
262 ------------------------------------------------------------------------------
263  PSEUDO-CODE
264 
265     static const Word16 cdown[7] =
266     {
267         32767, 32112, 32112, 32112,
268         32112, 32112, 22937
269     };
270 
271     Word16 tmp;
272     Word16 qua_ener_MR122;
273     Word16 qua_ener;
274 
275     // calculate median of last five gain values
276     tmp = gmed_n (st->gbuf,5);
277 
278     // new gain = minimum(median, past_gain) * cdown[state]
279     if (sub (tmp, st->past_gain_code) > 0)
280     {
281         tmp = st->past_gain_code;
282     }
283     tmp = mult (tmp, cdown[state]);
284     *gain_code = tmp;
285 
286     // update table of past quantized energies with average of
287     // current values
288 
289     gc_pred_average_limited(pred_state, &qua_ener_MR122, &qua_ener);
290     gc_pred_update(pred_state, qua_ener_MR122, qua_ener);
291 }
292 
293 ------------------------------------------------------------------------------
294  RESOURCES USED [optional]
295 
296  When the code is written for a specific target processor the
297  the resources used should be documented below.
298 
299  HEAP MEMORY USED: x bytes
300 
301  STACK MEMORY USED: x bytes
302 
303  CLOCK CYCLES: (cycle count equation for this function) + (variable
304                 used to represent cycle count for each subroutine
305                 called)
306      where: (cycle count variable) = cycle count for [subroutine
307                                      name]
308 
309 ------------------------------------------------------------------------------
310  CAUTION [optional]
311  [State any special notes, constraints or cautions for users of this function]
312 
313 ------------------------------------------------------------------------------
314 */
ec_gain_code(ec_gain_codeState * st,gc_predState * pred_state,Word16 state,Word16 * gain_code,Flag * pOverflow)315 void ec_gain_code(
316     ec_gain_codeState *st,    /* i/o : State struct                     */
317     gc_predState *pred_state, /* i/o : MA predictor state               */
318     Word16 state,             /* i   : state of the state machine       */
319     Word16 *gain_code,        /* o   : decoded innovation gain          */
320     Flag   *pOverflow
321 )
322 {
323     static const Word16 cdown[7] =
324     {
325         32767, 32112, 32112, 32112,
326         32112, 32112, 22937
327     };
328 
329     Word16 tmp;
330     Word16 qua_ener_MR122;
331     Word16 qua_ener;
332 
333     /* calculate median of last five gain values */
334     tmp = gmed_n(st->gbuf, 5);
335 
336     /* new gain = minimum(median, past_gain) * cdown[state] */
337     if (sub(tmp, st->past_gain_code, pOverflow) > 0)
338     {
339         tmp = st->past_gain_code;
340     }
341     tmp = mult(tmp, cdown[state], pOverflow);
342     *gain_code = tmp;
343 
344     /* update table of past quantized energies with average of
345      * current values
346      */
347     gc_pred_average_limited(pred_state, &qua_ener_MR122, &qua_ener, pOverflow);
348     gc_pred_update(pred_state, qua_ener_MR122, qua_ener);
349 }
350 
351 /****************************************************************************/
352 
353 /*
354 ------------------------------------------------------------------------------
355  FUNCTION NAME: ec_gain_code_update
356 ------------------------------------------------------------------------------
357  INPUT AND OUTPUT DEFINITIONS
358 
359  Inputs:
360   st = pointer to a pointer to a structure containing code state data of
361        stucture type ec_gain_codeState
362   bfi = a flag that indicates if the frame is bad of type Word16
363   prev_bf = a flag that indicates if the previous frame was bad of type Word16
364   gain_code = pointer to decoded innovation gain of type Word16
365   pOverflow = pointer to overflow indicator of type Flag
366 
367  Outputs:
368   st = pointer to a pointer to a structure containing code state data of
369        stucture type ec_gain_codeState
370   gain_code = pointer to decoded innovation gain of type Word16
371   pOverflow = 1 if there is an overflow else it is zero.
372 
373  Returns:
374     None.
375 
376  Global Variables Used:
377     None.
378 
379  Local Variables Needed:
380     None.
381 
382 ------------------------------------------------------------------------------
383  FUNCTION DESCRIPTION
384 
385   Purpose     : update the codebook gain concealment state;
386                 limit gain_code if the previous frame was bad
387                 Call this function always after decoding (or concealing)
388                 the gain
389 
390 ------------------------------------------------------------------------------
391  REQUIREMENTS
392 
393  None.
394 
395 ------------------------------------------------------------------------------
396  REFERENCES
397 
398  ec_gain.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
399 
400 ------------------------------------------------------------------------------
401  PSEUDO-CODE
402 
403     Word16 i;
404 
405     // limit gain_code by previous good gain if previous frame was bad
406     if (bfi == 0)
407     {
408         if (prev_bf != 0)
409         {
410             if (sub (*gain_code, st->prev_gc) > 0)
411             {
412                 *gain_code = st->prev_gc;
413             }
414         }
415         st->prev_gc = *gain_code;
416     }
417 
418     // update EC states: previous gain, gain buffer
419     st->past_gain_code = *gain_code;
420 
421     for (i = 1; i < 5; i++)
422     {
423         st->gbuf[i - 1] = st->gbuf[i];
424     }
425     st->gbuf[4] = *gain_code;
426 
427     return;
428 }
429 
430 ------------------------------------------------------------------------------
431  RESOURCES USED [optional]
432 
433  When the code is written for a specific target processor the
434  the resources used should be documented below.
435 
436  HEAP MEMORY USED: x bytes
437 
438  STACK MEMORY USED: x bytes
439 
440  CLOCK CYCLES: (cycle count equation for this function) + (variable
441                 used to represent cycle count for each subroutine
442                 called)
443      where: (cycle count variable) = cycle count for [subroutine
444                                      name]
445 
446 ------------------------------------------------------------------------------
447  CAUTION [optional]
448  [State any special notes, constraints or cautions for users of this function]
449 
450 ------------------------------------------------------------------------------
451 */
ec_gain_code_update(ec_gain_codeState * st,Word16 bfi,Word16 prev_bf,Word16 * gain_code,Flag * pOverflow)452 void ec_gain_code_update(
453     ec_gain_codeState *st,    /* i/o : State struct                     */
454     Word16 bfi,               /* i   : flag: frame is bad               */
455     Word16 prev_bf,           /* i   : flag: previous frame was bad     */
456     Word16 *gain_code,        /* i/o : decoded innovation gain          */
457     Flag   *pOverflow
458 )
459 {
460     Word16 i;
461 
462     /* limit gain_code by previous good gain if previous frame was bad */
463     if (bfi == 0)
464     {
465         if (prev_bf != 0)
466         {
467             if (sub(*gain_code, st->prev_gc, pOverflow) > 0)
468             {
469                 *gain_code = st->prev_gc;
470             }
471         }
472         st->prev_gc = *gain_code;
473     }
474 
475     /* update EC states: previous gain, gain buffer */
476     st->past_gain_code = *gain_code;
477 
478     for (i = 1; i < 5; i++)
479     {
480         st->gbuf[i - 1] = st->gbuf[i];
481     }
482     st->gbuf[4] = *gain_code;
483 
484     return;
485 }
486 
487 /****************************************************************************/
488 
489 /*
490 ------------------------------------------------------------------------------
491  FUNCTION NAME: ec_gain_pitch
492 ------------------------------------------------------------------------------
493  INPUT AND OUTPUT DEFINITIONS
494 
495  Inputs:
496   st = pointer to a pointer to a structure containing code
497        state data of stucture type ec_gain_pitchState
498   state = state of the state machine of type Word16
499   pOverflow = pointer to overflow indicator of type Flag
500 
501   Outputs:
502   state = pointer to a pointer to a structure containing code
503           state data of stucture type ec_gain_pitchState
504   gain_pitch = pointer to pitch gain (Q14) of type Word16
505   pOverflow = 1 if there is an overflow else it is zero.
506 
507  Returns:
508     None.
509 
510  Global Variables Used:
511     None.
512 
513  Local Variables Needed:
514     None.
515 
516 ------------------------------------------------------------------------------
517  FUNCTION DESCRIPTION
518 
519  This function conceals the error using code gain implementation in this
520  function.
521 
522 ------------------------------------------------------------------------------
523  REQUIREMENTS
524 
525  None.
526 
527 ------------------------------------------------------------------------------
528  REFERENCES
529 
530  ec_gain.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
531 
532 ------------------------------------------------------------------------------
533  PSEUDO-CODE
534 
535 
536     static const Word16 pdown[7] =
537     {
538         32767, 32112, 32112, 26214,
539         9830, 6553, 6553
540     };
541 
542     Word16 tmp;
543 
544     // calculate median of last five gains
545     tmp = gmed_n (st->pbuf, 5);
546 
547     // new gain = minimum(median, past_gain) * pdown[state]
548     if (sub (tmp, st->past_gain_pit) > 0)
549     {
550         tmp = st->past_gain_pit;
551     }
552     *gain_pitch = mult (tmp, pdown[state]);
553 
554 
555 ------------------------------------------------------------------------------
556  RESOURCES USED [optional]
557 
558  When the code is written for a specific target processor the
559  the resources used should be documented below.
560 
561  HEAP MEMORY USED: x bytes
562 
563  STACK MEMORY USED: x bytes
564 
565  CLOCK CYCLES: (cycle count equation for this function) + (variable
566                 used to represent cycle count for each subroutine
567                 called)
568      where: (cycle count variable) = cycle count for [subroutine
569                                      name]
570 
571 ------------------------------------------------------------------------------
572  CAUTION [optional]
573  [State any special notes, constraints or cautions for users of this function]
574 
575 ------------------------------------------------------------------------------
576 */
ec_gain_pitch(ec_gain_pitchState * st,Word16 state,Word16 * gain_pitch,Flag * pOverflow)577 void ec_gain_pitch(
578     ec_gain_pitchState *st, /* i/o : state variables                   */
579     Word16 state,           /* i   : state of the state machine        */
580     Word16 *gain_pitch,     /* o   : pitch gain (Q14)                  */
581     Flag   *pOverflow
582 )
583 {
584     static const Word16 pdown[7] =
585     {
586         32767, 32112, 32112, 26214,
587         9830, 6553, 6553
588     };
589 
590     Word16 tmp;
591 
592     /* calculate median of last five gains */
593     tmp = gmed_n(st->pbuf, 5);
594 
595     /* new gain = minimum(median, past_gain) * pdown[state] */
596     if (sub(tmp, st->past_gain_pit, pOverflow) > 0)
597     {
598         tmp = st->past_gain_pit;
599     }
600     *gain_pitch = mult(tmp, pdown[state], pOverflow);
601 }
602 
603 /****************************************************************************/
604 /*
605 ------------------------------------------------------------------------------
606  FUNCTION NAME: ec_gain_pitch_reset
607 ------------------------------------------------------------------------------
608  INPUT AND OUTPUT DEFINITIONS
609 
610  Inputs:
611   state = state of the state machine of type Word16
612   pOverflow = pointer to overflow indicator of type Flag
613 
614   Outputs:
615   state = pointer to a pointer to a structure containing code
616           state data of stucture type ec_gain_pitchState
617   pOverflow = 1 if there is an overflow else it is zero.
618 
619  Returns:
620     None.
621 
622  Global Variables Used:
623     None.
624 
625  Local Variables Needed:
626     None.
627 
628 ------------------------------------------------------------------------------
629  FUNCTION DESCRIPTION
630 
631  Function:   ec_gain_pitch_reset
632  Purpose:    Resets state memory
633 
634 ------------------------------------------------------------------------------
635  REQUIREMENTS
636 
637  None.
638 
639 ------------------------------------------------------------------------------
640  REFERENCES
641 
642  ec_gain.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
643 
644 ------------------------------------------------------------------------------
645  PSEUDO-CODE
646 
647 int ec_gain_pitch_reset (ec_gain_pitchState *state)
648 {
649   Word16 i;
650 
651   if (state == (ec_gain_pitchState *) NULL){
652       // fprintf(stderr, "ec_gain_pitch_reset: invalid parameter\n");
653       return -1;
654   }
655 
656   for(i = 0; i < 5; i++)
657       state->pbuf[i] = 1640;
658   state->past_gain_pit = 0;
659   state->prev_gp = 16384;
660 
661   return 0;
662 }
663 
664 ------------------------------------------------------------------------------
665  RESOURCES USED [optional]
666 
667  When the code is written for a specific target processor the
668  the resources used should be documented below.
669 
670  HEAP MEMORY USED: x bytes
671 
672  STACK MEMORY USED: x bytes
673 
674  CLOCK CYCLES: (cycle count equation for this function) + (variable
675                 used to represent cycle count for each subroutine
676                 called)
677      where: (cycle count variable) = cycle count for [subroutine
678                                      name]
679 
680 ------------------------------------------------------------------------------
681  CAUTION [optional]
682  [State any special notes, constraints or cautions for users of this function]
683 
684 ------------------------------------------------------------------------------
685 */
ec_gain_pitch_reset(ec_gain_pitchState * state)686 Word16 ec_gain_pitch_reset(ec_gain_pitchState *state)
687 {
688     Word16 i;
689 
690     if (state == (ec_gain_pitchState *) NULL)
691     {
692         /* fprintf(stderr, "ec_gain_pitch_reset: invalid parameter\n"); */
693         return -1;
694     }
695 
696     for (i = 0; i < 5; i++)
697         state->pbuf[i] = 1640;
698     state->past_gain_pit = 0;
699     state->prev_gp = 16384;
700 
701     return 0;
702 }
703 
704 /****************************************************************************/
705 
706 
707 /*
708 ------------------------------------------------------------------------------
709  FUNCTION NAME: ec_gain_pitch_update
710 ------------------------------------------------------------------------------
711  INPUT AND OUTPUT DEFINITIONS
712 
713  Inputs:
714   st = pointer to a pointer to a structure containing code
715        state data of stucture type ec_gain_pitchState
716   bfi = flag indicating the frame is bad of type Word16
717   prev_bf = flag indicating the previous frame was bad of type Word16
718   gain_pitch = pointer to pitch gain of type Word16
719   pOverflow = pointer to overflow indicator of type Flag
720 
721   Outputs:
722   state = pointer to a pointer to a structure containing code
723           state data of stucture type ec_gain_pitchState
724   gain_pitch = pointer to pitch gain of type Word16
725   pOverflow = 1 if there is an overflow else it is zero.
726 
727  Returns:
728     None.
729 
730  Global Variables Used:
731     None.
732 
733  Local Variables Needed:
734     None.
735 
736 ------------------------------------------------------------------------------
737  FUNCTION DESCRIPTION
738 
739   Purpose     : update the pitch gain concealment state;
740                 limit gain_pitch if the previous frame was bad
741                 Call this function always after decoding (or concealing)
742                 the gain
743 
744 ------------------------------------------------------------------------------
745  REQUIREMENTS
746 
747  None.
748 
749 ------------------------------------------------------------------------------
750  REFERENCES
751 
752  ec_gain.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
753 
754 ------------------------------------------------------------------------------
755  PSEUDO-CODE
756 
757     Word16 i;
758 
759     if (bfi == 0)
760     {
761         if (prev_bf != 0)
762         {
763             if (sub (*gain_pitch, st->prev_gp) > 0)
764             {
765                 *gain_pitch = st->prev_gp;
766             }
767         }
768         st->prev_gp = *gain_pitch;
769     }
770 
771     st->past_gain_pit = *gain_pitch;
772 
773     if (sub (st->past_gain_pit, 16384) > 0)  // if (st->past_gain_pit > 1.0)
774     {
775         st->past_gain_pit = 16384;
776     }
777     for (i = 1; i < 5; i++)
778     {
779         st->pbuf[i - 1] = st->pbuf[i];
780     }
781     st->pbuf[4] = st->past_gain_pit;
782 
783 
784 ------------------------------------------------------------------------------
785  RESOURCES USED [optional]
786 
787  When the code is written for a specific target processor the
788  the resources used should be documented below.
789 
790  HEAP MEMORY USED: x bytes
791 
792  STACK MEMORY USED: x bytes
793 
794  CLOCK CYCLES: (cycle count equation for this function) + (variable
795                 used to represent cycle count for each subroutine
796                 called)
797      where: (cycle count variable) = cycle count for [subroutine
798                                      name]
799 
800 ------------------------------------------------------------------------------
801  CAUTION [optional]
802  [State any special notes, constraints or cautions for users of this function]
803 
804 ------------------------------------------------------------------------------
805 */
ec_gain_pitch_update(ec_gain_pitchState * st,Word16 bfi,Word16 prev_bf,Word16 * gain_pitch,Flag * pOverflow)806 void ec_gain_pitch_update(
807     ec_gain_pitchState *st, /* i/o : state variables                   */
808     Word16 bfi,             /* i   : flag: frame is bad                */
809     Word16 prev_bf,         /* i   : flag: previous frame was bad      */
810     Word16 *gain_pitch,     /* i/o : pitch gain                        */
811     Flag   *pOverflow
812 )
813 {
814     Word16 i;
815 
816     if (bfi == 0)
817     {
818         if (prev_bf != 0)
819         {
820             if (sub(*gain_pitch, st->prev_gp, pOverflow) > 0)
821             {
822                 *gain_pitch = st->prev_gp;
823             }
824         }
825         st->prev_gp = *gain_pitch;
826     }
827 
828     st->past_gain_pit = *gain_pitch;
829 
830     if (sub(st->past_gain_pit, 16384, pOverflow) > 0)
831         /* if (st->past_gain_pit > 1.0) */
832     {
833         st->past_gain_pit = 16384;
834     }
835     for (i = 1; i < 5; i++)
836     {
837         st->pbuf[i - 1] = st->pbuf[i];
838     }
839     st->pbuf[4] = st->past_gain_pit;
840 }
841 
842 
843