www.pudn.com > p_voice.rar > CODLD8CP.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 : CODLD8CP.C 
*/ 
 
/*-----------------------------------------------------------------* 
 *   Functions coder_ld8c and init_coder_ld8c                      * 
 *             ~~~~~~~~~~     ~~~~~~~~~~~~~~~                      * 
 *-----------------------------------------------------------------*/ 
#include  
#include "typedef.h" 
#include "ld8k.h" 
#include "ld8cp.h" 
#include "tab_ld8k.h" 
#include "vad.h" 
#include "dtx.h" 
#include "sid.h" 
/*-----------------------------------------------------------* 
 *    Coder constant parameters (defined in "ld8k.h")        * 
 *-----------------------------------------------------------* 
 *   L_WINDOW    : LPC analysis window size.                 * 
 *   L_NEXT      : Samples of next frame needed for autocor. * 
 *   L_FRAME     : Frame size.                               * 
 *   L_SUBFR     : Sub-frame size.                           * 
 *   M           : LPC order.                                * 
 *   MP1         : LPC order+1                               * 
 *   L_TOTAL     : Total size of speech buffer.              * 
 *   PIT_MIN     : Minimum pitch lag.                        * 
 *   PIT_MAX     : Maximum pitch lag.                        * 
 *   L_INTERPOL  : Length of filter for interpolation        * 
 *-----------------------------------------------------------*/ 
 
 /*--------------------------------------------------------* 
  *         Static memory allocation.                      * 
  *--------------------------------------------------------*/ 
 
/* Speech vector */ 
static FLOAT old_speech[L_TOTAL]; 
static FLOAT *speech, *p_window; 
FLOAT  *new_speech;                       /* Global variable */ 
 
/* Weighted speech vector */ 
static FLOAT old_wsp[L_FRAME+PIT_MAX]; 
static FLOAT *wsp; 
 
/* Excitation vector */ 
static FLOAT old_exc[L_FRAME+PIT_MAX+L_INTERPOL]; 
static FLOAT *exc; 
 
/* Zero vector */ 
static FLOAT ai_zero[L_SUBFR+M_BWDP1]; 
static FLOAT *zero; 
 
/* 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 lsp_old_q[M]; 
 
/* Filter's memory */ 
static FLOAT mem_syn[M_BWD], mem_w0[M_BWD], mem_w[M_BWD]; 
static FLOAT mem_err[M_BWD+L_SUBFR], *error; 
static FLOAT pit_sharp; 
 
/* For G.729B */ 
/* DTX variables */ 
static int pastVad; 
static int ppastVad; 
static INT16 seed; 
 
/* for G.729E */ 
/* for the backward analysis */ 
static FLOAT prev_filter[M_BWDP1]; /* Previous selected filter */ 
 
static FLOAT rexp[M_BWDP1]; 
static FLOAT synth[L_ANA_BWD]; 
static FLOAT *synth_ptr; 
static int prev_lp_mode ; 
static FLOAT gamma1[2], gamma2[2];       /* Weighting factor for the 2 subframes */ 
static FLOAT A_t_bwd_mem[M_BWDP1]; 
static int bwd_dominant; 
static FLOAT C_int;              /* See file bwfw.c */ 
static INT16 glob_stat;  /* Mesure of global stationnarity */ 
static INT16 stat_bwd;       /* Nbre of consecutive backward frames */ 
static INT16 val_stat_bwd;   /* Value associated with stat_bwd */ 
 
/* Last backward A(z) for case of unstable filter */ 
static FLOAT old_A_bwd[M_BWDP1]; 
static FLOAT old_rc_bwd[2]; 
/* Last forkward A(z) for case of unstable filter */ 
static FLOAT old_A_fwd[MP1]; 
static FLOAT old_rc_fwd[2]; 
static FLOAT freq_prev[MA_NP][M];    /* previous LSP vector       */ 
 
static int lag_buf[5]={20,20, 20, 20,20}; 
static FLOAT pgain_buf[5]={(F)0.7,(F)0.7, (F)0.7, (F)0.7,(F)0.7}; 
#define         AVG(a,b,c,d) (int)(((a)+(b)+(c)+(d))/((F)4.0)+(F)0.5) 
 
/*---------------------------------------------------------------------------- 
 * init_coder_ld8c - initialization of variables for the encoder 
 *---------------------------------------------------------------------------- 
 */ 
 
void init_coder_ld8c( 
    int dtx_enable   /* input : DTX enable flag */ 
) 
{ 
/*-----------------------------------------------------------------------* 
*      Initialize pointers to speech vector.                            * 
*                                                                       * 
*                                                                       * 
*   |--------------------|-------------|-------------|------------|     * 
*     previous speech           sf1           sf2         L_NEXT        * 
*                                                                       * 
*   <----------------  Total speech vector (L_TOTAL)   ----------->     * 
*   |   <------------  LPC analysis window (L_WINDOW)  ----------->     * 
*   |   |               <-- present frame (L_FRAME) -->                 * 
* old_speech            |              <-- new speech (L_FRAME) -->     * 
*     p_wind            |              |                                * 
*                     speech           |                                * 
*                             new_speech                                * 
*-----------------------------------------------------------------------*/ 
    int   i; 
 
    new_speech = old_speech + L_TOTAL - L_FRAME;         /* New speech     */ 
    speech     = new_speech - L_NEXT;                    /* Present frame  */ 
    p_window   = old_speech + L_TOTAL - L_WINDOW;        /* For LPC window */ 
 
    /* Initialize static pointers */ 
    wsp    = old_wsp + PIT_MAX; 
    exc    = old_exc + PIT_MAX + L_INTERPOL; 
    zero   = ai_zero + M_BWDP1; 
    error  = mem_err + M_BWD; 
 
    /* Static vectors to zero */ 
    set_zero(old_speech, L_TOTAL); 
    set_zero(old_exc, PIT_MAX+L_INTERPOL); 
    set_zero(old_wsp, PIT_MAX); 
    set_zero(mem_syn, M_BWD); 
    set_zero(mem_w,   M_BWD); 
    set_zero(mem_w0,  M_BWD); 
    set_zero(mem_err, M_BWD); 
    set_zero(zero, L_SUBFR); 
    pit_sharp = SHARPMIN; 
     
    /* Initialize lsp_old_q[] */ 
    copy(lsp_old, lsp_old_q, M); 
     
    lsp_encw_resete(freq_prev); 
    init_exc_err(); 
     
    /* For G.729B */ 
    /* Initialize VAD/DTX parameters */ 
    if(dtx_enable == 1) { 
        pastVad = 1; 
        ppastVad = 1; 
        seed = INIT_SEED; 
        vad_init(); 
        init_lsfq_noise(); 
    } 
    /* for G.729E */ 
    /* for the backward analysis */ 
    set_zero(synth, L_ANA_BWD); 
    synth_ptr = synth + MEM_SYN_BWD; 
    prev_lp_mode = 0; 
    bwd_dominant = 0;              /* See file bwfw.c */ 
    C_int = (F)1.1;       /* Filter interpolation parameter */ 
    glob_stat = 10000;  /* Mesure of global stationnarity */ 
    stat_bwd = 0;       /* Nbre of consecutive backward frames */ 
    val_stat_bwd = 0;   /* Value associated with stat_bwd */ 
 
    for(i=0; i, , , ,*/ 
                                  
    /* Scalars */ 
    int   i, j, i_gamma, i_subfr; 
    int   T_op, t0, t0_min, t0_max, t0_frac; 
    int   index, taming; 
    FLOAT gain_pit, gain_code; 
 
    /* for G.729E */ 
    int sat_filter; 
    FLOAT freq_cur[M]; 
     
    /* For G.729B */ 
    FLOAT r_nbe[MP1]; 
    FLOAT lsfq_mem[MA_NP][M]; 
    int Vad; 
    FLOAT Energy_db; 
 
    int avg_lag; 
     
    /*------------------------------------------------------------------------* 
    *  - Perform LPC analysis:                                               * 
    *       * autocorrelation + lag windowing                                * 
    *       * Levinson-durbin algorithm to find a[]                          * 
    *       * convert a[] to lsp[]                                           * 
    *       * quantize and code the LSPs                                     * 
    *       * find the interpolated LSPs and convert to a[] for the 2        * 
    *         subframes (both quantized and unquantized)                     * 
    *------------------------------------------------------------------------*/ 
    /* ------------------- */ 
    /* LP Forward analysis */ 
    /* ------------------- */ 
    autocorr(p_window, NP, r_fwd);                     /* Autocorrelations */ 
    copy(r_fwd, r_nbe, MP1); 
    lag_window(NP, r_fwd);                             /* Lag windowing    */ 
    levinsone(M, r_fwd, &A_t_fwd[MP1], rc_fwd,         /* Levinson Durbin  */ 
        old_A_fwd, old_rc_fwd ); 
    az_lsp(&A_t_fwd[MP1], lsp_new, lsp_old);           /* From A(z) to lsp */ 
 
    /* For G.729B */ 
    /* ------ VAD ------- */ 
    if (dtx_enable == 1) { 
        lsp_lsf(lsp_new, lsf_new, M); 
        vad(rc_fwd[1], lsf_new, r_fwd, p_window, frame, 
            pastVad, ppastVad, &Vad, &Energy_db); 
 
        musdetect( rate, r_fwd[0],rc_fwd, lag_buf , pgain_buf, 
                      prev_lp_mode, frame,pastVad, &Vad, Energy_db); 
 
        update_cng(r_nbe, Vad); 
    } 
    else Vad = 1; 
 
    /* -------------------- */ 
    /* LP Backward analysis */ 
    /* -------------------- */ 
    if ( (rate-(1-Vad))== G729E) { 
 
        /* LPC recursive Window as in G728 */ 
        autocorr_hyb_window(synth, r_bwd, rexp); /* Autocorrelations */ 
        lag_window_bwd(r_bwd);  /* Lag windowing    */ 
        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[L_FRAME], &synth[0], MEM_SYN_BWD); 
 
    /*--------------------------------------------------------------------* 
    * Find interpolated LPC parameters in all subframes unquantized.      * 
    * The interpolated parameters are in array A_t[] of size (M+1)*4      * 
    *---------------------------------------------------------------------*/ 
    if( prev_lp_mode == 0) { 
        int_lpc(lsp_old, lsp_new, lsf_int, lsf_new, A_t_fwd); 
    } 
    else { 
        /* no interpolation */ 
        /* unquantized */ 
        lsp_az(lsp_new, A_t_fwd);           /* Subframe 1 */ 
        lsp_lsf(lsp_new, lsf_new, M);  /* transformation from LSP to LSF (freq.domain) */ 
        copy(lsf_new, lsf_int, M);      /* Subframe 1 */ 
    } 
 
    if(Vad == 1) { 
        /* ---------------- */ 
        /* LSP quantization */ 
        /* ---------------- */ 
        qua_lspe(lsp_new, lsp_new_q, code_lsp, freq_prev, freq_cur); 
 
        /*-------------------------------------------------------------------* 
        * Find interpolated LPC parameters in all subframes quantized.       * 
        * and the quantized interpolated parameters are in array Aq_t[]      * 
        *--------------------------------------------------------------------*/ 
        if( prev_lp_mode == 0) { 
            int_qlpc(lsp_old_q, lsp_new_q, A_t_fwd_q); 
        } 
        else { 
            /* no interpolation */ 
            lsp_az(lsp_new_q, &A_t_fwd_q[MP1]);              /* Subframe 2 */ 
            copy(&A_t_fwd_q[MP1], A_t_fwd_q, MP1);      /* Subframe 1 */ 
        } 
        /*---------------------------------------------------------------------* 
        * - Decision for the switch Forward / Backward                        * 
        *---------------------------------------------------------------------*/ 
        if(rate == G729E) { 
            set_lpc_mode(speech, A_t_fwd_q, A_t_bwd, &lp_mode,  
            lsp_new, lsp_old, &bwd_dominant, prev_lp_mode, prev_filter, &C_int, 
                &glob_stat, &stat_bwd, &val_stat_bwd); 
        } 
        else  
             update_bwd( &lp_mode, &bwd_dominant, &C_int, &glob_stat); 
    } 
    else  
         update_bwd( &lp_mode, &bwd_dominant, &C_int, &glob_stat); 
 
    /* ---------------------------------- */ 
    /* update the LSPs for the next frame */ 
    /* ---------------------------------- */ 
    copy(lsp_new, lsp_old, M); 
 
    /*----------------------------------------------------------------------* 
    * - Find the weighted input speech w_sp[] for the whole speech frame   * 
    *----------------------------------------------------------------------*/ 
    if(lp_mode == 0) { 
        m_ap = M; 
        if (bwd_dominant == 0) Ap = A_t_fwd; 
        else Ap = A_t_fwd_q; 
        perc_var(gamma1, gamma2, lsf_int, lsf_new, rc_fwd); 
    } 
    else { 
        if (bwd_dominant == 0) { 
            m_ap = M; 
            Ap = A_t_fwd; 
        } 
        else { 
            m_ap = M_BWD; 
            Ap = A_t_bwd; 
        } 
        perc_vare(gamma1, gamma2, bwd_dominant); 
    } 
    pAp = Ap; 
    for (i=0; i<2; i++) { 
        weight_az(pAp, gamma1[i], m_ap, Ap1); 
        weight_az(pAp, gamma2[i], m_ap, Ap2); 
        residue(m_ap, Ap1, &speech[i*L_SUBFR], &wsp[i*L_SUBFR], L_SUBFR); 
        syn_filte(m_ap,  Ap2, &wsp[i*L_SUBFR], &wsp[i*L_SUBFR], L_SUBFR, 
            &mem_w[M_BWD-m_ap], 0); 
        for(j=0; j PIT_MAX) { 
        t0_max = PIT_MAX; 
        t0_min = t0_max - 6; 
    } 
     
    /*------------------------------------------------------------------------* 
    *          Loop for every subframe in the analysis frame                 * 
    *------------------------------------------------------------------------* 
    *  To find the pitch and innovation parameters. The subframe size is     * 
    *  L_SUBFR and the loop is repeated 2 times.                             * 
    *     - find the weighted LPC coefficients                               * 
    *     - find the LPC residual signal res[]                               * 
    *     - compute the target signal for pitch search                       * 
    *     - compute impulse response of weighted synthesis filter (h1[])     * 
    *     - find the closed-loop pitch parameters                            * 
    *     - encode the pitch delay                                           * 
    *     - update the impulse response h1[] by including fixed-gain pitch   * 
    *     - find target vector for codebook search                           * 
    *     - codebook search                                                  * 
    *     - encode codebook address                                          * 
    *     - VQ of pitch and codebook gains                                   * 
    *     - find synthesis speech                                            * 
    *     - update states of weighting filter                                * 
    *------------------------------------------------------------------------*/ 
    pAp  = Ap;     /* pointer to interpolated "unquantized"LPC parameters           */ 
    pAq = Aq;      /* pointer to interpolated "quantized" LPC parameters */ 
         
    i_gamma = 0; 
     
    for (i_subfr = 0;  i_subfr < L_FRAME; i_subfr += L_SUBFR) { 
         
    /*---------------------------------------------------------------* 
    * Find the weighted LPC coefficients for the weighting filter.  * 
        *---------------------------------------------------------------*/ 
        weight_az(pAp, gamma1[i_gamma], m_ap, Ap1); 
        weight_az(pAp, gamma2[i_gamma], m_ap, Ap2); 
        i_gamma++; 
         
        /*---------------------------------------------------------------* 
        * Compute impulse response, h1[], of weighted synthesis filter  * 
        *---------------------------------------------------------------*/ 
        for (i = 0; i <=m_ap; i++) ai_zero[i] = Ap1[i]; 
        syn_filte(m_aq,  pAq, ai_zero, h1, L_SUBFR, zero, 0); 
        syn_filte(m_ap,  Ap2, h1, h1, L_SUBFR, zero, 0); 
         
        /*------------------------------------------------------------------------* 
        *                                                                        * 
        *          Find the target vector for pitch search:                      * 
        *          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                       * 
        *                                                                        * 
        *              |------|  res[n]                                          * 
        *  speech[n]---| A(z) |--------                                          * 
        *              |------|       |   |--------| error[n]  |------|          * 
        *                    zero -- (-)--| 1/A(z) |-----------| W(z) |-- target * 
        *                    exc          |--------|           |------|          * 
        *                                                                        * 
        * Instead of subtracting the zero-input response of filters from         * 
        * the weighted input speech, the above configuration is used to          * 
        * compute the target vector. This configuration gives better performance * 
        * with fixed-point implementation. The memory of 1/A(z) is updated by    * 
        * filtering (res[n]-exc[n]) through 1/A(z), or simply by subtracting     * 
        * the synthesis speech from the input speech:                            * 
        *    error[n] = speech[n] - syn[n].                                      * 
        * The memory of W(z) is updated by filtering error[n] through W(z),      * 
        * or more simply by subtracting the filtered adaptive and fixed          * 
        * codebook excitations from the target:                                  * 
        *     target[n] - gain_pit*y1[n] - gain_code*y2[n]                       * 
        * as these signals are already available.                                * 
        *                                                                        * 
        *------------------------------------------------------------------------*/ 
        residue(m_aq, pAq, &speech[i_subfr], &exc[i_subfr], L_SUBFR);   /* LPC residual */ 
        for (i=0; i> 1) & 0x0001); 
            } 
            ana++; 
        } 
        /*-----------------------------------------------------------------* 
        *   - find unity gain pitch excitation (adaptive codebook entry)  * 
        *     with fractional interpolation.                              * 
        *   - find filtered pitch exc. y1[]=exc[] convolve with h1[])     * 
        *   - compute pitch gain and limit between 0 and 1.2              * 
        *   - update target vector for codebook search                    * 
        *   - find LTP residual.                                          * 
        *-----------------------------------------------------------------*/ 
        pred_lt_3(&exc[i_subfr], t0, t0_frac, L_SUBFR); 
                 
        convolve(&exc[i_subfr], h1, y1, L_SUBFR); 
         
        gain_pit = g_pitch(xn, y1, g_coeff, L_SUBFR); 
         
        /* clip pitch gain if taming is necessary */ 
        taming = test_err(t0, t0_frac); 
 
        if(taming == 1){ 
            if ( gain_pit>  GPCLIP) { 
                gain_pit = GPCLIP; 
            } 
        } 
         
        for (i = 0; i < L_SUBFR; i++) 
            xn2[i] = xn[i] - y1[i]*gain_pit; 
         
        /*-----------------------------------------------------* 
        * - Innovative codebook search.                       * 
        *-----------------------------------------------------*/ 
         
        switch (rate) { 
                         
            case G729:    /* 8 kbit/s */ 
            {  
                index = ACELP_codebook(xn2, h1, t0, pit_sharp, i_subfr, code, 
                    y2, &i); 
                *ana++ = index;        /* Positions index */ 
                *ana++ = i;            /* Signs index     */ 
                break; 
            } 
 
            case G729D:    /* 6.4 kbit/s */ 
            { 
                index = ACELP_codebook64(xn2, h1, t0, pit_sharp, code, y2, &i); 
                *ana++ = index;        /* Positions index */ 
                *ana++ = i;            /* Signs index     */ 
                break; 
            } 
                 
            case G729E:    /* 11.8 kbit/s */ 
            { 
            /*-----------------------------------------------------------------* 
            * Include fixed-gain pitch contribution into impulse resp. h[]    * 
                *-----------------------------------------------------------------*/ 
                if(t0 < L_SUBFR) { 
                    for (i = t0; i < L_SUBFR; i++) { 
                        h1[i] += pit_sharp * h1[i-t0]; 
                    } 
                } 
                     
                /* calculate residual after long term prediction */ 
                for (i = 0; i < L_SUBFR;  i++) 
                    res2[i] -= gain_pit*exc[i+i_subfr]; 
                if (lp_mode == 0) 
                    ACELP_10i40_35bits(xn2, res2, h1, code, y2, ana); /* Forward */ 
                else 
                    ACELP_12i40_44bits(xn2, res2, h1, code, y2, ana); /* Backward */ 
                ana += 5; 
                 
                /*-----------------------------------------------------------------* 
                * Include fixed-gain pitch contribution into code[].              * 
                *-----------------------------------------------------------------*/ 
                if(t0 < L_SUBFR) 
                    for (i = t0; i < L_SUBFR; i++) 
                        code[i] += pit_sharp * code[i-t0]; 
                     
                break; 
            } 
             
            default : { 
                printf("Unrecognized bit rate\n"); 
                exit(-1); 
            } 
                 
 
        }  /* end of switch */ 
                 
         
        /*-----------------------------------------------------* 
        * - Quantization of gains.                            * 
        *-----------------------------------------------------*/ 
        corr_xy2( xn, y1, y2, g_coeff); 
         
        if (rate == G729D)  
            index = qua_gain_6k(code, g_coeff, L_SUBFR, &gain_pit, &gain_code, taming ); 
        else  
            index = qua_gain(code, g_coeff, L_SUBFR, &gain_pit, &gain_code, taming); 
         
        *ana++ = index; 
         
        /*------------------------------------------------------------* 
        * - Update pitch sharpening  with quantized gain_pit          * 
        *------------------------------------------------------------*/ 
        for (i= 0; i< 4; i++) 
            pgain_buf[i] = pgain_buf[i+1]; 
        pgain_buf[4] = gain_pit; 
 
        pit_sharp = gain_pit; 
        if (pit_sharp > SHARPMAX) pit_sharp = SHARPMAX; 
        if (pit_sharp < SHARPMIN) pit_sharp = SHARPMIN; 
         
        /*------------------------------------------------------* 
        * - Find the total excitation                          * 
        * - find synthesis speech corresponding to exc[]       * 
        * - update filters memories for finding the target     * 
        *   vector in the next subframe                        * 
        *   (update error[-m..-1] and mem_w_err[])             * 
        *   update error function for taming process           * 
        *------------------------------------------------------*/ 
        for (i = 0; i < L_SUBFR;  i++) 
            exc[i+i_subfr] = gain_pit*exc[i+i_subfr] + gain_code*code[i]; 
         
        update_exc_err(gain_pit, t0); 
                 
        syn_filte(m_aq,  pAq, &exc[i_subfr], &synth_ptr[i_subfr], L_SUBFR, 
            &mem_syn[M_BWD-m_aq], 0); 
        for(j=0; j shift to the left by L_FRAME:                 * 
    *     speech[], wsp[] and  exc[]                   * 
    *--------------------------------------------------*/ 
    copy(&old_speech[L_FRAME], &old_speech[0], L_TOTAL-L_FRAME); 
    copy(&old_wsp[L_FRAME], &old_wsp[0], PIT_MAX); 
    copy(&old_exc[L_FRAME], &old_exc[0], PIT_MAX+L_INTERPOL); 
    prev_lp_mode = lp_mode; 
    return; 
}