Initialize Tizen 2.3
[external/opencore-amr.git] / opencore / codecs_v2 / audio / gsm_amr / amr_nb / dec / src / ec_gains.cpp
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  Filename: ec_gains.cpp
36
37 ------------------------------------------------------------------------------
38  MODULE DESCRIPTION
39
40  These modules execute the code book gains for error concealment. This module
41  contains the init, reset, exit, and "main" functions in this process.
42
43 ------------------------------------------------------------------------------
44 */
45
46
47 /*----------------------------------------------------------------------------
48 ; INCLUDES
49 ----------------------------------------------------------------------------*/
50 #include "ec_gains.h"
51 #include "typedef.h"
52 #include "cnst.h"
53 #include "gmed_n.h"
54 #include "gc_pred.h"
55 #include "basic_op.h"
56
57
58 /*--------------------------------------------------------------------------*/
59 #ifdef __cplusplus
60 extern "C"
61 {
62 #endif
63
64     /*----------------------------------------------------------------------------
65     ; MACROS
66     ; Define module specific macros here
67     ----------------------------------------------------------------------------*/
68
69
70     /*----------------------------------------------------------------------------
71     ; DEFINES
72     ; Include all pre-processor statements here. Include conditional
73     ; compile variables also.
74     ----------------------------------------------------------------------------*/
75
76
77     /*----------------------------------------------------------------------------
78     ; LOCAL FUNCTION DEFINITIONS
79     ; Function Prototype declaration
80     ----------------------------------------------------------------------------*/
81
82
83     /*----------------------------------------------------------------------------
84     ; LOCAL VARIABLE DEFINITIONS
85     ; Variable declaration - defined here and used outside this module
86     ----------------------------------------------------------------------------*/
87
88     /*--------------------------------------------------------------------------*/
89 #ifdef __cplusplus
90 }
91 #endif
92
93 /*
94 ------------------------------------------------------------------------------
95  FUNCTION NAME: ec_gain_code_reset
96 ------------------------------------------------------------------------------
97  INPUT AND OUTPUT DEFINITIONS
98
99  Inputs:
100   state = pointer to a pointer to a structure containing code state data of
101           stucture type ec_gain_codeState
102
103  Outputs:
104     None.
105
106  Returns:
107     None
108
109  Global Variables Used:
110     None.
111
112  Local Variables Needed:
113     None.
114
115 ------------------------------------------------------------------------------
116  FUNCTION DESCRIPTION
117
118  This function resets the state data for the ec_gain module.
119
120 ------------------------------------------------------------------------------
121  REQUIREMENTS
122
123  None
124
125 ------------------------------------------------------------------------------
126  REFERENCES
127
128  None
129
130 ------------------------------------------------------------------------------
131  PSEUDO-CODE
132
133 int ec_gain_code_reset (ec_gain_codeState *state)
134 {
135   Word16 i;
136
137   if (state == (ec_gain_codeState *) NULL){
138       // fprintf(stderr, "ec_gain_code_reset: invalid parameter\n");
139       return -1;
140   }
141
142   for ( i = 0; i < 5; i++)
143       state->gbuf[i] = 1;
144   state->past_gain_code = 0;
145   state->prev_gc = 1;
146
147   return 0;
148 }
149
150 ------------------------------------------------------------------------------
151  CAUTION [optional]
152  [State any special notes, constraints or cautions for users of this function]
153
154 ------------------------------------------------------------------------------
155 */
156
157 Word16 ec_gain_code_reset(ec_gain_codeState *state)
158 {
159     Word16 i;
160
161     if (state == (ec_gain_codeState *) NULL)
162     {
163         /* fprintf(stderr, "ec_gain_code_reset: invalid parameter\n"); */
164         return -1;
165     }
166
167     for (i = 0; i < 5; i++)
168         state->gbuf[i] = 1;
169     state->past_gain_code = 0;
170     state->prev_gc = 1;
171
172     return 0;
173 }
174
175 /*
176 ------------------------------------------------------------------------------
177  FUNCTION NAME: ec_gain_code
178 ------------------------------------------------------------------------------
179  INPUT AND OUTPUT DEFINITIONS
180
181  Inputs:
182   st = pointer to a pointer to a structure containing code state data of
183        stucture type ec_gain_codeState
184   pred_state = pointer to MA predictor state of type gc_predState
185   state  = state of the state machine of type Word16
186   gain_code = pointer to decoded innovation gain of type Word16
187   pOverflow = pointer to overflow indicator of type Flag
188
189  Outputs:
190   st = pointer to a pointer to a structure containing code state data of
191        stucture type ec_gain_codeState
192   pred_state = pointer to MA predictor state of type gc_predState
193   pOverflow = 1 if there is an overflow else it is zero.
194
195  Returns:
196     None.
197
198  Global Variables Used:
199     None.
200
201  Local Variables Needed:
202     None.
203
204 ------------------------------------------------------------------------------
205  FUNCTION DESCRIPTION
206
207 This function does error concealment using the codebook. Call this function
208 only in BFI (instead of normal gain decoding function).
209
210 ------------------------------------------------------------------------------
211  REQUIREMENTS
212
213  None.
214
215 ------------------------------------------------------------------------------
216  REFERENCES
217
218  ec_gain.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
219
220 ------------------------------------------------------------------------------
221  PSEUDO-CODE
222
223     static const Word16 cdown[7] =
224     {
225         32767, 32112, 32112, 32112,
226         32112, 32112, 22937
227     };
228
229     Word16 tmp;
230     Word16 qua_ener_MR122;
231     Word16 qua_ener;
232
233     // calculate median of last five gain values
234     tmp = gmed_n (st->gbuf,5);
235
236     // new gain = minimum(median, past_gain) * cdown[state]
237     if (sub (tmp, st->past_gain_code) > 0)
238     {
239         tmp = st->past_gain_code;
240     }
241     tmp = mult (tmp, cdown[state]);
242     *gain_code = tmp;
243
244     // update table of past quantized energies with average of
245     // current values
246
247     gc_pred_average_limited(pred_state, &qua_ener_MR122, &qua_ener);
248     gc_pred_update(pred_state, qua_ener_MR122, qua_ener);
249 }
250
251 ------------------------------------------------------------------------------
252  CAUTION [optional]
253  [State any special notes, constraints or cautions for users of this function]
254
255 ------------------------------------------------------------------------------
256 */
257 void ec_gain_code(
258     ec_gain_codeState *st,    /* i/o : State struct                     */
259     gc_predState *pred_state, /* i/o : MA predictor state               */
260     Word16 state,             /* i   : state of the state machine       */
261     Word16 *gain_code,        /* o   : decoded innovation gain          */
262     Flag   *pOverflow
263 )
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, pOverflow) > 0)
280     {
281         tmp = st->past_gain_code;
282     }
283     tmp = mult(tmp, cdown[state], pOverflow);
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, pOverflow);
290     gc_pred_update(pred_state, qua_ener_MR122, qua_ener);
291 }
292
293 /****************************************************************************/
294
295 /*
296 ------------------------------------------------------------------------------
297  FUNCTION NAME: ec_gain_code_update
298 ------------------------------------------------------------------------------
299  INPUT AND OUTPUT DEFINITIONS
300
301  Inputs:
302   st = pointer to a pointer to a structure containing code state data of
303        stucture type ec_gain_codeState
304   bfi = a flag that indicates if the frame is bad of type Word16
305   prev_bf = a flag that indicates if the previous frame was bad of type Word16
306   gain_code = pointer to decoded innovation gain of type Word16
307   pOverflow = pointer to overflow indicator of type Flag
308
309  Outputs:
310   st = pointer to a pointer to a structure containing code state data of
311        stucture type ec_gain_codeState
312   gain_code = pointer to decoded innovation gain of type Word16
313   pOverflow = 1 if there is an overflow else it is zero.
314
315  Returns:
316     None.
317
318  Global Variables Used:
319     None.
320
321  Local Variables Needed:
322     None.
323
324 ------------------------------------------------------------------------------
325  FUNCTION DESCRIPTION
326
327   Purpose     : update the codebook gain concealment state;
328                 limit gain_code if the previous frame was bad
329                 Call this function always after decoding (or concealing)
330                 the gain
331
332 ------------------------------------------------------------------------------
333  REQUIREMENTS
334
335  None.
336
337 ------------------------------------------------------------------------------
338  REFERENCES
339
340  ec_gain.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
341
342 ------------------------------------------------------------------------------
343  PSEUDO-CODE
344
345     Word16 i;
346
347     // limit gain_code by previous good gain if previous frame was bad
348     if (bfi == 0)
349     {
350         if (prev_bf != 0)
351         {
352             if (sub (*gain_code, st->prev_gc) > 0)
353             {
354                 *gain_code = st->prev_gc;
355             }
356         }
357         st->prev_gc = *gain_code;
358     }
359
360     // update EC states: previous gain, gain buffer
361     st->past_gain_code = *gain_code;
362
363     for (i = 1; i < 5; i++)
364     {
365         st->gbuf[i - 1] = st->gbuf[i];
366     }
367     st->gbuf[4] = *gain_code;
368
369     return;
370 }
371
372 ------------------------------------------------------------------------------
373  CAUTION [optional]
374  [State any special notes, constraints or cautions for users of this function]
375
376 ------------------------------------------------------------------------------
377 */
378 void ec_gain_code_update(
379     ec_gain_codeState *st,    /* i/o : State struct                     */
380     Word16 bfi,               /* i   : flag: frame is bad               */
381     Word16 prev_bf,           /* i   : flag: previous frame was bad     */
382     Word16 *gain_code,        /* i/o : decoded innovation gain          */
383     Flag   *pOverflow
384 )
385 {
386     Word16 i;
387
388     /* limit gain_code by previous good gain if previous frame was bad */
389     if (bfi == 0)
390     {
391         if (prev_bf != 0)
392         {
393             if (sub(*gain_code, st->prev_gc, pOverflow) > 0)
394             {
395                 *gain_code = st->prev_gc;
396             }
397         }
398         st->prev_gc = *gain_code;
399     }
400
401     /* update EC states: previous gain, gain buffer */
402     st->past_gain_code = *gain_code;
403
404     for (i = 1; i < 5; i++)
405     {
406         st->gbuf[i - 1] = st->gbuf[i];
407     }
408     st->gbuf[4] = *gain_code;
409
410     return;
411 }
412
413 /****************************************************************************/
414
415 /*
416 ------------------------------------------------------------------------------
417  FUNCTION NAME: ec_gain_pitch
418 ------------------------------------------------------------------------------
419  INPUT AND OUTPUT DEFINITIONS
420
421  Inputs:
422   st = pointer to a pointer to a structure containing code
423        state data of stucture type ec_gain_pitchState
424   state = state of the state machine of type Word16
425   pOverflow = pointer to overflow indicator of type Flag
426
427   Outputs:
428   state = pointer to a pointer to a structure containing code
429           state data of stucture type ec_gain_pitchState
430   gain_pitch = pointer to pitch gain (Q14) of type Word16
431   pOverflow = 1 if there is an overflow else it is zero.
432
433  Returns:
434     None.
435
436  Global Variables Used:
437     None.
438
439  Local Variables Needed:
440     None.
441
442 ------------------------------------------------------------------------------
443  FUNCTION DESCRIPTION
444
445  This function conceals the error using code gain implementation in this
446  function.
447
448 ------------------------------------------------------------------------------
449  REQUIREMENTS
450
451  None.
452
453 ------------------------------------------------------------------------------
454  REFERENCES
455
456  ec_gain.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
457
458 ------------------------------------------------------------------------------
459  PSEUDO-CODE
460
461
462     static const Word16 pdown[7] =
463     {
464         32767, 32112, 32112, 26214,
465         9830, 6553, 6553
466     };
467
468     Word16 tmp;
469
470     // calculate median of last five gains
471     tmp = gmed_n (st->pbuf, 5);
472
473     // new gain = minimum(median, past_gain) * pdown[state]
474     if (sub (tmp, st->past_gain_pit) > 0)
475     {
476         tmp = st->past_gain_pit;
477     }
478     *gain_pitch = mult (tmp, pdown[state]);
479
480
481 ------------------------------------------------------------------------------
482  CAUTION [optional]
483  [State any special notes, constraints or cautions for users of this function]
484
485 ------------------------------------------------------------------------------
486 */
487 void ec_gain_pitch(
488     ec_gain_pitchState *st, /* i/o : state variables                   */
489     Word16 state,           /* i   : state of the state machine        */
490     Word16 *gain_pitch,     /* o   : pitch gain (Q14)                  */
491     Flag   *pOverflow
492 )
493 {
494     static const Word16 pdown[7] =
495     {
496         32767, 32112, 32112, 26214,
497         9830, 6553, 6553
498     };
499
500     Word16 tmp;
501
502     /* calculate median of last five gains */
503     tmp = gmed_n(st->pbuf, 5);
504
505     /* new gain = minimum(median, past_gain) * pdown[state] */
506     if (sub(tmp, st->past_gain_pit, pOverflow) > 0)
507     {
508         tmp = st->past_gain_pit;
509     }
510     *gain_pitch = mult(tmp, pdown[state], pOverflow);
511 }
512
513 /****************************************************************************/
514 /*
515 ------------------------------------------------------------------------------
516  FUNCTION NAME: ec_gain_pitch_reset
517 ------------------------------------------------------------------------------
518  INPUT AND OUTPUT DEFINITIONS
519
520  Inputs:
521   state = state of the state machine of type Word16
522   pOverflow = pointer to overflow indicator of type Flag
523
524   Outputs:
525   state = pointer to a pointer to a structure containing code
526           state data of stucture type ec_gain_pitchState
527   pOverflow = 1 if there is an overflow else it is zero.
528
529  Returns:
530     None.
531
532  Global Variables Used:
533     None.
534
535  Local Variables Needed:
536     None.
537
538 ------------------------------------------------------------------------------
539  FUNCTION DESCRIPTION
540
541  Function:   ec_gain_pitch_reset
542  Purpose:    Resets state memory
543
544 ------------------------------------------------------------------------------
545  REQUIREMENTS
546
547  None.
548
549 ------------------------------------------------------------------------------
550  REFERENCES
551
552  ec_gain.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
553
554 ------------------------------------------------------------------------------
555  PSEUDO-CODE
556
557 int ec_gain_pitch_reset (ec_gain_pitchState *state)
558 {
559   Word16 i;
560
561   if (state == (ec_gain_pitchState *) NULL){
562       // fprintf(stderr, "ec_gain_pitch_reset: invalid parameter\n");
563       return -1;
564   }
565
566   for(i = 0; i < 5; i++)
567       state->pbuf[i] = 1640;
568   state->past_gain_pit = 0;
569   state->prev_gp = 16384;
570
571   return 0;
572 }
573
574 ------------------------------------------------------------------------------
575  CAUTION [optional]
576  [State any special notes, constraints or cautions for users of this function]
577
578 ------------------------------------------------------------------------------
579 */
580 Word16 ec_gain_pitch_reset(ec_gain_pitchState *state)
581 {
582     Word16 i;
583
584     if (state == (ec_gain_pitchState *) NULL)
585     {
586         /* fprintf(stderr, "ec_gain_pitch_reset: invalid parameter\n"); */
587         return -1;
588     }
589
590     for (i = 0; i < 5; i++)
591         state->pbuf[i] = 1640;
592     state->past_gain_pit = 0;
593     state->prev_gp = 16384;
594
595     return 0;
596 }
597
598 /****************************************************************************/
599
600
601 /*
602 ------------------------------------------------------------------------------
603  FUNCTION NAME: ec_gain_pitch_update
604 ------------------------------------------------------------------------------
605  INPUT AND OUTPUT DEFINITIONS
606
607  Inputs:
608   st = pointer to a pointer to a structure containing code
609        state data of stucture type ec_gain_pitchState
610   bfi = flag indicating the frame is bad of type Word16
611   prev_bf = flag indicating the previous frame was bad of type Word16
612   gain_pitch = pointer to pitch gain of type Word16
613   pOverflow = pointer to overflow indicator of type Flag
614
615   Outputs:
616   state = pointer to a pointer to a structure containing code
617           state data of stucture type ec_gain_pitchState
618   gain_pitch = pointer to pitch gain of type Word16
619   pOverflow = 1 if there is an overflow else it is zero.
620
621  Returns:
622     None.
623
624  Global Variables Used:
625     None.
626
627  Local Variables Needed:
628     None.
629
630 ------------------------------------------------------------------------------
631  FUNCTION DESCRIPTION
632
633   Purpose     : update the pitch gain concealment state;
634                 limit gain_pitch if the previous frame was bad
635                 Call this function always after decoding (or concealing)
636                 the gain
637
638 ------------------------------------------------------------------------------
639  REQUIREMENTS
640
641  None.
642
643 ------------------------------------------------------------------------------
644  REFERENCES
645
646  ec_gain.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
647
648 ------------------------------------------------------------------------------
649  PSEUDO-CODE
650
651     Word16 i;
652
653     if (bfi == 0)
654     {
655         if (prev_bf != 0)
656         {
657             if (sub (*gain_pitch, st->prev_gp) > 0)
658             {
659                 *gain_pitch = st->prev_gp;
660             }
661         }
662         st->prev_gp = *gain_pitch;
663     }
664
665     st->past_gain_pit = *gain_pitch;
666
667     if (sub (st->past_gain_pit, 16384) > 0)  // if (st->past_gain_pit > 1.0)
668     {
669         st->past_gain_pit = 16384;
670     }
671     for (i = 1; i < 5; i++)
672     {
673         st->pbuf[i - 1] = st->pbuf[i];
674     }
675     st->pbuf[4] = st->past_gain_pit;
676
677
678 ------------------------------------------------------------------------------
679  CAUTION [optional]
680  [State any special notes, constraints or cautions for users of this function]
681
682 ------------------------------------------------------------------------------
683 */
684 void ec_gain_pitch_update(
685     ec_gain_pitchState *st, /* i/o : state variables                   */
686     Word16 bfi,             /* i   : flag: frame is bad                */
687     Word16 prev_bf,         /* i   : flag: previous frame was bad      */
688     Word16 *gain_pitch,     /* i/o : pitch gain                        */
689     Flag   *pOverflow
690 )
691 {
692     Word16 i;
693
694     if (bfi == 0)
695     {
696         if (prev_bf != 0)
697         {
698             if (sub(*gain_pitch, st->prev_gp, pOverflow) > 0)
699             {
700                 *gain_pitch = st->prev_gp;
701             }
702         }
703         st->prev_gp = *gain_pitch;
704     }
705
706     st->past_gain_pit = *gain_pitch;
707
708     if (sub(st->past_gain_pit, 16384, pOverflow) > 0)
709         /* if (st->past_gain_pit > 1.0) */
710     {
711         st->past_gain_pit = 16384;
712     }
713     for (i = 1; i < 5; i++)
714     {
715         st->pbuf[i - 1] = st->pbuf[i];
716     }
717     st->pbuf[4] = st->past_gain_pit;
718 }
719
720