diff options
Diffstat (limited to 'media/libstagefright/codecs/amrnb/dec/src/dec_amr.cpp')
-rw-r--r-- | media/libstagefright/codecs/amrnb/dec/src/dec_amr.cpp | 2374 |
1 files changed, 2374 insertions, 0 deletions
diff --git a/media/libstagefright/codecs/amrnb/dec/src/dec_amr.cpp b/media/libstagefright/codecs/amrnb/dec/src/dec_amr.cpp new file mode 100644 index 0000000..be15475 --- /dev/null +++ b/media/libstagefright/codecs/amrnb/dec/src/dec_amr.cpp @@ -0,0 +1,2374 @@ +/* ------------------------------------------------------------------ + * 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/dec_amr.c + Funtions: Decoder_amr_init + Decoder_amr_reset + Decoder_amr + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + This file contains the function used to decode one speech frame using a given + codec mode. The functions used to initialize, reset, and exit are also + included in this file. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include <string.h> + +#include "dec_amr.h" +#include "typedef.h" +#include "cnst.h" +#include "copy.h" +#include "set_zero.h" +#include "syn_filt.h" +#include "d_plsf.h" +#include "agc.h" +#include "int_lpc.h" +#include "dec_gain.h" +#include "dec_lag3.h" +#include "dec_lag6.h" +#include "d2_9pf.h" +#include "d2_11pf.h" +#include "d3_14pf.h" +#include "d4_17pf.h" +#include "d8_31pf.h" +#include "d1035pf.h" +#include "pred_lt.h" +#include "d_gain_p.h" +#include "d_gain_c.h" +#include "dec_gain.h" +#include "ec_gains.h" +#include "ph_disp.h" +#include "c_g_aver.h" +#include "int_lsf.h" +#include "lsp_lsf.h" +#include "lsp_avg.h" +#include "bgnscd.h" +#include "ex_ctrl.h" +#include "sqrt_l.h" +#include "frame.h" +#include "bitno_tab.h" +#include "b_cn_cod.h" +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; 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 +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Decoder_amr_init +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to a pointer to structures of type Decoder_amrState + + Outputs: + structure pointed to by the pointer which is pointed to by state is + initialized to each field's initial values + + state pointer points to the address of the memory allocated by + Decoder_amr_init function + + Returns: + return_value = 0, if the initialization was successful; -1, otherwise (int) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function allocates and initializes state memory used by the Decoder_amr + function. It stores the pointer to the filter status structure in state. This + pointer has to be passed to Decoder_amr in each call. The function returns + 0, if initialization was successful and -1, otherwise. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + dec_amr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int Decoder_amr_init (Decoder_amrState **state) +{ + Decoder_amrState* s; + Word16 i; + + if (state == (Decoder_amrState **) NULL){ + fprintf(stderr, "Decoder_amr_init: invalid parameter\n"); + return -1; + } + *state = NULL; + + // allocate memory + if ((s= (Decoder_amrState *) malloc(sizeof(Decoder_amrState))) == NULL){ + fprintf(stderr, "Decoder_amr_init: can not malloc state structure\n"); + return -1; + } + + s->T0_lagBuff = 40; + s->inBackgroundNoise = 0; + s->voicedHangover = 0; + for (i = 0; i < 9; i++) + s->ltpGainHistory[i] = 0; + + s->lsfState = NULL; + s->ec_gain_p_st = NULL; + s->ec_gain_c_st = NULL; + s->pred_state = NULL; + s->ph_disp_st = NULL; + s->dtxDecoderState = NULL; + + if (D_plsf_init(&s->lsfState) || + ec_gain_pitch_init(&s->ec_gain_p_st) || + ec_gain_code_init(&s->ec_gain_c_st) || + gc_pred_init(&s->pred_state) || + Cb_gain_average_init(&s->Cb_gain_averState) || + lsp_avg_init(&s->lsp_avg_st) || + Bgn_scd_init(&s->background_state) || + ph_disp_init(&s->ph_disp_st) || + dtx_dec_init(&s->dtxDecoderState)) { + Decoder_amr_exit(&s); + return -1; + } + + Decoder_amr_reset(s, (enum Mode)0); + *state = s; + + 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 Decoder_amr_init(Decoder_amrState *s) +{ + Word16 i; + + if (s == (Decoder_amrState *) NULL) + { + /* fprint(stderr, "Decoder_amr_init: invalid parameter\n"); */ + return(-1); + } + + s->T0_lagBuff = 40; + s->inBackgroundNoise = 0; + s->voicedHangover = 0; + + /* Initialize overflow Flag */ + + s->overflow = 0; + + for (i = 0; i < LTP_GAIN_HISTORY_LEN; i++) + { + s->ltpGainHistory[i] = 0; + } + + D_plsf_reset(&s->lsfState); + ec_gain_pitch_reset(&s->ec_gain_p_st); + ec_gain_code_reset(&s->ec_gain_c_st); + Cb_gain_average_reset(&s->Cb_gain_averState); + lsp_avg_reset(&s->lsp_avg_st); + Bgn_scd_reset(&s->background_state); + ph_disp_reset(&s->ph_disp_st); + dtx_dec_reset(&s->dtxDecoderState); + gc_pred_reset(&s->pred_state); + + Decoder_amr_reset(s, MR475); + + return(0); +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Decoder_amr_reset +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to a structure of type Decoder_amrState + mode = codec mode (enum Mode) + + Outputs: + structure pointed to by state is initialized to its reset value + + Returns: + return_value = 0, if reset was successful; -1, otherwise (int) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function resets the state memory used by the Decoder_amr function. It + returns a 0, if reset was successful and -1, otherwise. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + dec_amr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int Decoder_amr_reset (Decoder_amrState *state, enum Mode mode) +{ + Word16 i; + + if (state == (Decoder_amrState *) NULL){ + fprintf(stderr, "Decoder_amr_reset: invalid parameter\n"); + return -1; + } + + // Initialize static pointer + state->exc = state->old_exc + PIT_MAX + L_INTERPOL; + + // Static vectors to zero + Set_zero (state->old_exc, PIT_MAX + L_INTERPOL); + + if (mode != MRDTX) + Set_zero (state->mem_syn, M); + + // initialize pitch sharpening + state->sharp = SHARPMIN; + state->old_T0 = 40; + + // Initialize state->lsp_old [] + + if (mode != MRDTX) { + Copy(lsp_init_data, &state->lsp_old[0], M); + } + + // Initialize memories of bad frame handling + state->prev_bf = 0; + state->prev_pdf = 0; + state->state = 0; + + state->T0_lagBuff = 40; + state->inBackgroundNoise = 0; + state->voicedHangover = 0; + if (mode != MRDTX) { + for (i=0;i<9;i++) + state->excEnergyHist[i] = 0; + } + + for (i = 0; i < 9; i++) + state->ltpGainHistory[i] = 0; + + Cb_gain_average_reset(state->Cb_gain_averState); + if (mode != MRDTX) + lsp_avg_reset(state->lsp_avg_st); + D_plsf_reset(state->lsfState); + ec_gain_pitch_reset(state->ec_gain_p_st); + ec_gain_code_reset(state->ec_gain_c_st); + + if (mode != MRDTX) + gc_pred_reset(state->pred_state); + + Bgn_scd_reset(state->background_state); + state->nodataSeed = 21845; + ph_disp_reset(state->ph_disp_st); + if (mode != MRDTX) + dtx_dec_reset(state->dtxDecoderState); + + 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 Decoder_amr_reset(Decoder_amrState *state, enum Mode mode) +{ + Word16 i; + + if (state == (Decoder_amrState *) NULL) + { + /* fprint(stderr, "Decoder_amr_reset: invalid parameter\n"); */ + return(-1); + } + + /* Initialize static pointer */ + state->exc = state->old_exc + PIT_MAX + L_INTERPOL; + + /* Static vectors to zero */ + memset(state->old_exc, 0, sizeof(Word16)*(PIT_MAX + L_INTERPOL)); + + if (mode != MRDTX) + { + memset(state->mem_syn, 0, sizeof(Word16)*M); + } + /* initialize pitch sharpening */ + state->sharp = SHARPMIN; + state->old_T0 = 40; + + /* Initialize overflow Flag */ + + state->overflow = 0; + + /* Initialize state->lsp_old [] */ + + if (mode != MRDTX) + { + state->lsp_old[0] = 30000; + state->lsp_old[1] = 26000; + state->lsp_old[2] = 21000; + state->lsp_old[3] = 15000; + state->lsp_old[4] = 8000; + state->lsp_old[5] = 0; + state->lsp_old[6] = -8000; + state->lsp_old[7] = -15000; + state->lsp_old[8] = -21000; + state->lsp_old[9] = -26000; + } + + /* Initialize memories of bad frame handling */ + state->prev_bf = 0; + state->prev_pdf = 0; + state->state = 0; + + state->T0_lagBuff = 40; + state->inBackgroundNoise = 0; + state->voicedHangover = 0; + if (mode != MRDTX) + { + for (i = 0; i < EXC_ENERGY_HIST_LEN; i++) + { + state->excEnergyHist[i] = 0; + } + } + + for (i = 0; i < LTP_GAIN_HISTORY_LEN; i++) + { + state->ltpGainHistory[i] = 0; + } + + Cb_gain_average_reset(&(state->Cb_gain_averState)); + if (mode != MRDTX) + { + lsp_avg_reset(&(state->lsp_avg_st)); + } + D_plsf_reset(&(state->lsfState)); + ec_gain_pitch_reset(&(state->ec_gain_p_st)); + ec_gain_code_reset(&(state->ec_gain_c_st)); + + if (mode != MRDTX) + { + gc_pred_reset(&(state->pred_state)); + } + + Bgn_scd_reset(&(state->background_state)); + state->nodataSeed = 21845; + ph_disp_reset(&(state->ph_disp_st)); + if (mode != MRDTX) + { + dtx_dec_reset(&(state->dtxDecoderState)); + } + + return(0); +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Decoder_amr +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st = pointer to a structure of type Decoder_amrState + mode = codec mode (enum Mode) + parm = buffer of synthesis parameters (Word16) + frame_type = received frame type (enum RXFrameType) + synth = buffer containing synthetic speech (Word16) + A_t = buffer containing decoded LP filter in 4 subframes (Word16) + + Outputs: + structure pointed to by st contains the newly calculated decoder + parameters + synth buffer contains the decoded speech samples + A_t buffer contains the decoded LP filter parameters + + Returns: + return_value = 0 (int) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function performs the decoding of one speech frame for a given codec + mode. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + dec_amr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int Decoder_amr ( + Decoder_amrState *st, // i/o : State variables + enum Mode mode, // i : AMR mode + Word16 parm[], // i : vector of synthesis parameters + (PRM_SIZE) + enum RXFrameType frame_type, // i : received frame type + Word16 synth[], // o : synthesis speech (L_FRAME) + Word16 A_t[] // o : decoded LP filter in 4 subframes + (AZ_SIZE) +) +{ + // LPC coefficients + + Word16 *Az; // Pointer on A_t + + // LSPs + + Word16 lsp_new[M]; + Word16 lsp_mid[M]; + + // LSFs + + Word16 prev_lsf[M]; + Word16 lsf_i[M]; + + // Algebraic codevector + + Word16 code[L_SUBFR]; + + // excitation + + Word16 excp[L_SUBFR]; + Word16 exc_enhanced[L_SUBFR]; + + // Scalars + + Word16 i, i_subfr; + Word16 T0, T0_frac, index, index_mr475 = 0; + Word16 gain_pit, gain_code, gain_code_mix, pit_sharp, pit_flag, pitch_fac; + Word16 t0_min, t0_max; + Word16 delta_frc_low, delta_frc_range; + Word16 tmp_shift; + Word16 temp; + Word32 L_temp; + Word16 flag4; + Word16 carefulFlag; + Word16 excEnergy; + Word16 subfrNr; + Word16 evenSubfr = 0; + + Word16 bfi = 0; // bad frame indication flag + Word16 pdfi = 0; // potential degraded bad frame flag + + enum DTXStateType newDTXState; // SPEECH , DTX, DTX_MUTE + + // find the new DTX state SPEECH OR DTX + newDTXState = rx_dtx_handler(st->dtxDecoderState, frame_type); + + // DTX actions + if (sub(newDTXState, SPEECH) != 0 ) + { + Decoder_amr_reset (st, MRDTX); + + dtx_dec(st->dtxDecoderState, + st->mem_syn, + st->lsfState, + st->pred_state, + st->Cb_gain_averState, + newDTXState, + mode, + parm, synth, A_t); + // update average lsp + + Lsf_lsp(st->lsfState->past_lsf_q, st->lsp_old, M); + lsp_avg(st->lsp_avg_st, st->lsfState->past_lsf_q); + goto the_end; + } + + // SPEECH action state machine + if ((sub(frame_type, RX_SPEECH_BAD) == 0) || + (sub(frame_type, RX_NO_DATA) == 0) || + (sub(frame_type, RX_ONSET) == 0)) + { + bfi = 1; + if ((sub(frame_type, RX_NO_DATA) == 0) || + (sub(frame_type, RX_ONSET) == 0)) + { + build_CN_param(&st->nodataSeed, + prmno[mode], + bitno[mode], + parm); + } + } + else if (sub(frame_type, RX_SPEECH_DEGRADED) == 0) + { + pdfi = 1; + } + + if (bfi != 0) + { + st->state = add (st->state, 1); + } + else if (sub (st->state, 6) == 0) + + { + st->state = 5; + } + else + { + st->state = 0; + } + + if (sub (st->state, 6) > 0) + { + st->state = 6; + } + + // If this frame is the first speech frame after CNI period, + // set the BFH state machine to an appropriate state depending + // on whether there was DTX muting before start of speech or not + // If there was DTX muting, the first speech frame is muted. + // If there was no DTX muting, the first speech frame is not + // muted. The BFH state machine starts from state 5, however, to + // keep the audible noise resulting from a SID frame which is + // erroneously interpreted as a good speech frame as small as + // possible (the decoder output in this case is quickly muted) + + if (sub(st->dtxDecoderState->dtxGlobalState, DTX) == 0) + { + st->state = 5; + st->prev_bf = 0; + } + else if (sub(st->dtxDecoderState->dtxGlobalState, DTX_MUTE) == 0) + { + st->state = 5; + st->prev_bf = 1; + } + + // save old LSFs for CB gain smoothing + Copy (st->lsfState->past_lsf_q, prev_lsf, M); + + // decode LSF parameters and generate interpolated lpc coefficients + for the 4 subframes + if (sub (mode, MR122) != 0) + { + D_plsf_3(st->lsfState, mode, bfi, parm, lsp_new); + + // Advance synthesis parameters pointer + parm += 3; + + Int_lpc_1to3(st->lsp_old, lsp_new, A_t); + } + else + { + D_plsf_5 (st->lsfState, bfi, parm, lsp_mid, lsp_new); + + // Advance synthesis parameters pointer + parm += 5; + + Int_lpc_1and3 (st->lsp_old, lsp_mid, lsp_new, A_t); + } + + // update the LSPs for the next frame + for (i = 0; i < M; i++) + { + st->lsp_old[i] = lsp_new[i]; + } + + *------------------------------------------------------------------------* + * Loop for every subframe in the analysis frame * + *------------------------------------------------------------------------* + * The subframe size is L_SUBFR and the loop is repeated L_FRAME/L_SUBFR * + * times * + * - decode the pitch delay * + * - decode algebraic code * + * - decode pitch and codebook gains * + * - find the excitation and compute synthesis speech * + *------------------------------------------------------------------------* + + // pointer to interpolated LPC parameters + Az = A_t; + + evenSubfr = 0; + subfrNr = -1; + for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) + { + subfrNr = add(subfrNr, 1); + evenSubfr = sub(1, evenSubfr); + + // flag for first and 3th subframe + pit_flag = i_subfr; + + if (sub (i_subfr, L_FRAME_BY2) == 0) + { + if (sub(mode, MR475) != 0 && sub(mode, MR515) != 0) + { + pit_flag = 0; + } + } + + // pitch index + index = *parm++; + + *-------------------------------------------------------* + * - decode pitch lag and find adaptive codebook vector. * + *-------------------------------------------------------* + + if (sub(mode, MR122) != 0) + { + // flag4 indicates encoding with 4 bit resolution; + // this is needed for mode MR475, MR515, MR59 and MR67 + + flag4 = 0; + if ((sub (mode, MR475) == 0) || + (sub (mode, MR515) == 0) || + (sub (mode, MR59) == 0) || + (sub (mode, MR67) == 0) ) { + flag4 = 1; + } + + *-------------------------------------------------------* + * - get ranges for the t0_min and t0_max * + * - only needed in delta decoding * + *-------------------------------------------------------* + + delta_frc_low = 5; + delta_frc_range = 9; + + if ( sub(mode, MR795) == 0 ) + { + delta_frc_low = 10; + delta_frc_range = 19; + } + + t0_min = sub(st->old_T0, delta_frc_low); + if (sub(t0_min, PIT_MIN) < 0) + { + t0_min = PIT_MIN; + } + t0_max = add(t0_min, delta_frc_range); + if (sub(t0_max, PIT_MAX) > 0) + { + t0_max = PIT_MAX; + t0_min = sub(t0_max, delta_frc_range); + } + + Dec_lag3 (index, t0_min, t0_max, pit_flag, st->old_T0, + &T0, &T0_frac, flag4); + + st->T0_lagBuff = T0; + + if (bfi != 0) + { + if (sub (st->old_T0, PIT_MAX) < 0) + { // Graceful pitch + st->old_T0 = add(st->old_T0, 1); // degradation + } + T0 = st->old_T0; + T0_frac = 0; + + if ( st->inBackgroundNoise != 0 && + sub(st->voicedHangover, 4) > 0 && + ((sub(mode, MR475) == 0 ) || + (sub(mode, MR515) == 0 ) || + (sub(mode, MR59) == 0) ) + ) + { + T0 = st->T0_lagBuff; + } + } + + Pred_lt_3or6 (st->exc, T0, T0_frac, L_SUBFR, 1); + } + else + { + Dec_lag6 (index, PIT_MIN_MR122, + PIT_MAX, pit_flag, &T0, &T0_frac); + + if ( bfi == 0 && (pit_flag == 0 || sub (index, 61) < 0)) + { + } + else + { + st->T0_lagBuff = T0; + T0 = st->old_T0; + T0_frac = 0; + } + + Pred_lt_3or6 (st->exc, T0, T0_frac, L_SUBFR, 0); + } + + *-------------------------------------------------------* + * - (MR122 only: Decode pitch gain.) * + * - Decode innovative codebook. * + * - set pitch sharpening factor * + *-------------------------------------------------------* + + if (sub (mode, MR475) == 0 || sub (mode, MR515) == 0) + { // MR475, MR515 + index = *parm++; // index of position + i = *parm++; // signs + + decode_2i40_9bits (subfrNr, i, index, code); + + pit_sharp = shl (st->sharp, 1); + } + else if (sub (mode, MR59) == 0) + { // MR59 + index = *parm++; // index of position + i = *parm++; // signs + + decode_2i40_11bits (i, index, code); + + pit_sharp = shl (st->sharp, 1); + } + else if (sub (mode, MR67) == 0) + { // MR67 + index = *parm++; // index of position + i = *parm++; // signs + + decode_3i40_14bits (i, index, code); + + pit_sharp = shl (st->sharp, 1); + } + else if (sub (mode, MR795) <= 0) + { // MR74, MR795 + index = *parm++; // index of position + i = *parm++; // signs + + decode_4i40_17bits (i, index, code); + + pit_sharp = shl (st->sharp, 1); + } + else if (sub (mode, MR102) == 0) + { // MR102 + dec_8i40_31bits (parm, code); + parm += 7; + + pit_sharp = shl (st->sharp, 1); + } + else + { // MR122 + index = *parm++; + if (bfi != 0) + { + ec_gain_pitch (st->ec_gain_p_st, st->state, &gain_pit); + } + else + { + gain_pit = d_gain_pitch (mode, index); + } + ec_gain_pitch_update (st->ec_gain_p_st, bfi, st->prev_bf, + &gain_pit); + + dec_10i40_35bits (parm, code); + parm += 10; + + // pit_sharp = gain_pit; + // if (pit_sharp > 1.0) pit_sharp = 1.0; + + pit_sharp = shl (gain_pit, 1); + } + + *-------------------------------------------------------* + * - Add the pitch contribution to code[]. * + *-------------------------------------------------------* + for (i = T0; i < L_SUBFR; i++) + { + temp = mult (code[i - T0], pit_sharp); + code[i] = add (code[i], temp); + } + + *------------------------------------------------------------* + * - Decode codebook gain (MR122) or both pitch * + * gain and codebook gain (all others) * + * - Update pitch sharpening "sharp" with quantized gain_pit * + *------------------------------------------------------------* + + if (sub (mode, MR475) == 0) + { + // read and decode pitch and code gain + if (evenSubfr != 0) + { + index_mr475 = *parm++; // index of gain(s) + } + + if (bfi == 0) + { + Dec_gain(st->pred_state, mode, index_mr475, code, + evenSubfr, &gain_pit, &gain_code); + } + else + { + ec_gain_pitch (st->ec_gain_p_st, st->state, &gain_pit); + ec_gain_code (st->ec_gain_c_st, st->pred_state, st->state, + &gain_code); + } + ec_gain_pitch_update (st->ec_gain_p_st, bfi, st->prev_bf, + &gain_pit); + ec_gain_code_update (st->ec_gain_c_st, bfi, st->prev_bf, + &gain_code); + + pit_sharp = gain_pit; + if (sub (pit_sharp, SHARPMAX) > 0) + { + pit_sharp = SHARPMAX; + } + + } + else if ((sub (mode, MR74) <= 0) || + (sub (mode, MR102) == 0)) + { + // read and decode pitch and code gain + index = *parm++; // index of gain(s) + + if (bfi == 0) + { + Dec_gain(st->pred_state, mode, index, code, + evenSubfr, &gain_pit, &gain_code); + } + else + { + ec_gain_pitch (st->ec_gain_p_st, st->state, &gain_pit); + ec_gain_code (st->ec_gain_c_st, st->pred_state, st->state, + &gain_code); + } + ec_gain_pitch_update (st->ec_gain_p_st, bfi, st->prev_bf, + &gain_pit); + ec_gain_code_update (st->ec_gain_c_st, bfi, st->prev_bf, + &gain_code); + + pit_sharp = gain_pit; + if (sub (pit_sharp, SHARPMAX) > 0) + { + pit_sharp = SHARPMAX; + } + + if (sub (mode, MR102) == 0) + { + if (sub (st->old_T0, add(L_SUBFR, 5)) > 0) + { + pit_sharp = shr(pit_sharp, 2); + } + } + } + else + { + // read and decode pitch gain + index = *parm++; // index of gain(s) + + if (sub (mode, MR795) == 0) + { + // decode pitch gain + if (bfi != 0) + { + ec_gain_pitch (st->ec_gain_p_st, st->state, &gain_pit); + } + else + { + gain_pit = d_gain_pitch (mode, index); + } + ec_gain_pitch_update (st->ec_gain_p_st, bfi, st->prev_bf, + &gain_pit); + + // read and decode code gain + index = *parm++; + if (bfi == 0) + { + d_gain_code (st->pred_state, mode, index, code, &gain_code); + } + else + { + ec_gain_code (st->ec_gain_c_st, st->pred_state, st->state, + &gain_code); + } + ec_gain_code_update (st->ec_gain_c_st, bfi, st->prev_bf, + &gain_code); + + pit_sharp = gain_pit; + if (sub (pit_sharp, SHARPMAX) > 0) + { + pit_sharp = SHARPMAX; + } + } + else + { // MR122 + if (bfi == 0) + { + d_gain_code (st->pred_state, mode, index, code, &gain_code); + } + else + { + ec_gain_code (st->ec_gain_c_st, st->pred_state, st->state, + &gain_code); + } + ec_gain_code_update (st->ec_gain_c_st, bfi, st->prev_bf, + &gain_code); + + pit_sharp = gain_pit; + } + } + + // store pitch sharpening for next subframe + // (for modes which use the previous pitch gain for + // pitch sharpening in the search phase) + // do not update sharpening in even subframes for MR475 + if (sub(mode, MR475) != 0 || evenSubfr == 0) + { + st->sharp = gain_pit; + if (sub (st->sharp, SHARPMAX) > 0) + { + st->sharp = SHARPMAX; + } + } + + pit_sharp = shl (pit_sharp, 1); + if (sub (pit_sharp, 16384) > 0) + { + for (i = 0; i < L_SUBFR; i++) + { + temp = mult (st->exc[i], pit_sharp); + L_temp = L_mult (temp, gain_pit); + if (sub(mode, MR122)==0) + { + L_temp = L_shr (L_temp, 1); + } + excp[i] = pv_round (L_temp); + } + } + + *-------------------------------------------------------* + * - Store list of LTP gains needed in the source * + * characteristic detector (SCD) * + *-------------------------------------------------------* + if ( bfi == 0 ) + { + for (i = 0; i < 8; i++) + { + st->ltpGainHistory[i] = st->ltpGainHistory[i+1]; + } + st->ltpGainHistory[8] = gain_pit; + } + + *-------------------------------------------------------* + * - Limit gain_pit if in background noise and BFI * + * for MR475, MR515, MR59 * + *-------------------------------------------------------* + + if ( (st->prev_bf != 0 || bfi != 0) && st->inBackgroundNoise != 0 && + ((sub(mode, MR475) == 0) || + (sub(mode, MR515) == 0) || + (sub(mode, MR59) == 0)) + ) + { + if ( sub (gain_pit, 12288) > 0) // if (gain_pit > 0.75) in Q14 + gain_pit = add( shr( sub(gain_pit, 12288), 1 ), 12288 ); + // gain_pit = (gain_pit-0.75)/2.0 + 0.75; + + if ( sub (gain_pit, 14745) > 0) // if (gain_pit > 0.90) in Q14 + { + gain_pit = 14745; + } + } + + *-------------------------------------------------------* + * Calculate CB mixed gain * + *-------------------------------------------------------* + Int_lsf(prev_lsf, st->lsfState->past_lsf_q, i_subfr, lsf_i); + gain_code_mix = Cb_gain_average( + st->Cb_gain_averState, mode, gain_code, + lsf_i, st->lsp_avg_st->lsp_meanSave, bfi, + st->prev_bf, pdfi, st->prev_pdf, + st->inBackgroundNoise, st->voicedHangover); + + // make sure that MR74, MR795, MR122 have original code_gain + if ((sub(mode, MR67) > 0) && (sub(mode, MR102) != 0) ) + // MR74, MR795, MR122 + { + gain_code_mix = gain_code; + } + + *-------------------------------------------------------* + * - Find the total excitation. * + * - Find synthesis speech corresponding to st->exc[]. * + *-------------------------------------------------------* + if (sub(mode, MR102) <= 0) // MR475, MR515, MR59, MR67, MR74, MR795, MR102 + { + pitch_fac = gain_pit; + tmp_shift = 1; + } + else // MR122 + { + pitch_fac = shr (gain_pit, 1); + tmp_shift = 2; + } + + // copy unscaled LTP excitation to exc_enhanced (used in phase + * dispersion below) and compute total excitation for LTP feedback + + for (i = 0; i < L_SUBFR; i++) + { + exc_enhanced[i] = st->exc[i]; + + // st->exc[i] = gain_pit*st->exc[i] + gain_code*code[i]; + L_temp = L_mult (st->exc[i], pitch_fac); + // 12.2: Q0 * Q13 + // 7.4: Q0 * Q14 + L_temp = L_mac (L_temp, code[i], gain_code); + // 12.2: Q12 * Q1 + // 7.4: Q13 * Q1 + L_temp = L_shl (L_temp, tmp_shift); // Q16 + st->exc[i] = pv_round (L_temp); + } + + *-------------------------------------------------------* + * - Adaptive phase dispersion * + *-------------------------------------------------------* + ph_disp_release(st->ph_disp_st); // free phase dispersion adaption + + if ( ((sub(mode, MR475) == 0) || + (sub(mode, MR515) == 0) || + (sub(mode, MR59) == 0)) && + sub(st->voicedHangover, 3) > 0 && + st->inBackgroundNoise != 0 && + bfi != 0 ) + { + ph_disp_lock(st->ph_disp_st); // Always Use full Phase Disp. + } // if error in bg noise + + // apply phase dispersion to innovation (if enabled) and + compute total excitation for synthesis part + ph_disp(st->ph_disp_st, mode, + exc_enhanced, gain_code_mix, gain_pit, code, + pitch_fac, tmp_shift); + + *-------------------------------------------------------* + * - The Excitation control module are active during BFI.* + * - Conceal drops in signal energy if in bg noise. * + *-------------------------------------------------------* + + L_temp = 0; + for (i = 0; i < L_SUBFR; i++) + { + L_temp = L_mac (L_temp, exc_enhanced[i], exc_enhanced[i] ); + } + + L_temp = L_shr (L_temp, 1); // excEnergy = sqrt(L_temp) in Q0 + L_temp = sqrt_l_exp(L_temp, &temp); // function result + L_temp = L_shr(L_temp, add( shr(temp, 1), 15)); + L_temp = L_shr(L_temp, 2); // To cope with 16-bit and + excEnergy = extract_l(L_temp); // scaling in ex_ctrl() + + if ( ((sub (mode, MR475) == 0) || + (sub (mode, MR515) == 0) || + (sub (mode, MR59) == 0)) && + sub(st->voicedHangover, 5) > 0 && + st->inBackgroundNoise != 0 && + sub(st->state, 4) < 0 && + ( (pdfi != 0 && st->prev_pdf != 0) || + bfi != 0 || + st->prev_bf != 0) ) + { + carefulFlag = 0; + if ( pdfi != 0 && bfi == 0 ) + { + carefulFlag = 1; + } + + Ex_ctrl(exc_enhanced, + excEnergy, + st->excEnergyHist, + st->voicedHangover, + st->prev_bf, + carefulFlag); + } + + if ( st->inBackgroundNoise != 0 && + ( bfi != 0 || st->prev_bf != 0 ) && + sub(st->state, 4) < 0 ) + { + ; // do nothing! + } + else + { + // Update energy history for all modes + for (i = 0; i < 8; i++) + { + st->excEnergyHist[i] = st->excEnergyHist[i+1]; + } + st->excEnergyHist[8] = excEnergy; + } + *-------------------------------------------------------* + * Excitation control module end. * + *-------------------------------------------------------* + + if (sub (pit_sharp, 16384) > 0) + { + for (i = 0; i < L_SUBFR; i++) + { + excp[i] = add (excp[i], exc_enhanced[i]); + } + agc2 (exc_enhanced, excp, L_SUBFR); + Overflow = 0; + Syn_filt (Az, excp, &synth[i_subfr], L_SUBFR, + st->mem_syn, 0); + } + else + { + Overflow = 0; + Syn_filt (Az, exc_enhanced, &synth[i_subfr], L_SUBFR, + st->mem_syn, 0); + } + + if (Overflow != 0) // Test for overflow + { + for (i = 0; i < PIT_MAX + L_INTERPOL + L_SUBFR; i++) + { + st->old_exc[i] = shr(st->old_exc[i], 2); + } + for (i = 0; i < L_SUBFR; i++) + { + exc_enhanced[i] = shr(exc_enhanced[i], 2); + } + Syn_filt(Az, exc_enhanced, &synth[i_subfr], L_SUBFR, st->mem_syn, 1); + } + else + { + Copy(&synth[i_subfr+L_SUBFR-M], st->mem_syn, M); + } + + *--------------------------------------------------* + * Update signal for next frame. * + * -> shift to the left by L_SUBFR st->exc[] * + *--------------------------------------------------* + + Copy (&st->old_exc[L_SUBFR], &st->old_exc[0], PIT_MAX + L_INTERPOL); + + // interpolated LPC parameters for next subframe + Az += MP1; + + // store T0 for next subframe + st->old_T0 = T0; + } + + *-------------------------------------------------------* + * Call the Source Characteristic Detector which updates * + * st->inBackgroundNoise and st->voicedHangover. * + *-------------------------------------------------------* + + st->inBackgroundNoise = Bgn_scd(st->background_state, + &(st->ltpGainHistory[0]), + &(synth[0]), + &(st->voicedHangover) ); + + dtx_dec_activity_update(st->dtxDecoderState, + st->lsfState->past_lsf_q, + synth); + + // store bfi for next subframe + st->prev_bf = bfi; + st->prev_pdf = pdfi; + + *--------------------------------------------------* + * Calculate the LSF averages on the eight * + * previous frames * + *--------------------------------------------------* + + lsp_avg(st->lsp_avg_st, st->lsfState->past_lsf_q); + +the_end: + st->dtxDecoderState->dtxGlobalState = newDTXState; + + 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] + +------------------------------------------------------------------------------ +*/ + +void Decoder_amr( + Decoder_amrState *st, /* i/o : State variables */ + enum Mode mode, /* i : AMR mode */ + Word16 parm[], /* i : vector of synthesis parameters + (PRM_SIZE) */ + enum RXFrameType frame_type, /* i : received frame type */ + Word16 synth[], /* o : synthesis speech (L_FRAME) */ + Word16 A_t[] /* o : decoded LP filter in 4 subframes + (AZ_SIZE) */ +) +{ + /* LPC coefficients */ + + Word16 *Az; /* Pointer on A_t */ + + /* LSPs */ + + Word16 lsp_new[M]; + Word16 lsp_mid[M]; + + /* LSFs */ + + Word16 prev_lsf[M]; + Word16 lsf_i[M]; + + /* Algebraic codevector */ + + Word16 code[L_SUBFR]; + + /* excitation */ + + Word16 excp[L_SUBFR]; + Word16 exc_enhanced[L_SUBFR]; + + /* Scalars */ + + Word16 i; + Word16 i_subfr; + Word16 T0; + Word16 T0_frac; + Word16 index; + Word16 index_mr475 = 0; + Word16 gain_pit; + Word16 gain_code; + Word16 gain_code_mix; + Word16 pit_sharp; + Word16 pit_flag; + Word16 pitch_fac; + Word16 t0_min; + Word16 t0_max; + Word16 delta_frc_low; + Word16 delta_frc_range; + Word16 tmp_shift; + Word16 temp; + Word32 L_temp; + Word16 flag4; + Word16 carefulFlag; + Word16 excEnergy; + Word16 subfrNr; + Word16 evenSubfr = 0; + + Word16 bfi = 0; /* bad frame indication flag */ + Word16 pdfi = 0; /* potential degraded bad frame flag */ + + enum DTXStateType newDTXState; /* SPEECH , DTX, DTX_MUTE */ + Flag *pOverflow = &(st->overflow); /* Overflow flag */ + + + /* find the new DTX state SPEECH OR DTX */ + newDTXState = rx_dtx_handler(&(st->dtxDecoderState), frame_type, pOverflow); + + /* DTX actions */ + + if (newDTXState != SPEECH) + { + Decoder_amr_reset(st, MRDTX); + + dtx_dec(&(st->dtxDecoderState), + st->mem_syn, + &(st->lsfState), + &(st->pred_state), + &(st->Cb_gain_averState), + newDTXState, + mode, + parm, synth, A_t, pOverflow); + + /* update average lsp */ + Lsf_lsp( + st->lsfState.past_lsf_q, + st->lsp_old, + M, + pOverflow); + + lsp_avg( + &(st->lsp_avg_st), + st->lsfState.past_lsf_q, + pOverflow); + + goto the_end; + } + + /* SPEECH action state machine */ + if ((frame_type == RX_SPEECH_BAD) || (frame_type == RX_NO_DATA) || + (frame_type == RX_ONSET)) + { + bfi = 1; + + if ((frame_type == RX_NO_DATA) || (frame_type == RX_ONSET)) + { + build_CN_param(&st->nodataSeed, + prmno[mode], + bitno[mode], + parm, + pOverflow); + } + } + else if (frame_type == RX_SPEECH_DEGRADED) + { + pdfi = 1; + } + + if (bfi != 0) + { + st->state += 1; + } + else if (st->state == 6) + + { + st->state = 5; + } + else + { + st->state = 0; + } + + + if (st->state > 6) + { + st->state = 6; + } + + /* If this frame is the first speech frame after CNI period, */ + /* set the BFH state machine to an appropriate state depending */ + /* on whether there was DTX muting before start of speech or not */ + /* If there was DTX muting, the first speech frame is muted. */ + /* If there was no DTX muting, the first speech frame is not */ + /* muted. The BFH state machine starts from state 5, however, to */ + /* keep the audible noise resulting from a SID frame which is */ + /* erroneously interpreted as a good speech frame as small as */ + /* possible (the decoder output in this case is quickly muted) */ + + if (st->dtxDecoderState.dtxGlobalState == DTX) + { + st->state = 5; + st->prev_bf = 0; + } + else if (st->dtxDecoderState.dtxGlobalState == DTX_MUTE) + { + st->state = 5; + st->prev_bf = 1; + } + + /* save old LSFs for CB gain smoothing */ + Copy(st->lsfState.past_lsf_q, prev_lsf, M); + + /* decode LSF parameters and generate interpolated lpc coefficients + for the 4 subframes */ + + if (mode != MR122) + { + D_plsf_3( + &(st->lsfState), + mode, + bfi, + parm, + lsp_new, + pOverflow); + + /* Advance synthesis parameters pointer */ + parm += 3; + + Int_lpc_1to3( + st->lsp_old, + lsp_new, + A_t, + pOverflow); + } + else + { + D_plsf_5( + &(st->lsfState), + bfi, + parm, + lsp_mid, + lsp_new, + pOverflow); + + /* Advance synthesis parameters pointer */ + parm += 5; + + Int_lpc_1and3( + st->lsp_old, + lsp_mid, + lsp_new, + A_t, + pOverflow); + } + + /* update the LSPs for the next frame */ + for (i = 0; i < M; i++) + { + st->lsp_old[i] = lsp_new[i]; + } + + /*------------------------------------------------------------------------* + * Loop for every subframe in the analysis frame * + *------------------------------------------------------------------------* + * The subframe size is L_SUBFR and the loop is repeated L_FRAME/L_SUBFR * + * times * + * - decode the pitch delay * + * - decode algebraic code * + * - decode pitch and codebook gains * + * - find the excitation and compute synthesis speech * + *------------------------------------------------------------------------*/ + + /* pointer to interpolated LPC parameters */ + Az = A_t; + + evenSubfr = 0; + subfrNr = -1; + for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) + { + subfrNr += 1; + evenSubfr = 1 - evenSubfr; + + /* flag for first and 3th subframe */ + pit_flag = i_subfr; + + + if (i_subfr == L_FRAME_BY2) + { + if ((mode != MR475) && (mode != MR515)) + { + pit_flag = 0; + } + } + + /* pitch index */ + index = *parm++; + + /*-------------------------------------------------------* + * - decode pitch lag and find adaptive codebook vector. * + *-------------------------------------------------------*/ + + if (mode != MR122) + { + /* flag4 indicates encoding with 4 bit resolution; */ + /* this is needed for mode MR475, MR515, MR59 and MR67 */ + + flag4 = 0; + + if ((mode == MR475) || (mode == MR515) || (mode == MR59) || + (mode == MR67)) + { + flag4 = 1; + } + + /*-------------------------------------------------------* + * - get ranges for the t0_min and t0_max * + * - only needed in delta decoding * + *-------------------------------------------------------*/ + + delta_frc_low = 5; + delta_frc_range = 9; + + if (mode == MR795) + { + delta_frc_low = 10; + delta_frc_range = 19; + } + + t0_min = sub(st->old_T0, delta_frc_low, pOverflow); + + if (t0_min < PIT_MIN) + { + t0_min = PIT_MIN; + } + t0_max = add(t0_min, delta_frc_range, pOverflow); + + if (t0_max > PIT_MAX) + { + t0_max = PIT_MAX; + t0_min = t0_max - delta_frc_range; + } + + Dec_lag3(index, t0_min, t0_max, pit_flag, st->old_T0, + &T0, &T0_frac, flag4, pOverflow); + + st->T0_lagBuff = T0; + + if (bfi != 0) + { + if (st->old_T0 < PIT_MAX) + { /* Graceful pitch */ + st->old_T0 += 0; /* degradation */ + } + T0 = st->old_T0; + T0_frac = 0; + + if ((st->inBackgroundNoise != 0) && (st->voicedHangover > 4) && + ((mode == MR475) || (mode == MR515) || (mode == MR59))) + { + T0 = st->T0_lagBuff; + } + } + + Pred_lt_3or6(st->exc, T0, T0_frac, L_SUBFR, 1, pOverflow); + } + else + { + Dec_lag6(index, PIT_MIN_MR122, + PIT_MAX, pit_flag, &T0, &T0_frac, pOverflow); + + + if (!(bfi == 0 && (pit_flag == 0 || index < 61))) + { + st->T0_lagBuff = T0; + T0 = st->old_T0; + T0_frac = 0; + } + + Pred_lt_3or6(st->exc, T0, T0_frac, L_SUBFR, 0, pOverflow); + } + + /*-------------------------------------------------------* + * - (MR122 only: Decode pitch gain.) * + * - Decode innovative codebook. * + * - set pitch sharpening factor * + *-------------------------------------------------------*/ + if ((mode == MR475) || (mode == MR515)) + { /* MR475, MR515 */ + index = *parm++; /* index of position */ + i = *parm++; /* signs */ + + decode_2i40_9bits(subfrNr, i, index, code, pOverflow); + + L_temp = (Word32)st->sharp << 1; + if (L_temp != (Word32)((Word16) L_temp)) + { + pit_sharp = (st->sharp > 0) ? MAX_16 : MIN_16; + } + else + { + pit_sharp = (Word16) L_temp; + } + } + else if (mode == MR59) + { /* MR59 */ + index = *parm++; /* index of position */ + i = *parm++; /* signs */ + + decode_2i40_11bits(i, index, code); + + L_temp = (Word32)st->sharp << 1; + if (L_temp != (Word32)((Word16) L_temp)) + { + pit_sharp = (st->sharp > 0) ? MAX_16 : MIN_16; + } + else + { + pit_sharp = (Word16) L_temp; + } + } + else if (mode == MR67) + { /* MR67 */ + index = *parm++; /* index of position */ + i = *parm++; /* signs */ + + decode_3i40_14bits(i, index, code); + + L_temp = (Word32)st->sharp << 1; + if (L_temp != (Word32)((Word16) L_temp)) + { + pit_sharp = (st->sharp > 0) ? MAX_16 : MIN_16; + } + else + { + pit_sharp = (Word16) L_temp; + } + } + else if (mode <= MR795) + { /* MR74, MR795 */ + index = *parm++; /* index of position */ + i = *parm++; /* signs */ + + decode_4i40_17bits(i, index, code); + + L_temp = (Word32)st->sharp << 1; + if (L_temp != (Word32)((Word16) L_temp)) + { + pit_sharp = (st->sharp > 0) ? MAX_16 : MIN_16; + } + else + { + pit_sharp = (Word16) L_temp; + } + } + else if (mode == MR102) + { /* MR102 */ + dec_8i40_31bits(parm, code, pOverflow); + parm += 7; + + L_temp = (Word32)st->sharp << 1; + if (L_temp != (Word32)((Word16) L_temp)) + { + pit_sharp = (st->sharp > 0) ? MAX_16 : MIN_16; + } + else + { + pit_sharp = (Word16) L_temp; + } + } + else + { /* MR122 */ + index = *parm++; + + if (bfi != 0) + { + ec_gain_pitch( + &(st->ec_gain_p_st), + st->state, + &gain_pit, + pOverflow); + } + else + { + gain_pit = d_gain_pitch(mode, index); + } + ec_gain_pitch_update( + &(st->ec_gain_p_st), + bfi, + st->prev_bf, + &gain_pit, + pOverflow); + + + dec_10i40_35bits(parm, code); + parm += 10; + + /* pit_sharp = gain_pit; */ + /* if (pit_sharp > 1.0) pit_sharp = 1.0; */ + + L_temp = (Word32)gain_pit << 1; + if (L_temp != (Word32)((Word16) L_temp)) + { + pit_sharp = (gain_pit > 0) ? MAX_16 : MIN_16; + } + else + { + pit_sharp = (Word16) L_temp; + } + } + /*-------------------------------------------------------* + * - Add the pitch contribution to code[]. * + *-------------------------------------------------------*/ + for (i = T0; i < L_SUBFR; i++) + { + temp = mult(*(code + i - T0), pit_sharp, pOverflow); + *(code + i) = add(*(code + i), temp, pOverflow); + + } + + /*------------------------------------------------------------* + * - Decode codebook gain (MR122) or both pitch * + * gain and codebook gain (all others) * + * - Update pitch sharpening "sharp" with quantized gain_pit * + *------------------------------------------------------------*/ + if (mode == MR475) + { + /* read and decode pitch and code gain */ + + if (evenSubfr != 0) + { + index_mr475 = *parm++; /* index of gain(s) */ + } + + if (bfi == 0) + { + Dec_gain( + &(st->pred_state), + mode, + index_mr475, + code, + evenSubfr, + &gain_pit, + &gain_code, + pOverflow); + } + else + { + ec_gain_pitch( + &(st->ec_gain_p_st), + st->state, + &gain_pit, + pOverflow); + + ec_gain_code( + &(st->ec_gain_c_st), + &(st->pred_state), + st->state, + &gain_code, + pOverflow); + } + ec_gain_pitch_update( + &st->ec_gain_p_st, + bfi, + st->prev_bf, + &gain_pit, + pOverflow); + + ec_gain_code_update( + &st->ec_gain_c_st, + bfi, + st->prev_bf, + &gain_code, + pOverflow); + + pit_sharp = gain_pit; + + if (pit_sharp > SHARPMAX) + { + pit_sharp = SHARPMAX; + } + + } + else if ((mode <= MR74) || (mode == MR102)) + { + /* read and decode pitch and code gain */ + index = *parm++; /* index of gain(s) */ + + if (bfi == 0) + { + Dec_gain( + &(st->pred_state), + mode, + index, + code, + evenSubfr, + &gain_pit, + &gain_code, + pOverflow); + } + else + { + ec_gain_pitch( + &(st->ec_gain_p_st), + st->state, + &gain_pit, + pOverflow); + + ec_gain_code( + &(st->ec_gain_c_st), + &(st->pred_state), + st->state, + &gain_code, + pOverflow); + } + + ec_gain_pitch_update( + &(st->ec_gain_p_st), + bfi, + st->prev_bf, + &gain_pit, + pOverflow); + + ec_gain_code_update( + &(st->ec_gain_c_st), + bfi, + st->prev_bf, + &gain_code, + pOverflow); + + pit_sharp = gain_pit; + + if (pit_sharp > SHARPMAX) + { + pit_sharp = SHARPMAX; + } + + if (mode == MR102) + { + if (st->old_T0 > (L_SUBFR + 5)) + { + if (pit_sharp < 0) + { + pit_sharp = ~((~pit_sharp) >> 2); + } + else + { + pit_sharp = pit_sharp >> 2; + } + } + } + } + else + { + /* read and decode pitch gain */ + index = *parm++; /* index of gain(s) */ + + if (mode == MR795) + { + /* decode pitch gain */ + if (bfi != 0) + { + ec_gain_pitch( + &(st->ec_gain_p_st), + st->state, + &gain_pit, + pOverflow); + } + else + { + gain_pit = d_gain_pitch(mode, index); + } + ec_gain_pitch_update( + &(st->ec_gain_p_st), + bfi, + st->prev_bf, + &gain_pit, + pOverflow); + + /* read and decode code gain */ + index = *parm++; + + if (bfi == 0) + { + d_gain_code( + &(st->pred_state), + mode, + index, + code, + &gain_code, + pOverflow); + } + else + { + ec_gain_code( + &(st->ec_gain_c_st), + &(st->pred_state), + st->state, + &gain_code, + pOverflow); + } + + ec_gain_code_update( + &(st->ec_gain_c_st), + bfi, + st->prev_bf, + &gain_code, + pOverflow); + + pit_sharp = gain_pit; + + if (pit_sharp > SHARPMAX) + { + pit_sharp = SHARPMAX; + } + } + else + { /* MR122 */ + + if (bfi == 0) + { + d_gain_code( + &(st->pred_state), + mode, + index, + code, + &gain_code, + pOverflow); + } + else + { + ec_gain_code( + &(st->ec_gain_c_st), + &(st->pred_state), + st->state, + &gain_code, + pOverflow); + } + + ec_gain_code_update( + &(st->ec_gain_c_st), + bfi, + st->prev_bf, + &gain_code, + pOverflow); + + pit_sharp = gain_pit; + } + } + + /* store pitch sharpening for next subframe */ + /* (for modes which use the previous pitch gain for */ + /* pitch sharpening in the search phase) */ + /* do not update sharpening in even subframes for MR475 */ + if ((mode != MR475) || (evenSubfr == 0)) + { + st->sharp = gain_pit; + + if (st->sharp > SHARPMAX) + { + st->sharp = SHARPMAX; + } + } + + pit_sharp = shl(pit_sharp, 1, pOverflow); + + if (pit_sharp > 16384) + { + for (i = 0; i < L_SUBFR; i++) + { + temp = mult(st->exc[i], pit_sharp, pOverflow); + L_temp = L_mult(temp, gain_pit, pOverflow); + + if (mode == MR122) + { + if (L_temp < 0) + { + L_temp = ~((~L_temp) >> 1); + } + else + { + L_temp = L_temp >> 1; + } + } + *(excp + i) = pv_round(L_temp, pOverflow); + } + } + + /*-------------------------------------------------------* + * - Store list of LTP gains needed in the source * + * characteristic detector (SCD) * + *-------------------------------------------------------*/ + + if (bfi == 0) + { + for (i = 0; i < 8; i++) + { + st->ltpGainHistory[i] = st->ltpGainHistory[i+1]; + } + st->ltpGainHistory[8] = gain_pit; + } + + /*-------------------------------------------------------* + * - Limit gain_pit if in background noise and BFI * + * for MR475, MR515, MR59 * + *-------------------------------------------------------*/ + + + if ((st->prev_bf != 0 || bfi != 0) && st->inBackgroundNoise != 0 && + ((mode == MR475) || (mode == MR515) || (mode == MR59))) + { + + if (gain_pit > 12288) /* if (gain_pit > 0.75) in Q14*/ + { + gain_pit = ((gain_pit - 12288) >> 1) + 12288; + /* gain_pit = (gain_pit-0.75)/2.0 + 0.75; */ + } + + if (gain_pit > 14745) /* if (gain_pit > 0.90) in Q14*/ + { + gain_pit = 14745; + } + } + + /*-------------------------------------------------------* + * Calculate CB mixed gain * + *-------------------------------------------------------*/ + Int_lsf( + prev_lsf, + st->lsfState.past_lsf_q, + i_subfr, + lsf_i, + pOverflow); + + gain_code_mix = + Cb_gain_average( + &(st->Cb_gain_averState), + mode, + gain_code, + lsf_i, + st->lsp_avg_st.lsp_meanSave, + bfi, + st->prev_bf, + pdfi, + st->prev_pdf, + st->inBackgroundNoise, + st->voicedHangover, + pOverflow); + + /* make sure that MR74, MR795, MR122 have original code_gain*/ + if ((mode > MR67) && (mode != MR102)) + /* MR74, MR795, MR122 */ + { + gain_code_mix = gain_code; + } + + /*-------------------------------------------------------* + * - Find the total excitation. * + * - Find synthesis speech corresponding to st->exc[]. * + *-------------------------------------------------------*/ + if (mode <= MR102) /* MR475, MR515, MR59, MR67, MR74, MR795, MR102*/ + { + pitch_fac = gain_pit; + tmp_shift = 1; + } + else /* MR122 */ + { + if (gain_pit < 0) + { + pitch_fac = ~((~gain_pit) >> 1); + } + else + { + pitch_fac = gain_pit >> 1; + } + tmp_shift = 2; + } + + /* copy unscaled LTP excitation to exc_enhanced (used in phase + * dispersion below) and compute total excitation for LTP feedback + */ + for (i = 0; i < L_SUBFR; i++) + { + exc_enhanced[i] = st->exc[i]; + + /* st->exc[i] = gain_pit*st->exc[i] + gain_code*code[i]; */ + L_temp = L_mult(st->exc[i], pitch_fac, pOverflow); + /* 12.2: Q0 * Q13 */ + /* 7.4: Q0 * Q14 */ + L_temp = L_mac(L_temp, code[i], gain_code, pOverflow); + /* 12.2: Q12 * Q1 */ + /* 7.4: Q13 * Q1 */ + L_temp = L_shl(L_temp, tmp_shift, pOverflow); /* Q16 */ + st->exc[i] = pv_round(L_temp, pOverflow); + } + + /*-------------------------------------------------------* + * - Adaptive phase dispersion * + *-------------------------------------------------------*/ + ph_disp_release(&(st->ph_disp_st)); /* free phase dispersion adaption */ + + + if (((mode == MR475) || (mode == MR515) || (mode == MR59)) && + (st->voicedHangover > 3) && (st->inBackgroundNoise != 0) && + (bfi != 0)) + { + ph_disp_lock(&(st->ph_disp_st)); /* Always Use full Phase Disp. */ + } /* if error in bg noise */ + + /* apply phase dispersion to innovation (if enabled) and + compute total excitation for synthesis part */ + ph_disp( + &(st->ph_disp_st), + mode, + exc_enhanced, + gain_code_mix, + gain_pit, + code, + pitch_fac, + tmp_shift, + pOverflow); + + /*-------------------------------------------------------* + * - The Excitation control module are active during BFI.* + * - Conceal drops in signal energy if in bg noise. * + *-------------------------------------------------------*/ + L_temp = 0; + for (i = 0; i < L_SUBFR; i++) + { + L_temp = L_mac(L_temp, *(exc_enhanced + i), *(exc_enhanced + i), pOverflow); + } + + /* excEnergy = sqrt(L_temp) in Q0 */ + if (L_temp < 0) + { + L_temp = ~((~L_temp) >> 1); + } + else + { + L_temp = L_temp >> 1; + } + + L_temp = sqrt_l_exp(L_temp, &temp, pOverflow); + /* To cope with 16-bit and scaling in ex_ctrl() */ + L_temp = L_shr(L_temp, (Word16)((temp >> 1) + 15), pOverflow); + if (L_temp < 0) + { + excEnergy = (Word16)(~((~L_temp) >> 2)); + } + else + { + excEnergy = (Word16)(L_temp >> 2); + } + + if (((mode == MR475) || (mode == MR515) || (mode == MR59)) && + (st->voicedHangover > 5) && (st->inBackgroundNoise != 0) && + (st->state < 4) && + ((pdfi != 0 && st->prev_pdf != 0) || bfi != 0 || st->prev_bf != 0)) + { + carefulFlag = 0; + + if (pdfi != 0 && bfi == 0) + { + carefulFlag = 1; + } + + Ex_ctrl(exc_enhanced, + excEnergy, + st->excEnergyHist, + st->voicedHangover, + st->prev_bf, + carefulFlag, pOverflow); + } + + if (!((st->inBackgroundNoise != 0) && (bfi != 0 || st->prev_bf != 0) && + (st->state < 4))) + { + /* Update energy history for all modes */ + for (i = 0; i < 8; i++) + { + st->excEnergyHist[i] = st->excEnergyHist[i+1]; + } + st->excEnergyHist[8] = excEnergy; + } + /*-------------------------------------------------------* + * Excitation control module end. * + *-------------------------------------------------------*/ + if (pit_sharp > 16384) + { + for (i = 0; i < L_SUBFR; i++) + { + *(excp + i) = add(*(excp + i), *(exc_enhanced + i), pOverflow); + + } + agc2(exc_enhanced, excp, L_SUBFR, pOverflow); + *pOverflow = 0; + Syn_filt(Az, excp, &synth[i_subfr], L_SUBFR, + st->mem_syn, 0); + } + else + { + *pOverflow = 0; + Syn_filt(Az, exc_enhanced, &synth[i_subfr], L_SUBFR, + st->mem_syn, 0); + } + + if (*pOverflow != 0) /* Test for overflow */ + { + for (i = PIT_MAX + L_INTERPOL + L_SUBFR - 1; i >= 0; i--) + { + if (st->old_exc[i] < 0) + { + st->old_exc[i] = ~((~st->old_exc[i]) >> 2); + } + else + { + st->old_exc[i] = st->old_exc[i] >> 2; + } + + } + + for (i = L_SUBFR - 1; i >= 0; i--) + { + if (*(exc_enhanced + i) < 0) + { + *(exc_enhanced + i) = ~((~(*(exc_enhanced + i))) >> 2); + } + else + { + *(exc_enhanced + i) = *(exc_enhanced + i) >> 2; + } + } + Syn_filt(Az, exc_enhanced, &synth[i_subfr], L_SUBFR, st->mem_syn, 1); + } + else + { + Copy(&synth[i_subfr+L_SUBFR-M], st->mem_syn, M); + } + + /*--------------------------------------------------* + * Update signal for next frame. * + * -> shift to the left by L_SUBFR st->exc[] * + *--------------------------------------------------*/ + + Copy(&st->old_exc[L_SUBFR], &st->old_exc[0], PIT_MAX + L_INTERPOL); + + /* interpolated LPC parameters for next subframe */ + Az += MP1; + + /* store T0 for next subframe */ + st->old_T0 = T0; + } + + /*-------------------------------------------------------* + * Call the Source Characteristic Detector which updates * + * st->inBackgroundNoise and st->voicedHangover. * + *-------------------------------------------------------*/ + + st->inBackgroundNoise = + Bgn_scd( + &(st->background_state), + &(st->ltpGainHistory[0]), + &(synth[0]), + &(st->voicedHangover), + pOverflow); + + dtx_dec_activity_update( + &(st->dtxDecoderState), + st->lsfState.past_lsf_q, + synth, + pOverflow); + + /* store bfi for next subframe */ + st->prev_bf = bfi; + st->prev_pdf = pdfi; + + /*--------------------------------------------------* + * Calculate the LSF averages on the eight * + * previous frames * + *--------------------------------------------------*/ + lsp_avg( + &(st->lsp_avg_st), + st->lsfState.past_lsf_q, + pOverflow); + +the_end: + st->dtxDecoderState.dtxGlobalState = newDTXState; + +// return(0); +} |