1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
18 /****************************************************************************************
19 Portions of this file are derived from the following 3GPP standard:
22 ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
23 Available from http://www.3gpp.org
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 ****************************************************************************************/
30 ------------------------------------------------------------------------------
35 Filename: ec_gains.cpp
37 ------------------------------------------------------------------------------
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.
43 ------------------------------------------------------------------------------
47 /*----------------------------------------------------------------------------
49 ----------------------------------------------------------------------------*/
58 /*--------------------------------------------------------------------------*/
64 /*----------------------------------------------------------------------------
66 ; Define module specific macros here
67 ----------------------------------------------------------------------------*/
70 /*----------------------------------------------------------------------------
72 ; Include all pre-processor statements here. Include conditional
73 ; compile variables also.
74 ----------------------------------------------------------------------------*/
77 /*----------------------------------------------------------------------------
78 ; LOCAL FUNCTION DEFINITIONS
79 ; Function Prototype declaration
80 ----------------------------------------------------------------------------*/
83 /*----------------------------------------------------------------------------
84 ; LOCAL VARIABLE DEFINITIONS
85 ; Variable declaration - defined here and used outside this module
86 ----------------------------------------------------------------------------*/
88 /*--------------------------------------------------------------------------*/
94 ------------------------------------------------------------------------------
95 FUNCTION NAME: ec_gain_code_reset
96 ------------------------------------------------------------------------------
97 INPUT AND OUTPUT DEFINITIONS
100 state = pointer to a pointer to a structure containing code state data of
101 stucture type ec_gain_codeState
109 Global Variables Used:
112 Local Variables Needed:
115 ------------------------------------------------------------------------------
118 This function resets the state data for the ec_gain module.
120 ------------------------------------------------------------------------------
125 ------------------------------------------------------------------------------
130 ------------------------------------------------------------------------------
133 int ec_gain_code_reset (ec_gain_codeState *state)
137 if (state == (ec_gain_codeState *) NULL){
138 // fprintf(stderr, "ec_gain_code_reset: invalid parameter\n");
142 for ( i = 0; i < 5; i++)
144 state->past_gain_code = 0;
150 ------------------------------------------------------------------------------
152 [State any special notes, constraints or cautions for users of this function]
154 ------------------------------------------------------------------------------
157 Word16 ec_gain_code_reset(ec_gain_codeState *state)
161 if (state == (ec_gain_codeState *) NULL)
163 /* fprintf(stderr, "ec_gain_code_reset: invalid parameter\n"); */
167 for (i = 0; i < 5; i++)
169 state->past_gain_code = 0;
176 ------------------------------------------------------------------------------
177 FUNCTION NAME: ec_gain_code
178 ------------------------------------------------------------------------------
179 INPUT AND OUTPUT DEFINITIONS
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
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.
198 Global Variables Used:
201 Local Variables Needed:
204 ------------------------------------------------------------------------------
207 This function does error concealment using the codebook. Call this function
208 only in BFI (instead of normal gain decoding function).
210 ------------------------------------------------------------------------------
215 ------------------------------------------------------------------------------
218 ec_gain.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
220 ------------------------------------------------------------------------------
223 static const Word16 cdown[7] =
225 32767, 32112, 32112, 32112,
230 Word16 qua_ener_MR122;
233 // calculate median of last five gain values
234 tmp = gmed_n (st->gbuf,5);
236 // new gain = minimum(median, past_gain) * cdown[state]
237 if (sub (tmp, st->past_gain_code) > 0)
239 tmp = st->past_gain_code;
241 tmp = mult (tmp, cdown[state]);
244 // update table of past quantized energies with average of
247 gc_pred_average_limited(pred_state, &qua_ener_MR122, &qua_ener);
248 gc_pred_update(pred_state, qua_ener_MR122, qua_ener);
251 ------------------------------------------------------------------------------
253 [State any special notes, constraints or cautions for users of this function]
255 ------------------------------------------------------------------------------
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 */
265 static const Word16 cdown[7] =
267 32767, 32112, 32112, 32112,
272 Word16 qua_ener_MR122;
275 /* calculate median of last five gain values */
276 tmp = gmed_n(st->gbuf, 5);
278 /* new gain = minimum(median, past_gain) * cdown[state] */
279 if (sub(tmp, st->past_gain_code, pOverflow) > 0)
281 tmp = st->past_gain_code;
283 tmp = mult(tmp, cdown[state], pOverflow);
286 /* update table of past quantized energies with average of
289 gc_pred_average_limited(pred_state, &qua_ener_MR122, &qua_ener, pOverflow);
290 gc_pred_update(pred_state, qua_ener_MR122, qua_ener);
293 /****************************************************************************/
296 ------------------------------------------------------------------------------
297 FUNCTION NAME: ec_gain_code_update
298 ------------------------------------------------------------------------------
299 INPUT AND OUTPUT DEFINITIONS
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
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.
318 Global Variables Used:
321 Local Variables Needed:
324 ------------------------------------------------------------------------------
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)
332 ------------------------------------------------------------------------------
337 ------------------------------------------------------------------------------
340 ec_gain.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
342 ------------------------------------------------------------------------------
347 // limit gain_code by previous good gain if previous frame was bad
352 if (sub (*gain_code, st->prev_gc) > 0)
354 *gain_code = st->prev_gc;
357 st->prev_gc = *gain_code;
360 // update EC states: previous gain, gain buffer
361 st->past_gain_code = *gain_code;
363 for (i = 1; i < 5; i++)
365 st->gbuf[i - 1] = st->gbuf[i];
367 st->gbuf[4] = *gain_code;
372 ------------------------------------------------------------------------------
374 [State any special notes, constraints or cautions for users of this function]
376 ------------------------------------------------------------------------------
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 */
388 /* limit gain_code by previous good gain if previous frame was bad */
393 if (sub(*gain_code, st->prev_gc, pOverflow) > 0)
395 *gain_code = st->prev_gc;
398 st->prev_gc = *gain_code;
401 /* update EC states: previous gain, gain buffer */
402 st->past_gain_code = *gain_code;
404 for (i = 1; i < 5; i++)
406 st->gbuf[i - 1] = st->gbuf[i];
408 st->gbuf[4] = *gain_code;
413 /****************************************************************************/
416 ------------------------------------------------------------------------------
417 FUNCTION NAME: ec_gain_pitch
418 ------------------------------------------------------------------------------
419 INPUT AND OUTPUT DEFINITIONS
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
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.
436 Global Variables Used:
439 Local Variables Needed:
442 ------------------------------------------------------------------------------
445 This function conceals the error using code gain implementation in this
448 ------------------------------------------------------------------------------
453 ------------------------------------------------------------------------------
456 ec_gain.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
458 ------------------------------------------------------------------------------
462 static const Word16 pdown[7] =
464 32767, 32112, 32112, 26214,
470 // calculate median of last five gains
471 tmp = gmed_n (st->pbuf, 5);
473 // new gain = minimum(median, past_gain) * pdown[state]
474 if (sub (tmp, st->past_gain_pit) > 0)
476 tmp = st->past_gain_pit;
478 *gain_pitch = mult (tmp, pdown[state]);
481 ------------------------------------------------------------------------------
483 [State any special notes, constraints or cautions for users of this function]
485 ------------------------------------------------------------------------------
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) */
494 static const Word16 pdown[7] =
496 32767, 32112, 32112, 26214,
502 /* calculate median of last five gains */
503 tmp = gmed_n(st->pbuf, 5);
505 /* new gain = minimum(median, past_gain) * pdown[state] */
506 if (sub(tmp, st->past_gain_pit, pOverflow) > 0)
508 tmp = st->past_gain_pit;
510 *gain_pitch = mult(tmp, pdown[state], pOverflow);
513 /****************************************************************************/
515 ------------------------------------------------------------------------------
516 FUNCTION NAME: ec_gain_pitch_reset
517 ------------------------------------------------------------------------------
518 INPUT AND OUTPUT DEFINITIONS
521 state = state of the state machine of type Word16
522 pOverflow = pointer to overflow indicator of type Flag
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.
532 Global Variables Used:
535 Local Variables Needed:
538 ------------------------------------------------------------------------------
541 Function: ec_gain_pitch_reset
542 Purpose: Resets state memory
544 ------------------------------------------------------------------------------
549 ------------------------------------------------------------------------------
552 ec_gain.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
554 ------------------------------------------------------------------------------
557 int ec_gain_pitch_reset (ec_gain_pitchState *state)
561 if (state == (ec_gain_pitchState *) NULL){
562 // fprintf(stderr, "ec_gain_pitch_reset: invalid parameter\n");
566 for(i = 0; i < 5; i++)
567 state->pbuf[i] = 1640;
568 state->past_gain_pit = 0;
569 state->prev_gp = 16384;
574 ------------------------------------------------------------------------------
576 [State any special notes, constraints or cautions for users of this function]
578 ------------------------------------------------------------------------------
580 Word16 ec_gain_pitch_reset(ec_gain_pitchState *state)
584 if (state == (ec_gain_pitchState *) NULL)
586 /* fprintf(stderr, "ec_gain_pitch_reset: invalid parameter\n"); */
590 for (i = 0; i < 5; i++)
591 state->pbuf[i] = 1640;
592 state->past_gain_pit = 0;
593 state->prev_gp = 16384;
598 /****************************************************************************/
602 ------------------------------------------------------------------------------
603 FUNCTION NAME: ec_gain_pitch_update
604 ------------------------------------------------------------------------------
605 INPUT AND OUTPUT DEFINITIONS
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
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.
624 Global Variables Used:
627 Local Variables Needed:
630 ------------------------------------------------------------------------------
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)
638 ------------------------------------------------------------------------------
643 ------------------------------------------------------------------------------
646 ec_gain.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
648 ------------------------------------------------------------------------------
657 if (sub (*gain_pitch, st->prev_gp) > 0)
659 *gain_pitch = st->prev_gp;
662 st->prev_gp = *gain_pitch;
665 st->past_gain_pit = *gain_pitch;
667 if (sub (st->past_gain_pit, 16384) > 0) // if (st->past_gain_pit > 1.0)
669 st->past_gain_pit = 16384;
671 for (i = 1; i < 5; i++)
673 st->pbuf[i - 1] = st->pbuf[i];
675 st->pbuf[4] = st->past_gain_pit;
678 ------------------------------------------------------------------------------
680 [State any special notes, constraints or cautions for users of this function]
682 ------------------------------------------------------------------------------
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 */
698 if (sub(*gain_pitch, st->prev_gp, pOverflow) > 0)
700 *gain_pitch = st->prev_gp;
703 st->prev_gp = *gain_pitch;
706 st->past_gain_pit = *gain_pitch;
708 if (sub(st->past_gain_pit, 16384, pOverflow) > 0)
709 /* if (st->past_gain_pit > 1.0) */
711 st->past_gain_pit = 16384;
713 for (i = 1; i < 5; i++)
715 st->pbuf[i - 1] = st->pbuf[i];
717 st->pbuf[4] = st->past_gain_pit;