www.pudn.com > SMV_Code.rar > decoder.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. */
/*=========================================================================*/
/* */
/*-------------------------------------------------------------------*/
/*===================================================================*/
/* FILE: decoder.c */
/*-------------------------------------------------------------------*/
/* PURPOSE : Speech Coding @ Selectable Bitrate (SMV) */
/*===================================================================*/
/*----------------------------------------------------------------------------*/
/*-------------------------------- INCLUDE -----------------------------------*/
/*----------------------------------------------------------------------------*/
#include "typedef.h"
#include "main.h"
#include "const.h"
#include "mcutil.h"
#include "gputil.h"
#include "ext_var.h"
#include "lib_ini.h"
#include "lib_lpc.h"
#include "lib_qlsf.h"
#include "lib_geq.h"
#include "lib_bit.h"
#include "lib_cla.h"
#include "lib_pit.h"
#include "lib_ltp.h"
#include "lib_ppr.h"
#include "lib_fcs.h"
#include "lib_gcb.h"
#include "lib_flt.h"
#include "lib_snr.h"
#include "nelp.h"
#ifdef DATA
#include "tty.h"
#include "dtmf.h"
#include "tables.h"
#endif
#ifdef WMOPS
#include "lib_wmp.h"
#endif
/*----------------------------------------------------------------------------*/
/*--------------------------------- FUNCTIONS --------------------------------*/
/*----------------------------------------------------------------------------*/
/*===================================================================*/
/* FUNCTION : dec_smv_frame (). */
/*-------------------------------------------------------------------*/
/* PURPOSE : Performs processing on one frame. */
/*-------------------------------------------------------------------*/
/* ALGORITHM : */
/*-------------------------------------------------------------------*/
/* INPUT ARGUMENTS : */
/* _ (INT16 []) serial: intput frame bitstream. */
/*-------------------------------------------------------------------*/
/* OUTPUT ARGUMENTS : */
/* _ (FLOAT64 []) sigout: output decoded frame. */
/*-------------------------------------------------------------------*/
/* INPUT/OUTPUT ARGUMENTS : */
/* _ None. */
/*-------------------------------------------------------------------*/
/* RETURN ARGUMENTS : */
/* _ None. */
/*===================================================================*/
void dec_smv_frame (INT16 PackedWords [], FLOAT64 *sigout, INT16 switch_flag)
{
/*-------------------------------------------------------------------*/
INT16 i_sf,i_s, l_sf, i,j, n_sf;
INT16 seed_dec_2k=0;
/*-------------------------------------------------------------------*/
/* Parameters for bitstream processing */
/*-------------------------------------------------------------------*/
INT16 parm[3];
INT16 shft_count;
INT16 PackWdsPtr[2];
PARAMETER channel;
/*-------------------------------------------------------------------*/
/* Gain MA-VQ */
/*-------------------------------------------------------------------*/
FLOAT64 gainQ[N_SF_MAX];
FLOAT64 *Ptr_gp_tab;
/*-------------------------------------------------------------------*/
/* LSF quantisation */
/*-------------------------------------------------------------------*/
INT16 exp_flg;
FLOAT64 lsfq_new_dec[NP], lpcgain_q;
FLOAT64 **pdcfq_dec;
/*-------------------------------------------------------------------*/
/* Parameters for excitation */
/*-------------------------------------------------------------------*/
FLOAT64 **qua_fcod, **unfcod_dec;
/*-------------------------------------------------------------------*/
/* Parameters for synthesis */
/*-------------------------------------------------------------------*/
FLOAT64 *sigsyn_dec;
/*-------------------------------------------------------------------*/
/* Bad Frame Concealement */
/*-------------------------------------------------------------------*/
INT16 bfi;
INT16 update;
FLOAT64 enrg;
FLOAT64 fec_refl[NP];
FLOAT64 temp_lagf;
FLOAT64 ET_buf[N_SF_MAX];
/*-------------------------------------------------------------------*/
FLOAT64 ForPitch_dec[L_FRM];
FLOAT64 ForPitch_decTEMP[L_FRM];
static FLOAT64 prev_lpcg=0.0;
FLOAT64 SNR_dec;
FLOAT64 sub_refl[NP];
FLOAT64 fec_e_lsf[NP];
#ifdef DATA
/*-------------------------------------------------------------------*/
/* DATA,TTY DTMF */
/*-------------------------------------------------------------------*/
INT16 sigout_16[L_FRM];
INT16 dtmf_digit;
INT16 tty_type;
INT16 chk_data; /*=0 speech, 1 data, 2 speech+data */
static Word16 chk_data_last=0;
Word16 SVS;
static Word16 dtmf_digit_last=-1;
static Word16 header_last=-1;
#endif
/*-------------------------------------------------------------------*/
/* Bad Rate Detection */
/*-------------------------------------------------------------------*/
FLOAT64 x=0.0, y=0.0, z=0.0;
INT16 SavePackedWords[PACKWDSNUM];
UNS_INT16 unst_1;
/*============================================================================*/
/* ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ */
/* ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ */
/* ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ DECODER ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ */
/* ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ */
/* ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ */
/*============================================================================*/
/*-------------------------------------------------------------------*/
/* Allocate temporary memory */
/*-------------------------------------------------------------------*/
pdcfq_dec = dmatrix (0, N_SF_MAX, 0, NP-1);
MaxIdx_dec = svector (0, MAXPN-1);
qua_fcod = dmatrix (0, 1, 0, L_FRM-1);
unfcod_dec = dmatrix (0, 1, 0, L_SF-1);
wsp_m_dec = dvector (0, L_WSP-1);
pred_energy_d38 = dvector (0, GVQ_VEC_SIZE_3D-1);
pred_energy_d410 = dvector (0, GVQ_VEC_SIZE_4D-1);
gain_code_vector = dvector (0, GVQ_VEC_SIZE_4D-1);
sigsyn_dec = dvector (0, L_SF+NP-1);
/*------------------------------------------------------------------*/
/* Pointers set-up */
/*------------------------------------------------------------------*/
INI_pointer_setup_dec ();
/*============================================================================*/
/* ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ BFI MANAGEMENT ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ */
/*============================================================================*/
#ifdef WMOPS
WMP_cnt_move (3);
WMP_cnt_test (6);
WMP_cnt_add (1);
#endif
bfi = 0;
update = 0;
/*-------------------------------------------------------------------*/
/* Initalizing bit un-packing parameters */
/*-------------------------------------------------------------------*/
PackWdsPtr[0] = 16;
PackWdsPtr[1] = 1;
switch (PackedWords[0])
{
case 0:
/* Blank frame rate. To be erased */
bfi = 1;
break;
case 1: channel.fix_rate = RATE0_8K;
break;
case 2: channel.fix_rate = RATE2_0K;
break;
case 3: channel.fix_rate = RATE4_0K;
break;
case 4: channel.fix_rate = RATE8_5K;
break;
case 14: bfi = 1;
break;
case 15:
/* Full-rate likely frame rate. To be erased*/
bfi = 1;
break;
default:
/* Invalid frame rate. To be erased */
bfi = 1;
break;
}
if (bfi == 0)
{
#ifdef DATA
ini_svector(data_buf,0,DATA_SIZE+5-1,0);
chk_data=0;
if ((channel.fix_rate==RATE8_5K)||(channel.fix_rate==RATE4_0K))
{
/*-----------------------------------------------------------*/
/* Check for possible data bits */
/*-----------------------------------------------------------*/
cpy_svector(PackedWords,SavePackedWords,0,PACKWDSNUM-1);
BIT_bits_to_data (PackedWords, PackWdsPtr,data_buf,&channel.
fix_rate,&chk_data);
cpy_svector(SavePackedWords,PackedWords,0,PACKWDSNUM-1);
}
PackWdsPtr[0] = 16;
PackWdsPtr[1] = 1;
/*---------------------------------------------------------------*/
/* Get speech bits if speech or speech+data */
/*---------------------------------------------------------------*/
if ((chk_data==2 )||(chk_data==0))
{
/*-----------------------------------------------------------*/
/* If speech+data read SVS bit */
/*-----------------------------------------------------------*/
if (chk_data==2)
BIT_bitunpack (&SVS, (UNS_INT16 *) PackedWords, 1,
PackWdsPtr);
/*----------------------------------------------------------*/
/* Use the remaining packet redundancy in the half-rate */
/* type 0 2-pulse FCB for bad rate check */
/*----------------------------------------------------------*/
if (channel.fix_rate==RATE4_0K)
{
/* Back up first */
cpy_svector(PackedWords,SavePackedWords,0,PACKWDSNUM-1);
i = PackWdsPtr[0] ;
j = PackWdsPtr[1] ;
/* Get the type bit first */
BIT_bitunpack (&unst_1, (UNS_INT16 *) PackedWords,
1, PackWdsPtr);
if (unst_1 == 0)
{
BIT_bitunpack (&unst_1, (UNS_INT16 *) PackedWords,
16, PackWdsPtr);
BIT_bitunpack (&unst_1, (UNS_INT16 *) PackedWords,
16, PackWdsPtr);
BIT_bitunpack (&unst_1, (UNS_INT16 *) PackedWords,
16, PackWdsPtr);
BIT_bitunpack (&unst_1, (UNS_INT16 *) PackedWords,
1, PackWdsPtr);
/* Getting BIT 51 - BIT 65 if chk_data !=2 */
/* Getting BIT 52 - BIT 66 if chk_data ==2 */
BIT_bitunpack (&unst_1, (UNS_INT16 *) PackedWords,
15, PackWdsPtr);
if ( (unst_1>=0x7FC8 && unst_1 <=0x7FFF)||
(unst_1>=0x5FC8 && unst_1 <=0x5FFF) )
bfi=1;
/* Getting BIT 66 - BIT 80 if chk_data !=2 */
/* Getting BIT 67 - BIT 81 if chk_data ==2 */
/* Reminder:0x7FC8 is reserved for data transmission */
BIT_bitunpack (&unst_1, (UNS_INT16 *) PackedWords,
15, PackWdsPtr);
if (unst_1 != 0x7FC8)
{
if ( (unst_1>=0x7FC9 && unst_1 <=0x7FFF)||
(unst_1>=0x5FC8 && unst_1 <=0x5FFF) )
bfi=1;
}
}
cpy_svector(SavePackedWords,PackedWords,0,PACKWDSNUM-1);
PackWdsPtr[0] = i ;
PackWdsPtr[1] = j ;
}
bfi = BIT_bits_to_cdbk_index (PackedWords, PackWdsPtr,
&channel);
}
#else
/*---------------------------------------------------------------*/
/* Use the remaining packet redundancy in the half-rate type 0 */
/* 2-pulse FCB for bad rate check */
/*---------------------------------------------------------------*/
if (channel.fix_rate==RATE4_0K)
{
/* Back up first */
cpy_svector(PackedWords,SavePackedWords,0,PACKWDSNUM-1);
i = PackWdsPtr[0] ;
j = PackWdsPtr[1] ;
/* Get the type bit first */
BIT_bitunpack (&unst_1, (UNS_INT16 *) PackedWords, 1,
PackWdsPtr);
if (unst_1 == 0)
{
BIT_bitunpack (&unst_1, (UNS_INT16 *) PackedWords,
16, PackWdsPtr);
BIT_bitunpack (&unst_1, (UNS_INT16 *) PackedWords,
16, PackWdsPtr);
BIT_bitunpack (&unst_1, (UNS_INT16 *) PackedWords,
16, PackWdsPtr);
BIT_bitunpack (&unst_1, (UNS_INT16 *) PackedWords,
1, PackWdsPtr);
/* Getting BIT 51 - BIT 65 */
BIT_bitunpack (&unst_1, (UNS_INT16 *) PackedWords,
15, PackWdsPtr);
if ( (unst_1>=0x7FC8 && unst_1 <=0x7FFF)||
(unst_1>=0x5FC8 && unst_1 <=0x5FFF) )
bfi=1;
/* Getting BIT 66 - BIT 80 */
/* Reminder: 0x7FC8 is reserved for data transmission */
BIT_bitunpack (&unst_1, (UNS_INT16 *) PackedWords,
15, PackWdsPtr);
if (unst_1 != 0x7FC8)
{
if ( (unst_1>=0x7FC9 && unst_1 <=0x7FFF)||
(unst_1>=0x5FC8 && unst_1 <=0x5FFF) )
bfi=1;
}
}
cpy_svector(SavePackedWords,PackedWords,0,PACKWDSNUM-1);
PackWdsPtr[0] = i ;
PackWdsPtr[1] = j ;
}
/*---------------------------------------------------------------*/
/* Decode bit-stream if is a good frame */
/*---------------------------------------------------------------*/
bfi = BIT_bits_to_cdbk_index (PackedWords, PackWdsPtr, &channel);
#endif
#ifdef DATA
/*---------------------------------------------------------------*/
/* do following checks for non data only cases */
/*---------------------------------------------------------------*/
if ((chk_data !=1) &&(dtmf_digit_last == -1))
{
#endif
/*---------------------------------------------------------------*/
/* Check badrate flag in full-rate and 1/4-rate */
/*---------------------------------------------------------------*/
if (channel.badrate_flag==1)
bfi=1;
/*---------------------------------------------------------------*/
/* Filter type 3 in 1/4-rate NELP is illegal */
/*---------------------------------------------------------------*/
if (channel.fix_rate==RATE2_0K && channel.idx_gainVQ[3]==3)
bfi=1;
/*---------------------------------------------------------------*/
/* Bad-rate detection schemes using illegal rate/type transitions*/
/*---------------------------------------------------------------*/
if (past_bfi==0)
{
/*-----------------------------------------------------------*/
/* Type-1 frame to 1/8th rate is illegal */
/*-----------------------------------------------------------*/
if (SVS_deci_mem==1 && channel.fix_rate==RATE0_8K)
bfi=1;
/*-----------------------------------------------------------*/
/* Type-1 frame to 1/4th rate is illegal */
/*-----------------------------------------------------------*/
if (SVS_deci_mem==1 && channel.fix_rate==RATE2_0K)
bfi=1;
/*-----------------------------------------------------------*/
/* Big lag change is illegal */
/*-----------------------------------------------------------*/
if (SVS_deci_mem==1 && channel.idx_SVS_deci==1)
{
if (channel.fix_rate == RATE8_5K)
{
x = PitLagTab8b[channel.idx_pitch[0]];
if (fabs(x-pitchf_dec)>15)
{
/*-----------------------------------------------*/
/* Note:pitchf_dec is the previous lag */
/*-----------------------------------------------*/
bfi=1;
}
}
else if (channel.fix_rate==RATE4_0K)
{
x = PitLagTab7b[channel.idx_pitch[0]];
if (fabs(x-pitchf_dec)>15 && x>40.0)
{
/*-----------------------------------------------*/
/* Note:pitchf_dec is the previous lag */
/*-----------------------------------------------*/
bfi=1;
}
}
}
if (ppast_bfi==0)
{
/*------------------------------------------------------*/
/* Eighth/quarter-rate to Type-1 frame is illegal */
/*------------------------------------------------------*/
if (channel.idx_SVS_deci==1 &&
(fix_rate_dec_mem==RATE0_8K ||
fix_rate_dec_mem==RATE2_0K))
{
if (fix_rate_dec_mem2 <= RATE2_0K)
{
bfi=1;
}
else
{
ini_dvector(ext_dec, 0, MAX_LAG+L_SF-1, 0.0);
ini_dvector(ext_dec_fec, 0, MAX_LAG+L_SF-1, 0.0);
ini_dvector(PF_mem_syn, 0, NP-1, 0.0);
ini_dvector(synth_mem_dec, 0, NP-1, 0.0);
past_energyq_2d[0]=past_energyq_2d[1];
past_energyq_4d[0]=past_energyq_4d[1];
past_fixed_energy = 0.0;
for (i = 0; i < NP; i++)
lsfq_old_dec[i] = lsf_ini [i];
}
}
}
}
#ifdef DATA
}
#endif
}
if (bfi == 0)
{
#ifdef DATA
/*---------------------------------------------------------------*/
/* do following checks for non data cases and bfi=0 */
/*---------------------------------------------------------------*/
if ((chk_data !=1) &&(dtmf_digit_last == -1))
{
#endif
#ifdef WMOPS
WMP_cnt_move (7);
WMP_cnt_test (3);
WMP_cnt_sub (2);
WMP_cnt_logic (1);
WMP_cnt_shift (1);
#endif
if (channel.fix_rate == RATE2_0K )
{
parm[0] = channel.idx_lsf[0];
parm[1] = channel.idx_lsf[1];
parm[2] = channel.idx_lsf[2];
seed_dec_2k = 0x0000;
shft_count = 14;
for (j = 0; j < 3; j++)
{
shft_count -= bitno0_2k[j];
seed_dec_2k = seed_dec_2k ^
(((INT64) parm[j] ) << shft_count);
}
}
if (channel.fix_rate == RATE0_8K)
{
parm[0] = channel.idx_lsf[0];
parm[1] = channel.idx_lsf[1];
parm[2] = channel.idx_lsf[2];
shft_count = 11;
for (j = 0; j < 3; j++)
{
shft_count -= bitno1[j];
seed_dec = seed_dec ^(((long) parm[j] ) << shft_count);
}
/*-------------------------------------------------------*/
/* Decode the 1/8 rate gain first to see whether */
/* it is a bad packet */
/*-------------------------------------------------------*/
GCB_gauss_excit_dec (&seed_dec, L_FRM, qua_unfcod[1]);
if ((fix_rate_dec_mem == RATE4_0K) ||
(fix_rate_dec_mem == RATE2_0K))
{
if (SVS_deci_mem == 0)
GEQ_update_mem_2d_to_4d();
else
GEQ_update_mem_3d_to_4d();
}
/*-------------------------------------------------------*/
/* Decode the fixed codebook gain for sub-frame */
/* # 1 coded with 5 bits */
/*-------------------------------------------------------*/
if (GEQ_dec_gains_1_5 (channel.idx_gainVQ[0], qua_gainQ,
qua_unfcod[1], 0)==1)
{
bfi=1;
}
for (i = 0; i < N_SF4; i++) qua_gainQ[1][i] = qua_gainQ[1][0];
}
#ifdef DATA
}
#endif
}
if (bfi == 1)
{
N_bfi++;
bfh_oh = BFH_OH+1;
nbfi_count = 0;
frm_erasure++;
channel.fix_rate = fix_rate_dec_mem;
channel.idx_SVS_deci = SVS_deci_mem;
#ifdef DATA
/*------------------------------------------------------------*/
/* Use last chk_data (0=speech,1=data,2=data+speech and header */
/*------------------------------------------------------------*/
chk_data=chk_data_last;
data_buf[0]=header_last;
for (i=1; i 0) {N_bfi = 0; bfh_oh--;}
if (nbfi_count < 5) nbfi_count++;
}
if (nbfi_count > 3) bfi_caution = 0;
if (channel.fix_rate != RATE0_8K && fix_rate_dec_mem == RATE0_8K &&
SNR_dec_mem > 50.0 && past_bfi == 1)
ini_dvector(past_energyq_4d, 0, GVQ_VEC_SIZE_4D-1, -30.0);
/*-------------------------------------------------------------------*/
/* Reset the seed for 0.8 Kbs */
/*-------------------------------------------------------------------*/
if (channel.fix_rate != RATE0_8K )
seed_dec = (INT16)0x0E76;
/*============================================================================*/
/* ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ LSF INVERSE QUANTIZATION AND INTERPOLATION ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤*/
/*============================================================================*/
/*-------------------------------------------------------------------*/
/* Get the quantized lsf */
/*-------------------------------------------------------------------*/
#ifdef DATA
/*-------------------------------------------------------------------*/
/* If only data, skip decoding code */
/*-------------------------------------------------------------------*/
if ((chk_data !=1) &&(dtmf_digit_last==-1))
{
#endif
LSF_Q_lsf_decode (bfi_caution, &exp_flg, lsfq_new_dec,
channel.idx_lsf, bfi, nbfi_count, channel.fix_rate);
/*-------------------------------------------------------------------*/
/* Interpolate the QUANTIZED lsf and calculate corresponding */
/* the LPC coefficients */
/*-------------------------------------------------------------------*/
#ifdef WMOPS
WMP_cnt_test (5);
#endif
if (channel.fix_rate == RATE4_0K)
{
LPC_interpolation (lsfq_new_dec, (FLOAT64 *)NULL, lsfq_old_dec,
pdcfq_dec, 1, channel.idx_SVS_deci);
}
else
{
if (channel.fix_rate==RATE8_5K && channel.idx_SVS_deci==0)
{
if (bfi == 0)
{
LPC_adptive_interp_dec (lsfq_new_dec, lsfq_old_dec,
pdcfq_dec,
channel.idx_lpc_int);
}
else
LPC_adptive_interp_dec (lsfq_new_dec, lsfq_old_dec,
pdcfq_dec, 0);
}
else
LPC_adptive_interp_dec (lsfq_new_dec, lsfq_old_dec,
pdcfq_dec, 0);
}
if (channel.fix_rate != RATE4_0K)
LPC_pred2refl (pdcfq_dec[3], fec_refl, NP);
else
{
if (channel.idx_SVS_deci == 1)
LPC_pred2refl (pdcfq_dec[2], fec_refl, NP);
else
LPC_pred2refl (pdcfq_dec[1], fec_refl, NP);
}
/*-------------------------------------------------------------------*/
/* Determination of the flatness of the input speech */
/*-------------------------------------------------------------------*/
CLA_Identify_Input (channel.idx_SVS_deci, pdcfq_dec[0],
lsfq_new_dec[0], pgain_past_dec, &lpcgain_q,
channel.fix_rate, &FlatSp_Flag_dec,
&SVS_Count_dec, &Vad_0_Count_dec, &Av_value_dec);
/*-------------------------------------------------------------------*/
/* Interpolation of Pitch Lag */
/*-------------------------------------------------------------------*/
#ifdef WMOPS
WMP_cnt_test (1);
#endif
if (channel.idx_SVS_deci == 1)
{
PIT_pitch_track_recons (fix_rate_dec_mem, bfi, past_bfi, ppast_bfi,
lag_f, SVS_deci_mem, qua_gainQ, channel,
&pitchf_dec, pitch_f_mem, ForPitch_decTEMP);
PIT_PitchInterpolat (pitchf_dec, pitch_f_mem, ForPitch_dec, 0);
}
#ifdef WMOPS
WMP_cnt_test (3);
#endif
if (bfi == 0)
{
if (channel.idx_SVS_deci == 0)
{
if (channel.fix_rate == RATE8_5K)
temp_lagf = PitLagTab8b[channel.idx_pitch[0]];
else if (channel.fix_rate == RATE4_0K)
temp_lagf = PitLagTab7b[channel.idx_pitch[0]];
}
}
LTP_adap_cbk_correction (fix_rate_dec_mem, bfi, past_bfi, ppast_bfi,
qua_gainQ, gainQ, SVS_deci_mem, temp_lagf,
&update, pitchf_dec, pitch_f_mem, lag, lag_f,
ForPitch_decTEMP, ext_dec_fec, ext_dec,
unfcod_dec, qua_unfcod, channel);
/*-------------------------------------------------------------------*/
/* Gaussian excitation for very low bit rates */
/*-------------------------------------------------------------------*/
#ifdef WMOPS
WMP_cnt_test (3);
#endif
if ((channel.fix_rate == RATE2_0K) || (channel.fix_rate == RATE0_8K))
{
cpy_dvector(gp_buf+4,gp_buf, 0, 4-1);
ini_dvector(gp_buf+4, 0, 4-1, 0.0);
if (channel.fix_rate == RATE2_0K)
{
#ifdef WMOPS
WMP_cnt_test (4);
#endif
if( (fix_rate_dec_mem == RATE8_5K || fix_rate_dec_mem ==RATE0_8K) )
GEQ_update_mem_4d_to_2d();
else if( fix_rate_dec_mem == RATE4_0K && SVS_deci_mem != 0 )
GEQ_update_mem_3d_to_2d();
#ifdef WMOPS
WMP_fwc ("");
#endif
nelp_decoder(seed_dec_2k, fix_rate_dec_mem, qua_unfcod[1],
qua_gainQ[1], channel.idx_gainVQ, N_bfi);
#ifdef WMOPS
WMP_fwc ("nelp_decoder");
#endif
}
else if (bfi != 0)
{ /* only in FER frames */
#ifdef WMOPS
WMP_cnt_move (N_SF4);
#endif
GCB_gauss_excit_dec (&seed_dec, L_FRM, qua_unfcod[1]);
/*-------------------------------------------------------*/
/* Decode the fixed codebook gain for sub-frame */
/* # 1 coded with 6 bits */
/*-------------------------------------------------------*/
GEQ_dec_gains_1_5 (channel.idx_gainVQ[0], qua_gainQ,
qua_unfcod[1], N_bfi);
for (i = 0; i < N_SF4; i++)
qua_gainQ[1][i] = qua_gainQ[1][0];
}
}
/*============================================================================*/
/* ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ SUB-FRAME PROCESSING ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ */
/*============================================================================*/
/*----------------------------------------------------------------------------*/
/*-----------------------------VARIABLE DESCRIPTION --------------------------*/
/*----------------------------------------------------------------------------*/
/* */
/* pdcfq_dec - quantized prediction coefficients */
/* unfcod_dec[0] - adaptive codebook (ACB) vector */
/* unfcod_dec[1] - algebraic codebook (CDBK) vector */
/* gainQ[0] - ACB gain */
/* gainQ[1] - CDBK gain */
/* */
/* ext_dec - adaptive codebook */
/* lag[i_sf] - integral lag of the current subframe */
/* lagf[i_sf] - fractional lag of the current subframe */
/* */
/*----------------------------------------------------------------------------*/
/*-------------------------------------------------------------------*/
/* Set number of subframes */
/*-------------------------------------------------------------------*/
#ifdef WMOPS
WMP_cnt_test (2);
WMP_cnt_move (1);
#endif
if (channel.fix_rate != RATE4_0K)
n_sf=N_SF4;
else
{
if (channel.idx_SVS_deci == 1)
n_sf = N_SF3;
else
n_sf = N_SF2;
}
/*----------------------------------------------------------------------------*/
/*¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ Decoding loop on the sub-frames ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤*/
/*----------------------------------------------------------------------------*/
/*-------------------------------------------------------------------*/
/* Restoring the memory for the synthesis */
/*-------------------------------------------------------------------*/
cpy_dvector(sigsyn_dec_mem, sigsyn_dec, 0, NP-1);
i_s = 0;
for (i_sf = 0; i_sf < n_sf; i_sf++)
{
/*===========================================================*/
/*-----------------------------------------------------------*/
/* Set length of subframe */
/*-----------------------------------------------------------*/
#ifdef WMOPS
WMP_cnt_test (3);
WMP_cnt_move (1);
#endif
if (channel.fix_rate != RATE4_0K)
l_sf = L_SF4;
else
{
if (channel.idx_SVS_deci == 1)
{
if (i_sf == N_SF3-1)
l_sf = L_SF3;
else
l_sf = L_SF0;
}
else
l_sf = L_SF;
}
/*-----------------------------------------------------------*/
/* Adaptive Codebook Contribution */
/*-----------------------------------------------------------*/
#ifdef WMOPS
WMP_cnt_test (3);
WMP_cnt_move (4);
#endif
if ((channel.fix_rate == RATE8_5K) ||
(channel.fix_rate == RATE4_0K))
{
if (channel.idx_SVS_deci == 1)
{
LTP_PP_pitch_ext_decod (ForPitch_dec+i_s, ext_dec,
i_sf, unfcod_dec[0], lag,
lag_f, l_sf);
cpy_dvector (unfcod_dec[0], qua_unfcod[0]+i_s, 0,
l_sf-1);
}
else
{
if (channel.fix_rate == RATE8_5K)
LTP_8_5k_pitch_decod (fec_refl[0],bfi, ext_dec, i_sf,
unfcod_dec[0], lag, lag_f, l_sf,
channel.idx_pitch);
else
LTP_7b_pitch_decod (fec_refl[0], bfi, ext_dec, i_sf,
unfcod_dec[0], lag, lag_f, l_sf,
channel.idx_pitch);
cpy_dvector(unfcod_dec[0], qua_unfcod[0]+i_s,
0, l_sf-1);
}
}
else
{
gainQ[0] = 0.0;
qua_gainQ[0][i_sf] = 0.0;
ini_dvector(unfcod_dec[0], 0, l_sf-1, 0.0);
ini_dvector(qua_unfcod[0]+i_s, 0, l_sf-1, 0.0);
}
/*-----------------------------------------------------------*/
/* Fixed Codebook Contribution */
/*-----------------------------------------------------------*/
#ifdef WMOPS
WMP_cnt_test (3);
WMP_cnt_move (1);
#endif
switch (channel.fix_rate)
{
/*-------------------------------------------------------*/
/* RATE 8.5 kps */
/*-------------------------------------------------------*/
case RATE8_5K:
if (channel.idx_SVS_deci == 1)
{
Ptr_gp_tab = gp4_tab;
GEQ_Dec_PitchGain (N_bfi, i_sf, channel.idx_Gp_VQ,
gainQ,Ptr_gp_tab, GVQ_VEC_SIZE_4D);
if (bfi == 0)
FCS_cdbk_decod_8500BPS (unfcod_dec[1],
l_sf, i_sf, lag[i_sf],
gainQ[0], &channel, 1);
}
else
{
if (bfi == 0)
FCS_cdbk_decod_8500BPS (unfcod_dec[1],
l_sf, i_sf, lag[i_sf],
pgain_past_dec,
&channel, 0);
}
break;
/*-------------------------------------------------------*/
/* RATE 4.0 kps */
/*-------------------------------------------------------*/
case RATE4_0K:
if (channel.idx_SVS_deci == 1)
{
Ptr_gp_tab = gp3_tab;
GEQ_Dec_PitchGain (N_bfi, i_sf, channel.idx_Gp_VQ,
gainQ, Ptr_gp_tab, GVQ_VEC_SIZE_3D);
if (bfi == 0)
FCS_cdbk_decod_4000BPS (ext_dec,
pdcfq_dec[i_sf],
unfcod_dec[1], l_sf,
i_sf, lag[i_sf], gainQ[0],
fix_rate_dec_mem, lpcgain_q,
&channel, 1);
}
else
{
if (bfi == 0)
FCS_cdbk_decod_4000BPS (ext_dec,
pdcfq_dec[i_sf],
unfcod_dec[1], l_sf,
i_sf, lag[i_sf],
pgain_past_dec,
fix_rate_dec_mem, lpcgain_q,
&channel, 0);
}
break;
/*-------------------------------------------------------*/
/* RATE 2.0 kps */
/*-------------------------------------------------------*/
case RATE2_0K:
cpy_dvector (qua_unfcod[1]+i_s, unfcod_dec[1], 0,
l_sf-1);
gainQ[1]=qua_gainQ[1][i_sf]=1.0;
break;
/*------------------------------------------------------*/
/* RATE 0.8 kps */
/*------------------------------------------------------*/
case RATE0_8K:
break;
default: nrerror ("Invalid rate !!");
break;
}
/*-----------------------------------------------------------*/
#ifdef WMOPS
WMP_cnt_test (3);
#endif
if ((bfi == 1) && ((channel.fix_rate == RATE8_5K) ||
(channel.fix_rate == RATE4_0K)))
{
GCB_gauss_excit_dec (&seed_bfi_exc, l_sf, unfcod_dec[1]);
}
/*-----------------------------------------------------------*/
/* Adaptive and Fixed Codebook Gains */
/*-----------------------------------------------------------*/
#ifdef WMOPS
WMP_cnt_test (12);
WMP_cnt_move (4);
#endif
if ((channel.fix_rate == RATE8_5K) ||
(channel.fix_rate == RATE4_0K))
{
/*------------------------------------------------------*/
/* RATE 8.5 kbps and 4.0 kbps */
/*------------------------------------------------------*/
cpy_dvector (unfcod_dec[1], qua_unfcod[1]+i_s, 0, l_sf-1);
if (channel.idx_SVS_deci == 0)
{
if (i_sf==0 && type0count<32767)
type0count++;
if (channel.fix_rate == RATE8_5K)
{
if (fix_rate_dec_mem==RATE0_8K && ppast_bfi==0 && i_sf==0)
{
past_energyq_4d[1] = past_energyq_4d[0];
past_energyq_4d[2] = past_energyq_4d[0];
past_energyq_4d[3] = past_energyq_4d[0];
}
if (((fix_rate_dec_mem == RATE4_0K) ||
(fix_rate_dec_mem == RATE2_0K)) &&
(i_sf == 0))
{
if (SVS_deci_mem == 0)
GEQ_update_mem_2d_to_4d();
else
GEQ_update_mem_3d_to_4d();
}
GEQ_dec_gains_2_7(channel.fix_rate,lag[0],
enrg_buff[2], onset_flg_dec,
fec_refl[0],
channel.idx_gainVQ[i_sf],
gainQ, N_bfi, unfcod_dec[1],
i_sf, l_sf);
if (type0count<50)
{
LPC_pred2refl (pdcfq_dec[i_sf], sub_refl, NP);
for(i=0,x=1.0;i21000.0 )
{
type0count=50;
gainQ[1]=0.0;
past_energyq_4d[0] = -20.0;
}
}
}
else
{
if (fix_rate_dec_mem==RATE0_8K && ppast_bfi==0 && i_sf==0)
{
past_energyq_4d[1] = past_energyq_4d[0];
past_energyq_4d[2] = past_energyq_4d[0];
past_energyq_4d[3] = past_energyq_4d[0];
}
if (((fix_rate_dec_mem == RATE8_5K) ||
(fix_rate_dec_mem ==RATE0_8K)) &&
(i_sf == 0))
{
GEQ_update_mem_4d_to_2d();
}
else
{
if ((fix_rate_dec_mem == RATE4_0K) &&
(SVS_deci_mem != 0) &&
(i_sf == 0))
{
GEQ_update_mem_3d_to_2d();
}
}
GEQ_dec_gains_2_7(channel.fix_rate,lag[0],
enrg_buff[2], onset_flg_dec,
fec_refl[0],
channel.idx_gainVQ[i_sf],
gainQ, N_bfi, unfcod_dec[1],
i_sf, l_sf);
if (type0count<50)
{
LPC_pred2refl (pdcfq_dec[i_sf], sub_refl, NP);
for(i=0,x=1.0;i18000.0 )
{
type0count=50;
gainQ[1]=0.0;
past_energyq_2d[0] = -20.0;
}
}
}
}
else
{
if (channel.fix_rate == RATE8_5K)
{
if (((fix_rate_dec_mem == RATE4_0K) ||
(fix_rate_dec_mem == RATE2_0K))&& (i_sf == 0))
{
if (SVS_deci_mem == 0)
GEQ_update_mem_2d_to_4d();
else
GEQ_update_mem_3d_to_4d();
}
GEQ_dec_gc_4_10 (channel.idx_Gc_VQ, &(gainQ[1]),
N_bfi, unfcod_dec, i_sf);
}
else
{
if (((fix_rate_dec_mem == RATE8_5K) ||
(fix_rate_dec_mem == RATE0_8K)) && (i_sf == 0))
GEQ_update_mem_4d_to_3d();
else if (SVS_deci_mem == 0)
GEQ_update_mem_2d_to_3d();
GEQ_dec_gc_3_8(channel.idx_Gc_VQ, &(gainQ[1]),
N_bfi,unfcod_dec, i_sf);
}
}
qua_gainQ[1][i_sf] = gainQ[1];
qua_gainQ[0][i_sf] = gainQ[0];
pgain_past_dec = gainQ[0];
if (pgain_past_dec < PAST_PGAIN_MIN)
pgain_past_dec = PAST_PGAIN_MIN;
if (pgain_past_dec > PAST_PGAIN_MAX)
pgain_past_dec = PAST_PGAIN_MAX;
}
else
{
/*---------------------------------------------------*/
/* RATE 2.0 kbps and 0.8 kbps */
/*---------------------------------------------------*/
gainQ[0] = 0.0;
pgain_past_dec = 0.0;
qua_gainQ[0][i_sf]=0.0;
gainQ[1]=qua_gainQ[1][i_sf];
if (channel.fix_rate== RATE2_0K)
gainQ[1]=qua_gainQ[1][i_sf]=1.0;
}
/*-------------------------------------------------------*/
/* Build the excitation */
/*-------------------------------------------------------*/
#ifdef WMOPS
WMP_cnt_test (1);
#endif
if (exp_flg == 1)
wad_dvector(qua_unfcod[0]+i_s, gainQ[0],
qua_unfcod[1]+i_s, 0.7*gainQ[1],
ext_dec+MAX_LAG, 0, l_sf-1);
else
wad_dvector(qua_unfcod[0]+i_s, gainQ[0],
qua_unfcod[1]+i_s, gainQ[1],
ext_dec+MAX_LAG, 0, l_sf-1);
if (N_bfi <= 2)
{
GEQ_energy_extrapolation (i_s, i_sf, l_sf, gainQ,
qua_unfcod, bfi, lag_f, ext_dec,
Prev_Beta_Pitch, ET_buf,
ForPitch_dec, channel);
}
/*-----------------------------------------------------------*/
/* Synthesis filter */
/*-----------------------------------------------------------*/
FLT_filterAP (pdcfq_dec[i_sf], ext_dec+MAX_LAG, sigsyn_dec+NP,
synth_mem_dec, NP, l_sf);
if (channel.idx_SVS_deci == 1 && bfi ==0)
{
if (i_sf==0)
y=0.0;
dot_dvector (sigsyn_dec+NP, sigsyn_dec+NP,
&z, 0, l_sf-1);
y += z;
if (i_sf==n_sf-1)
{
type1en[arrayindex]=(INT16)(10.0*log10(y)+0.5);
arrayindex = (++arrayindex)%LEN_TYPE1EN;
maxenergy = type1en[0];
for (i=1;imaxenergy)
maxenergy = (FLOAT64) type1en[i];
}
type0count=0;
}
/*-----------------------------------------------------------*/
/* Post processing */
/*-----------------------------------------------------------*/
PPR_post_process (sigsyn_dec, pdcfq_dec[i_sf], lag_f[i_sf],
l_sf, FlatSp_Flag_dec, channel.fix_rate,
bfi, N_bfi);
/*-----------------------------------------------------------*/
/* Update the synthesized speech buffer */
/*-----------------------------------------------------------*/
cpy_dvector(sigsyn_dec+NP, sigout+i_s, 0, l_sf-1);
/*-----------------------------------------------------------*/
/* Update the adaptive codebook */
/*-----------------------------------------------------------*/
cpy_dvector(ext_dec+l_sf, ext_dec, 0, MAX_LAG-1);
i_s += l_sf;
/*===========================================================*/
}
#ifdef WMOPS
WMP_cnt_test (17);
WMP_cnt_move (4);
#endif
if ((channel.fix_rate == RATE4_0K) &&
(channel.idx_SVS_deci == 1))
{
cpy_dvector(gp_buf+4, gp_buf, 0, 4-1);
gp_buf[4] = qua_gainQ[0][0];
gp_buf[5] = gp_buf[6] = qua_gainQ[0][1];
gp_buf[7] = qua_gainQ[0][2];
}
else
{
if ((channel.fix_rate == RATE4_0K) &&
(channel.idx_SVS_deci!=1))
{
cpy_dvector(gp_buf+4,gp_buf, 0, 4-1);
if ((ET_buf[0] < 40.0) && (qua_gainQ[0][0] > 0.7))
gp_buf[4] = gp_buf[5] = 0.4;
else
gp_buf[4] = gp_buf[5] = qua_gainQ[0][0];
if ((ET_buf[1] < 40.0) && (qua_gainQ[0][1] > 0.7))
gp_buf[6] = gp_buf[7] = 0.4;
else
gp_buf[6] = gp_buf[7] = qua_gainQ[0][1];
}
else
{
if (channel.fix_rate == RATE8_5K)
{
cpy_dvector(gp_buf+4, gp_buf, 0, 4-1);
for (i = 0; i < 4; i++)
{
if ((ET_buf[i] < 40.0) && (qua_gainQ[0][i] > 0.7)
&& (channel.idx_SVS_deci != 1))
gp_buf[i+4] = 0.4;
else
gp_buf[i+4] = qua_gainQ[0][i];
}
}
}
}
/*-------------------------------------------------------------------*/
/* Estimation of LPC gain for FEC */
/*-------------------------------------------------------------------*/
#ifdef WMOPS
WMP_cnt_mac (NP);
WMP_cnt_mult (NP+1);
WMP_cnt_transc (1);
#endif
LPC_pred2refl (pdcfq_dec[n_sf-1], sub_refl, NP);
sub_lpcg = 1.0;
for (i = 0; i < NP; i++)
sub_lpcg *= (1.0-sqr(sub_refl[i]));
sub_lpcg = -10.0*log10(sub_lpcg+EPSI);
#ifdef WMOPS
WMP_cnt_move (1);
WMP_cnt_mult (1);
WMP_cnt_transc (1);
WMP_cnt_test (4);
WMP_cnt_sub (3);
WMP_cnt_move (2);
#endif
SNR_Calc_SNR_dec(channel.fix_rate, sigout, &SNR_dec, &enrg);
enrg_buff[0] = enrg_buff[1];
enrg_buff[1] = enrg_buff[2];
enrg_buff[2] = 10.0*log10(enrg/L_FRM+EPSI);
if( ((enrg_buff[2] - enrg_buff[1] > 13.0) ||
(enrg_buff[2] - enrg_buff[0] > 13.0)
|| (sub_lpcg-prev_lpcg > 7.0)) && enrg_buff[2]> 45.0)
onset_flg_dec = 1;
else
onset_flg_dec = 0;
prev_lpcg = sub_lpcg;
#ifdef WMOPS
WMP_cnt_test (7);
WMP_cnt_move (5);
#endif
if( (fec_refl[0] > 0.4 || (channel.fix_rate == RATE0_8K &&
SNR_dec > 50.0)) && bfi == 1)
{
LSF_Q_lsf_predict(&B_40k[LQMA_40k*NP], qes_dec, LQMA_40k,
fec_e_lsf);
dif_dvector(Mean_removed_flat_lsf, fec_e_lsf, qes_dec[0],
0, NP-1);
bfi_caution = 1;
}
ppast_bfi = past_bfi;
past_bfi = bfi;
/*-------------------------------------------------------------------*/
/* Update the memories for next frame */
/*-------------------------------------------------------------------*/
SVS_deci_mem = channel.idx_SVS_deci;
fix_rate_dec_mem2 = fix_rate_dec_mem;
fix_rate_dec_mem = channel.fix_rate;
SNR_dec_mem = SNR_dec;
#ifdef DATA
}
else
{
INI_reset_decoder ();
ini_dvector(sigout, 0, L_FRM-1, 0.0);
}
/*-------------------------------------------------------------------*/
/* Generate DTMF, TTY tones */
/*-------------------------------------------------------------------*/
/*-------------------------------------------------------------------*/
/* Zero out speech if only data or */
/* first frame after dtmf */
/*-------------------------------------------------------------------*/
if (chk_data == 0)
data_buf[0] = -1;
if (chk_data == 1 )
ini_dvector(sigout, 0, L_FRM-1, 0.0);
for (i = 0; i < L_FRM; i++)
sigout_16[i] = (INT16) sigout[i];
if (chk_data >= 1)
{
if (data_buf[0] == TTY_HEADER)
{
tty_dec_header = data_buf[1]&0x00ff;
tty_type = data_buf[1]>>8;
tty_dec_char = data_buf[2];
tty_dec_baud_rate = data_buf[3];
tty_dec_flag = tty_dec (sigout_16, 0, tty_dec_header,
tty_dec_char, tty_dec_baud_rate,
bfi,
0, /* Subframe index */
1, /* Num of subframes */
L_FRM);
if (tty_dec_flag !=0)
for (i = 0; i < L_FRM; i++)
sigout[i] = (FLOAT64)sigout_16[i];
}
/*---------------------------------------------------------------*/
/* If 00)&&(N_bfi<3)&&(dtmf_digit_last>0))
{
data_buf[0] = DTMF_HEADER;
data_buf[1] = dtmf_digit_last;
}
/*---------------------------------------------------------------*/
/* If more than 2 bad frames, stop generating dtmf tones */
/*---------------------------------------------------------------*/
if ((data_buf[0] == DTMF_HEADER)&&(N_bfi<3))
{
/*-----------------------------------------------------------*/
/* Get dtmf_digit */
/*-----------------------------------------------------------*/
dtmf_digit = (INT16)data_buf[1];
if (dtmf_digit > 0)
{
/*-------------------------------------------------------*/
/* Generate dtmf tones */
/*-------------------------------------------------------*/
dtmf_tone_gen(dtmf_digit,dtmf_digit_last,L_FRM,sigout);
}
else
{
/*-------------------------------------------------------*/
/* Silence frame after dtmf tone */
/*-------------------------------------------------------*/
ini_dvector(sigout, 0, L_FRM-1, 0.0);
}
dtmf_digit_last = dtmf_digit;
}
else
{
dtmf_digit_last = -1;
}
}
else
{
dtmf_digit_last = -1;
tty_dec_flag = tty_dec( sigout_16, 1, tty_dec_header,
tty_dec_char, tty_dec_baud_rate, bfi,
0, /* Subframe index */
1, /* Num of subframes */
L_FRM);
if (tty_dec_flag !=0)
for (i=0; i