www.pudn.com > p_voice.rar > DECLD8CP.C
/*
ITU-T G.729 Annex C+ - Reference C code for floating point
implementation of G.729 Annex C+
(integration of Annexes B, D and E)
Version 2.1 of October 1999
*/
/*
File : DECLD8CP.C
*/
/*-----------------------------------------------------------------*
* Functions init_decod_ld8c and decod_ld8c *
*-----------------------------------------------------------------*/
#include "typedef.h"
#include "ld8k.h"
#include "ld8cp.h"
#include "dtx.h"
#include "sid.h"
/*---------------------------------------------------------------*
* Decoder constant parameters (defined in "ld8k.h") *
*---------------------------------------------------------------*
* L_FRAME : Frame size. *
* L_SUBFR : Sub-frame size. *
* M : LPC order. *
* MP1 : LPC order+1 *
* PIT_MIN : Minimum pitch lag. *
* PIT_MAX : Maximum pitch lag. *
* L_INTERPOL : Length of filter for interpolation *
* PRM_SIZE : Size of vector containing analysis parameters *
*---------------------------------------------------------------*/
/*--------------------------------------------------------*
* Static memory allocation. *
*--------------------------------------------------------*/
/* Excitation vector */
static FLOAT old_exc[L_FRAME+PIT_MAX+L_INTERPOL];
static FLOAT *exc;
/* Lsp (Line spectral pairs) */
static FLOAT lsp_old[M]={
(F)0.9595, (F)0.8413, (F)0.6549, (F)0.4154, (F)0.1423,
(F)-0.1423, (F)-0.4154, (F)-0.6549, (F)-0.8413, (F)-0.9595};
static FLOAT mem_syn[M_BWD]; /* Filter's memory */
static FLOAT sharp ; /* pitch sharpening of previous fr */
static FLOAT gain_code; /* fixed codebook gain */
static FLOAT gain_pitch ; /* adaptive codebook gain */
static int prev_t0; /* integer delay of previous frame */
static int prev_t0_frac; /* integer delay of previous frame */
/* for G.729B */
static INT16 seed_fer;
/* CNG variables */
static int past_ftyp;
static INT16 seed;
static FLOAT sid_sav;
/* for the backward analysis */
static FLOAT rexp[M_BWDP1];
static FLOAT A_bwd_mem[M_BWDP1];
static FLOAT A_t_bwd_mem[M_BWDP1];
static int prev_voicing, prev_bfi, prev_lp_mode;
static FLOAT c_fe, c_int;
static FLOAT prev_filter[M_BWDP1]; /* Previous selected filter */
static int prev_pitch;
static int stat_pitch;
static int pitch_sta, frac_sta;
/* Last backward A(z) for case of unstable filter */
static FLOAT old_A_bwd[M_BWDP1];
static FLOAT old_rc_bwd[2];
static FLOAT gain_pit_mem;
static FLOAT gain_cod_mem;
static FLOAT c_muting;
static int count_bfi;
static int stat_bwd;
static FLOAT freq_prev[MA_NP][M];
/* static memory for frame erase operation */
static int prev_ma; /* previous MA prediction coef.*/
static FLOAT prev_lsp[M]; /* previous LSP vector */
/*--------------------------------------------------------------------------
* init_decod_ld8c - Initialization of variables for the decoder section.
*--------------------------------------------------------------------------
*/
void init_decod_ld8c(void)
{
/* Initialize static pointer */
exc = old_exc + PIT_MAX + L_INTERPOL;
/* Static vectors to zero */
set_zero(old_exc, PIT_MAX+L_INTERPOL);
set_zero(mem_syn, M_BWD);
sharp = SHARPMIN;
prev_t0 = 60;
prev_t0_frac = 0;
gain_code = (F)0.;
gain_pitch = (F)0.;
lsp_decw_resete(freq_prev, prev_lsp, &prev_ma);
set_zero(A_bwd_mem, M_BWDP1);
set_zero(A_t_bwd_mem, M_BWDP1);
A_bwd_mem[0] = (F)1.;
A_t_bwd_mem[0] = (F)1.;
prev_voicing = 0;
prev_bfi = 0;
prev_lp_mode = 0;
c_fe = (F)0.;
c_int = (F)1.1; /* Filter interpolation parameter */
set_zero(prev_filter, M_BWDP1);
prev_filter[0] = (F)1.;
prev_pitch = 30;
stat_pitch = 0;
set_zero(old_A_bwd, M_BWDP1);
set_zero(rexp, M_BWDP1);
old_A_bwd[0] = (F)1.;
set_zero(old_rc_bwd, 2);
gain_pit_mem = (F)0.;
gain_cod_mem = (F)0.;
c_muting = (F)1.;
count_bfi = 0;
stat_bwd = 0;
/* for G.729B */
seed_fer = (INT16)21845;
past_ftyp = 3;
seed = INIT_SEED;
sid_sav = (FLOAT)0.;
init_lsfq_noise();
return;
}
/*--------------------------------------------------------------------------
* decod_ld8c - decoder
*--------------------------------------------------------------------------
*/
void decod_ld8c(
int parm[], /* (i) : vector of synthesis parameters
parm[0] = bad frame indicator (bfi) */
int voicing, /* (i) : voicing decision from previous frame */
FLOAT synth_buf[], /* (i/o) : synthesis speech */
FLOAT Az_dec[], /* (o) : decoded LP filter in 2 subframes */
int *t0_first, /* (o) : decoded pitch lag in first subframe */
int *bwd_dominant,/* (o) : bwd dominant indicator */
int *m_pst, /* (o) : LPC order for postfilter */
int *Vad /* output: decoded frame type */
)
{
/* Scalars */
int i, j, i_subfr;
int t0, t0_frac, index;
int bfi;
int lp_mode; /* Backward / Forward mode indication */
FLOAT g_p, g_c; /* fixed and adaptive codebook gain */
int bad_pitch; /* bad pitch indicator */
FLOAT tmp;
FLOAT energy;
int rate;
/* Tables */
FLOAT A_t_bwd[2*M_BWDP1]; /* LPC Backward filter */
FLOAT A_t_fwd[2*MP1]; /* LPC Forward filter */
FLOAT rc_bwd[M_BWD]; /* LPC backward reflection coefficients */
FLOAT r_bwd[M_BWDP1]; /* Autocorrelations (backward) */
FLOAT lsp_new[M]; /* LSPs */
FLOAT code[L_SUBFR]; /* ACELP codevector */
FLOAT exc_phdisp[L_SUBFR]; /* excitation after phase dispersion */
FLOAT *pA_t; /* Pointer on A_t */
int stationnary;
int m_aq;
FLOAT *synth;
int sat_filter;
/* for G.729B */
int ftyp;
FLOAT lsfq_mem[MA_NP][M];
synth = synth_buf + MEM_SYN_BWD;
/* Test bad frame indicator (bfi) */
bfi = *parm++;
/* Test frame type */
ftyp = *parm++;
if(bfi == 1) {
ftyp = past_ftyp;
if(ftyp == 1) ftyp = 0;
parm[-1] = ftyp;
}
*Vad = ftyp;
rate = ftyp - 2;
/* Decoding the Backward/Forward LPC decision */
/* ------------------------------------------ */
if( rate != G729E) lp_mode = 0;
else {
if (bfi != 0) {
lp_mode = prev_lp_mode; /* Frame erased => lp_mode = previous lp_mode */
*parm++ = lp_mode;
}
else {
lp_mode = *parm++;
}
if(prev_bfi != 0) voicing = prev_voicing;
}
if( bfi == 0) {
c_muting = (F)1.;
count_bfi = 0;
}
/* -------------------- */
/* Backward LP analysis */
/* -------------------- */
if (rate == G729E) {
/* LPC recursive Window as in G728 */
autocorr_hyb_window(synth_buf, r_bwd, rexp); /* Autocorrelations */
lag_window_bwd(r_bwd); /* Lag windowing */
/* Levinson (as in G729) */
levinsone(M_BWD, r_bwd, &A_t_bwd[M_BWDP1], rc_bwd,
old_A_bwd, old_rc_bwd );
/* Tests saturation of A_t_bwd */
sat_filter = 0;
for (i=M_BWDP1; i<2*M_BWDP1; i++) if (A_t_bwd[i] >= (F)8.) sat_filter = 1;
if (sat_filter == 1) copy(A_t_bwd_mem, &A_t_bwd[M_BWDP1], M_BWDP1);
else copy(&A_t_bwd[M_BWDP1], A_t_bwd_mem, M_BWDP1);
/* Additional bandwidth expansion on backward filter */
weight_az(&A_t_bwd[M_BWDP1], GAMMA_BWD, M_BWD, &A_t_bwd[M_BWDP1]);
}
/*--------------------------------------------------*
* Update synthesis signal for next frame. *
*--------------------------------------------------*/
copy(&synth_buf[L_FRAME], &synth_buf[0], MEM_SYN_BWD);
if(lp_mode == 1) {
if ((c_fe != (F)0.)) {
/* Interpolation of the backward filter after a bad frame */
/* A_t_bwd(z) = c_fe . A_bwd_mem(z) + (1 - c_fe) . A_t_bwd(z) */
/* ---------------------------------------------------------- */
tmp = (F)1. - c_fe;
pA_t = A_t_bwd + M_BWDP1;
for (i=0; i3))
copy(&A_t_bwd[M_BWDP1], A_bwd_mem, M_BWDP1);
/* for G.729B */
/* Processing non active frames (SID & not transmitted: ftyp = 1 or 0) */
if(ftyp < 2) {
/* get_decfreq_prev(lsfq_mem); */
for (i=0; i PIT_MAX) {
prev_t0 = PIT_MAX;
}
}
}
*t0_first = t0; /* If first frame */
}
else { /* second subframe */
if( bfi == 0) {
dec_lag3cp(index, PIT_MIN, PIT_MAX, i_subfr, &t0, &t0_frac, rate);
prev_t0 = t0;
prev_t0_frac = t0_frac;
}
else {
t0 = prev_t0;
if (rate == G729E) {
t0_frac = prev_t0_frac;
}
else {
t0_frac = 0;
prev_t0++;
if(prev_t0 > PIT_MAX) prev_t0 = PIT_MAX;
}
}
}
/*-------------------------------------------------*
* - Find the adaptive codebook vector. *
*-------------------------------------------------*/
pred_lt_3(&exc[i_subfr], t0, t0_frac, L_SUBFR);
/* --------------------------------- */
/* pitch tracking for frame erasures */
/* --------------------------------- */
if( rate == G729E) {
track_pit(&prev_t0, &prev_t0_frac, &prev_pitch, &stat_pitch,
&pitch_sta, &frac_sta);
}
else {
i = prev_t0;
j = prev_t0_frac;
track_pit(&i, &j, &prev_pitch, &stat_pitch,
&pitch_sta, &frac_sta);
}
/*-------------------------------------------------------*
* - Decode innovative codebook. *
*-------------------------------------------------------*/
if(bfi != 0) { /* Bad frame */
parm[0] = (int)random_g729c(&seed_fer);
parm[1] = (int)random_g729c(&seed_fer);
if (rate == G729E) {
parm[2] = (int)random_g729c(&seed_fer);
parm[3] = (int)random_g729c(&seed_fer);
parm[4] = (int)random_g729c(&seed_fer);
}
}
stationnary = 0; /* to avoid visual warning */
if (rate == G729) {
/* case 8 kbps */
decod_ACELP(parm[1], parm[0], code);
parm += 2;
/* for gain decoding in case of frame erasure */
stat_bwd = 0;
stationnary = 0;
}
else if (rate == G729D) {
/* case 8 kbps */
decod_ACELP64(parm[1], parm[0], code);
parm += 2;
/* for gain decoding in case of frame erasure */
stat_bwd = 0;
stationnary = 0;
}
else if (rate == G729E) {
/* case 11.8 kbps */
if (lp_mode == 0) {
dec_ACELP_10i40_35bits(parm, code);
/* for gain decoding in case of frame erasure */
stat_bwd = 0;
stationnary = 0;
}
else {
dec_ACELP_12i40_44bits(parm, code);
/* for gain decoding in case of frame erasure */
stat_bwd++;
if (stat_bwd >= 30) {
stationnary = 1;
stat_bwd = 30;
}
else stationnary = 0;
}
parm += 5;
}
/*-------------------------------------------------------*
* - Add the fixed-gain pitch contribution to code[]. *
*-------------------------------------------------------*/
for (i = t0; i < L_SUBFR; i++) code[i] += sharp * code[i-t0];
/*-------------------------------------------------*
* - Decode pitch and codebook gains. *
*-------------------------------------------------*/
index = *parm++; /* index of energy VQ */
if (rate == G729D)
dec_gain_6k(index, code, L_SUBFR, bfi, &gain_pitch, &gain_code);
else
dec_gaine(index, code, L_SUBFR, bfi, &gain_pitch, &gain_code, rate,
gain_pit_mem, gain_cod_mem, &c_muting, count_bfi, stationnary);
/*-------------------------------------------------------------*
* - Update previous gains
*-------------------------------------------------------------*/
gain_pit_mem = gain_pitch;
gain_cod_mem = gain_code;
/*-------------------------------------------------------------*
* - Update pitch sharpening "sharp" with quantized gain_pitch *
*-------------------------------------------------------------*/
sharp = gain_pitch;
if (sharp > SHARPMAX) sharp = SHARPMAX;
if (sharp < SHARPMIN) sharp = SHARPMIN;
/*-------------------------------------------------------*
* - Find the total excitation. *
* - Find synthesis speech corresponding to exc[]. *
*-------------------------------------------------------*/
if(bfi != 0) { /* Bad frame */
count_bfi++;
if (voicing == 0 ) {
g_p = (F)0.;
g_c = gain_code;
}
else {
g_p = gain_pitch;
g_c = (F)0.;
}
}
else {
g_p = gain_pitch;
g_c = gain_code;
}
for (i = 0; i < L_SUBFR; i++) {
exc[i+i_subfr] = g_p * exc[i+i_subfr] + g_c * code[i];
}
if (rate == G729D) {
PhDisp(&exc[i_subfr], exc_phdisp, gain_code, gain_pitch, code);
syn_filte(m_aq, pA_t, exc_phdisp, &synth[i_subfr], L_SUBFR,
&mem_syn[M_BWD-m_aq], 0);
}
else {
syn_filte(m_aq, pA_t, &exc[i_subfr], &synth[i_subfr], L_SUBFR,
&mem_syn[M_BWD-m_aq], 0);
/* Updates state machine for phase dispersion in
6.4 kbps mode, if running at other rate */
Update_PhDisp(gain_pitch, gain_code);
}
copy(&synth[i_subfr+L_SUBFR-M_BWD], mem_syn, M_BWD);
pA_t += m_aq+1; /* interpolated LPC parameters for next subframe */
}
}
/*------------*
* For G729b
*-----------*/
if(bfi == 0) {
sid_sav = (FLOAT)0.0;
for(i=0; i= (F)40.) tst_bwd_dominant(bwd_dominant, lp_mode);
/*--------------------------------------------------*
* Update signal for next frame. *
* -> shift to the left by L_FRAME exc[] *
*--------------------------------------------------*/
copy(&old_exc[L_FRAME], &old_exc[0], PIT_MAX+L_INTERPOL);
if( lp_mode == 0) {
copy(A_t_fwd, Az_dec, 2*MP1);
*m_pst = M;
}
else {
copy(A_t_bwd, Az_dec, 2*M_BWDP1);
*m_pst = M_BWD;
}
prev_bfi = bfi;
prev_lp_mode = lp_mode;
prev_voicing = voicing;
if (bfi != 0) c_fe = (F)1.;
else {
if (lp_mode == 0) c_fe = 0;
else {
if (*bwd_dominant == 1) c_fe -= (F)0.1;
else c_fe -= (F)0.5;
if (c_fe < 0) c_fe= 0;
}
}
return;
}