blob: 84681319db513a56cb40d7f1880cadc1f9a8cc0b [file] [log] [blame]
/* ------------------------------------------------------------------
* 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);
}