www.pudn.com > SMV_Code.rar > lib_ltp.c
/*============================================================================*/
/*=========================================================================*/
/* Each of the companies; Ericsson, Lucent, Mindspeed, Motorola, Nokia, */
/* Nortel Networks, and Qualcomm (hereinafter referred to individually as */
/* “Source” or collectively as “Sources”) do hereby state: */
/* */
/* To the extent to which the Source(s) may legally and freely do so, */
/* the Source(s), upon submission of a Contribution, grant(s) a free, */
/* irrevocable, non-exclusive, license to the Third Generation Partnership */
/* Project 2 (3GPP2) and its Organizational Partners: ARIB, CCSA, TIA, */
/* TTA, and TTC, under the Source’s copyright or copyright license rights */
/* in the Contribution, to, in whole or in part, copy, make derivative */
/* works, perform, display and distribute the Contribution and derivative */
/* works thereof consistent with 3GPP2’s and each Organizational Partner’s */
/* policies and procedures, with the right to (i) sublicense the foregoing */
/* rights consistent with 3GPP2’s and each Organizational Partner’s */
/* policies and procedures and (ii) copyright and sell, if applicable) in */
/* 3GPP2's name or each Organizational Partner’s name any 3GPP2 or */
/* transposed Publication even though this Publication may contain the */
/* Contribution or a derivative work thereof. The Contribution shall */
/* disclose any known limitations on the Source’s rights to license as */
/* herein provided. */
/* */
/* When a Contribution is submitted by the Source(s) to assist the */
/* formulating groups of 3GPP2 or any of its Organizational Partners, */
/* it is proposed to the Committee as a basis for discussion and is not */
/* to be construed as a binding proposal on the Source(s). The Source(s) */
/* specifically reserve(s) the right to amend or modify the material */
/* contained in the Contribution. Nothing contained in the Contribution */
/* shall, except as herein expressly provided, be construed as conferring */
/* by implication, estoppel or otherwise, any license or right under */
/* (i) any existing or later issuing patent, whether or not the use of */
/* information in the document necessarily employs an invention of any */
/* existing or later issued patent, (ii) any copyright, (iii) any */
/* trademark, or (iv) any other intellectual property right. */
/* */
/* With respect to the Software necessary for the practice of any or all */
/* Normative portions of the Selectable Mode Vocoder (SMV) as it exists on */
/* the date of submittal of this form, should the SMV be approved as a */
/* Specification or Report by 3GPP2, or as a transposed Standard by any of */
/* the 3GPP2’s Organizational Partners, the Source(s) state(s) that a */
/* worldwide license to reproduce, use and distribute the Software, the */
/* license rights to which are held by the Source(s), will be made */
/* available to applicants under terms and conditions that are reasonable */
/* and non-discriminatory, which may include monetary compensation, */
/* and only to the extent necessary for the practice of any or all of the */
/* Normative portions of the SMV or the field of use of practice of the */
/* SMV Specification, Report, or Standard. The statement contained above */
/* is irrevocable and shall be binding upon the Source(s). In the event */
/* the rights of the Source(s) in and to copyright or copyright license */
/* rights subject to such commitment are assigned or transferred, */
/* the Source(s) shall notify the assignee or transferee of the existence */
/* of such commitments. */
/*=========================================================================*/
/* */
/*-------------------------------------------------------------------*/
/*===================================================================*/
/* LIBRARY: lib_ltp.c */
/*-------------------------------------------------------------------*/
/* PURPOSE : Long Term Prediction library */
/*===================================================================*/
/*----------------------------------------------------------------------------*/
/*----------------------------------- INCLUDE --------------------------------*/
/*----------------------------------------------------------------------------*/
#include "typedef.h"
#include "main.h"
#include "const.h"
#include "gputil.h"
#include "mcutil.h"
#include "ext_var.h"
#include "lib_flt.h"
#include "lib_ltp.h"
#include "lib_pit.h"
#ifdef WMOPS
#include "lib_wmp.h"
#endif
/*----------------------------------------------------------------------------*/
/*---------------------------------- FUNCTIONS -------------------------------*/
/*----------------------------------------------------------------------------*/
/*===================================================================*/
/* FUNCTION : LTP_init_lib (). */
/*-------------------------------------------------------------------*/
/* PURPOSE : This function initialise the gloval variable of the */
/* library LTP. */
/*-------------------------------------------------------------------*/
/* ALGORITHM : */
/*-------------------------------------------------------------------*/
/* INPUT ARGUMENTS : */
/* _ None. */
/*-------------------------------------------------------------------*/
/* OUTPUT ARGUMENTS : */
/* _ None. */
/*-------------------------------------------------------------------*/
/* INPUT/OUTPUT ARGUMENTS : */
/* _ None. */
/*-------------------------------------------------------------------*/
/* RETURN ARGUMENTS : */
/* _ None. */
/*===================================================================*/
void LTP_init_lib (void)
{
/*-------------------------------------------------------------------*/
ini_dvector(lag_f, 0, N_SF_MAX-1, 30.0);
ini_svector(lag, 0, N_SF_MAX-1, 30);
#ifdef ENC_CMP
ini_dvector (NewTg_mem, 0, NP-1, 0.0);
ini_dvector (ext, 0, MAX_LAG+L_SF-1, 0.0);
#endif
#ifdef DEC_CMP
ini_dvector (ext_dec, 0, MAX_LAG+L_SF-1, 0.0);
#endif
/*-------------------------------------------------------------------*/
return;
/*-------------------------------------------------------------------*/
}
/*----------------------------------------------------------------------------*/
/*===================================================================*/
/* FUNCTION : D2A_interp_1sthalf (). */
/*-------------------------------------------------------------------*/
/* PURPOSE : This function performs a bandlimited interpolation of */
/* a given signal to compute a value between two */
/* digitized samples. */
/* The top half of the sinc table is used. */
/* */
/*-------------------------------------------------------------------*/
/* ALGORITHM : */
/*-------------------------------------------------------------------*/
/* INPUT ARGUMENTS : */
/* _ (FLOAT64 []) w : Weighting function. */
/* _ (FLOAT64 []) s : signal. */
/* _ (INT16 ) WinLim : half Weighting function length. */
/* _ (FLOAT64 ) t : Time point of the signal value */
/* between two samples. */
/*-------------------------------------------------------------------*/
/* OUTPUT ARGUMENTS : */
/* _ None. */
/*-------------------------------------------------------------------*/
/* INPUT/OUTPUT ARGUMENTS : */
/* _ None. */
/*-------------------------------------------------------------------*/
/* RETURN ARGUMENTS : */
/* _ (FLOAT64 ) X : Interpolated signal sample. */
/*===================================================================*/
FLOAT64 D2A_interp_1sthalf (FLOAT64 w[], FLOAT64 s[], FLOAT64 t,
INT16 WinLim)
{
/*-------------------------------------------------------------------*/
INT16 i, k, L1, L2;
FLOAT64 X;
/*-------------------------------------------------------------------*/
L1 = (INT16)t-(WinLim-1); /* WinLim is constant */
L2 = L1+(2*WinLim); /* WinLim is constant */
X = 0.0;
#ifdef WMOPS
WMP_cnt_mac(L2-L1);
WMP_cnt_add(2);
WMP_cnt_move(3);
#endif
for (i = 0, k = L1; k < L2; i++, k++)
X += s[k]*w[i];
/*-------------------------------------------------------------------*/
return X;
/*-------------------------------------------------------------------*/
}
/*----------------------------------------------------------------------------*/
/*===================================================================*/
/* FUNCTION : D2A_interp_2ndhalf (). */
/*-------------------------------------------------------------------*/
/* PURPOSE : This function performs a bandlimited interpolation of */
/* a given signal to compute a value between two */
/* digitized samples. */
/* The bottom half of the sinc table is used. */
/* */
/*-------------------------------------------------------------------*/
/* ALGORITHM : */
/*-------------------------------------------------------------------*/
/* INPUT ARGUMENTS : */
/* _ (FLOAT64 []) w : Weighting function. */
/* _ (FLOAT64 []) s : signal. */
/* _ (INT16 ) WinLim : half Weighting function length. */
/* _ (FLOAT64 ) t : Time point of the signal value */
/* between two samples. */
/*-------------------------------------------------------------------*/
/* OUTPUT ARGUMENTS : */
/* _ None. */
/*-------------------------------------------------------------------*/
/* INPUT/OUTPUT ARGUMENTS : */
/* _ None. */
/*-------------------------------------------------------------------*/
/* RETURN ARGUMENTS : */
/* _ (FLOAT64 ) X : Interpolated signal sample. */
/*===================================================================*/
FLOAT64 D2A_interp_2ndhalf (FLOAT64 w[], FLOAT64 s[], FLOAT64 t,
INT16 WinLim)
{
/*-------------------------------------------------------------------*/
INT16 i, k, L1, L2;
FLOAT64 X;
/*-------------------------------------------------------------------*/
L1 = (INT16)t-(WinLim-1); /* WinLim is constant */
L2 = L1+(2*WinLim); /* WinLim is constant */
X = 0.0;
#ifdef WMOPS
WMP_cnt_mac(L2-L1);
WMP_cnt_add(2);
WMP_cnt_move(3);
#endif
for (i = 2*WinLim-1, k = L1; k < L2; i--, k++)
X += s[k]*w[i];
/*-------------------------------------------------------------------*/
return X;
/*-------------------------------------------------------------------*/
}
/*----------------------------------------------------------------------------*/
#ifdef ENC_CMP
/*===================================================================*/
/* FUNCTION : LTP_Idx_Serach (). */
/*-------------------------------------------------------------------*/
/* PURPOSE : This function produces the extract the N bits index */
/* corresponding to the pitch value */
/*-------------------------------------------------------------------*/
/* ALGORITHM : */
/*-------------------------------------------------------------------*/
/* INPUT ARGUMENTS : */
/* _ (FLOAT64 ) pit : pitch value. */
/* _ (FLOAT64 []) tab : pitch quantization table. */
/* _ (INT16 ) low_idx: lower table index. */
/* _ (INT16 ) high_idx: higher table index. */
/*-------------------------------------------------------------------*/
/* OUTPUT ARGUMENTS : */
/* _ (INT16 *) idx : corresponding index. */
/*-------------------------------------------------------------------*/
/* INPUT/OUTPUT ARGUMENTS : */
/* _ None. */
/*-------------------------------------------------------------------*/
/* RETURN ARGUMENTS : */
/* _ None. */
/*===================================================================*/
void LTP_Idx_Serach (FLOAT64 pit, FLOAT64 tab[], INT16 low_idx, INT16 high_idx,
INT16 *idx)
{
/*------------------------------------------------------------------*/
INT16 mid_idx ;
/*------------------------------------------------------------------*/
/* Perform binary search of a pitch table */
/*------------------------------------------------------------------*/
while(1)
{
#ifdef WMOPS
WMP_cnt_test (1);
WMP_cnt_add (1);
WMP_cnt_shift(1);
#endif
mid_idx = (low_idx + high_idx) >> 1;
if (mid_idx == low_idx)
break;
#ifdef WMOPS
WMP_cnt_test(1);
WMP_cnt_move(1);
#endif
if (tab[mid_idx] > pit)
high_idx = mid_idx;
else
low_idx = mid_idx;
}
#ifdef WMOPS
WMP_cnt_test(1);
WMP_cnt_sub (2);
WMP_cnt_move(1);
#endif
if ((tab[high_idx] - pit) < (pit - tab[low_idx]))
*idx = high_idx ;
else
*idx = mid_idx ;
/*------------------------------------------------------------------*/
return ;
/*------------------------------------------------------------------*/
}
/*------------------------------------------------------------------------*/
#endif
/*----------------------------------------------------------------------------*/
#ifdef ENC_CMP
/*===================================================================*/
/* FUNCTION : LTP_lag_to_idx7b (). */
/*-------------------------------------------------------------------*/
/* PURPOSE : This function quantizes the given pitch into 7 bits. */
/*-------------------------------------------------------------------*/
/* ALGORITHM : */
/*-------------------------------------------------------------------*/
/* INPUT ARGUMENTS : */
/* _ (FLOAT64 ) pit : pitch value. */
/*-------------------------------------------------------------------*/
/* OUTPUT ARGUMENTS : */
/* _ None. */
/*-------------------------------------------------------------------*/
/* INPUT/OUTPUT ARGUMENTS : */
/* _ None. */
/*-------------------------------------------------------------------*/
/* RETURN ARGUMENTS : */
/* _ (INT16 ) idx : corresponding index. */
/*===================================================================*/
INT16 LTP_lag_to_idx7b (FLOAT64 pit)
{
/*-------------------------------------------------------------------*/
INT16 idx;
/*-------------------------------------------------------------------*/
LTP_Idx_Serach(pit, PitLagTab7b, 0, MAX_PIT_IDX_7b, &idx);
/*-------------------------------------------------------------------*/
return (idx);
/*-------------------------------------------------------------------*/
}
/*----------------------------------------------------------------------------*/
/*===================================================================*/
/* FUNCTION : LTP_lag_to_idx8b (). */
/*-------------------------------------------------------------------*/
/* PURPOSE : This function quantizes the given pitch into 8 bits. */
/*-------------------------------------------------------------------*/
/* ALGORITHM : */
/*-------------------------------------------------------------------*/
/* INPUT ARGUMENTS : */
/* _ (FLOAT64 ) pit : pitch value. */
/*-------------------------------------------------------------------*/
/* OUTPUT ARGUMENTS : */
/* _ None. */
/*-------------------------------------------------------------------*/
/* INPUT/OUTPUT ARGUMENTS : */
/* _ None. */
/*-------------------------------------------------------------------*/
/* RETURN ARGUMENTS : */
/* _ (INT16 ) idx : corresponding index. */
/*===================================================================*/
INT16 LTP_lag_to_idx8b( FLOAT64 pit)
{
/*-----------------------------------------------------------------*/
INT16 idx;
/*-----------------------------------------------------------------*/
LTP_Idx_Serach(pit, PitLagTab8b, 0, MAX_PIT_IDX_8b, &idx);
/*-----------------------------------------------------------------*/
return (idx);
/*-----------------------------------------------------------------*/
}
#endif
/*---------------------------------------------------------------------------*/
/*===================================================================*/
/* FUNCTION : LTP_Allocate_Sinc_Tab (). */
/*-------------------------------------------------------------------*/
/* PURPOSE : This function selects the weighting function to be */
/* used for the bandlimited interpolation */
/*-------------------------------------------------------------------*/
/* INPUT ARGUMENTS : */
/* _ (FLOAT64 ) t : time location where the interpolation is */
/* desired */
/*-------------------------------------------------------------------*/
/* OUTPUT ARGUMENTS : */
/* _ (INT16 *) m : index to the weighting function */
/*-------------------------------------------------------------------*/
/* INPUT/OUTPUT ARGUMENTS : */
/* _ None. */
/*-------------------------------------------------------------------*/
/* RETURN ARGUMENTS : */
/* _ None. */
/*===================================================================*/
void LTP_Allocate_Sinc_Tab (FLOAT64 t, INT16 *m)
{
/*-------------------------------------------------------------------*/
FLOAT64 f;
INT16 T;
/*-------------------------------------------------------------------*/
#ifdef WMOPS
WMP_cnt_add (1);
WMP_cnt_mult (1);
WMP_cnt_sub (1);
#endif
T = (INT16)t;
f = t - (FLOAT64)T;
*m = (INT16)(f*(FLOAT64)DELT_F2 + 0.500001);
/*-------------------------------------------------------------------*/
return;
/*-------------------------------------------------------------------*/
}
/*----------------------------------------------------------------------------*/
/*===================================================================*/
/* FUNCTION : LTP_excit_vari_pitch (). */
/*-------------------------------------------------------------------*/
/* PURPOSE : This function calculates LTP excitation with */
/* interpolated pitch track. */
/*-------------------------------------------------------------------*/
/* ALGORITHM : */
/*-------------------------------------------------------------------*/
/* INPUT ARGUMENTS : */
/* _ (FLOAT64 []) SincWindows : table of interpolation weights. */
/* _ (FLOAT64 []) PitFun : Pitch track. */
/* _ (FLOAT64 []) LTm : Excitation memory. */
/* _ (INT16 ) L_LTm : Length of the excitation memory.*/
/* _ (INT16 ) Len : Length of the LTP excitation. */
/*-------------------------------------------------------------------*/
/* OUTPUT ARGUMENTS : */
/* _ (FLOAT64 []) E : LTP excitation. */
/*-------------------------------------------------------------------*/
/* INPUT/OUTPUT ARGUMENTS : */
/* _ None. */
/*-------------------------------------------------------------------*/
/* RETURN ARGUMENTS : */
/* _ None. */
/*===================================================================*/
void LTP_excit_vari_pitch (FLOAT64 PitFun[],INT16 L_LTm,FLOAT64 LTm[],INT16 Len,
FLOAT64 E[])
{
/*-------------------------------------------------------------------*/
FLOAT64 t, *Weight;
INT16 k, m;
/*-------------------------------------------------------------------*/
#ifdef WMOPS
WMP_cnt_mult(2*Len);
WMP_cnt_add(2*Len);
WMP_cnt_sub(Len);
WMP_cnt_move(2*Len);
WMP_cnt_test (Len);
#endif
for (k = 0; k < Len; k++)
{
t = L_LTm + k - PitFun[k];
LTP_Allocate_Sinc_Tab(t, &m);
if (m <= NUM_SINC_WIN/2)
{
Weight = SincWindows_E + m*LEN_SINC_E;
E[k] = D2A_interp_1sthalf (Weight, LTm,
t, SINC_LIMIT_E);
}
else
{
Weight = SincWindows_E + (NUM_SINC_WIN-m-1)*LEN_SINC_E;
E[k] = D2A_interp_2ndhalf (Weight, LTm,
t, SINC_LIMIT_E);
}
LTm[L_LTm+k] = E[k];
}
/*-------------------------------------------------------------------*/
return;
/*-------------------------------------------------------------------*/
}
/*----------------------------------------------------------------------------*/
/*===================================================================*/
/* FUNCTION : LTP_excit_const_pitch (). */
/*-------------------------------------------------------------------*/
/* PURPOSE : This function calculates LTP excitation with */
/* constant pitch track. */
/*-------------------------------------------------------------------*/
/* ALGORITHM : */
/*-------------------------------------------------------------------*/
/* INPUT ARGUMENTS : */
/* _ (FLOAT64 ) Pit_f : Pitch lag (fractional). */
/* _ (FLOAT64 []) LTm : Excitation memory. */
/* _ (INT16 ) L_LTm : Length of the excitation memory.*/
/* _ (INT16 ) Len : Length of the LTP excitation. */
/* _ (INT16 ) mem_flag : memory update flag. */
/*-------------------------------------------------------------------*/
/* OUTPUT ARGUMENTS : */
/* _ (FLOAT64 []) E : LTP excitation. */
/*-------------------------------------------------------------------*/
/* INPUT/OUTPUT ARGUMENTS : */
/* _ None. */
/*-------------------------------------------------------------------*/
/* RETURN ARGUMENTS : */
/* _ None. */
/*===================================================================*/
void LTP_excit_const_pitch (FLOAT64 Pit_f,INT16 L_LTm, FLOAT64 LTm[],INT16 Len,
FLOAT64 E[],INT16 mem_flag)
{
/*-------------------------------------------------------------------*/
INT16 k, m;
FLOAT64 t, *Weight;
FLOAT64 (*D2A_interp)(FLOAT64*, FLOAT64*, FLOAT64, INT16);
/*-------------------------------------------------------------------*/
#ifdef WMOPS
WMP_cnt_shift(2);
WMP_cnt_mult (1);
WMP_cnt_add (Len);
WMP_cnt_sub (1+Len);
WMP_cnt_move (5+2*Len);
WMP_cnt_test (Len);
WMP_cnt_test (1);
WMP_cnt_move (1);
#endif
t = L_LTm - Pit_f;
LTP_Allocate_Sinc_Tab(t, &m);
if (m <= NUM_SINC_WIN/2)
{
Weight = SincWindows_E + m*LEN_SINC_E;
D2A_interp = D2A_interp_1sthalf ;
}
else
{
Weight = SincWindows_E + (NUM_SINC_WIN-m-1)*LEN_SINC_E;
D2A_interp = D2A_interp_2ndhalf ;
}
for (k = 0; k < Len; k++)
{
t = L_LTm + k - Pit_f;
E[k] = D2A_interp (Weight, LTm, t,
SINC_LIMIT_E);
if (mem_flag == 1)
LTm[L_LTm+k] = E[k];
}
/*-------------------------------------------------------------------*/
return;
/*-------------------------------------------------------------------*/
}
/*----------------------------------------------------------------------------*/
/*===================================================================*/
/* FUNCTION : LTP_FineIndex_search (). */
/*-------------------------------------------------------------------*/
/* PURPOSE : This function does the fine search of the correlation.*/
/*-------------------------------------------------------------------*/
/* ALGORITHM : */
/*-------------------------------------------------------------------*/
/* INPUT ARGUMENTS : */
/* _ (FLOAT64 []) PitTab: table of pitch values. */
/* _ (INT16 ) P1 : the lower end of the search range. */
/* _ (INT16 ) P2 : the higher end of the search range.*/
/* _ (INT16 ) LowL : lower pitch value. */
/* _ (INT16 ) L_R: length of correlation. */
/*-------------------------------------------------------------------*/
/* OUTPUT ARGUMENTS : */
/* _ (INT16 ) index : memory update flag. */
/*-------------------------------------------------------------------*/
/* INPUT/OUTPUT ARGUMENTS : */
/* _ (FLOAT64 []) R: correlation. */
/*-------------------------------------------------------------------*/
/* RETURN ARGUMENTS : */
/* _ None. */
/*===================================================================*/
void LTP_FineIndex_search (FLOAT64 PitTab[], INT16 P1,INT16 P2,INT16 LowL,
INT16 L_R,FLOAT64 R[],INT16 *index)
{
/*-------------------------------------------------------------------*/
FLOAT64 t, GG, MaxR=0, *Weight;
INT16 T, i, m;
/*-------------------------------------------------------------------*/
/* Search for the best precise pitch and index */
/*-------------------------------------------------------------------*/
#ifdef WMOPS
WMP_cnt_shift ((P2-P1+1)+1);
WMP_cnt_add (2*(P2-P1+1));
WMP_cnt_sub (2*(P2-P1+1));
WMP_cnt_mult (2*(P2-P1+1));
WMP_cnt_test ((P2-P1+1));
WMP_cnt_logic ((P2-P1+1));
WMP_cnt_move (4*(P2-P1+1)+2);
WMP_cnt_test ((P2-P1+1));
#endif
for (i = P1; i <= P2; i++)
{
t = PitTab[i] - LowL;
LTP_Allocate_Sinc_Tab (t, &m);
if (m <= NUM_SINC_WIN/2)
{
Weight = SincWindows + m*LEN_SINC;
GG = D2A_interp_1sthalf (Weight, R, t, SINC_LIMIT);
}
else
{
Weight = SincWindows + (NUM_SINC_WIN-m-1)*LEN_SINC;
GG = D2A_interp_2ndhalf (Weight, R, t, SINC_LIMIT);
}
if (i == P1 || GG > MaxR)
{
MaxR = GG;
(*index) = i;
}
}
T = (INT16)(PitTab[*index] + 0.5 - LowL);
R[T] = MaxR;
/*-------------------------------------------------------------------*/
return;
/*-------------------------------------------------------------------*/
}
/*----------------------------------------------------------------------------*/
/*===================================================================*/
/* FUNCTION : LTP_PP_pitch_ext (). */
/*-------------------------------------------------------------------*/
/* PURPOSE : This function extracts the adaptive codebook */
/* excitation for pitch pre-processing (Mode 1) at the */
/* encoder. */
/*-------------------------------------------------------------------*/
/* ALGORITHM : */
/*-------------------------------------------------------------------*/
/* INPUT ARGUMENTS : */
/* _ (FLOAT64 []) PitFun: Pitch track. */
/* _ (FLOAT64 []) Tgs: target signal. */
/* _ (FLOAT64 []) ext: excitation signal. */
/* _ (FLOAT64 []) hh: impulse response. */
/* _ (INT16 ) i_sf : sub-frame number. */
/* _ (INT16 ) l_sf : sub-frame size. */
/*-------------------------------------------------------------------*/
/* OUTPUT ARGUMENTS : */
/* _ (INT16 *) lag : lag value. */
/* _ (FLOAT64 *) lag_f: fractional lag value. */
/* _ (FLOAT64 *) R_ltp: pitch correlation. */
/* _ (FLOAT64 []) unfcod: unfiltered excitation. */
/* _ (FLOAT64 []) fcod: filtered excitation. */
/*-------------------------------------------------------------------*/
/* INPUT/OUTPUT ARGUMENTS : */
/* _ None. */
/*-------------------------------------------------------------------*/
/* RETURN ARGUMENTS : */
/* _ None. */
/*===================================================================*/
void LTP_PP_pitch_ext (FLOAT64 PitFun[],FLOAT64 Tgs [], FLOAT64 ext [],
FLOAT64 hh [], INT16 i_sf,FLOAT64 *unfcod,
FLOAT64 *fcod, INT16 *lag, FLOAT64 *lag_f,
FLOAT64 *R_ltp, INT16 l_sf)
{
/*-------------------------------------------------------------------*/
FLOAT64 pgain;
/*-------------------------------------------------------------------*/
/* LTP excitation : unfcod[] */
/*-------------------------------------------------------------------*/
#ifdef WMOPS
WMP_cnt_test(2);
WMP_cnt_mult(2);
WMP_cnt_sqrt(1);
WMP_cnt_move(1);
#endif
LTP_PP_pitch_ext_decod (PitFun, ext, i_sf, unfcod, lag, lag_f,l_sf);
/*-------------------------------------------------------------------*/
/* Compute fcod[], pgain, and R_ltp */
/*-------------------------------------------------------------------*/
LTP_fcod_pgain_Rp (unfcod, fcod, hh, l_sf, Tgs, &pgain, R_ltp);
/*-------------------------------------------------------------------*/
return;
/*-------------------------------------------------------------------*/
}
/*----------------------------------------------------------------------------*/
/*===================================================================*/
/* FUNCTION : LTP_PP_pitch_ext_decod (). */
/*-------------------------------------------------------------------*/
/* PURPOSE : This function extracts the adaptive codebook */
/* excitation for pitch pre-processing (Mode 1) at the */
/* decoder. */
/*-------------------------------------------------------------------*/
/* ALGORITHM : */
/*-------------------------------------------------------------------*/
/* INPUT ARGUMENTS : */
/* _ (FLOAT64 []) PitFun: Pitch track. */
/* _ (FLOAT64 []) ext: excitation signal. */
/* _ (INT16 ) i_sf : sub-frame number. */
/* _ (INT16 ) l_sf : sub-frame size. */
/*-------------------------------------------------------------------*/
/* OUTPUT ARGUMENTS : */
/* _ (INT16 *) lag : lag value. */
/* _ (FLOAT64 *) lag_f: fractional lag value. */
/* _ (FLOAT64 []) unfcod: unfiltered excitation. */
/*-------------------------------------------------------------------*/
/* INPUT/OUTPUT ARGUMENTS : */
/* _ None. */
/*-------------------------------------------------------------------*/
/* RETURN ARGUMENTS : */
/* _ None. */
/*===================================================================*/
void LTP_PP_pitch_ext_decod (FLOAT64 PitFun[],FLOAT64 ext[], INT16 i_sf,
FLOAT64 *unfcod, INT16 *lag, FLOAT64 *lag_f,
INT16 l_sf)
{
/*-------------------------------------------------------------------*/
FLOAT64 tmp[L_SF];
/*-------------------------------------------------------------------*/
/* LTP excitation : unfcod[] */
/*-------------------------------------------------------------------*/
#ifdef WMOPS
WMP_cnt_add(1);
WMP_cnt_shift(1);
WMP_cnt_move(2);
WMP_cnt_shift(2);
#endif
cpy_dvector (ext+MAX_LAG, tmp, 0, L_SF-1);
LTP_excit_vari_pitch(PitFun, MAX_LAG, ext, l_sf, unfcod);
cpy_dvector(tmp, ext+MAX_LAG, 0, L_SF-1);
/*-------------------------------------------------------------------*/
/* pitch */
/*-------------------------------------------------------------------*/
lag[i_sf] = (INT16)(PitFun[l_sf/2]+0.5);
lag_f[i_sf] = PitFun[l_sf/2];
/*-------------------------------------------------------------------*/
return;
/*-------------------------------------------------------------------*/
}
/*----------------------------------------------------------------------------*/
#ifdef ENC_CMP
/*============================================================================*/
/*===================================================================*/
/* FUNCTION : LTP_Calc_Rp (). */
/*-------------------------------------------------------------------*/
/* PURPOSE : This function calculate the pitch correlation. */
/*-------------------------------------------------------------------*/
/* INPUT ARGUMENTS : */
/* _ (INT16 ) IP1 : lower search position. */
/* _ (INT16 ) IP2 : higher search position. */
/* _ (FLOAT64 []) ext: excitation signal. */
/* _ (FLOAT64 []) Tgs: target signal. */
/* _ (INT16 ) l_sf : sub-frame size. */
/* _ (FLOAT64 []) hh: impulse response. */
/*-------------------------------------------------------------------*/
/* OUTPUT ARGUMENTS : */
/* _ (FLOAT64 []) Rp: pitch correlation. */
/*-------------------------------------------------------------------*/
/* INPUT/OUTPUT ARGUMENTS : */
/* _ None. */
/*-------------------------------------------------------------------*/
/* RETURN ARGUMENTS : */
/* _ None. */
/*===================================================================*/
void LTP_Calc_Rp(INT16 IP1, INT16 IP2, FLOAT64 ext[], FLOAT64 Tgs[],
FLOAT64 hh[], INT16 l_sf, FLOAT64 Rp[])
{
/*-------------------------------------------------------------------*/
INT16 i, k;
FLOAT64 ftmp[L_SF], denominator;
/*-------------------------------------------------------------------*/
#ifdef WMOPS
WMP_cnt_test((IP2-IP1+1)*2);
WMP_cnt_div ((IP2-IP1+1));
WMP_cnt_sqrt ((IP2-IP1+1));
#endif
for (i = IP1; i <= IP2; i++)
{
if (i == IP1)
FLT_convolve(ext+MAX_LAG-i , hh, ftmp, l_sf);
else
{
#ifdef WMOPS
WMP_cnt_mac (l_sf);
WMP_cnt_move (l_sf);
WMP_cnt_mult (1);
#endif
for (k = l_sf-1; k > 0; k--)
ftmp[k] = ftmp[k-1] + ext[MAX_LAG-i]*hh[k];
ftmp[0] = ext[MAX_LAG-i]*hh[0];
}
dot_dvector (Tgs, ftmp, &Rp[i-IP1], 0, l_sf-1);
dot_dvector(ftmp, ftmp, &denominator, 0, l_sf-1);
Rp[i-IP1] /= sqrt(MAX(denominator, 0.1));
}
/*-------------------------------------------------------------------*/
return;
/*-------------------------------------------------------------------*/
}
/*----------------------------------------------------------------------------*/
/*===================================================================*/
/* FUNCTION : LTP_Integer_Pit_Search (). */
/*-------------------------------------------------------------------*/
/* PURPOSE : This function find the optimum integer pitch. */
/*-------------------------------------------------------------------*/
/* INPUT ARGUMENTS : */
/* _ (FLOAT64 []) Rp: pitch correlation. */
/* _ (INT16 ) IP1 : lower search position. */
/* _ (INT16 ) IP2 : higher search position. */
/* _ (INT16 ) LowL : starting position. */
/*-------------------------------------------------------------------*/
/* OUTPUT ARGUMENTS : */
/* _ (INT16 *) PITCHi : optimal pitch index. */
/* _ (FLOAT64 *) MaxR : maximum correlation. */
/*-------------------------------------------------------------------*/
/* INPUT/OUTPUT ARGUMENTS : */
/* _ None. */
/*-------------------------------------------------------------------*/
/* RETURN ARGUMENTS : */
/* _ None. */
/*===================================================================*/
void LTP_Integer_Pit_Search (FLOAT64 Rp[], INT16 IP1, INT16 IP2, INT16 LowL,
INT16 *PITCHi, FLOAT64 *MaxR)
{
INT16 i;
/*----------------------------------------------------------------------*/
#ifdef WMOPS
WMP_cnt_test(IP2-IP1);
WMP_cnt_move(2);
#endif
*MaxR = Rp[IP1-LowL];
*PITCHi = IP1;
for (i = IP1+1; i <= IP2; i++)
{
if (Rp[i-LowL] > *MaxR)
{
#ifdef WMOPS
WMP_cnt_move(2);
#endif
*MaxR = Rp[i-LowL];
*PITCHi = i;
}
}
}
/*----------------------------------------------------------------------------*/
/*===================================================================*/
/* FUNCTION : LTP_low_idx (). */
/*-------------------------------------------------------------------*/
/* PURPOSE : This function searches for the smallest pitch codebook*/
/* index within the range [idx0 idx1] such that the */
/* corresponding codebook entry is >= the given limit */
/*-------------------------------------------------------------------*/
/* ALGORITHM : */
/*-------------------------------------------------------------------*/
/* INPUT ARGUMENTS : */
/* _ (INT16 ) idx0 : lower bound of the search range. */
/* _ (INT16 ) idx1 : upper bound of the search range. */
/* _ (FLOAT64 []) tab: pitch codebook. */
/* _ (INT16 ) limit : a pitch value. */
/*-------------------------------------------------------------------*/
/* OUTPUT ARGUMENTS : */
/* _ (Word16 *) low_i : the resulting idx. */
/*-------------------------------------------------------------------*/
/* INPUT/OUTPUT ARGUMENTS : */
/* _ None. */
/*-------------------------------------------------------------------*/
/* RETURN ARGUMENTS : */
/* _ None. */
/*===================================================================*/
void LTP_low_idx (INT16 idx0, INT16 idx1, FLOAT64 tab[], FLOAT64 limit,
INT16 *low_i)
{
/*-----------------------------------------------------------------*/
INT16 i;
/*-----------------------------------------------------------------*/
#ifdef WMOPS
WMP_cnt_test(idx1-idx0+1);
#endif
for (i = idx0; i <= idx1; i++)
{
if (tab[i] >= limit)
{
#ifdef WMOPS
WMP_cnt_move(1);
#endif
*low_i = i;
break;
}
}
/*-----------------------------------------------------------------*/
return;
/*-----------------------------------------------------------------*/
}
/*---------------------------------------------------------------------------*/
/*===================================================================*/
/* FUNCTION : LTP_high_idx (). */
/*-------------------------------------------------------------------*/
/* PURPOSE : This function searches for the largest pitch codebook */
/* index within the range [idx0 idx1] such that the */
/* corresponding codebook entry is <= the given limit */
/*-------------------------------------------------------------------*/
/* ALGORITHM : */
/*-------------------------------------------------------------------*/
/* INPUT ARGUMENTS : */
/* _ (INT16 ) idx0 : lower bound of the search range. */
/* _ (INT16 ) idx1 : upper bound of the search range. */
/* _ (FLOAT64 []) tab: pitch codebook. */
/* _ (INT16 ) limit: a pitch value. */
/*-------------------------------------------------------------------*/
/* OUTPUT ARGUMENTS : */
/* _ (Word16 *) high_i: the resulting idx. */
/*-------------------------------------------------------------------*/
/* INPUT/OUTPUT ARGUMENTS : */
/* _ None. */
/*-------------------------------------------------------------------*/
/* RETURN ARGUMENTS : */
/* _ None. */
/*===================================================================*/
void LTP_high_idx (INT16 idx0, INT16 idx1, FLOAT64 tab[], FLOAT64 limit,
INT16 *high_i)
{
/*-------------------------------------------------------------------*/
INT16 i;
/*-------------------------------------------------------------------*/
#ifdef WMOPS
WMP_cnt_test(idx1-idx0+1);
#endif
for (i = idx1; i >= idx0; i--)
{
if (tab[i] <= limit)
{
#ifdef WMOPS
WMP_cnt_move(1);
#endif
*high_i = i;
break;
}
}
/*-------------------------------------------------------------------*/
return;
/*-------------------------------------------------------------------*/
}
#endif
/*-------------------------------------------------------------------------*/
/*===================================================================*/
/* FUNCTION : LTP_fcod_pgain_Rp (). */
/*-------------------------------------------------------------------*/
/* PURPOSE : This function calculte the fitered excitation and the */
/* corresponding pitch gain and correlation. */
/*-------------------------------------------------------------------*/
/* INPUT ARGUMENTS : */
/* _ (FLOAT64 []) unfcod: unfiltered excitation. */
/* _ (FLOAT64 []) Tgs: target signal. */
/* _ (FLOAT64 []) hh: impulse response. */
/* _ (INT16 ) l_sf : sub-frame size. */
/*-------------------------------------------------------------------*/
/* OUTPUT ARGUMENTS : */
/* _ (FLOAT64 *) pgain: pitch gain. */
/* _ (FLOAT64 *) R_ltp: pitch correlation. */
/* _ (FLOAT64 []) fcod: filtered excitation. */
/*-------------------------------------------------------------------*/
/* INPUT/OUTPUT ARGUMENTS : */
/* _ None. */
/*-------------------------------------------------------------------*/
/* RETURN ARGUMENTS : */
/* _ None. */
/*===================================================================*/
void LTP_fcod_pgain_Rp (FLOAT64 unfcod[], FLOAT64 fcod[], FLOAT64 hh[],
INT16 l_sf, FLOAT64 Tgs[], FLOAT64 *pgain,
FLOAT64 *R_ltp)
{
/*-------------------------------------------------------------------*/
FLOAT64 numerator, denominator, eng_Tgs;
/*-------------------------------------------------------------------*/
/* Filter the pitch vector (LTP excitation) */
/*-------------------------------------------------------------------*/
FLT_convolve(unfcod , hh, fcod, l_sf);
/*-------------------------------------------------------------------*/
/* Compute the pitch gain (LTP gain) */
/*-------------------------------------------------------------------*/
dot_dvector (Tgs, fcod, &numerator, 0, l_sf-1);
dot_dvector (fcod, fcod, &denominator, 0, l_sf-1);
dot_dvector (Tgs, Tgs, &eng_Tgs, 0, l_sf-1);
#ifdef WMOPS
WMP_cnt_test(4);
WMP_cnt_div(2);
WMP_cnt_sqrt(1);
WMP_cnt_move(2);
#endif
(*pgain) = numerator / MAX(denominator, 0.1);
(*R_ltp) = MAX(numerator, 0.0) / sqrt(MAX(denominator*eng_Tgs, 0.1));
/*-------------------------------------------------------------------*/
/* Limit the pitch gain -> 0 <= pgain <= 1.2 */
/*-------------------------------------------------------------------*/
if ((*pgain) < 0.0) (*pgain) = 0.0;
if ((*pgain) > 1.2) (*pgain) = 1.2;
/*-------------------------------------------------------------------*/
return;
/*-------------------------------------------------------------------*/
}
/*----------------------------------------------------------------------------*/
#ifdef ENC_CMP
/*===================================================================*/
/* FUNCTION : LTP_close_7b_pitch (). */
/*-------------------------------------------------------------------*/
/* PURPOSE : This function performs the traditional search of the */
/* the adaptive codebook in Mode 0. */
/*-------------------------------------------------------------------*/
/* ALGORITHM : */
/*-------------------------------------------------------------------*/
/* INPUT ARGUMENTS : */
/* _ (FLOAT64 []) Tgs: target signal. */
/* _ (FLOAT64 []) ext: excitation signal. */
/* _ (FLOAT64 []) hh: impulse response. */
/* _ (INT16 ) i_sf : sub-frame number. */
/* _ (INT16 ) l_sf : sub-frame size. */
/* _ (INT16 ) frm_class_pp : pitch pre-proc. classification. */
/*-------------------------------------------------------------------*/
/* OUTPUT ARGUMENTS : */
/* _ (INT16 *) lag : lag value. */
/* _ (FLOAT64 *) lag_f: fractional lag value. */
/* _ (FLOAT64 *) pgain: pitch gain. */
/* _ (FLOAT64 *) R_ltp: LTP criterion. */
/* _ (FLOAT64 []) unfcod: unfiltered excitation. */
/* _ (FLOAT64 []) fcod: filtered excitation. */
/* _ (INT16 *) pit_idx : pitch index. */
/*-------------------------------------------------------------------*/
/* INPUT/OUTPUT ARGUMENTS : */
/* _ None. */
/*-------------------------------------------------------------------*/
/* RETURN ARGUMENTS : */
/* _ None. */
/*===================================================================*/
void LTP_close_7b_pitch (FLOAT64 Tgs [], FLOAT64 ext [], FLOAT64 hh [],
INT16 i_sf, FLOAT64 unfcod [],
FLOAT64 fcod [], INT16 *lag,FLOAT64 *lag_f,
FLOAT64 *pgain, FLOAT64 *R_ltp, INT16 l_sf,
INT16 frm_class_pp, INT16 pit_idx [])
{
/*-------------------------------------------------------------------*/
FLOAT64 MaxR;
INT16 IP1, IP2, L_Rp, PITCHi;
FLOAT64 Rp[20] = {0.0};
/*-------------------------------------------------------------------*/
/* Searching range */
/*-------------------------------------------------------------------*/
#ifdef WMOPS
WMP_cnt_test(6);
WMP_cnt_logic(2);
WMP_cnt_add(3);
WMP_cnt_sub(3);
WMP_cnt_mult(1);
WMP_cnt_move(3);
#endif
if (lag[i_sf] < MIN_LAG2) lag[i_sf] *=2;
IP1 = MAX(MIN_LAG2, lag[i_sf] - 3);
IP2 = MIN(HI_LAG2, lag[i_sf] + 3);
if ((frm_class_pp > 0) && (i_sf == N_SF2-1) && (lag[i_sf] > l_sf*0.75))
{
IP1 = MAX(MIN_LAG2, lag[i_sf]-1);
IP2 = MIN(HI_LAG2, lag[i_sf]+1);
}
/*-------------------------------------------------------------------*/
/* Integer correlation for integer lag */
/*-------------------------------------------------------------------*/
L_Rp = IP2 - IP1 + 1;
#ifdef VERBOSE
if (L_Rp >= 20)
nrerror("L_Rp>=20 !!");
#endif
/*-------------------------------------------------------------------*/
LTP_Calc_Rp (IP1, IP2, ext, Tgs, hh, l_sf, Rp);
/*-------------------------------------------------------------------*/
/* Searching for integer pitch */
/*-------------------------------------------------------------------*/
LTP_Integer_Pit_Search (Rp, IP1, IP2, IP1, &PITCHi, &MaxR);
#ifdef WMOPS
WMP_cnt_test(4);
WMP_cnt_move(1);
WMP_cnt_logic(2);
#endif
if ((MaxR < 0) && (i_sf==N_SF2-1) && (frm_class_pp > 0))
PITCHi = lag[i_sf];
/*-------------------------------------------------------------------*/
/* LTP excitation : unfcod[] */
/*-------------------------------------------------------------------*/
pit_idx[i_sf] = PITCHi - MIN_LAG2;
LTP_7b_pitch_decod (0.0, 0, ext, i_sf, unfcod, lag, lag_f, l_sf, pit_idx);
/*-------------------------------------------------------------------*/
/* Compute fcod[], pgain, and R_ltp */
/*-------------------------------------------------------------------*/
LTP_fcod_pgain_Rp (unfcod, fcod, hh, l_sf, Tgs, pgain, R_ltp);
/*-------------------------------------------------------------------*/
return;
/*-------------------------------------------------------------------*/
}
#endif
/*----------------------------------------------------------------------------*/
/*===================================================================*/
/* FUNCTION : LTP_7b_pitch_decod (). */
/*-------------------------------------------------------------------*/
/* PURPOSE : This function decodes the traditional adaptive */
/* codebook contribution. */
/*-------------------------------------------------------------------*/
/* ALGORITHM : */
/*-------------------------------------------------------------------*/
/* INPUT ARGUMENTS : */
/* _ (INT16 ) bfi : bad frame indicator. */
/* _ (FLOAT64 []) ext: excitation signal. */
/* _ (INT16 ) i_sf : sub-frame number. */
/* _ (INT16 ) l_sf : sub-frame size. */
/* _ (INT16 *) pit_idx : pitch index. */
/*-------------------------------------------------------------------*/
/* OUTPUT ARGUMENTS : */
/* _ (INT16 *) lag : lag value. */
/* _ (FLOAT64 *) lag_f: fractional lag value. */
/* _ (FLOAT64 []) unfcod: unfiltered excitation. */
/*-------------------------------------------------------------------*/
/* INPUT/OUTPUT ARGUMENTS : */
/* _ None. */
/*-------------------------------------------------------------------*/
/* RETURN ARGUMENTS : */
/* _ None. */
/*===================================================================*/
void LTP_7b_pitch_decod (FLOAT64 refl, INT16 bfi, FLOAT64 ext [], INT16 i_sf,
FLOAT64 unfcod [], INT16 lag [], FLOAT64 lag_f [],
INT16 l_sf, INT16 pit_idx [])
{
/*-------------------------------------------------------------------*/
FLOAT64 pit_f;
INT16 i, PITCHi;
/*-------------------------------------------------------------------*/
/* Decode lag */
/*-------------------------------------------------------------------*/
if (bfi == 0)
{
#ifdef WMOPS
WMP_cnt_test(1);
WMP_cnt_add(2);
WMP_cnt_move(3);
#endif
lag[i_sf] = pit_idx[i_sf] + MIN_LAG2;
lag_f[i_sf] = lag[i_sf];
}
else
{
#ifdef WMOPS
WMP_cnt_test(3);
WMP_cnt_add(1);
WMP_cnt_move(3);
#endif
if( refl < 0.0)
lag[i_sf] = lag[1];
else
{
if (i_sf == 0)
lag[i_sf] = MIN(lag[1]+1, HI_LAG2);
else
lag[i_sf] = MIN(lag[i_sf-1]+1, HI_LAG2);
}
lag_f[i_sf] = (FLOAT64) lag[i_sf];
pit_f = (FLOAT64) lag[i_sf];
}
/*-------------------------------------------------------------------*/
/* LTP excitation : unfcod[] */
/*-------------------------------------------------------------------*/
PITCHi = lag[i_sf];
cpy_dvector (ext+MAX_LAG-PITCHi, unfcod, 0, l_sf-1);
for (i=PITCHi; i 0) && (i_sf == N_SF4-1))
{
IP1 = MAX(MIN_LAG, lag[i_sf]-1);
IP2 = MIN(HI_LAG2, lag[i_sf]+1);
if (DifPitTab[0] >= IP2)
PP2 = 0;
if (DifPitTab[31] <= IP1)
PP1 = 31;
LTP_low_idx (0, 31, DifPitTab, (FLOAT64)IP1, &PP1);
LTP_high_idx (0, 31, DifPitTab, (FLOAT64)IP2, &PP2);
}
IP1 = (INT16) (DifPitTab[PP1] + 0.5);
IP2 = (INT16) (DifPitTab[PP2] + 0.5);
}
/*-------------------------------------------------------------------*/
/* Integer correlation for integer lag */
/*-------------------------------------------------------------------*/
LowL = IP1 - SINC_LIMIT - 1;
HighL = IP2 + SINC_LIMIT + 1;
L_Rp = HighL - LowL + 1;
#ifdef VERBOSE
if (L_Rp >= 2*SINC_LIMIT + 40)
nrerror("L_Rp>=2*SINC_LIMIT+24 !! \n");
#endif
/*-------------------------------------------------------------------*/
LTP_Calc_Rp (LowL, HighL, ext, Tgs, hh, l_sf, Rp);
/*-------------------------------------------------------------------*/
/* Searching for integer pitch */
/*-------------------------------------------------------------------*/
LTP_Integer_Pit_Search (Rp, IP1, IP2, LowL, &PITCHi, &MaxR);
#ifdef WMOPS
WMP_cnt_test(4);
WMP_cnt_move(1);
WMP_cnt_logic(2);
#endif
if ((MaxR < 0) && (frm_class_pp > 0) && (i_sf == N_SF4-1))
PITCHi = lag[i_sf];
/*-------------------------------------------------------------------*/
/* Fine index searching */
/*-------------------------------------------------------------------*/
#ifdef WMOPS
WMP_cnt_test(2);
#endif
if ((i_sf == 0) || (i_sf == N_SF4/2))
{
PP1 = LTP_lag_to_idx8b(MAX(PITCHi - 0.9, MIN_LAG));
PP2 = LTP_lag_to_idx8b(MIN(PITCHi + 0.9, HI_LAG2));
#ifdef WMOPS
WMP_cnt_add(1);
WMP_cnt_move(5);
#endif
LTP_FineIndex_search (PitLagTab8b, PP1, PP2, LowL, L_Rp, Rp,
pit_idx+i_sf);
pit_f = PitLagTab8b[pit_idx[i_sf]];
lag[i_sf] = (INT16)(pit_f + 0.5);
lag_f[i_sf] = pit_f;
}
else
{
if (DifPitTab[PP1] >= (PITCHi+0.9))
PP2 = PP1;
if (DifPitTab[PP2] <= (PITCHi-0.9))
PP1 = PP2;
LTP_low_idx (PP1, PP2, DifPitTab, (FLOAT64)(PITCHi-0.9), &PP1);
LTP_high_idx (PP1, PP2, DifPitTab, (FLOAT64)(PITCHi+0.9), &PP2);
#ifdef WMOPS
WMP_cnt_test(1);
WMP_cnt_add(1);
WMP_cnt_move(4);
#endif
LTP_FineIndex_search (DifPitTab, PP1, PP2, LowL, L_Rp, Rp,
pit_idx+i_sf);
pit_f = DifPitTab[pit_idx[i_sf]];
lag[i_sf] = (INT16)(pit_f + 0.5);
lag_f[i_sf] = pit_f;
}
/*-------------------------------------------------------------------*/
/* LTP excitation : unfcod[] */
/*-------------------------------------------------------------------*/
cpy_dvector (ext+MAX_LAG, ftmp, 0, l_sf-1);
LTP_excit_const_pitch (pit_f, MAX_LAG, ext, l_sf, unfcod, 1);
cpy_dvector (ftmp, ext+MAX_LAG, 0, l_sf-1);
/*-------------------------------------------------------------------*/
/* Compute fcod[], pgain, and R_ltp */
/*-------------------------------------------------------------------*/
LTP_fcod_pgain_Rp (unfcod, fcod, hh, l_sf, Tgs, pgain, R_ltp);
/*-------------------------------------------------------------------*/
return;
/*-------------------------------------------------------------------*/
}
#endif
/*----------------------------------------------------------------------------*/
#ifdef DEC_CMP
/*===================================================================*/
/* FUNCTION : LTP_pitch_decodtemp (). */
/*-------------------------------------------------------------------*/
/* PURPOSE : This function perfroms a temporary decoding of the */
/* LTP information codebook contribution. */
/*-------------------------------------------------------------------*/
/* ALGORITHM : */
/*-------------------------------------------------------------------*/
/* INPUT ARGUMENTS : */
/* _ (FLOAT64 []) ext: excitation signal. */
/* _ (INT16 ) i_sf : sub-frame number. */
/* _ (INT16 ) l_sf : sub-frame size. */
/* _ (FLOAT64 ) pit_f: fractional lag value. */
/*-------------------------------------------------------------------*/
/* OUTPUT ARGUMENTS : */
/* _ (FLOAT64 []) unfcod: unfiltered LTP excitation. */
/*-------------------------------------------------------------------*/
/* INPUT/OUTPUT ARGUMENTS : */
/* _ None. */
/*-------------------------------------------------------------------*/
/* RETURN ARGUMENTS : */
/* _ None. */
/*===================================================================*/
void LTP_pitch_decodtemp (FLOAT64 ext [], INT16 i_sf, FLOAT64 unfcod [],
FLOAT64 pit_f, INT16 l_sf)
{
/*-------------------------------------------------------------------*/
FLOAT64 LTm[MAX_LAG+L_SF];
/*-------------------------------------------------------------------*/
cpy_dvector (ext, LTm, 0, MAX_LAG-1);
LTP_excit_const_pitch (pit_f, MAX_LAG, LTm, l_sf, unfcod, 1);
/*-------------------------------------------------------------------*/
return;
/*-------------------------------------------------------------------*/
}
/*----------------------------------------------------------------------------*/
/*===================================================================*/
/* FUNCTION : LTP_8_5k_pitch_decod (). */
/*-------------------------------------------------------------------*/
/* PURPOSE : This function decodes the traditional adaptive */
/* codebook contribution in Mode 0. */
/*-------------------------------------------------------------------*/
/* ALGORITHM : */
/*-------------------------------------------------------------------*/
/* INPUT ARGUMENTS : */
/* _ (INT16 ) bfi : bad frame indicator. */
/* _ (FLOAT64 []) ext: excitation signal. */
/* _ (INT16 ) i_sf : sub-frame number. */
/* _ (INT16 ) l_sf : sub-frame size. */
/* _ (INT16 *) pit_idx : pitch index. */
/*-------------------------------------------------------------------*/
/* OUTPUT ARGUMENTS : */
/* _ (INT16 *) lag : lag value. */
/* _ (FLOAT64 *) lag_f: fractional lag value. */
/* _ (FLOAT64 []) unfcod: unfiltered excitation. */
/*-------------------------------------------------------------------*/
/* INPUT/OUTPUT ARGUMENTS : */
/* _ None. */
/*-------------------------------------------------------------------*/
/* RETURN ARGUMENTS : */
/* _ None. */
/*===================================================================*/
void LTP_8_5k_pitch_decod (FLOAT64 refl, INT16 bfi, FLOAT64 ext [], INT16 i_sf,
FLOAT64 unfcod [], INT16 lag [], FLOAT64 lag_f [],
INT16 l_sf, INT16 pit_idx [])
{
/*-------------------------------------------------------------------*/
FLOAT64 LTm[MAX_LAG+L_SF], pit_f, DifPitTab[33];
INT16 i;
/*-------------------------------------------------------------------*/
/* Decode lag */
/*-------------------------------------------------------------------*/
if (bfi == 0)
{
#ifdef WMOPS
WMP_cnt_test(3);
WMP_cnt_logic(1);
WMP_cnt_add(1+16);
WMP_cnt_sub(1+16);
WMP_cnt_move(3);
#endif
if ((i_sf == 1) || (i_sf == N_SF4-1))
{
for (i = 0; i < 16; i++)
DifPitTab [16+i] = MIN (HI_LAG2,
lag_f[i_sf-1]+PitLagTab5b[i]);
for (i = 1; i <= 16; i++)
DifPitTab [16-i] = MAX(MIN_LAG,
lag_f[i_sf-1]-PitLagTab5b[i]);
pit_f = DifPitTab[pit_idx[i_sf]];
}
else
pit_f = PitLagTab8b[pit_idx[i_sf]];
lag[i_sf] = (INT16)(pit_f+0.5);
lag_f[i_sf] = pit_f;
}
else
{
#ifdef WMOPS
WMP_cnt_test(3);
WMP_cnt_add(1);
WMP_cnt_move(3);
#endif
if( refl < 0.0)
lag[i_sf] = lag[3];
else
{
if (i_sf == 0)
lag[i_sf] = MIN(lag[3]+1, HI_LAG2);
else
lag[i_sf] = MIN(lag[i_sf-1]+1, HI_LAG2);
}
lag_f[i_sf] = (FLOAT64) lag[i_sf];
pit_f = (FLOAT64) lag[i_sf];
}
/*-------------------------------------------------------------------*/
/* LTP excitation : unfcod[] */
/*-------------------------------------------------------------------*/
cpy_dvector (ext, LTm, 0, MAX_LAG-1);
LTP_excit_const_pitch (pit_f, MAX_LAG, LTm, l_sf, unfcod, 1);
/*-------------------------------------------------------------------*/
return;
/*-------------------------------------------------------------------*/
}
/*----------------------------------------------------------------------------*/
/*===================================================================*/
/* FUNCTION : LTP_adap_cbk_correction (). */
/*-------------------------------------------------------------------*/
/* PURPOSE : This function extrapolated the adaptive codebook */
/* excitation when a frame erasure occurs. */
/*-------------------------------------------------------------------*/
/* ALGORITHM : */
/*-------------------------------------------------------------------*/
/* INPUT ARGUMENTS : */
/* _ (INT16 ) fix_rate_m: previous frame bit-rate. */
/* _ (INT16 ) bfi: frame # n Bad Frame Indicator. */
/* _ (INT16 ) past_bfi: frame # n-1 Bad Frame Indicator. */
/* _ (INT16 ) ppast_bfi: frame # n-2 Bad Frame Indicator. */
/* _ (FLOAT64 **) qua_gainQ: adaptive and fixed codebook gains. */
/* _ (INT16 ) SVS_deci_m: frame # n-1 mode indicator. */
/* _ (FLOAT64 []) lag_f: decoded pitch lags */
/* _ (FLOAT64 ) temp_lagf: extrapolated fractional pitch lags */
/*-------------------------------------------------------------------*/
/* OUTPUT ARGUMENTS : */
/* _ (INT16 *) update : update flag. */
/* _ (INT16 []) lag : extrapolated lag values. */
/* _ (FLOAT64 **) gainQ: adaptive and fixed codebook gains. */
/* _ (FLOAT64 []) lag_f: extrapolated fract. lag values. */
/* _ (FLOAT64 *) ForPitch_decTEMP: interpolated pitch track. */
/* _ (FLOAT64 []) ext_dec : updated LTP memory. */
/* _ (FLOAT64 **) unfcod_dec : extrapolated LTP excitation. */
/* _ (FLOAT64 []) pitchf : pitch value. */
/*-------------------------------------------------------------------*/
/* INPUT/OUTPUT ARGUMENTS : */
/* _ (FLOAT64 []) pitch_f_mem : past pitch values. */
/* _ (FLOAT64 []) tempext_dec : temporary LTP memory. */
/*-------------------------------------------------------------------*/
/* RETURN ARGUMENTS : */
/* _ None. */
/*===================================================================*/
void LTP_adap_cbk_correction (INT16 fix_rate_m, INT16 bfi, INT16 past_bfi,
INT16 ppast_bfi, FLOAT64 **qua_gainQ,
FLOAT64 gainQ [], INT16 SVS_deci_m,
FLOAT64 temp_lagf, INT16 *update, FLOAT64 pitchf,
FLOAT64 pitch_f_mem [], INT16 lag [],
FLOAT64 lag_f [], FLOAT64 ForPitch_decTEMP [],
FLOAT64 tempext_dec [], FLOAT64 ext_dec [],
FLOAT64 **unfcod_dec, FLOAT64 **qua_unfcod,
PARAMETER channel)
{
/*-------------------------------------------------------------------*/
INT16 n_sf, i_s, i_sf, l_sf;
INT16 curr_lsf;
FLOAT64 *px, temp_lag;
FLOAT64 FET, PFET, AA;
FLOAT64 BB;
/*-------------------------------------------------------------------*/
if ((bfi == 0) && (past_bfi == 1) && (ppast_bfi == 0) &&
((channel.fix_rate == RATE4_0K) || (channel.fix_rate == RATE8_5K))
&& ((fix_rate_m == RATE4_0K) || (fix_rate_m == RATE8_5K)) &&
(qua_gainQ[0][0] > 0.5))
{
#ifdef WMOPS
WMP_cnt_test(5+8*4);
WMP_cnt_logic(5+2*4);
WMP_cnt_add(2+4*4);
WMP_cnt_mult(2+4*4);
WMP_cnt_move(9+5*4);
WMP_cnt_sqrt(4);
#endif
if (fix_rate_m == RATE8_5K)
n_sf = N_SF4;
else
{
if (SVS_deci_m == 1)
n_sf = N_SF3;
else
n_sf = N_SF2;
}
if (channel.fix_rate ==RATE8_5K)
curr_lsf = L_SF4;
else
curr_lsf = L_SF0;
if ((SVS_deci_m == 1) && (channel.idx_SVS_deci == 0))
{
/*-------------------------------------------------------*/
/* PP then LTP */
/*-------------------------------------------------------*/
temp_lag = (temp_lagf- pitch_f_mem [0])*159.0 /
((double) L_FRM+curr_lsf-1.0)+pitch_f_mem [0];
PIT_PitchInterpolat (temp_lag, pitch_f_mem,
ForPitch_decTEMP, 0);
}
/*------------------------------------------------------------*/
/* Sub-frame loop */
/*------------------------------------------------------------*/
i_s = 0;
for (i_sf = 0; i_sf < n_sf; i_sf++)
{
/*=======================================================*/
/*-------------------------------------------------------*/
/* Set subframe size */
/*-------------------------------------------------------*/
if (fix_rate_m != RATE4_0K)
l_sf = L_SF4;
else
{
if (SVS_deci_m == 1)
{
if (i_sf == N_SF3-1)
l_sf = L_SF3;
else
l_sf = L_SF0;
}
else
l_sf = L_SF;
}
/*-------------------------------------------------------*/
/* Adaptive Codebook Contribution */
/*-------------------------------------------------------*/
if (SVS_deci_m == 1)
{
/*----------------------------------------------------*/
/* PP then LTP ( LTP or PP ) */
/*----------------------------------------------------*/
LTP_PP_pitch_ext_decod (ForPitch_decTEMP+i_s,
tempext_dec, i_sf, unfcod_dec[0],
lag, lag_f, l_sf);
}
else
{
if ((SVS_deci_m == 0) && (channel.idx_SVS_deci == 1))
{
/*-----------------------------------------------*/
/* LTP then PP */
/*-----------------------------------------------*/
temp_lag = ((pitchf- lag_f[0])*(i_sf+1.0)*l_sf)/
((double) L_FRM*2.0) + lag_f[0];
}
else
{
/*-----------------------------------------------*/
/* LTP then PP */
/*-----------------------------------------------*/
temp_lag = ((temp_lagf - lag_f[0])*(i_sf+1.0)*l_sf) /
((double) L_FRM+curr_lsf) + lag_f[0];
}
lag[i_sf] = (short) temp_lag;
LTP_pitch_decodtemp(tempext_dec, i_sf, unfcod_dec[0],
temp_lag, l_sf);
}
/*---------------------------------------------------------*/
/* Gains */
/*---------------------------------------------------------*/
gainQ[0] = qua_gainQ[0][i_sf];
gainQ[1] = qua_gainQ[1][i_sf];
/*--------------------------------------------------------*/
/* RE-Build the excitation */
/*--------------------------------------------------------*/
wad_dvector (unfcod_dec[0], gainQ[0], qua_unfcod[1]+i_s,
gainQ[1], tempext_dec+MAX_LAG, 0, l_sf-1);
dot_dvector (tempext_dec+MAX_LAG, tempext_dec+MAX_LAG, &FET,
0, l_sf-1);
FET += EPSI;
if (SVS_deci_m == 1)
px = tempext_dec+MAX_LAG-(INT16)ForPitch_decTEMP[i_s];
else
px = tempext_dec+MAX_LAG-lag[i_sf];
dot_dvector (px, px, &PFET, 0, l_sf-1);
if( SVS_deci_m == 1 && i_sf ==0)
BB = 0.95;
else if( gainQ[0] > 0.5 && i_sf ==0)
BB = 0.90;
else if(i_sf ==0)
BB = 0.9;
else
BB = 1.0;
AA = BB*sqrt(PFET/FET);
px = tempext_dec+MAX_LAG;
sca_dvector(px, AA, px, 0, l_sf-1);
cpy_dvector (tempext_dec+l_sf, tempext_dec, 0, MAX_LAG-1);
i_s += l_sf;
/*=======================================================*/
}
/*------------------------------------------------------------*/
/* Replace Adaptive CB */
/*------------------------------------------------------------*/
#ifdef WMOPS
WMP_cnt_test(12+6*54);
WMP_cnt_logic(12+12*54);
WMP_cnt_add(8);
WMP_cnt_sub(8);
WMP_cnt_div(6);
WMP_cnt_transc(6);
WMP_cnt_mult(6);
WMP_cnt_move(9+5*4);
#endif
/*-----------------------------------------------------------*/
/* Replace Adaptive CB */
/*-----------------------------------------------------------*/
cpy_dvector(tempext_dec, ext_dec,0,MAX_LAG-1);
(*update) = 1;
}
/*------------------------------------------------------------------*/
return;
/*------------------------------------------------------------------*/
}
#endif
/*----------------------------------------------------------------------------*/
/*============================================================================*/
/*------------------------------------- END ----------------------------------*/
/*============================================================================*/