Пример #1
0
/*----------------------------------------------------------------------------
; FUNCTION CODE
----------------------------------------------------------------------------*/
void d_gain_code(
    gc_predState *pred_state, /* i/o : MA predictor state               */
    enum Mode mode,           /* i   : AMR mode (MR795 or MR122)        */
    Word16 index,             /* i   : received quantization index      */
    Word16 code[],            /* i   : innovation codevector            */
    Word16 *gain_code,        /* o   : decoded innovation gain          */
    Flag   *pOverflow
)
{
    Word16 gcode0, exp, frac;
    const Word16 *p;
    Word16 qua_ener_MR122, qua_ener;
    Word16 exp_inn_en;
    Word16 frac_inn_en;
    Word32 L_tmp;
    Word16 tbl_tmp;
    Word16 temp;
    /*-------------- Decode codebook gain ---------------*/

    /*-------------------------------------------------------------------*
     *  predict codebook gain                                            *
     *  ~~~~~~~~~~~~~~~~~~~~~                                            *
     *  gc0     = Pow2(int(d)+frac(d))                                   *
     *          = 2^exp + 2^frac                                         *
     *                                                                   *
     *-------------------------------------------------------------------*/

    gc_pred(pred_state, mode, code, &exp, &frac,
            &exp_inn_en, &frac_inn_en, pOverflow);

    tbl_tmp = add(add(index, index, pOverflow), index, pOverflow);

    p = &qua_gain_code[tbl_tmp];

    /* Different scalings between MR122 and the other modes */
    temp = sub((Word16)mode, (Word16)MR122, pOverflow);
    if (temp == 0)
    {
        gcode0 = (Word16)(Pow2(exp, frac, pOverflow));    /* predicted gain */
        gcode0 = shl(gcode0, 4, pOverflow);
        *gain_code = shl(mult(gcode0, *p++, pOverflow), 1, pOverflow);
    }
    else
    {
        gcode0 = (Word16)(Pow2(14, frac, pOverflow));
        L_tmp = L_mult(*p++, gcode0, pOverflow);
        L_tmp = L_shr(L_tmp, sub(9, exp, pOverflow), pOverflow);
        *gain_code = extract_h(L_tmp);          /* Q1 */
    }

    /*-------------------------------------------------------------------*
     *  update table of past quantized energies                          *
     *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                          *
     *-------------------------------------------------------------------*/
    qua_ener_MR122 = *p++;
    qua_ener = *p++;
    gc_pred_update(pred_state, qua_ener_MR122, qua_ener);

    return;
}
Пример #2
0
/*
------------------------------------------------------------------------------
 FUNCTION NAME: ec_gain_code
------------------------------------------------------------------------------
 INPUT AND OUTPUT DEFINITIONS

 Inputs:
  st = pointer to a pointer to a structure containing code state data of
       stucture type ec_gain_codeState
  pred_state = pointer to MA predictor state of type gc_predState
  state  = state of the state machine of type Word16
  gain_code = pointer to decoded innovation gain of type Word16
  pOverflow = pointer to overflow indicator of type Flag

 Outputs:
  st = pointer to a pointer to a structure containing code state data of
       stucture type ec_gain_codeState
  pred_state = pointer to MA predictor state of type gc_predState
  pOverflow = 1 if there is an overflow else it is zero.

 Returns:
    None.

 Global Variables Used:
    None.

 Local Variables Needed:
    None.

------------------------------------------------------------------------------
 FUNCTION DESCRIPTION

This function does error concealment using the codebook. Call this function
only in BFI (instead of normal gain decoding function).

------------------------------------------------------------------------------
 REQUIREMENTS

 None.

------------------------------------------------------------------------------
 REFERENCES

 ec_gain.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001

------------------------------------------------------------------------------
 PSEUDO-CODE

    static const Word16 cdown[7] =
    {
        32767, 32112, 32112, 32112,
        32112, 32112, 22937
    };

    Word16 tmp;
    Word16 qua_ener_MR122;
    Word16 qua_ener;

    // calculate median of last five gain values
    tmp = gmed_n (st->gbuf,5);

    // new gain = minimum(median, past_gain) * cdown[state]
    if (sub (tmp, st->past_gain_code) > 0)
    {
        tmp = st->past_gain_code;
    }
    tmp = mult (tmp, cdown[state]);
    *gain_code = tmp;

    // update table of past quantized energies with average of
    // current values

    gc_pred_average_limited(pred_state, &qua_ener_MR122, &qua_ener);
    gc_pred_update(pred_state, qua_ener_MR122, qua_ener);
}

------------------------------------------------------------------------------
 CAUTION [optional]
 [State any special notes, constraints or cautions for users of this function]

------------------------------------------------------------------------------
*/
void ec_gain_code(
    ec_gain_codeState *st,    /* i/o : State struct                     */
    gc_predState *pred_state, /* i/o : MA predictor state               */
    Word16 state,             /* i   : state of the state machine       */
    Word16 *gain_code,        /* o   : decoded innovation gain          */
    Flag   *pOverflow
)
{
    static const Word16 cdown[7] =
    {
        32767, 32112, 32112, 32112,
        32112, 32112, 22937
    };

    Word16 tmp;
    Word16 qua_ener_MR122;
    Word16 qua_ener;

    /* calculate median of last five gain values */
    tmp = gmed_n(st->gbuf, 5);

    /* new gain = minimum(median, past_gain) * cdown[state] */
    if (sub(tmp, st->past_gain_code, pOverflow) > 0)
    {
        tmp = st->past_gain_code;
    }
    tmp = mult(tmp, cdown[state], pOverflow);
    *gain_code = tmp;

    /* update table of past quantized energies with average of
     * current values
     */
    gc_pred_average_limited(pred_state, &qua_ener_MR122, &qua_ener, pOverflow);
    gc_pred_update(pred_state, qua_ener_MR122, qua_ener);
}
Пример #3
0
/*
********************************************************************************
*                         PRIVATE PROGRAM CODE
********************************************************************************
*/
void MR475_quant_store_results(

    gc_predState *pred_st, /* i/o: gain predictor state struct               */
    const Word16 *p,       /* i  : pointer to selected quantizer table entry */
    Word16 gcode0,         /* i  : predicted CB gain,     Q(14 - exp_gcode0) */
    Word16 exp_gcode0,     /* i  : exponent of predicted CB gain,        Q0  */
    Word16 *gain_pit,      /* o  : Pitch gain,                           Q14 */
    Word16 *gain_cod       /* o  : Code gain,                            Q1  */
)
{

    Word16 g_code, exp, frac, tmp;
    Word32 L_tmp;

    Word16 qua_ener_MR122; /* o  : quantized energy error, MR122 version Q10 */
    Word16 qua_ener;       /* o  : quantized energy error,               Q10 */

    /* Read the quantized gains */
    *gain_pit = *p++;                
    g_code = *p++;                   

    /*------------------------------------------------------------------*
     *  calculate final fixed codebook gain:                            *
     *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                            *
     *                                                                  *
     *   gc = gc0 * g                                                   *
     *------------------------------------------------------------------*/

    L_tmp = L_mult(g_code, gcode0);
    L_tmp = L_shr(L_tmp, sub(10, exp_gcode0));
    *gain_cod = extract_h(L_tmp);

    /*------------------------------------------------------------------*
     *  calculate predictor update values and update gain predictor:    *
     *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~    *
     *                                                                  *
     *   qua_ener       = log2(g)                                       *
     *   qua_ener_MR122 = 20*log10(g)                                   *
     *------------------------------------------------------------------*/

    Log2 (L_deposit_l (g_code), &exp, &frac); /* Log2(x Q12) = log2(x) + 12 */
    exp = sub(exp, 12);

    tmp = shr_r (frac, 5);
    qua_ener_MR122 = add (tmp, shl (exp, 10));

    L_tmp = Mpy_32_16(exp, frac, 24660); /* 24660 Q12 ~= 6.0206 = 20*log10(2) */
    qua_ener = round (L_shl (L_tmp, 13)); /* Q12 * Q0 = Q13 -> Q10 */

    gc_pred_update(pred_st, qua_ener_MR122, qua_ener);
}
Пример #4
0
/*************************************************************************
 *
 *   FUNCTION:  Dec_gain()
 *
 *   PURPOSE: Decode the pitch and codebook gains
 *
 ************************************************************************/
void Dec_gain(
    gc_predState *pred_state, /* i/o: MA predictor state           */
    enum Mode mode,           /* i  : AMR mode                     */
    Word16 index,             /* i  : index of quantization.       */
    Word16 code[],            /* i  : Innovative vector.           */
    Word16 evenSubfr,         /* i  : Flag for even subframes      */     
    Word16 * gain_pit,        /* o  : Pitch gain.                  */
    Word16 * gain_cod         /* o  : Code gain.                   */
)
{
    const Word16 *p;
    Word16 frac, gcode0, exp, qua_ener, qua_ener_MR122;
    Word16 g_code;
    Word32 L_tmp;
    
    /* Read the quantized gains (table depends on mode) */
    index = shl (index, 2);
    
    test(); test(); test();
    if (    sub (mode, MR102) == 0
         || sub (mode, MR74) == 0
         || sub (mode, MR67) == 0)
    {
        p = &table_gain_highrates[index];                  move16 ();
        
        *gain_pit = *p++;                                  move16 ();
        g_code = *p++;                                     move16 ();
        qua_ener_MR122 = *p++;                             move16 ();
        qua_ener = *p;                                     move16 ();
    }
    else
    {
        test();
        if (sub (mode, MR475) == 0)
        {
            index = add (index, shl(sub(1, evenSubfr), 1));
            p = &table_gain_MR475[index];                  move16 ();
            
            *gain_pit = *p++;                              move16 ();
            g_code = *p++;                                 move16 ();
            
            /*---------------------------------------------------------*
             *  calculate predictor update values (not stored in 4.75  *
             *  quantizer table to save space):                        *
             *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  *
             *                                                         *
             *   qua_ener       = log2(g)                              *
             *   qua_ener_MR122 = 20*log10(g)                          *
             *---------------------------------------------------------*/

            /* Log2(x Q12) = log2(x) + 12 */
            Log2 (L_deposit_l (g_code), &exp, &frac); 
            exp = sub(exp, 12);
    
            qua_ener_MR122 = add (shr_r (frac, 5), shl (exp, 10));
    
            /* 24660 Q12 ~= 6.0206 = 20*log10(2) */
            L_tmp = Mpy_32_16(exp, frac, 24660);
            qua_ener = round (L_shl (L_tmp, 13)); /* Q12 * Q0 = Q13 -> Q10 */
        }
        else
        {
            p = &table_gain_lowrates[index];                move16 ();
            
            *gain_pit = *p++;                               move16 ();
            g_code = *p++;                                  move16 ();
            qua_ener_MR122 = *p++;                          move16 ();
            qua_ener = *p;                                  move16 ();
        }
    }
    
    /*-------------------------------------------------------------------*
     *  predict codebook gain                                            *
     *  ~~~~~~~~~~~~~~~~~~~~~                                            *
     *  gc0     = Pow2(int(d)+frac(d))                                   *
     *          = 2^exp + 2^frac                                         *
     *                                                                   *
     *  gcode0 (Q14) = 2^14*2^frac = gc0 * 2^(14-exp)                    *
     *-------------------------------------------------------------------*/

    gc_pred(pred_state, mode, code, &exp, &frac, NULL, NULL);

    gcode0 = extract_l(Pow2(14, frac));

    /*------------------------------------------------------------------*
     *  read quantized gains, update table of past quantized energies   *
     *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~   *
     *  st->past_qua_en(Q10) = 20 * Log10(g_fac) / constant             *
     *                       = Log2(g_fac)                              *
     *                       = qua_ener                                 *
     *                                           constant = 20*Log10(2) *
     *------------------------------------------------------------------*/

    L_tmp = L_mult(g_code, gcode0);
    L_tmp = L_shr(L_tmp, sub(10, exp));
    *gain_cod = extract_h(L_tmp);

    /* update table of past quantized energies */

    gc_pred_update(pred_state, qua_ener_MR122, qua_ener);

    return;
}
Пример #5
0
//=============================================================================
//函数名称:Dec_gain
//函数功能:解码的音调和码书增益
//=============================================================================
void Dec_gain(
    gc_predState *pred_state, /* i/o: MA predictor state           */
    enum Mode mode,           /* i  : AMR mode                     */
    Word16 index,             /* i  : index of quantization.       */
    Word16 code[],            /* i  : Innovative vector.           */
    Word16 evenSubfr,         /* i  : Flag for even subframes      */
    Word16 * gain_pit,        /* o  : Pitch gain.                  */
    Word16 * gain_cod,        /* o  : Code gain.                   */
    Flag   * pOverflow
)
{
    const Word16 *p;
    Word16 frac;
    Word16 gcode0;
    Word16 exp;
    Word16 qua_ener;
    Word16 qua_ener_MR122;
    Word16 g_code;
    Word32 L_tmp;
    Word16 temp1;
    Word16 temp2;

    /* Read the quantized gains (table depends on mode) */
    //阅读量化收益(表取决于模式)
    index = shl(index, 2, pOverflow);

    if (mode == MR102 || mode == MR74 || mode == MR67)
    {
        p = &table_gain_highrates[index];

        *gain_pit = *p++;
        g_code = *p++;
        qua_ener_MR122 = *p++;
        qua_ener = *p;
    }
    else
    {
        if (mode == MR475)
        {
            index += (1 ^ evenSubfr) << 1; /* evenSubfr is 0 or 1 */

            if (index > (MR475_VQ_SIZE*4 - 2))
            {
                index = (MR475_VQ_SIZE * 4 - 2); /* avoid possible buffer overflow */
            }

            p = &table_gain_MR475[index];

            *gain_pit = *p++;
            g_code = *p++;

            /*---------------------------------------------------------*
             *  calculate predictor update values (not stored in 4.75  *
             *  quantizer table to save space):                        *
             *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  *
             *                                                         *
             *   qua_ener       = log2(g)                              *
             *   qua_ener_MR122 = 20*log10(g)                          *
             *---------------------------------------------------------*/
            //计算预测更新值(不存储在4.75量化表,以节省空间)

            /* Log2(x Q12) = log2(x) + 12 */
            temp1 = (Word16) L_deposit_l(g_code);
            Log2(temp1, &exp, &frac, pOverflow);
            exp = sub(exp, 12, pOverflow);

            temp1 = shr_r(frac, 5, pOverflow);
            temp2 = shl(exp, 10, pOverflow);
            qua_ener_MR122 = add(temp1, temp2, pOverflow);

            /* 24660 Q12 ~= 6.0206 = 20*log10(2) */
            L_tmp = Mpy_32_16(exp, frac, 24660, pOverflow);
            L_tmp = L_shl(L_tmp, 13, pOverflow);
            qua_ener = pv_round(L_tmp, pOverflow);
            /* Q12 * Q0 = Q13 -> Q10 */
        }
        else
        {
            p = &table_gain_lowrates[index];

            *gain_pit = *p++;
            g_code = *p++;
            qua_ener_MR122 = *p++;
            qua_ener = *p;
        }
    }

    /*-------------------------------------------------------------------*
     *  predict codebook gain                                            *
     *  ~~~~~~~~~~~~~~~~~~~~~                                            *
     *  gc0     = Pow2(int(d)+frac(d))                                   *
     *          = 2^exp + 2^frac                                         *
     *                                                                   *
     *  gcode0 (Q14) = 2^14*2^frac = gc0 * 2^(14-exp)                    *
     *-------------------------------------------------------------------*/

    gc_pred(pred_state, mode, code, &exp, &frac, NULL, NULL, pOverflow);

    gcode0 = (Word16) Pow2(14, frac, pOverflow);

    /*------------------------------------------------------------------*
     *  read quantized gains, update table of past quantized energies   *
     *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~   *
     *  st->past_qua_en(Q10) = 20 * Log10(g_fac) / constant             *
     *                       = Log2(g_fac)                              *
     *                       = qua_ener                                 *
     *                                           constant = 20*Log10(2) *
     *------------------------------------------------------------------*/

    L_tmp = L_mult(g_code, gcode0, pOverflow);
    temp1 = sub(10, exp, pOverflow);
    L_tmp = L_shr(L_tmp, temp1, pOverflow);
    *gain_cod = extract_h(L_tmp);

    /* update table of past quantized energies */
    //过去的量化能量表更新

    gc_pred_update(pred_state, qua_ener_MR122, qua_ener);

    return;
}
Пример #6
0
int gainQuant(
    gainQuantState *st,   /* i/o : State struct                      */
    enum Mode mode,       /* i   : coder mode                        */
    Word16 res[],         /* i   : LP residual,                 Q0   */
    Word16 exc[],         /* i   : LTP excitation (unfiltered), Q0   */
    Word16 code[],        /* i   : CB innovation (unfiltered),  Q13  */
                          /*       (unsharpened for MR475)           */
    Word16 xn[],          /* i   : Target vector.                    */
    Word16 xn2[],         /* i   : Target vector.                    */
    Word16 y1[],          /* i   : Adaptive codebook.                */
    Word16 Y2[],          /* i   : Filtered innovative vector.       */
    Word16 g_coeff[],     /* i   : Correlations <xn y1> <y1 y1>      */
                          /*       Compute in G_pitch().             */
    Word16 even_subframe, /* i   : even subframe indicator flag      */
    Word16 gp_limit,      /* i   : pitch gain limit                  */
    Word16 *sf0_gain_pit, /* o   : Pitch gain sf 0.   MR475          */
    Word16 *sf0_gain_cod, /* o   : Code gain sf 0.    MR475          */
    Word16 *gain_pit,     /* i/o : Pitch gain.                       */
    Word16 *gain_cod,     /* o   : Code gain.                        */
                          /*       MR475: gain_* unquantized in even */
                          /*       subframes, quantized otherwise    */
    Word16 **anap         /* o   : Index of quantization             */
)
{
    Word16 exp_gcode0;
    Word16 frac_gcode0;
    Word16 qua_ener_MR122;
    Word16 qua_ener;
    Word16 frac_coeff[5];
    Word16 exp_coeff[5];
    Word16 exp_en, frac_en;
    Word16 cod_gain_exp, cod_gain_frac;
            
    test ();
    if (sub (mode, MR475) == 0)
    {
        test ();
        if (even_subframe != 0)
        {
            /* save position in output parameter stream and current
               state of codebook gain predictor */
            st->gain_idx_ptr = (*anap)++;
            gc_pred_copy(st->gc_predSt, st->gc_predUnqSt);
            
            /* predict codebook gain (using "unquantized" predictor)*/
            /* (note that code[] is unsharpened in MR475)           */
            gc_pred(st->gc_predUnqSt, mode, code,
                    &st->sf0_exp_gcode0, &st->sf0_frac_gcode0,
                    &exp_en, &frac_en);
            
            /* calculate energy coefficients for quantization
               and store them in state structure (will be used
               in next subframe when real quantizer is run) */
            calc_filt_energies(mode, xn, xn2, y1, Y2, g_coeff,
                               st->sf0_frac_coeff, st->sf0_exp_coeff,
                               &cod_gain_frac, &cod_gain_exp);

            /* store optimum codebook gain (Q1) */
            *gain_cod = shl (cod_gain_frac, add (cod_gain_exp, 1));
                                                         move16 ();

            calc_target_energy(xn,
                               &st->sf0_exp_target_en, &st->sf0_frac_target_en);

            /* calculate optimum codebook gain and update
               "unquantized" predictor                    */
            MR475_update_unq_pred(st->gc_predUnqSt,
                                  st->sf0_exp_gcode0, st->sf0_frac_gcode0,
                                  cod_gain_exp, cod_gain_frac);
            
            /* the real quantizer is not run here... */
        }
        else
        {
            /* predict codebook gain (using "unquantized" predictor) */
            /* (note that code[] is unsharpened in MR475)            */
            gc_pred(st->gc_predUnqSt, mode, code,
                    &exp_gcode0, &frac_gcode0,
                    &exp_en, &frac_en);
            
            /* calculate energy coefficients for quantization */
            calc_filt_energies(mode, xn, xn2, y1, Y2, g_coeff,
                               frac_coeff, exp_coeff,
                               &cod_gain_frac, &cod_gain_exp);

            calc_target_energy(xn, &exp_en, &frac_en);

            /* run real (4-dim) quantizer and update real gain predictor */
            *st->gain_idx_ptr = MR475_gain_quant(
                st->gc_predSt,
                st->sf0_exp_gcode0, st->sf0_frac_gcode0, 
                st->sf0_exp_coeff,  st->sf0_frac_coeff,
                st->sf0_exp_target_en, st->sf0_frac_target_en,
                code,
                exp_gcode0, frac_gcode0, 
                exp_coeff, frac_coeff,
                exp_en, frac_en,
                gp_limit,
                sf0_gain_pit, sf0_gain_cod,   
                gain_pit, gain_cod);
        }
    }
    else
    {
        /*-------------------------------------------------------------------*
         *  predict codebook gain and quantize                               *
         *  (also compute normalized CB innovation energy for MR795)         *
         *-------------------------------------------------------------------*/
        gc_pred(st->gc_predSt, mode, code, &exp_gcode0, &frac_gcode0,
                &exp_en, &frac_en);
        
        test ();
        if (sub(mode, MR122) == 0)
        {
            *gain_cod = G_code (xn2, Y2); move16 ();
            *(*anap)++ = q_gain_code (mode, exp_gcode0, frac_gcode0,
                                      gain_cod, &qua_ener_MR122, &qua_ener);
            move16 ();
        }
        else
        {
            /* calculate energy coefficients for quantization */
            calc_filt_energies(mode, xn, xn2, y1, Y2, g_coeff,
                               frac_coeff, exp_coeff,
                               &cod_gain_frac, &cod_gain_exp);
            
            test ();
            if (sub (mode, MR795) == 0)
            {
                MR795_gain_quant(st->adaptSt, res, exc, code,
                                 frac_coeff, exp_coeff,
                                 exp_en, frac_en,
                                 exp_gcode0, frac_gcode0, L_SUBFR,
                                 cod_gain_frac, cod_gain_exp,
                                 gp_limit, gain_pit, gain_cod,
                                 &qua_ener_MR122, &qua_ener,
                                 anap);
            }
            else
            {
                *(*anap)++ = Qua_gain(mode,
                                      exp_gcode0, frac_gcode0,
                                      frac_coeff, exp_coeff, gp_limit,
                                      gain_pit, gain_cod,
                                      &qua_ener_MR122, &qua_ener);
                move16 ();
            }
        }
        
        /*------------------------------------------------------------------*
         *  update table of past quantized energies                         *
         *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                         *
         *  st->past_qua_en(Q10) = 20 * Log10(qua_gain_code) / constant     *
         *                       = Log2(qua_gain_code)                      *
         *                       = qua_ener                                 *
         *                                           constant = 20*Log10(2) *
         *------------------------------------------------------------------*/
        gc_pred_update(st->gc_predSt, qua_ener_MR122, qua_ener);
    }
        
    return 0;
}