/* ------------------------------------------------------------------ * Copyright (C) 1998-2009 PacketVideo * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. * See the License for the specific language governing permissions * and limitations under the License. * ------------------------------------------------------------------- */ /**************************************************************************************** Portions of this file are derived from the following 3GPP standard: 3GPP TS 26.073 ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec Available from http://www.3gpp.org (C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) Permission to distribute, modify and use this file under the standard license terms listed above has been obtained from the copyright holder. ****************************************************************************************/ /* ------------------------------------------------------------------------------ Pathname: ./audio/gsm-amr/c/src/ec_gain.c Funtions: Date: 01/28/2002 ------------------------------------------------------------------------------ REVISION HISTORY Description: Removed the functions ec_gain_code_init, ec_gain_pitch_init, ech_gain_code_exit, and ec_gain_pitch_exit. The ec_gains related structures are no longer dynamically allocated. Description: Updated include files and input/output sections. Description: Replaced OSCL mem type functions and eliminated include files that now are chosen by OSCL definitions Description: Replaced "int" and/or "char" with OSCL defined types. Description: Added #ifdef __cplusplus around extern'ed table. Description: ------------------------------------------------------------------------------ MODULE DESCRIPTION These modules execute the code book gains for error concealment. This module contains the init, reset, exit, and "main" functions in this process. ------------------------------------------------------------------------------ */ /*---------------------------------------------------------------------------- ; INCLUDES ----------------------------------------------------------------------------*/ #include "ec_gains.h" #include "typedef.h" #include "cnst.h" #include "gmed_n.h" #include "gc_pred.h" #include "basic_op.h" /*--------------------------------------------------------------------------*/ #ifdef __cplusplus extern "C" { #endif /*---------------------------------------------------------------------------- ; MACROS ; Define module specific macros here ----------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------- ; DEFINES ; Include all pre-processor statements here. Include conditional ; compile variables also. ----------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------- ; LOCAL FUNCTION DEFINITIONS ; Function Prototype declaration ----------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------- ; LOCAL VARIABLE DEFINITIONS ; Variable declaration - defined here and used outside this module ----------------------------------------------------------------------------*/ extern const Word16 qua_gain_pitch[]; extern const Word16 qua_gain_code[]; /*--------------------------------------------------------------------------*/ #ifdef __cplusplus } #endif /* ------------------------------------------------------------------------------ FUNCTION NAME: ec_gain_code_reset ------------------------------------------------------------------------------ INPUT AND OUTPUT DEFINITIONS Inputs: state = pointer to a pointer to a structure containing code state data of stucture type ec_gain_codeState Outputs: None. Returns: None Global Variables Used: None. Local Variables Needed: None. ------------------------------------------------------------------------------ FUNCTION DESCRIPTION This function resets the state data for the ec_gain module. ------------------------------------------------------------------------------ REQUIREMENTS None ------------------------------------------------------------------------------ REFERENCES None ------------------------------------------------------------------------------ PSEUDO-CODE int ec_gain_code_reset (ec_gain_codeState *state) { Word16 i; if (state == (ec_gain_codeState *) NULL){ // fprintf(stderr, "ec_gain_code_reset: invalid parameter\n"); return -1; } for ( i = 0; i < 5; i++) state->gbuf[i] = 1; state->past_gain_code = 0; state->prev_gc = 1; return 0; } ------------------------------------------------------------------------------ RESOURCES USED [optional] When the code is written for a specific target processor the the resources used should be documented below. HEAP MEMORY USED: x bytes STACK MEMORY USED: x bytes CLOCK CYCLES: (cycle count equation for this function) + (variable used to represent cycle count for each subroutine called) where: (cycle count variable) = cycle count for [subroutine name] ------------------------------------------------------------------------------ CAUTION [optional] [State any special notes, constraints or cautions for users of this function] ------------------------------------------------------------------------------ */ Word16 ec_gain_code_reset(ec_gain_codeState *state) { Word16 i; if (state == (ec_gain_codeState *) NULL) { /* fprintf(stderr, "ec_gain_code_reset: invalid parameter\n"); */ return -1; } for (i = 0; i < 5; i++) state->gbuf[i] = 1; state->past_gain_code = 0; state->prev_gc = 1; return 0; } /* ------------------------------------------------------------------------------ FUNCTION NAME: ec_gain_code ------------------------------------------------------------------------------ INPUT AND OUTPUT DEFINITIONS Inputs: st = pointer to a pointer to a structure containing code state data of stucture type ec_gain_codeState pred_state = pointer to MA predictor state of type gc_predState state = state of the state machine of type Word16 gain_code = pointer to decoded innovation gain of type Word16 pOverflow = pointer to overflow indicator of type Flag Outputs: st = pointer to a pointer to a structure containing code state data of stucture type ec_gain_codeState pred_state = pointer to MA predictor state of type gc_predState pOverflow = 1 if there is an overflow else it is zero. Returns: None. Global Variables Used: None. Local Variables Needed: None. ------------------------------------------------------------------------------ FUNCTION DESCRIPTION This function does error concealment using the codebook. Call this function only in BFI (instead of normal gain decoding function). ------------------------------------------------------------------------------ REQUIREMENTS None. ------------------------------------------------------------------------------ REFERENCES ec_gain.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 ------------------------------------------------------------------------------ PSEUDO-CODE static const Word16 cdown[7] = { 32767, 32112, 32112, 32112, 32112, 32112, 22937 }; Word16 tmp; Word16 qua_ener_MR122; Word16 qua_ener; // calculate median of last five gain values tmp = gmed_n (st->gbuf,5); // new gain = minimum(median, past_gain) * cdown[state] if (sub (tmp, st->past_gain_code) > 0) { tmp = st->past_gain_code; } tmp = mult (tmp, cdown[state]); *gain_code = tmp; // update table of past quantized energies with average of // current values gc_pred_average_limited(pred_state, &qua_ener_MR122, &qua_ener); gc_pred_update(pred_state, qua_ener_MR122, qua_ener); } ------------------------------------------------------------------------------ RESOURCES USED [optional] When the code is written for a specific target processor the the resources used should be documented below. HEAP MEMORY USED: x bytes STACK MEMORY USED: x bytes CLOCK CYCLES: (cycle count equation for this function) + (variable used to represent cycle count for each subroutine called) where: (cycle count variable) = cycle count for [subroutine name] ------------------------------------------------------------------------------ CAUTION [optional] [State any special notes, constraints or cautions for users of this function] ------------------------------------------------------------------------------ */ void ec_gain_code( ec_gain_codeState *st, /* i/o : State struct */ gc_predState *pred_state, /* i/o : MA predictor state */ Word16 state, /* i : state of the state machine */ Word16 *gain_code, /* o : decoded innovation gain */ Flag *pOverflow ) { static const Word16 cdown[7] = { 32767, 32112, 32112, 32112, 32112, 32112, 22937 }; Word16 tmp; Word16 qua_ener_MR122; Word16 qua_ener; /* calculate median of last five gain values */ tmp = gmed_n(st->gbuf, 5); /* new gain = minimum(median, past_gain) * cdown[state] */ if (sub(tmp, st->past_gain_code, pOverflow) > 0) { tmp = st->past_gain_code; } tmp = mult(tmp, cdown[state], pOverflow); *gain_code = tmp; /* update table of past quantized energies with average of * current values */ gc_pred_average_limited(pred_state, &qua_ener_MR122, &qua_ener, pOverflow); gc_pred_update(pred_state, qua_ener_MR122, qua_ener); } /****************************************************************************/ /* ------------------------------------------------------------------------------ FUNCTION NAME: ec_gain_code_update ------------------------------------------------------------------------------ INPUT AND OUTPUT DEFINITIONS Inputs: st = pointer to a pointer to a structure containing code state data of stucture type ec_gain_codeState bfi = a flag that indicates if the frame is bad of type Word16 prev_bf = a flag that indicates if the previous frame was bad of type Word16 gain_code = pointer to decoded innovation gain of type Word16 pOverflow = pointer to overflow indicator of type Flag Outputs: st = pointer to a pointer to a structure containing code state data of stucture type ec_gain_codeState gain_code = pointer to decoded innovation gain of type Word16 pOverflow = 1 if there is an overflow else it is zero. Returns: None. Global Variables Used: None. Local Variables Needed: None. ------------------------------------------------------------------------------ FUNCTION DESCRIPTION Purpose : update the codebook gain concealment state; limit gain_code if the previous frame was bad Call this function always after decoding (or concealing) the gain ------------------------------------------------------------------------------ REQUIREMENTS None. ------------------------------------------------------------------------------ REFERENCES ec_gain.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 ------------------------------------------------------------------------------ PSEUDO-CODE Word16 i; // limit gain_code by previous good gain if previous frame was bad if (bfi == 0) { if (prev_bf != 0) { if (sub (*gain_code, st->prev_gc) > 0) { *gain_code = st->prev_gc; } } st->prev_gc = *gain_code; } // update EC states: previous gain, gain buffer st->past_gain_code = *gain_code; for (i = 1; i < 5; i++) { st->gbuf[i - 1] = st->gbuf[i]; } st->gbuf[4] = *gain_code; return; } ------------------------------------------------------------------------------ RESOURCES USED [optional] When the code is written for a specific target processor the the resources used should be documented below. HEAP MEMORY USED: x bytes STACK MEMORY USED: x bytes CLOCK CYCLES: (cycle count equation for this function) + (variable used to represent cycle count for each subroutine called) where: (cycle count variable) = cycle count for [subroutine name] ------------------------------------------------------------------------------ CAUTION [optional] [State any special notes, constraints or cautions for users of this function] ------------------------------------------------------------------------------ */ void ec_gain_code_update( ec_gain_codeState *st, /* i/o : State struct */ Word16 bfi, /* i : flag: frame is bad */ Word16 prev_bf, /* i : flag: previous frame was bad */ Word16 *gain_code, /* i/o : decoded innovation gain */ Flag *pOverflow ) { Word16 i; /* limit gain_code by previous good gain if previous frame was bad */ if (bfi == 0) { if (prev_bf != 0) { if (sub(*gain_code, st->prev_gc, pOverflow) > 0) { *gain_code = st->prev_gc; } } st->prev_gc = *gain_code; } /* update EC states: previous gain, gain buffer */ st->past_gain_code = *gain_code; for (i = 1; i < 5; i++) { st->gbuf[i - 1] = st->gbuf[i]; } st->gbuf[4] = *gain_code; return; } /****************************************************************************/ /* ------------------------------------------------------------------------------ FUNCTION NAME: ec_gain_pitch ------------------------------------------------------------------------------ INPUT AND OUTPUT DEFINITIONS Inputs: st = pointer to a pointer to a structure containing code state data of stucture type ec_gain_pitchState state = state of the state machine of type Word16 pOverflow = pointer to overflow indicator of type Flag Outputs: state = pointer to a pointer to a structure containing code state data of stucture type ec_gain_pitchState gain_pitch = pointer to pitch gain (Q14) of type Word16 pOverflow = 1 if there is an overflow else it is zero. Returns: None. Global Variables Used: None. Local Variables Needed: None. ------------------------------------------------------------------------------ FUNCTION DESCRIPTION This function conceals the error using code gain implementation in this function. ------------------------------------------------------------------------------ REQUIREMENTS None. ------------------------------------------------------------------------------ REFERENCES ec_gain.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 ------------------------------------------------------------------------------ PSEUDO-CODE static const Word16 pdown[7] = { 32767, 32112, 32112, 26214, 9830, 6553, 6553 }; Word16 tmp; // calculate median of last five gains tmp = gmed_n (st->pbuf, 5); // new gain = minimum(median, past_gain) * pdown[state] if (sub (tmp, st->past_gain_pit) > 0) { tmp = st->past_gain_pit; } *gain_pitch = mult (tmp, pdown[state]); ------------------------------------------------------------------------------ RESOURCES USED [optional] When the code is written for a specific target processor the the resources used should be documented below. HEAP MEMORY USED: x bytes STACK MEMORY USED: x bytes CLOCK CYCLES: (cycle count equation for this function) + (variable used to represent cycle count for each subroutine called) where: (cycle count variable) = cycle count for [subroutine name] ------------------------------------------------------------------------------ CAUTION [optional] [State any special notes, constraints or cautions for users of this function] ------------------------------------------------------------------------------ */ void ec_gain_pitch( ec_gain_pitchState *st, /* i/o : state variables */ Word16 state, /* i : state of the state machine */ Word16 *gain_pitch, /* o : pitch gain (Q14) */ Flag *pOverflow ) { static const Word16 pdown[7] = { 32767, 32112, 32112, 26214, 9830, 6553, 6553 }; Word16 tmp; /* calculate median of last five gains */ tmp = gmed_n(st->pbuf, 5); /* new gain = minimum(median, past_gain) * pdown[state] */ if (sub(tmp, st->past_gain_pit, pOverflow) > 0) { tmp = st->past_gain_pit; } *gain_pitch = mult(tmp, pdown[state], pOverflow); } /****************************************************************************/ /* ------------------------------------------------------------------------------ FUNCTION NAME: ec_gain_pitch_reset ------------------------------------------------------------------------------ INPUT AND OUTPUT DEFINITIONS Inputs: state = state of the state machine of type Word16 pOverflow = pointer to overflow indicator of type Flag Outputs: state = pointer to a pointer to a structure containing code state data of stucture type ec_gain_pitchState pOverflow = 1 if there is an overflow else it is zero. Returns: None. Global Variables Used: None. Local Variables Needed: None. ------------------------------------------------------------------------------ FUNCTION DESCRIPTION Function: ec_gain_pitch_reset Purpose: Resets state memory ------------------------------------------------------------------------------ REQUIREMENTS None. ------------------------------------------------------------------------------ REFERENCES ec_gain.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 ------------------------------------------------------------------------------ PSEUDO-CODE int ec_gain_pitch_reset (ec_gain_pitchState *state) { Word16 i; if (state == (ec_gain_pitchState *) NULL){ // fprintf(stderr, "ec_gain_pitch_reset: invalid parameter\n"); return -1; } for(i = 0; i < 5; i++) state->pbuf[i] = 1640; state->past_gain_pit = 0; state->prev_gp = 16384; return 0; } ------------------------------------------------------------------------------ RESOURCES USED [optional] When the code is written for a specific target processor the the resources used should be documented below. HEAP MEMORY USED: x bytes STACK MEMORY USED: x bytes CLOCK CYCLES: (cycle count equation for this function) + (variable used to represent cycle count for each subroutine called) where: (cycle count variable) = cycle count for [subroutine name] ------------------------------------------------------------------------------ CAUTION [optional] [State any special notes, constraints or cautions for users of this function] ------------------------------------------------------------------------------ */ Word16 ec_gain_pitch_reset(ec_gain_pitchState *state) { Word16 i; if (state == (ec_gain_pitchState *) NULL) { /* fprintf(stderr, "ec_gain_pitch_reset: invalid parameter\n"); */ return -1; } for (i = 0; i < 5; i++) state->pbuf[i] = 1640; state->past_gain_pit = 0; state->prev_gp = 16384; return 0; } /****************************************************************************/ /* ------------------------------------------------------------------------------ FUNCTION NAME: ec_gain_pitch_update ------------------------------------------------------------------------------ INPUT AND OUTPUT DEFINITIONS Inputs: st = pointer to a pointer to a structure containing code state data of stucture type ec_gain_pitchState bfi = flag indicating the frame is bad of type Word16 prev_bf = flag indicating the previous frame was bad of type Word16 gain_pitch = pointer to pitch gain of type Word16 pOverflow = pointer to overflow indicator of type Flag Outputs: state = pointer to a pointer to a structure containing code state data of stucture type ec_gain_pitchState gain_pitch = pointer to pitch gain of type Word16 pOverflow = 1 if there is an overflow else it is zero. Returns: None. Global Variables Used: None. Local Variables Needed: None. ------------------------------------------------------------------------------ FUNCTION DESCRIPTION Purpose : update the pitch gain concealment state; limit gain_pitch if the previous frame was bad Call this function always after decoding (or concealing) the gain ------------------------------------------------------------------------------ REQUIREMENTS None. ------------------------------------------------------------------------------ REFERENCES ec_gain.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 ------------------------------------------------------------------------------ PSEUDO-CODE Word16 i; if (bfi == 0) { if (prev_bf != 0) { if (sub (*gain_pitch, st->prev_gp) > 0) { *gain_pitch = st->prev_gp; } } st->prev_gp = *gain_pitch; } st->past_gain_pit = *gain_pitch; if (sub (st->past_gain_pit, 16384) > 0) // if (st->past_gain_pit > 1.0) { st->past_gain_pit = 16384; } for (i = 1; i < 5; i++) { st->pbuf[i - 1] = st->pbuf[i]; } st->pbuf[4] = st->past_gain_pit; ------------------------------------------------------------------------------ RESOURCES USED [optional] When the code is written for a specific target processor the the resources used should be documented below. HEAP MEMORY USED: x bytes STACK MEMORY USED: x bytes CLOCK CYCLES: (cycle count equation for this function) + (variable used to represent cycle count for each subroutine called) where: (cycle count variable) = cycle count for [subroutine name] ------------------------------------------------------------------------------ CAUTION [optional] [State any special notes, constraints or cautions for users of this function] ------------------------------------------------------------------------------ */ void ec_gain_pitch_update( ec_gain_pitchState *st, /* i/o : state variables */ Word16 bfi, /* i : flag: frame is bad */ Word16 prev_bf, /* i : flag: previous frame was bad */ Word16 *gain_pitch, /* i/o : pitch gain */ Flag *pOverflow ) { Word16 i; if (bfi == 0) { if (prev_bf != 0) { if (sub(*gain_pitch, st->prev_gp, pOverflow) > 0) { *gain_pitch = st->prev_gp; } } st->prev_gp = *gain_pitch; } st->past_gain_pit = *gain_pitch; if (sub(st->past_gain_pit, 16384, pOverflow) > 0) /* if (st->past_gain_pit > 1.0) */ { st->past_gain_pit = 16384; } for (i = 1; i < 5; i++) { st->pbuf[i - 1] = st->pbuf[i]; } st->pbuf[4] = st->past_gain_pit; }