ec_gains.cpp revision 4f1efc098cb5791c3e9f483f2af84aef70d2d0a0
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/****************************************************************************************
19Portions 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)
26Permission to distribute, modify and use this file under the standard license
27terms 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
82extern "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
159int 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
199Word16 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
249This function does error concealment using the codebook. Call this function
250only 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*/
315void 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*/
452void 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*/
577void 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
647int 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*/
686Word16 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*/
806void 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