diff options
Diffstat (limited to 'media/libstagefright/codecs/amrnb/enc/src/cod_amr.cpp')
-rw-r--r-- | media/libstagefright/codecs/amrnb/enc/src/cod_amr.cpp | 1608 |
1 files changed, 1608 insertions, 0 deletions
diff --git a/media/libstagefright/codecs/amrnb/enc/src/cod_amr.cpp b/media/libstagefright/codecs/amrnb/enc/src/cod_amr.cpp new file mode 100644 index 0000000..8468131 --- /dev/null +++ b/media/libstagefright/codecs/amrnb/enc/src/cod_amr.cpp @@ -0,0 +1,1608 @@ +/* ------------------------------------------------------------------ + * 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/cod_amr.c + Funtions: cod_amr_init + cod_amr_reset + cod_amr_exit + cod_amr_first + cod_amr + + Date: 06/09/2000 + +------------------------------------------------------------------------------ + REVISION HISTORY + + Description: Made changes based on comments from the review meeting. + + Description: Synchronized file with UMTS version 3.2.0. Updated coding + template. Removed unnecessary include files. + + Description: Added initialization of the overflow flag in cod_amr_init() + and in cod_amr_reset(). This overflow flag is now part of + the cod_amrState structure. + + Description: Cleaned up INCLUDES. removed inclusion of basic_op.h and repeat + inclusion of copy.h + + Description: Updated function call to dtx_enc + + Description: For cod_amr_first() and cod_amr() + 1. Replaced copy() function with memcpy() + + 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 + + These functions comprise the main encoder routine operating on a frame basis. + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include <stdlib.h> +#include <string.h> + +#include "cod_amr.h" +#include "typedef.h" +#include "cnst.h" +#include "copy.h" +#include "qua_gain.h" +#include "lpc.h" +#include "lsp.h" +#include "pre_big.h" +#include "ol_ltp.h" +#include "p_ol_wgh.h" +#include "spreproc.h" +#include "cl_ltp.h" +#include "pred_lt.h" +#include "spstproc.h" +#include "cbsearch.h" +#include "gain_q.h" +#include "convolve.h" +#include "ton_stab.h" +#include "vad.h" +#include "dtx_enc.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 +----------------------------------------------------------------------------*/ + +/* Spectral expansion factors */ + +static const Word16 gamma1[M] = +{ + 30802, 28954, 27217, 25584, 24049, + 22606, 21250, 19975, 18777, 17650 +}; + +/* gamma1 differs for the 12k2 coder */ +static const Word16 gamma1_12k2[M] = +{ + 29491, 26542, 23888, 21499, 19349, + 17414, 15672, 14105, 12694, 11425 +}; + +static const Word16 gamma2[M] = +{ + 19661, 11797, 7078, 4247, 2548, + 1529, 917, 550, 330, 198 +}; + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: cod_amr_init +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to a pointer to a structure of type cod_amrState + + Outputs: + Structure pointed to by the pointer pointed to by state is + initialized to its reset value + state points to the allocated memory + + Returns: + Returns 0 if memory was successfully initialized, + otherwise returns -1. + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function allocates memory and initializes state variables. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + cod_amr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int cod_amr_init (cod_amrState **state, Flag dtx) +{ + cod_amrState* s; + + if (state == (cod_amrState **) NULL){ + fprintf(stderr, "cod_amr_init: invalid parameter\n"); + return -1; + } + *state = NULL; + + // allocate memory + if ((s= (cod_amrState *) malloc(sizeof(cod_amrState))) == NULL){ + fprintf(stderr, "cod_amr_init: can not malloc state structure\n"); + return -1; + } + + s->lpcSt = NULL; + s->lspSt = NULL; + s->clLtpSt = NULL; + s->gainQuantSt = NULL; + s->pitchOLWghtSt = NULL; + s->tonStabSt = NULL; + s->vadSt = NULL; + s->dtx_encSt = NULL; + s->dtx = dtx; + + // Init sub states + if (cl_ltp_init(&s->clLtpSt) || + lsp_init(&s->lspSt) || + gainQuant_init(&s->gainQuantSt) || + p_ol_wgh_init(&s->pitchOLWghtSt) || + ton_stab_init(&s->tonStabSt) || +#ifndef VAD2 + vad1_init(&s->vadSt) || +#else + vad2_init(&s->vadSt) || +#endif + dtx_enc_init(&s->dtx_encSt) || + lpc_init(&s->lpcSt)) { + cod_amr_exit(&s); + return -1; + } + + cod_amr_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 cod_amr_init(cod_amrState **state, Flag dtx) +{ + cod_amrState* s; + + if (state == (cod_amrState **) NULL) + { + /* fprint(stderr, "cod_amr_init: invalid parameter\n"); */ + return(-1); + } + *state = NULL; + + /* allocate memory */ + if ((s = (cod_amrState *) malloc(sizeof(cod_amrState))) == NULL) + { + /* fprint(stderr, "cod_amr_init: + can not malloc state structure\n"); */ + return(-1); + } + + s->lpcSt = NULL; + s->lspSt = NULL; + s->clLtpSt = NULL; + s->gainQuantSt = NULL; + s->pitchOLWghtSt = NULL; + s->tonStabSt = NULL; + s->vadSt = NULL; + s->dtx_encSt = NULL; + s->dtx = dtx; + + /* Initialize overflow Flag */ + + s->overflow = 0; + + + /* Init sub states */ + if (cl_ltp_init(&s->clLtpSt) || + lsp_init(&s->lspSt) || + gainQuant_init(&s->gainQuantSt) || + p_ol_wgh_init(&s->pitchOLWghtSt) || + ton_stab_init(&s->tonStabSt) || +#ifndef VAD2 + vad1_init(&s->vadSt) || +#else + vad2_init(&s->vadSt) || +#endif + dtx_enc_init(&s->dtx_encSt) || + lpc_init(&s->lpcSt)) + { + cod_amr_exit(&s); + return(-1); + } + + cod_amr_reset(s); + + *state = s; + + return(0); +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: cod_amr_reset +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to a structure of type cod_amrState + + Outputs: + Structure pointed to by state is initialized to initial values. + + Returns: + Returns 0 if memory was successfully initialized, + otherwise returns -1. + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function resets the state memory for cod_amr. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + cod_amr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int cod_amr_reset (cod_amrState *st) +{ + Word16 i; + + if (st == (cod_amrState *) NULL){ + fprintf(stderr, "cod_amr_reset: invalid parameter\n"); + return -1; + } + + *-----------------------------------------------------------------------* + * Initialize pointers to speech vector. * + *-----------------------------------------------------------------------* + + st->new_speech = st->old_speech + L_TOTAL - L_FRAME; // New speech + + st->speech = st->new_speech - L_NEXT; // Present frame + + st->p_window = st->old_speech + L_TOTAL - L_WINDOW; // For LPC window + st->p_window_12k2 = st->p_window - L_NEXT; // EFR LPC window: no lookahead + + // Initialize static pointers + + st->wsp = st->old_wsp + PIT_MAX; + st->exc = st->old_exc + PIT_MAX + L_INTERPOL; + st->zero = st->ai_zero + MP1; + st->error = st->mem_err + M; + st->h1 = &st->hvec[L_SUBFR]; + + // Static vectors to zero + + Set_zero(st->old_speech, L_TOTAL); + Set_zero(st->old_exc, PIT_MAX + L_INTERPOL); + Set_zero(st->old_wsp, PIT_MAX); + Set_zero(st->mem_syn, M); + Set_zero(st->mem_w, M); + Set_zero(st->mem_w0, M); + Set_zero(st->mem_err, M); + Set_zero(st->zero, L_SUBFR); + Set_zero(st->hvec, L_SUBFR); // set to zero "h1[-L_SUBFR..-1]" + + // OL LTP states + for (i = 0; i < 5; i++) + { + st->old_lags[i] = 40; + } + + // Reset lpc states + lpc_reset(st->lpcSt); + + // Reset lsp states + lsp_reset(st->lspSt); + + // Reset clLtp states + cl_ltp_reset(st->clLtpSt); + + gainQuant_reset(st->gainQuantSt); + + p_ol_wgh_reset(st->pitchOLWghtSt); + + ton_stab_reset(st->tonStabSt); + +#ifndef VAD2 + vad1_reset(st->vadSt); +#else + vad2_reset(st->vadSt); +#endif + + dtx_enc_reset(st->dtx_encSt); + + st->sharp = SHARPMIN; + + 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 cod_amr_reset(cod_amrState *st) +{ + Word16 i; + + if (st == (cod_amrState *) NULL) + { + /* fprint(stderr, "cod_amr_reset: invalid parameter\n"); */ + return(-1); + } + + /*-----------------------------------------------------------------------* + * Initialize pointers to speech vector. * + *-----------------------------------------------------------------------*/ + + st->new_speech = st->old_speech + L_TOTAL - L_FRAME; /* New speech */ + + st->speech = st->new_speech - L_NEXT; /* Present frame */ + + st->p_window = st->old_speech + L_TOTAL - L_WINDOW; /* For LPC window */ + st->p_window_12k2 = st->p_window - L_NEXT; /* EFR LPC window: no lookahead */ + + /* Initialize static pointers */ + + st->wsp = st->old_wsp + PIT_MAX; + st->exc = st->old_exc + PIT_MAX + L_INTERPOL; + st->zero = st->ai_zero + MP1; + st->error = st->mem_err + M; + st->h1 = &st->hvec[L_SUBFR]; + + /* Initialize overflow Flag */ + + st->overflow = 0; + + /* Static vectors to zero */ + memset(st->old_speech, 0, sizeof(Word16)*L_TOTAL); + memset(st->old_exc, 0, sizeof(Word16)*(PIT_MAX + L_INTERPOL)); + memset(st->old_wsp, 0, sizeof(Word16)*PIT_MAX); + memset(st->mem_syn, 0, sizeof(Word16)*M); + memset(st->mem_w, 0, sizeof(Word16)*M); + memset(st->mem_w0, 0, sizeof(Word16)*M); + memset(st->mem_err, 0, sizeof(Word16)*M); + memset(st->zero, 0, sizeof(Word16)*L_SUBFR); + memset(st->hvec, 0, sizeof(Word16)*L_SUBFR); /* set to zero "h1[-L_SUBFR..-1]" */ + + /* OL LTP states */ + for (i = 0; i < 5; i++) + { + st->old_lags[i] = 40; + } + + /* Reset lpc states */ + lpc_reset(st->lpcSt); + + /* Reset lsp states */ + lsp_reset(st->lspSt); + + /* Reset clLtp states */ + cl_ltp_reset(st->clLtpSt); + + gainQuant_reset(st->gainQuantSt); + + p_ol_wgh_reset(st->pitchOLWghtSt); + + ton_stab_reset(st->tonStabSt); + +#ifndef VAD2 + vad1_reset(st->vadSt); +#else + vad2_reset(st->vadSt); +#endif + + dtx_enc_reset(st->dtx_encSt); + + st->sharp = SHARPMIN; + + return(0); +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: cod_amr_exit +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to a pointer to a structure of type cod_amrState + + Outputs: + state points to a NULL address + + Returns: + None. + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function frees the memory used for state memory. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + cod_amr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +void cod_amr_exit (cod_amrState **state) +{ + if (state == NULL || *state == NULL) + return; + + // dealloc members + lpc_exit(&(*state)->lpcSt); + lsp_exit(&(*state)->lspSt); + gainQuant_exit(&(*state)->gainQuantSt); + cl_ltp_exit(&(*state)->clLtpSt); + p_ol_wgh_exit(&(*state)->pitchOLWghtSt); + ton_stab_exit(&(*state)->tonStabSt); +#ifndef VAD2 + vad1_exit(&(*state)->vadSt); +#else + vad2_exit(&(*state)->vadSt); +#endif + dtx_enc_exit(&(*state)->dtx_encSt); + + // 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 cod_amr_exit(cod_amrState **state) +{ + if (state == NULL || *state == NULL) + { + return; + } + + /* dealloc members */ + lpc_exit(&(*state)->lpcSt); + lsp_exit(&(*state)->lspSt); + gainQuant_exit(&(*state)->gainQuantSt); + cl_ltp_exit(&(*state)->clLtpSt); + p_ol_wgh_exit(&(*state)->pitchOLWghtSt); + ton_stab_exit(&(*state)->tonStabSt); +#ifndef VAD2 + vad1_exit(&(*state)->vadSt); +#else + vad2_exit(&(*state)->vadSt); +#endif + dtx_enc_exit(&(*state)->dtx_encSt); + + /* deallocate memory */ + free(*state); // BX + *state = NULL; + + return; +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: cod_amr_first +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st = pointer to a structure of type cod_amrState + new_speech = pointer to buffer of length L_FRAME that contains + the speech input (Word16) + + Outputs: + The structure of type cod_amrState pointed to by st is updated. + + Returns: + return_value = 0 (int) + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function copes with look-ahead and calls cod_amr. + No input argument are passed to this function. However, before + calling this function, 40 new speech data should be copied to the + vector new_speech[]. This is a global pointer which is declared in + this file (it points to the end of speech buffer minus 200). + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + cod_amr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int cod_amr_first(cod_amrState *st, // i/o : State struct + Word16 new_speech[]) // i : speech input (L_FRAME) +{ + Copy(new_speech,&st->new_speech[-L_NEXT], L_NEXT); + // Copy(new_speech,st->new_speech,L_FRAME); + + 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 cod_amr_first(cod_amrState *st, /* i/o : State struct */ + Word16 new_speech[]) /* i : speech input (L_FRAME) */ +{ + + memcpy(&st->new_speech[-L_NEXT], new_speech, L_NEXT*sizeof(Word16)); + + /* Copy(new_speech,st->new_speech,L_FRAME); */ + + return(0); +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: cod_amr +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st = pointer to a structure of type cod_amrState + mode = AMR mode of type enum Mode + new_speech = pointer to buffer of length L_FRAME that contains + the speech input of type Word16 + ana = pointer to the analysis parameters of type Word16 + usedMode = pointer to the used mode of type enum Mode + synth = pointer to a buffer containing the local synthesis speech of + type Word16 + + Outputs: + The structure of type cod_amrState pointed to by st is updated. + The analysis parameter buffer pointed to by ana is updated. + The value pointed to by usedMode is updated. + The local synthesis speech buffer pointed to by synth is updated. + + Returns: + return_value = 0 (int) + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function is the main encoder routine. It is called every 20 ms speech + frame, operating on the newly read 160 speech samples. It performs the + principle encoding functions to produce the set of encoded parameters + which include the LSP, adaptive codebook, and fixed codebook + quantization indices (addresses and gains). + + Before calling this function, 160 new speech data should be copied to the + vector new_speech[]. This is a global pointer which is declared in + this file (it points to the end of speech buffer minus 160). + + The outputs of the function are: + ana[]: vector of analysis parameters. + synth[]: Local synthesis speech (for debugging purposes) + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + cod_amr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int cod_amr( + cod_amrState *st, // i/o : State struct + enum Mode mode, // i : AMR mode + Word16 new_speech[], // i : speech input (L_FRAME) + Word16 ana[], // o : Analysis parameters + enum Mode *usedMode, // o : used mode + Word16 synth[] // o : Local synthesis +) +{ + // LPC coefficients + Word16 A_t[(MP1) * 4]; // A(z) unquantized for the 4 subframes + Word16 Aq_t[(MP1) * 4]; // A(z) quantized for the 4 subframes + Word16 *A, *Aq; // Pointer on A_t and Aq_t + Word16 lsp_new[M]; + + // Other vectors + Word16 xn[L_SUBFR]; // Target vector for pitch search + Word16 xn2[L_SUBFR]; // Target vector for codebook search + Word16 code[L_SUBFR]; // Fixed codebook excitation + Word16 y1[L_SUBFR]; // Filtered adaptive excitation + Word16 y2[L_SUBFR]; // Filtered fixed codebook excitation + Word16 gCoeff[6]; // Correlations between xn, y1, & y2: + Word16 res[L_SUBFR]; // Short term (LPC) prediction residual + Word16 res2[L_SUBFR]; // Long term (LTP) prediction residual + + // Vector and scalars needed for the MR475 + Word16 xn_sf0[L_SUBFR]; // Target vector for pitch search + Word16 y2_sf0[L_SUBFR]; // Filtered codebook innovation + Word16 code_sf0[L_SUBFR]; // Fixed codebook excitation + Word16 h1_sf0[L_SUBFR]; // The impulse response of sf0 + Word16 mem_syn_save[M]; // Filter memory + Word16 mem_w0_save[M]; // Filter memory + Word16 mem_err_save[M]; // Filter memory + Word16 sharp_save; // Sharpening + Word16 evenSubfr; // Even subframe indicator + Word16 T0_sf0 = 0; // Integer pitch lag of sf0 + Word16 T0_frac_sf0 = 0; // Fractional pitch lag of sf0 + Word16 i_subfr_sf0 = 0; // Position in exc[] for sf0 + Word16 gain_pit_sf0; // Quantized pitch gain for sf0 + Word16 gain_code_sf0; // Quantized codebook gain for sf0 + + // Scalars + Word16 i_subfr, subfrNr; + Word16 T_op[L_FRAME/L_FRAME_BY2]; + Word16 T0, T0_frac; + Word16 gain_pit, gain_code; + + // Flags + Word16 lsp_flag = 0; // indicates resonance in LPC filter + Word16 gp_limit; // pitch gain limit value + Word16 vad_flag; // VAD decision flag + Word16 compute_sid_flag; // SID analysis flag + + Copy(new_speech, st->new_speech, L_FRAME); + + *usedMode = mode; + + // DTX processing + if (st->dtx) + { // no test() call since this if is only in simulation env + // Find VAD decision + +#ifdef VAD2 + vad_flag = vad2 (st->new_speech, st->vadSt); + vad_flag = vad2 (st->new_speech+80, st->vadSt) || vad_flag; +#else + vad_flag = vad1(st->vadSt, st->new_speech); +#endif + + // NB! usedMode may change here + compute_sid_flag = tx_dtx_handler(st->dtx_encSt, + vad_flag, + usedMode); + } + else + { + compute_sid_flag = 0; + } + + *------------------------------------------------------------------------* + * - Perform LPC analysis: * + * * autocorrelation + lag windowing * + * * Levinson-durbin algorithm to find a[] * + * * convert a[] to lsp[] * + * * quantize and code the LSPs * + * * find the interpolated LSPs and convert to a[] for all * + * subframes (both quantized and unquantized) * + *------------------------------------------------------------------------* + + // LP analysis + lpc(st->lpcSt, mode, st->p_window, st->p_window_12k2, A_t); + + + // From A(z) to lsp. LSP quantization and interpolation + lsp(st->lspSt, mode, *usedMode, A_t, Aq_t, lsp_new, &ana); + + + // Buffer lsp's and energy + dtx_buffer(st->dtx_encSt, + lsp_new, + st->new_speech); + + // Check if in DTX mode + if (sub(*usedMode, MRDTX) == 0) + { + dtx_enc(st->dtx_encSt, + compute_sid_flag, + st->lspSt->qSt, + st->gainQuantSt->gc_predSt, + &ana); + + Set_zero(st->old_exc, PIT_MAX + L_INTERPOL); + Set_zero(st->mem_w0, M); + Set_zero(st->mem_err, M); + Set_zero(st->zero, L_SUBFR); + Set_zero(st->hvec, L_SUBFR); // set to zero "h1[-L_SUBFR..-1]" + // Reset lsp states + lsp_reset(st->lspSt); + Copy(lsp_new, st->lspSt->lsp_old, M); + Copy(lsp_new, st->lspSt->lsp_old_q, M); + + // Reset clLtp states + cl_ltp_reset(st->clLtpSt); + st->sharp = SHARPMIN; + } + else + { + // check resonance in the filter + lsp_flag = check_lsp(st->tonStabSt, st->lspSt->lsp_old); + } + + *----------------------------------------------------------------------* + * - Find the weighted input speech w_sp[] for the whole speech frame * + * - Find the open-loop pitch delay for first 2 subframes * + * - Set the range for searching closed-loop pitch in 1st subframe * + * - Find the open-loop pitch delay for last 2 subframes * + *----------------------------------------------------------------------* + +#ifdef VAD2 + if (st->dtx) + { // no test() call since this if is only in simulation env + st->vadSt->L_Rmax = 0; + st->vadSt->L_R0 = 0; + } +#endif + for(subfrNr = 0, i_subfr = 0; + subfrNr < L_FRAME/L_FRAME_BY2; + subfrNr++, i_subfr += L_FRAME_BY2) + { + // Pre-processing on 80 samples + pre_big(mode, gamma1, gamma1_12k2, gamma2, A_t, i_subfr, st->speech, + st->mem_w, st->wsp); + + if ((sub(mode, MR475) != 0) && (sub(mode, MR515) != 0)) + { + // Find open loop pitch lag for two subframes + ol_ltp(st->pitchOLWghtSt, st->vadSt, mode, &st->wsp[i_subfr], + &T_op[subfrNr], st->old_lags, st->ol_gain_flg, subfrNr, + st->dtx); + } + } + + if ((sub(mode, MR475) == 0) || (sub(mode, MR515) == 0)) + { + // Find open loop pitch lag for ONE FRAME ONLY + // search on 160 samples + + ol_ltp(st->pitchOLWghtSt, st->vadSt, mode, &st->wsp[0], &T_op[0], + st->old_lags, st->ol_gain_flg, 1, st->dtx); + T_op[1] = T_op[0]; + } + +#ifdef VAD2 + if (st->dtx) + { // no test() call since this if is only in simulation env + LTP_flag_update(st->vadSt, mode); + } +#endif + +#ifndef VAD2 + // run VAD pitch detection + if (st->dtx) + { // no test() call since this if is only in simulation env + vad_pitch_detection(st->vadSt, T_op); + } +#endif + + if (sub(*usedMode, MRDTX) == 0) + { + goto the_end; + } + + *------------------------------------------------------------------------* + * Loop for every subframe in the analysis frame * + *------------------------------------------------------------------------* + * To find the pitch and innovation parameters. The subframe size is * + * L_SUBFR and the loop is repeated L_FRAME/L_SUBFR times. * + * - find the weighted LPC coefficients * + * - find the LPC residual signal res[] * + * - compute the target signal for pitch search * + * - compute impulse response of weighted synthesis filter (h1[]) * + * - find the closed-loop pitch parameters * + * - encode the pitch dealy * + * - update the impulse response h1[] by including fixed-gain pitch * + * - find target vector for codebook search * + * - codebook search * + * - encode codebook address * + * - VQ of pitch and codebook gains * + * - find synthesis speech * + * - update states of weighting filter * + *------------------------------------------------------------------------* + + A = A_t; // pointer to interpolated LPC parameters + Aq = Aq_t; // pointer to interpolated quantized LPC parameters + + evenSubfr = 0; + subfrNr = -1; + for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) + { + subfrNr = add(subfrNr, 1); + evenSubfr = sub(1, evenSubfr); + + // Save states for the MR475 mode + if ((evenSubfr != 0) && (sub(*usedMode, MR475) == 0)) + { + Copy(st->mem_syn, mem_syn_save, M); + Copy(st->mem_w0, mem_w0_save, M); + Copy(st->mem_err, mem_err_save, M); + sharp_save = st->sharp; + } + + *-----------------------------------------------------------------* + * - Preprocessing of subframe * + *-----------------------------------------------------------------* + if (sub(*usedMode, MR475) != 0) + { + subframePreProc(*usedMode, gamma1, gamma1_12k2, + gamma2, A, Aq, &st->speech[i_subfr], + st->mem_err, st->mem_w0, st->zero, + st->ai_zero, &st->exc[i_subfr], + st->h1, xn, res, st->error); + } + else + { // MR475 + subframePreProc(*usedMode, gamma1, gamma1_12k2, + gamma2, A, Aq, &st->speech[i_subfr], + st->mem_err, mem_w0_save, st->zero, + st->ai_zero, &st->exc[i_subfr], + st->h1, xn, res, st->error); + + // save impulse response (modified in cbsearch) + if (evenSubfr != 0) + { + Copy (st->h1, h1_sf0, L_SUBFR); + } + } + + // copy the LP residual (res2 is modified in the CL LTP search) + Copy (res, res2, L_SUBFR); + + + *-----------------------------------------------------------------* + * - Closed-loop LTP search * + *-----------------------------------------------------------------* + cl_ltp(st->clLtpSt, st->tonStabSt, *usedMode, i_subfr, T_op, st->h1, + &st->exc[i_subfr], res2, xn, lsp_flag, xn2, y1, + &T0, &T0_frac, &gain_pit, gCoeff, &ana, + &gp_limit); + + // update LTP lag history + if ((subfrNr == 0) && (st->ol_gain_flg[0] > 0)) + { + st->old_lags[1] = T0; + } + + if ((sub(subfrNr, 3) == 0) && (st->ol_gain_flg[1] > 0)) + { + st->old_lags[0] = T0; + } + + + *-----------------------------------------------------------------* + * - Inovative codebook search (find index and gain) * + *-----------------------------------------------------------------* + cbsearch(xn2, st->h1, T0, st->sharp, gain_pit, res2, + code, y2, &ana, *usedMode, subfrNr); + + *------------------------------------------------------* + * - Quantization of gains. * + *------------------------------------------------------* + gainQuant(st->gainQuantSt, *usedMode, res, &st->exc[i_subfr], code, + xn, xn2, y1, y2, gCoeff, evenSubfr, gp_limit, + &gain_pit_sf0, &gain_code_sf0, + &gain_pit, &gain_code, &ana); + + // update gain history + update_gp_clipping(st->tonStabSt, gain_pit); + + if (sub(*usedMode, MR475) != 0) + { + // Subframe Post Porcessing + subframePostProc(st->speech, *usedMode, i_subfr, gain_pit, + gain_code, Aq, synth, xn, code, y1, y2, st->mem_syn, + st->mem_err, st->mem_w0, st->exc, &st->sharp); + } + else + { + if (evenSubfr != 0) + { + i_subfr_sf0 = i_subfr; + Copy(xn, xn_sf0, L_SUBFR); + Copy(y2, y2_sf0, L_SUBFR); + Copy(code, code_sf0, L_SUBFR); + T0_sf0 = T0; + T0_frac_sf0 = T0_frac; + + // Subframe Post Porcessing + subframePostProc(st->speech, *usedMode, i_subfr, gain_pit, + gain_code, Aq, synth, xn, code, y1, y2, + mem_syn_save, st->mem_err, mem_w0_save, + st->exc, &st->sharp); + st->sharp = sharp_save; + } + else + { + // update both subframes for the MR475 + + // Restore states for the MR475 mode + Copy(mem_err_save, st->mem_err, M); + + // re-build excitation for sf 0 + Pred_lt_3or6(&st->exc[i_subfr_sf0], T0_sf0, T0_frac_sf0, + L_SUBFR, 1); + Convolve(&st->exc[i_subfr_sf0], h1_sf0, y1, L_SUBFR); + + Aq -= MP1; + subframePostProc(st->speech, *usedMode, i_subfr_sf0, + gain_pit_sf0, gain_code_sf0, Aq, + synth, xn_sf0, code_sf0, y1, y2_sf0, + st->mem_syn, st->mem_err, st->mem_w0, st->exc, + &sharp_save); // overwrites sharp_save + Aq += MP1; + + // re-run pre-processing to get xn right (needed by postproc) + // (this also reconstructs the unsharpened h1 for sf 1) + subframePreProc(*usedMode, gamma1, gamma1_12k2, + gamma2, A, Aq, &st->speech[i_subfr], + st->mem_err, st->mem_w0, st->zero, + st->ai_zero, &st->exc[i_subfr], + st->h1, xn, res, st->error); + + // re-build excitation sf 1 (changed if lag < L_SUBFR) + Pred_lt_3or6(&st->exc[i_subfr], T0, T0_frac, L_SUBFR, 1); + Convolve(&st->exc[i_subfr], st->h1, y1, L_SUBFR); + + subframePostProc(st->speech, *usedMode, i_subfr, gain_pit, + gain_code, Aq, synth, xn, code, y1, y2, + st->mem_syn, st->mem_err, st->mem_w0, + st->exc, &st->sharp); + } + } + + + A += MP1; // interpolated LPC parameters for next subframe + Aq += MP1; + } + + Copy(&st->old_exc[L_FRAME], &st->old_exc[0], PIT_MAX + L_INTERPOL); + +the_end: + + *--------------------------------------------------* + * Update signal for next frame. * + *--------------------------------------------------* + Copy(&st->old_wsp[L_FRAME], &st->old_wsp[0], PIT_MAX); + + Copy(&st->old_speech[L_FRAME], &st->old_speech[0], L_TOTAL - L_FRAME); + + 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 cod_amr( + cod_amrState *st, /* i/o : State struct */ + enum Mode mode, /* i : AMR mode */ + Word16 new_speech[], /* i : speech input (L_FRAME) */ + Word16 ana[], /* o : Analysis parameters */ + enum Mode *usedMode, /* o : used mode */ + Word16 synth[] /* o : Local synthesis */ +) +{ + /* LPC coefficients */ + Word16 A_t[(MP1) * 4]; /* A(z) unquantized for the 4 subframes */ + Word16 Aq_t[(MP1) * 4]; /* A(z) quantized for the 4 subframes */ + Word16 *A, *Aq; /* Pointer on A_t and Aq_t */ + Word16 lsp_new[M]; + + /* Other vectors */ + Word16 xn[L_SUBFR]; /* Target vector for pitch search */ + Word16 xn2[L_SUBFR]; /* Target vector for codebook search */ + Word16 code[L_SUBFR]; /* Fixed codebook excitation */ + Word16 y1[L_SUBFR]; /* Filtered adaptive excitation */ + Word16 y2[L_SUBFR]; /* Filtered fixed codebook excitation */ + Word16 gCoeff[6]; /* Correlations between xn, y1, & y2: */ + Word16 res[L_SUBFR]; /* Short term (LPC) prediction residual */ + Word16 res2[L_SUBFR]; /* Long term (LTP) prediction residual */ + + /* Vector and scalars needed for the MR475 */ + Word16 xn_sf0[L_SUBFR]; /* Target vector for pitch search */ + Word16 y2_sf0[L_SUBFR]; /* Filtered codebook innovation */ + Word16 code_sf0[L_SUBFR]; /* Fixed codebook excitation */ + Word16 h1_sf0[L_SUBFR]; /* The impulse response of sf0 */ + Word16 mem_syn_save[M]; /* Filter memory */ + Word16 mem_w0_save[M]; /* Filter memory */ + Word16 mem_err_save[M]; /* Filter memory */ + Word16 sharp_save; /* Sharpening */ + Word16 evenSubfr; /* Even subframe indicator */ + Word16 T0_sf0 = 0; /* Integer pitch lag of sf0 */ + Word16 T0_frac_sf0 = 0; /* Fractional pitch lag of sf0 */ + Word16 i_subfr_sf0 = 0; /* Position in exc[] for sf0 */ + Word16 gain_pit_sf0; /* Quantized pitch gain for sf0 */ + Word16 gain_code_sf0; /* Quantized codebook gain for sf0 */ + + /* Scalars */ + Word16 i_subfr, subfrNr; + Word16 T_op[L_FRAME/L_FRAME_BY2]; + Word16 T0, T0_frac; + Word16 gain_pit, gain_code; + + /* Flags */ + Word16 lsp_flag = 0; /* indicates resonance in LPC filter */ + Word16 gp_limit; /* pitch gain limit value */ + Word16 vad_flag; /* VAD decision flag */ + Word16 compute_sid_flag; /* SID analysis flag */ + Flag *pOverflow = &(st->overflow); /* Overflow flag */ + + + memcpy(st->new_speech, new_speech, L_FRAME*sizeof(Word16)); + + *usedMode = mode; + + /* DTX processing */ + if (st->dtx) + { + /* Find VAD decision */ +#ifdef VAD2 + vad_flag = vad2(st->new_speech, st->vadSt, pOverflow); + vad_flag = vad2(st->new_speech + 80, st->vadSt, pOverflow) || vad_flag; +#else + vad_flag = vad1(st->vadSt, st->new_speech, pOverflow); +#endif + + /* NB! usedMode may change here */ + compute_sid_flag = tx_dtx_handler(st->dtx_encSt, + vad_flag, + usedMode, pOverflow); + } + else + { + compute_sid_flag = 0; + } + + /*------------------------------------------------------------------------* + * - Perform LPC analysis: * + * * autocorrelation + lag windowing * + * * Levinson-durbin algorithm to find a[] * + * * convert a[] to lsp[] * + * * quantize and code the LSPs * + * * find the interpolated LSPs and convert to a[] for all * + * subframes (both quantized and unquantized) * + *------------------------------------------------------------------------*/ + + /* LP analysis */ + lpc(st->lpcSt, mode, st->p_window, st->p_window_12k2, A_t, pOverflow); + + /* From A(z) to lsp. LSP quantization and interpolation */ + lsp(st->lspSt, mode, *usedMode, A_t, Aq_t, lsp_new, &ana, pOverflow); + + /* Buffer lsp's and energy */ + dtx_buffer(st->dtx_encSt, + lsp_new, + st->new_speech, pOverflow); + + /* Check if in DTX mode */ + + if (*usedMode == MRDTX) + { + dtx_enc(st->dtx_encSt, + compute_sid_flag, + st->lspSt->qSt, + &(st->gainQuantSt->gc_predSt), + &ana, pOverflow); + + memset(st->old_exc, 0, sizeof(Word16)*(PIT_MAX + L_INTERPOL)); + memset(st->mem_w0, 0, sizeof(Word16)*M); + memset(st->mem_err, 0, sizeof(Word16)*M); + memset(st->zero, 0, sizeof(Word16)*L_SUBFR); + memset(st->hvec, 0, sizeof(Word16)*L_SUBFR); /* set to zero "h1[-L_SUBFR..-1]" */ + /* Reset lsp states */ + lsp_reset(st->lspSt); + + memcpy(st->lspSt->lsp_old, lsp_new, M*sizeof(Word16)); + memcpy(st->lspSt->lsp_old_q, lsp_new, M*sizeof(Word16)); + + /* Reset clLtp states */ + cl_ltp_reset(st->clLtpSt); + st->sharp = SHARPMIN; + } + else + { + /* check resonance in the filter */ + lsp_flag = check_lsp(st->tonStabSt, st->lspSt->lsp_old, pOverflow); + } + + /*----------------------------------------------------------------------* + * - Find the weighted input speech w_sp[] for the whole speech frame * + * - Find the open-loop pitch delay for first 2 subframes * + * - Set the range for searching closed-loop pitch in 1st subframe * + * - Find the open-loop pitch delay for last 2 subframes * + *----------------------------------------------------------------------*/ + +#ifdef VAD2 + if (st->dtx) + { + st->vadSt->L_Rmax = 0; + st->vadSt->L_R0 = 0; + } +#endif + + for (subfrNr = 0, i_subfr = 0; + subfrNr < L_FRAME / L_FRAME_BY2; + subfrNr++, i_subfr += L_FRAME_BY2) + { + /* Pre-processing on 80 samples */ + pre_big(mode, gamma1, gamma1_12k2, gamma2, A_t, i_subfr, st->speech, + st->mem_w, st->wsp, pOverflow); + + + if ((mode != MR475) && (mode != MR515)) + { + /* Find open loop pitch lag for two subframes */ + ol_ltp(st->pitchOLWghtSt, st->vadSt, mode, &st->wsp[i_subfr], + &T_op[subfrNr], st->old_lags, st->ol_gain_flg, subfrNr, + st->dtx, pOverflow); + } + } + + if ((mode == MR475) || (mode == MR515)) + { + /* Find open loop pitch lag for ONE FRAME ONLY */ + /* search on 160 samples */ + + ol_ltp(st->pitchOLWghtSt, st->vadSt, mode, &st->wsp[0], &T_op[0], + st->old_lags, st->ol_gain_flg, 1, st->dtx, pOverflow); + T_op[1] = T_op[0]; + } + +#ifdef VAD2 + if (st->dtx) + { + LTP_flag_update(st->vadSt, (Word16) mode, pOverflow); + } +#endif + +#ifndef VAD2 + /* run VAD pitch detection */ + if (st->dtx) + { + vad_pitch_detection(st->vadSt, T_op, pOverflow); + } +#endif + + if (*usedMode == MRDTX) + { + goto the_end; + } + + /*------------------------------------------------------------------------* + * Loop for every subframe in the analysis frame * + *------------------------------------------------------------------------* + * To find the pitch and innovation parameters. The subframe size is * + * L_SUBFR and the loop is repeated L_FRAME/L_SUBFR times. * + * - find the weighted LPC coefficients * + * - find the LPC residual signal res[] * + * - compute the target signal for pitch search * + * - compute impulse response of weighted synthesis filter (h1[]) * + * - find the closed-loop pitch parameters * + * - encode the pitch dealy * + * - update the impulse response h1[] by including fixed-gain pitch * + * - find target vector for codebook search * + * - codebook search * + * - encode codebook address * + * - VQ of pitch and codebook gains * + * - find synthesis speech * + * - update states of weighting filter * + *------------------------------------------------------------------------*/ + + A = A_t; /* pointer to interpolated LPC parameters */ + Aq = Aq_t; /* pointer to interpolated quantized LPC parameters */ + + evenSubfr = 0; + subfrNr = -1; + for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) + { + subfrNr++; + evenSubfr = 1 - evenSubfr; + + /* Save states for the MR475 mode */ + + if ((evenSubfr != 0) && (*usedMode == MR475)) + { + memcpy(mem_syn_save, st->mem_syn, M*sizeof(Word16)); + memcpy(mem_w0_save, st->mem_w0, M*sizeof(Word16)); + memcpy(mem_err_save, st->mem_err, M*sizeof(Word16)); + + sharp_save = st->sharp; + } + + /*-----------------------------------------------------------------* + * - Preprocessing of subframe * + *-----------------------------------------------------------------*/ + + if (*usedMode != MR475) + { + subframePreProc(*usedMode, gamma1, gamma1_12k2, + gamma2, A, Aq, &st->speech[i_subfr], + st->mem_err, st->mem_w0, st->zero, + st->ai_zero, &st->exc[i_subfr], + st->h1, xn, res, st->error); + } + else + { /* MR475 */ + subframePreProc(*usedMode, gamma1, gamma1_12k2, + gamma2, A, Aq, &st->speech[i_subfr], + st->mem_err, mem_w0_save, st->zero, + st->ai_zero, &st->exc[i_subfr], + st->h1, xn, res, st->error); + + /* save impulse response (modified in cbsearch) */ + + if (evenSubfr != 0) + { + memcpy(h1_sf0, st->h1, L_SUBFR*sizeof(Word16)); + + } + } + + /* copy the LP residual (res2 is modified in the CL LTP search) */ + memcpy(res2, res, L_SUBFR*sizeof(Word16)); + + /*-----------------------------------------------------------------* + * - Closed-loop LTP search * + *-----------------------------------------------------------------*/ + cl_ltp(st->clLtpSt, st->tonStabSt, *usedMode, i_subfr, T_op, st->h1, + &st->exc[i_subfr], res2, xn, lsp_flag, xn2, y1, + &T0, &T0_frac, &gain_pit, gCoeff, &ana, + &gp_limit, pOverflow); + + /* update LTP lag history */ + + if ((subfrNr == 0) && (st->ol_gain_flg[0] > 0)) + { + st->old_lags[1] = T0; + } + + + if ((subfrNr == 3) && (st->ol_gain_flg[1] > 0)) + { + st->old_lags[0] = T0; + } + + /*-----------------------------------------------------------------* + * - Inovative codebook search (find index and gain) * + *-----------------------------------------------------------------*/ + cbsearch(xn2, st->h1, T0, st->sharp, gain_pit, res2, + code, y2, &ana, *usedMode, subfrNr, pOverflow); + + /*------------------------------------------------------* + * - Quantization of gains. * + *------------------------------------------------------*/ + gainQuant(st->gainQuantSt, *usedMode, res, &st->exc[i_subfr], code, + xn, xn2, y1, y2, gCoeff, evenSubfr, gp_limit, + &gain_pit_sf0, &gain_code_sf0, + &gain_pit, &gain_code, &ana, pOverflow); + + /* update gain history */ + update_gp_clipping(st->tonStabSt, gain_pit, pOverflow); + + + if (*usedMode != MR475) + { + /* Subframe Post Porcessing */ + subframePostProc(st->speech, *usedMode, i_subfr, gain_pit, + gain_code, Aq, synth, xn, code, y1, y2, st->mem_syn, + st->mem_err, st->mem_w0, st->exc, &st->sharp, pOverflow); + } + else + { + + if (evenSubfr != 0) + { + i_subfr_sf0 = i_subfr; + + memcpy(xn_sf0, xn, L_SUBFR*sizeof(Word16)); + memcpy(y2_sf0, y2, L_SUBFR*sizeof(Word16)); + memcpy(code_sf0, code, L_SUBFR*sizeof(Word16)); + + T0_sf0 = T0; + T0_frac_sf0 = T0_frac; + + /* Subframe Post Porcessing */ + subframePostProc(st->speech, *usedMode, i_subfr, gain_pit, + gain_code, Aq, synth, xn, code, y1, y2, + mem_syn_save, st->mem_err, mem_w0_save, + st->exc, &st->sharp, pOverflow); + st->sharp = sharp_save; + } + else + { + /* update both subframes for the MR475 */ + + /* Restore states for the MR475 mode */ + memcpy(st->mem_err, mem_err_save, M*sizeof(Word16)); + + + /* re-build excitation for sf 0 */ + Pred_lt_3or6(&st->exc[i_subfr_sf0], T0_sf0, T0_frac_sf0, + L_SUBFR, 1, pOverflow); + Convolve(&st->exc[i_subfr_sf0], h1_sf0, y1, L_SUBFR); + + Aq -= MP1; + subframePostProc(st->speech, *usedMode, i_subfr_sf0, + gain_pit_sf0, gain_code_sf0, Aq, + synth, xn_sf0, code_sf0, y1, y2_sf0, + st->mem_syn, st->mem_err, st->mem_w0, st->exc, + &sharp_save, pOverflow); /* overwrites sharp_save */ + Aq += MP1; + + /* re-run pre-processing to get xn right (needed by postproc) */ + /* (this also reconstructs the unsharpened h1 for sf 1) */ + subframePreProc(*usedMode, gamma1, gamma1_12k2, + gamma2, A, Aq, &st->speech[i_subfr], + st->mem_err, st->mem_w0, st->zero, + st->ai_zero, &st->exc[i_subfr], + st->h1, xn, res, st->error); + + /* re-build excitation sf 1 (changed if lag < L_SUBFR) */ + Pred_lt_3or6(&st->exc[i_subfr], T0, T0_frac, L_SUBFR, 1, pOverflow); + Convolve(&st->exc[i_subfr], st->h1, y1, L_SUBFR); + + subframePostProc(st->speech, *usedMode, i_subfr, gain_pit, + gain_code, Aq, synth, xn, code, y1, y2, + st->mem_syn, st->mem_err, st->mem_w0, + st->exc, &st->sharp, pOverflow); + } + } + + A += MP1; /* interpolated LPC parameters for next subframe */ + Aq += MP1; + } + + memcpy(&st->old_exc[0], &st->old_exc[L_FRAME], (PIT_MAX + L_INTERPOL)*sizeof(Word16)); + +the_end: + + /*--------------------------------------------------* + * Update signal for next frame. * + *--------------------------------------------------*/ + + memcpy(&st->old_wsp[0], &st->old_wsp[L_FRAME], PIT_MAX*sizeof(Word16)); + memcpy(&st->old_speech[0], &st->old_speech[L_FRAME], (L_TOTAL - L_FRAME)*sizeof(Word16)); + + return(0); +} + + |