/* ------------------------------------------------------------------ * 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/cl_ltp.c Funtions: cl_ltp_init cl_ltp_reset cl_ltp_exit cl_ltp Date: 06/07/2000 ------------------------------------------------------------------------------ REVISION HISTORY Description: Placed into PV template and optimized. Description: Synchronized file with UMTS version 3.2.0. Updated coding template. Removed unnecessary include files. Description: Removed basic_op.h and oper_32b.h in the include section, and added basicop_malloc.h. Description: Fixed typecasting issue in TI C compiler. Description: Added pOverflow parameter -- fixed minor template problem. Description: 1. Eliminated unused include file typedef.h. 2. Replaced array addressing by pointers 3. Eliminated if-else checks for saturation 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: ------------------------------------------------------------------------------ MODULE DESCRIPTION This file contains functions that perform closed-loop fractional pitch search. ------------------------------------------------------------------------------ */ /*---------------------------------------------------------------------------- ; INCLUDES ----------------------------------------------------------------------------*/ #include #include "cl_ltp.h" #include "basicop_malloc.h" #include "cnst.h" #include "convolve.h" #include "g_pitch.h" #include "pred_lt.h" #include "pitch_fr.h" #include "enc_lag3.h" #include "enc_lag6.h" #include "q_gain_p.h" #include "ton_stab.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: cl_ltp_init ------------------------------------------------------------------------------ INPUT AND OUTPUT DEFINITIONS Inputs: state = Pointer to a pointer to a clLtpState structure Outputs: state points to the newly created clLtpState structure. Returns: This function returns 0 upon success and -1 upon failure. Global Variables Used: None Local Variables Needed: None ------------------------------------------------------------------------------ FUNCTION DESCRIPTION Allocates state memory and initializes state memory ------------------------------------------------------------------------------ REQUIREMENTS None. ------------------------------------------------------------------------------ REFERENCES cl_ltp.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 ------------------------------------------------------------------------------ PSEUDO-CODE int cl_ltp_init (clLtpState **state) { clLtpState* s; if (state == (clLtpState **) NULL){ fprintf(stderr, "cl_ltp_init: invalid parameter\n"); return -1; } *state = NULL; // allocate memory if ((s= (clLtpState *) malloc(sizeof(clLtpState))) == NULL){ fprintf(stderr, "cl_ltp_init: can not malloc state structure\n"); return -1; } // init the sub state if (Pitch_fr_init(&s->pitchSt)) { cl_ltp_exit(&s); return -1; } cl_ltp_reset(s); *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 cl_ltp_init(clLtpState **state) { clLtpState* s; if (state == (clLtpState **) NULL) { /*fprint(stderr, "cl_ltp_init: invalid parameter\n");*/ return(-1); } *state = NULL; /* allocate memory */ if ((s = (clLtpState *) malloc(sizeof(clLtpState))) == NULL) { /*fprint(stderr, "cl_ltp_init: can not malloc state structure\n");*/ return(-1); } /* init the sub state */ if (Pitch_fr_init(&s->pitchSt)) { cl_ltp_exit(&s); return(-1); } cl_ltp_reset(s); *state = s; return(0); } /****************************************************************************/ /* ------------------------------------------------------------------------------ FUNCTION NAME: cl_ltp_reset ------------------------------------------------------------------------------ INPUT AND OUTPUT DEFINITIONS Inputs: state = pointer to the clLtpState structure to be reset Outputs: The state structure pointed to by clLtpState *state is reset. Returns: The function returns int 0 if successful, -1 otherwise. Global Variables Used: None Local Variables Needed: None ------------------------------------------------------------------------------ FUNCTION DESCRIPTION Initializes state memory to zero. ------------------------------------------------------------------------------ REQUIREMENTS ------------------------------------------------------------------------------ REFERENCES cl_ltp.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 ------------------------------------------------------------------------------ PSEUDO-CODE int cl_ltp_reset (clLtpState *state) { if (state == (clLtpState *) NULL){ fprintf(stderr, "cl_ltp_reset: invalid parameter\n"); return -1; } // Reset pitch search states Pitch_fr_reset (state->pitchSt); 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 cl_ltp_reset(clLtpState *state) { if (state == (clLtpState *) NULL) { /*fprint(stderr, "cl_ltp_reset: invalid parameter\n"); */ return(-1); } /* Reset pitch search states */ Pitch_fr_reset(state->pitchSt); return(0); } /****************************************************************************/ /* ------------------------------------------------------------------------------ FUNCTION NAME: cl_ltp_exit ------------------------------------------------------------------------------ INPUT AND OUTPUT DEFINITIONS Inputs: clLtpState **state = Reference to the state object to be freed. Outputs: The memory used by the structure which is pointed to by 'state' is freed. Returns: None Global Variables Used: None Local Variables Needed: None ------------------------------------------------------------------------------ FUNCTION DESCRIPTION The memory used for state memory is freed ------------------------------------------------------------------------------ REQUIREMENTS None ------------------------------------------------------------------------------ REFERENCES cl_ltp.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 ------------------------------------------------------------------------------ PSEUDO-CODE void cl_ltp_exit (clLtpState **state) { if (state == NULL || *state == NULL) return; // dealloc members Pitch_fr_exit(&(*state)->pitchSt); // deallocate memory free(*state); *state = NULL; 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 cl_ltp_exit(clLtpState **state) { if (state == NULL || *state == NULL) { return; } /* dealloc members */ Pitch_fr_exit(&(*state)->pitchSt); /* deallocate memory */ free(*state); *state = NULL; return; } /****************************************************************************/ /* ------------------------------------------------------------------------------ FUNCTION NAME: cl_ltp ------------------------------------------------------------------------------ INPUT AND OUTPUT DEFINITIONS Inputs: clSt = pointer to the clLtpState struct tonSt = pointer to the tonStabState structure mode = codec mode value, of type enum Mode frameOffset = offset to subframe (Word16) T_op = pointer to buffer of open loop pitch lags (Word16) h1 = pointer to impulse response vector (Word16) exc = pointer to excitation vector (Word16) res2 = pointer to long term prediction residual (Word16) xn = pointer to target vector for pitch search (Word16) lsp_flag = LSP resonance flag (Word16) Outputs: clSt = pointer to the clLtpState struct tonSt = pointer to the tonStabState structure exc = pointer to excitation vector (Word16) res2 = pointer to long term prediction residual (Word16) xn2 = pointer to target vector for codebook search (Word16) yl = pointer to buffer of filtered adaptive excitation (Word16) T0 = pointer to pitch delay (integer part) (Word16) T0_frac = pointer to pitch delay (fractional part) (Word16) gain_pit = pointer to pitch gain (Word16) g_coeff = pointer to array of correlations between xn, y1, & y2 (Word16) anap = pointer to pointer to analysis parameters (Word16) gp_limit = pointer to the pitch gain limit (Word16) pOverflow = pointer to overflow indicator (Flag) Returns: return_value = 0 (int) Global Variables Used: None Local Variables Needed: None ------------------------------------------------------------------------------ FUNCTION DESCRIPTION This function performs closed-loop fractional pitch search. ------------------------------------------------------------------------------ REQUIREMENTS None. ------------------------------------------------------------------------------ REFERENCES cl_ltp.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 ------------------------------------------------------------------------------ PSEUDO-CODE FOR cl_ltp int cl_ltp ( clLtpState *clSt, // i/o : State struct tonStabState *tonSt, // i/o : State struct enum Mode mode, // i : coder mode Word16 frameOffset, // i : Offset to subframe Word16 T_op[], // i : Open loop pitch lags Word16 *h1, // i : Impulse response vector Q12 Word16 *exc, // i/o : Excitation vector Q0 Word16 res2[], // i/o : Long term prediction residual Q0 Word16 xn[], // i : Target vector for pitch search Q0 Word16 lsp_flag, // i : LSP resonance flag Word16 xn2[], // o : Target vector for codebook search Q0 Word16 y1[], // o : Filtered adaptive excitation Q0 Word16 *T0, // o : Pitch delay (integer part) Word16 *T0_frac, // o : Pitch delay (fractional part) Word16 *gain_pit, // o : Pitch gain Q14 Word16 g_coeff[], // o : Correlations between xn, y1, & y2 Word16 **anap, // o : Analysis parameters Word16 *gp_limit // o : pitch gain limit ) { Word16 i; Word16 index; Word32 L_temp; // temporarily variable Word16 resu3; // flag for upsample resolution Word16 gpc_flag; *----------------------------------------------------------------------* * Closed-loop fractional pitch search * *----------------------------------------------------------------------* *T0 = Pitch_fr(clSt->pitchSt, mode, T_op, exc, xn, h1, L_SUBFR, frameOffset, T0_frac, &resu3, &index); *(*anap)++ = index; *-----------------------------------------------------------------* * - find unity gain pitch excitation (adapitve codebook entry) * * with fractional interpolation. * * - find filtered pitch exc. y1[]=exc[] convolve with h1[]) * * - compute pitch gain and limit between 0 and 1.2 * * - update target vector for codebook search * * - find LTP residual. * *-----------------------------------------------------------------* Pred_lt_3or6(exc, *T0, *T0_frac, L_SUBFR, resu3); Convolve(exc, h1, y1, L_SUBFR); // gain_pit is Q14 for all modes *gain_pit = G_pitch(mode, xn, y1, g_coeff, L_SUBFR); // check if the pitch gain should be limit due to resonance in LPC filter gpc_flag = 0; *gp_limit = MAX_16; if ((lsp_flag != 0) && (sub(*gain_pit, GP_CLIP) > 0)) { gpc_flag = check_gp_clipping(tonSt, *gain_pit); } // special for the MR475, MR515 mode; limit the gain to 0.85 to // cope with bit errors in the decoder in a better way. if ((sub (mode, MR475) == 0) || (sub (mode, MR515) == 0)) { if ( sub (*gain_pit, 13926) > 0) { *gain_pit = 13926; // 0.85 in Q14 } if (gpc_flag != 0) { *gp_limit = GP_CLIP; } } else { if (gpc_flag != 0) { *gp_limit = GP_CLIP; *gain_pit = GP_CLIP; } // For MR122, gain_pit is quantized here and not in gainQuant if (sub(mode, MR122)==0) { *(*anap)++ = q_gain_pitch(MR122, *gp_limit, gain_pit, NULL, NULL); } } // update target vector und evaluate LTP residual for (i = 0; i < L_SUBFR; i++) { L_temp = L_mult(y1[i], *gain_pit); L_temp = L_shl(L_temp, 1); xn2[i] = sub(xn[i], extract_h(L_temp)); L_temp = L_mult(exc[i], *gain_pit); L_temp = L_shl(L_temp, 1); res2[i] = sub(res2[i], extract_h(L_temp)); } 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 cl_ltp( clLtpState *clSt, /* i/o : State struct */ tonStabState *tonSt, /* i/o : State struct */ enum Mode mode, /* i : coder mode */ Word16 frameOffset, /* i : Offset to subframe */ Word16 T_op[], /* i : Open loop pitch lags */ Word16 *h1, /* i : Impulse response vector Q12 */ Word16 *exc, /* i/o : Excitation vector Q0 */ Word16 res2[], /* i/o : Long term prediction residual Q0 */ Word16 xn[], /* i : Target vector for pitch search Q0 */ Word16 lsp_flag, /* i : LSP resonance flag */ Word16 xn2[], /* o : Target vector for codebook search Q0 */ Word16 yl[], /* o : Filtered adaptive excitation Q0 */ Word16 *T0, /* o : Pitch delay (integer part) */ Word16 *T0_frac, /* o : Pitch delay (fractional part) */ Word16 *gain_pit, /* o : Pitch gain Q14 */ Word16 g_coeff[], /* o : Correlations between xn, y1, & y2 */ Word16 **anap, /* o : Analysis parameters */ Word16 *gp_limit, /* o : pitch gain limit */ Flag *pOverflow /* o : overflow indicator */ ) { register Word16 i; Word16 index; Word32 L_temp; /* temporarily variable */ Word16 resu3; /* flag for upsample resolution */ Word16 gpc_flag; Word16 temp; Word16 *p_exc; Word16 *p_xn; Word16 *p_xn2; Word16 *p_yl; /*----------------------------------------------------------------------* * Closed-loop fractional pitch search * *----------------------------------------------------------------------*/ *T0 = Pitch_fr( clSt->pitchSt, mode, T_op, exc, xn, h1, L_SUBFR, frameOffset, T0_frac, &resu3, &index, pOverflow); *(*anap)++ = index; /*-----------------------------------------------------------------* * - find unity gain pitch excitation (adapitve codebook entry) * * with fractional interpolation. * * - find filtered pitch exc. y1[]=exc[] convolve with h1[]) * * - compute pitch gain and limit between 0 and 1.2 * * - update target vector for codebook search * * - find LTP residual. * *-----------------------------------------------------------------*/ Pred_lt_3or6( exc, *T0, *T0_frac, L_SUBFR, resu3, pOverflow); Convolve(exc, h1, yl, L_SUBFR); /* gain_pit is Q14 for all modes */ *gain_pit = G_pitch( mode, xn, yl, g_coeff, L_SUBFR, pOverflow); /* check if the pitch gain should be limit due to resonance in LPC filter */ gpc_flag = 0; *gp_limit = MAX_16; if ((lsp_flag != 0) && ((Word32)(*gain_pit) > GP_CLIP)) { gpc_flag = check_gp_clipping(tonSt, *gain_pit, pOverflow); } /* special for the MR475, MR515 mode; limit the gain to 0.85 to */ /* cope with bit errors in the decoder in a better way. */ if ((mode == MR475) || (mode == MR515)) { *gain_pit = ((Word32) * gain_pit > 13926) ? 13926 : *gain_pit; if (gpc_flag != 0) { *gp_limit = GP_CLIP; } } else { if (gpc_flag != 0) { *gp_limit = GP_CLIP; *gain_pit = GP_CLIP; } /* For MR122, gain_pit is quantized here and not in gainQuant */ if (mode == MR122) { *(*anap)++ = q_gain_pitch( MR122, *gp_limit, gain_pit, NULL, NULL, pOverflow); } } p_exc = &exc[0]; p_xn = &xn[0]; p_xn2 = &xn2[0]; p_yl = &yl[0]; temp = *gain_pit; /* update target vector und evaluate LTP residual */ for (i = 0; i < L_SUBFR; i++) { L_temp = ((Word32) * (p_yl++) * temp) >> 14; *(p_xn2++) = *(p_xn++) - (Word16)L_temp; L_temp = ((Word32) * (p_exc++) * temp) >> 14; res2[i] -= (Word16)L_temp; } }