Пример #1
0
static void search_2i40(
    Word16 dn[],         /* i : correlation between target and h[] */
    Word16 rr[][L_CODE], /* i : matrix of autocorrelation          */
    Word16 codvec[],     /* o : algebraic codebook vector          */
    Flag   * pOverflow   /* o : Flag set when overflow occurs      */
)
{
    Word16 i0;
    Word16 i1;
    Word16 ix = 0; /* initialization only needed to keep gcc silent */
    Word16 track1;
    Word16 track2;
    Word16 ipos[NB_PULSE];

    Word16 psk;
    Word16 ps0;
    Word16 ps1;
    Word16 sq;
    Word16 sq1;

    Word16 alpk;
    Word16 alp;
    Word16 alp_16;

    Word32 s;
    Word32 alp0;
    Word32 alp1;

    Word16 i;
    Word16 *p_codvec = &codvec[0];

    psk = -1;
    alpk = 1;

    for (i = 0; i < NB_PULSE; i++)
    {
        *(p_codvec++) = i;
    }

    /*------------------------------------------------------------------*
    * main loop: try 2x4  tracks.                                      *
    *------------------------------------------------------------------*/

    for (track1 = 0; track1 < 2; track1++)
    {
        for (track2 = 0; track2 < 4; track2++)
        {
            /* fix starting position */
            ipos[0] = startPos1[track1];
            ipos[1] = startPos2[track2];

            /*----------------------------------------------------------------*
            * i0 loop: try 8 positions.                                      *
            *----------------------------------------------------------------*/
            for (i0 = ipos[0]; i0 < L_CODE; i0 += STEP)
            {
                ps0 = dn[i0];

                /* alp0 = L_mult(rr[i0][i0], _1_4, pOverflow); */
                alp0 = (Word32) rr[i0][i0] << 14;

                /*-------------------------------------------------------------*
                * i1 loop: 8 positions.                                       *
                *-------------------------------------------------------------*/

                sq = -1;
                alp = 1;
                ix = ipos[1];

                /*---------------------------------------------------------------*
                * These index have low complexity address computation because   *
                * they are, in fact, pointers with fixed increment. For example,*
                * "rr[i0][i2]" is a pointer initialized to "&rr[i0][ipos[2]]"   *
                * and incremented by "STEP".                                    *
                *---------------------------------------------------------------*/

                for (i1 = ipos[1]; i1 < L_CODE; i1 += STEP)
                {
                    /* idx increment = STEP */
                    ps1 = add_16(ps0, dn[i1], pOverflow);

                    /* alp1 = alp0 + rr[i0][i1] + 1/2*rr[i1][i1]; */

                    /* idx incr = STEP */
                    /* alp1 = L_mac(alp0, rr[i1][i1], _1_4, pOverflow); */
                    alp1 = alp0 + ((Word32) rr[i1][i1] << 14);

                    /* idx incr = STEP */
                    /* alp1 = L_mac(alp1, rr[i0][i1], _1_2, pOverflow); */
                    alp1 += (Word32) rr[i0][i1] << 15;

                    /* sq1 = mult(ps1, ps1, pOverflow); */
                    sq1 = (Word16)(((Word32) ps1 * ps1) >> 15);

                    /* alp_16 = pv_round(alp1, pOverflow); */
                    alp_16 = (Word16)((alp1 + (Word32) 0x00008000L) >> 16);

                    /* s = L_mult(alp, sq1, pOverflow); */
                    s = ((Word32) alp * sq1) << 1;

                    /* s =L_msu(s, sq, alp_16, pOverflow); */
                    s -= (((Word32) sq * alp_16) << 1);

                    if (s > 0)
                    {
                        sq = sq1;
                        alp = alp_16;
                        ix = i1;
                    }

                } /* for (i1 = ipos[1]; i1 < L_CODE; i1 += STEP) */

                /* memorize codevector if this one is better than the last one. */

                /* s = L_mult(alpk, sq, pOverflow); */
                s = ((Word32) alpk * sq) << 1;

                /* s = L_msu(s, psk, alp, pOverflow); */
                s -= (((Word32) psk * alp) << 1);

                if (s > 0)
                {
                    psk = sq;
                    alpk = alp;
                    p_codvec = &codvec[0];

                    *(p_codvec++) = i0;
                    *(p_codvec) = ix;
                }

            } /* for (i0 = ipos[0]; i0 < L_CODE; i0 += STEP) */

        } /* for (track2 = 0; track2 < 4; track2++) */

    } /* for (track1 = 0; track1 < 2; track1++) */

    return;

} /* search_2i40 */
Пример #2
0
/*
------------------------------------------------------------------------------
 FUNCTION NAME: build_code
------------------------------------------------------------------------------
 INPUT AND OUTPUT DEFINITIONS

 Inputs:
    codvec,  position of pulses, array of type Word16
    dn_sign, sign of pulses, array of type Word16
    h,       impulse response of weighted synthesis filter, Word16 array

 Outputs:

    cod,       innovative code vector, array of type Word16
    y[],       filtered innovative code, array of type Word16
    sign[],    sign of 2 pulses, array of type Word16
    pOverflow, Flag set when overflow occurs, pointer of type Flag *

 Returns:

 Global Variables Used:
    None

 Local Variables Needed:
    None

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

 Builds the codeword, the filtered codeword and index of the
 codevector, based on the signs and positions of 2 pulses.

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

 None

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

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

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

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

------------------------------------------------------------------------------
*/
static Word16 build_code(
    Word16 codvec[],    /* i : position of pulses                            */
    Word16 dn_sign[],   /* i : sign of pulses                                */
    Word16 cod[],       /* o : innovative code vector                        */
    Word16 h[],         /* i : impulse response of weighted synthesis filter */
    Word16 y[],         /* o : filtered innovative code                      */
    Word16 sign[],      /* o : sign of 2 pulses                              */
    Flag   * pOverflow  /* o : Flag set when overflow occurs                 */
)
{
    Word16 i;
    Word16 j;
    Word16 k;
    Word16 track;
    Word16 index;
    Word16 _sign[NB_PULSE];
    Word16 indx;
    Word16 rsign;
    Word16 tempWord;

    Word16 *p0;
    Word16 *p1;

    Word32 s;

    for (i = 0; i < L_CODE; i++)
    {
        cod[i] = 0;
    }

    indx = 0;
    rsign = 0;

    for (k = 0; k < NB_PULSE; k++)
    {
        i = codvec[k];      /* read pulse position */
        j = dn_sign[i];     /* read sign           */

        /* index = pos/5 */
        /* index = mult(i, 6554, pOverflow); */
        index = (Word16)(((Word32) i * 6554) >> 15);

        /* track = pos%5 */
        /* tempWord =
            L_mult(
            index,
            5,
            pOverflow); */
        tempWord = (index << 3) + (index << 1);

        /* tempWord =
            L_shr(
            tempWord,
            1,
            pOverflow); */
        tempWord >>= 1;


        /* track =
            sub(
            i,
            tempWord,
            pOverflow); */
        track = i - tempWord;

        tempWord = track;

        if (tempWord == 0)
        {
            track = 1;

            /* index =
                shl(
                index,
                6,
                pOverflow); */
            index <<= 6;
        }
        else if (track == 1)
        {
            tempWord = k;

            if (tempWord == 0)
            {
                track = 0;
                /* index =
                    shl(
                    index,
                    1,
                    pOverflow); */
                index <<= 1;
            }
            else
            {
                track = 1;

                /* tempWord =
                    shl(
                    index,
                    6,
                    pOverflow); */
                tempWord = index << 6;

                /* index =
                    add(
                    tempWord,
                    16,
                    pOverflow); */
                index = tempWord + 16;
            }
        }
        else if (track == 2)
        {
            track = 1;

            /* tempWord =
                shl(
                index,
                6,
                pOverflow); */
            tempWord = index << 6;

            /* index =
                add(
                tempWord,
                32,
                pOverflow); */
            index = tempWord + 32;
        }
        else if (track == 3)
        {
            track = 0;

            /* tempWord =
                shl(
                index,
                1,
                pOverflow); */
            tempWord = index << 1;

            /* index =
                add(
                tempWord,
                1,
                pOverflow); */
            index = tempWord + 1;
        }
        else if (track == 4)
        {
            track = 1;

            /* tempWord =
                shl(
                index,
                6,
                pOverflow); */
            tempWord = index << 6;

            /* index =
                add(
                tempWord,
                48,
                pOverflow); */
            index = tempWord + 48;
        }

        if (j > 0)
        {
            cod[i] = 8191;
            _sign[k] = 32767;

            tempWord =
                shl(
                    1,
                    track,
                    pOverflow);

            rsign =
                add_16(
                    rsign,
                    tempWord,
                    pOverflow);
        }
        else
        {
            cod[i] = -8192;
            _sign[k] = (Word16) - 32768L;
        }

        indx =
            add_16(
                indx,
                index,
                pOverflow);
    }
    *sign = rsign;

    p0 = h - codvec[0];
    p1 = h - codvec[1];

    for (i = 0; i < L_CODE; i++)
    {
        s = 0;

        s =
            L_mac(
                s,
                *p0++,
                _sign[0],
                pOverflow);

        s =
            L_mac(
                s,
                *p1++,
                _sign[1],
                pOverflow);

        y[i] =
            pv_round(
                s,
                pOverflow);
    }

    return indx;
}
Пример #3
0
Word16 Cb_gain_average(
    Cb_gain_averageState *st, /* i/o : State variables for CB gain averaging */
    enum Mode mode,           /* i   : AMR mode                              */
    Word16 gain_code,         /* i   : CB gain                            Q1 */
    Word16 lsp[],             /* i   : The LSP for the current frame     Q15 */
    Word16 lspAver[],         /* i   : The average of LSP for 8 frames   Q15 */
    Word16 bfi,               /* i   : bad frame indication flag             */
    Word16 prev_bf,           /* i   : previous bad frame indication flag    */
    Word16 pdfi,              /* i   : potential degraded bad frame ind flag */
    Word16 prev_pdf,          /* i   : prev pot. degraded bad frame ind flag */
    Word16 inBackgroundNoise, /* i   : background noise decision             */
    Word16 voicedHangover,    /* i   : # of frames after last voiced frame   */
    Flag   *pOverflow
)
{
    Word16 i;
    Word16 cbGainMix;
    Word16 diff;
    Word16 tmp_diff;
    Word16 bgMix;
    Word16 cbGainMean;
    Word32 L_sum;
    Word16 tmp[M];
    Word16 tmp1;
    Word16 tmp2;
    Word16 shift1;
    Word16 shift2;
    Word16 shift;

    /*---------------------------------------------------------*
     * Compute mixed cb gain, used to make cb gain more        *
     * smooth in background noise for modes 5.15, 5.9 and 6.7  *
     * states that needs to be updated by all                  *
     *---------------------------------------------------------*/

    /* set correct cbGainMix for MR74, MR795, MR122 */
    cbGainMix = gain_code;

    /*-------------------------------------------------------*
     *   Store list of CB gain needed in the CB gain         *
     *   averaging                                           *
     *-------------------------------------------------------*/
    for (i = 0; i < (L_CBGAINHIST - 1); i++)
    {
        st->cbGainHistory[i] = st->cbGainHistory[i+1];
    }
    st->cbGainHistory[L_CBGAINHIST-1] = gain_code;

    diff = 0;

    /* compute lsp difference */
    for (i = 0; i < M; i++)
    {
        tmp1 = abs_s(sub(*(lspAver + i), *(lsp + i), pOverflow));
        /* Q15      */
        shift1 = norm_s(tmp1) - 1 ;                     /* Qn       */
        tmp1 = shl(tmp1, shift1, pOverflow);            /* Q15+Qn   */
        shift2 = norm_s(*(lspAver + i));                /* Qm       */
        tmp2 = shl(*(lspAver + i), shift2, pOverflow);  /* Q15+Qm   */
        tmp[i] = div_s(tmp1, tmp2);        /* Q15+(Q15+Qn)-(Q15+Qm) */

        shift = 2 + shift1 - shift2;

        if (shift >= 0)
        {
            *(tmp + i) = shr(*(tmp + i), shift, pOverflow);
            /* Q15+Qn-Qm-Qx=Q13 */
        }
        else
        {
            *(tmp + i) = shl(*(tmp + i), negate(shift), pOverflow);
            /* Q15+Qn-Qm-Qx=Q13 */
        }

        diff = add_16(diff, *(tmp + i), pOverflow);           /* Q13 */
    }

    /* Compute hangover */

    if (diff > 5325)                /* 0.65 in Q11 */
    {
        st->hangVar += 1;
    }
    else
    {
        st->hangVar = 0;
    }


    if (st->hangVar > 10)
    {
        /* Speech period, reset hangover variable */
        st->hangCount = 0;
    }

    /* Compute mix constant (bgMix) */
    bgMix = 8192;    /* 1 in Q13 */

    if ((mode <= MR67) || (mode == MR102))
        /* MR475, MR515, MR59, MR67, MR102 */
    {
        /* if errors and presumed noise make smoothing probability stronger */

        if (((((pdfi != 0) && (prev_pdf != 0)) || (bfi != 0) ||
                (prev_bf != 0))
                && (voicedHangover > 1)
                && (inBackgroundNoise != 0)
                && ((mode == MR475) || (mode == MR515) ||
                    (mode == MR59))))
        {
            /* bgMix = min(0.25, max(0.0, diff-0.55)) / 0.25; */
            tmp_diff = diff - 4506;   /* 0.55 in Q13 */
        }
        else
        {
            /* bgMix = min(0.25, max(0.0, diff-0.40)) / 0.25; */
            tmp_diff = diff - 3277; /* 0.4 in Q13 */
        }

        /* max(0.0, diff-0.55)  or  */
        /* max(0.0, diff-0.40) */
        if (tmp_diff > 0)
        {
            tmp1 = tmp_diff;
        }
        else
        {
            tmp1 = 0;
        }

        /* min(0.25, tmp1) */
        if (2048 < tmp1)
        {
            bgMix = 8192;
        }
        else
        {
            bgMix = shl(tmp1, 2, pOverflow);
        }

        if ((st->hangCount < 40) || (diff > 5325)) /* 0.65 in Q13 */
        {
            /* disable mix if too short time since */
            bgMix = 8192;
        }

        /* Smoothen the cb gain trajectory  */
        /* smoothing depends on mix constant bgMix */
        L_sum = L_mult(6554, st->cbGainHistory[2], pOverflow);
        /* 0.2 in Q15; L_sum in Q17 */

        for (i = 3; i < L_CBGAINHIST; i++)
        {
            L_sum = L_mac(L_sum, 6554, st->cbGainHistory[i], pOverflow);
        }
        cbGainMean = pv_round(L_sum, pOverflow);               /* Q1 */

        /* more smoothing in error and bg noise (NB no DFI used here) */

        if (((bfi != 0) || (prev_bf != 0)) && (inBackgroundNoise != 0)
                && ((mode == MR475) || (mode == MR515)
                    || (mode == MR59)))
        {
            /* 0.143 in Q15; L_sum in Q17    */
            L_sum = L_mult(4681, st->cbGainHistory[0], pOverflow);
            for (i = 1; i < L_CBGAINHIST; i++)
            {
                L_sum =
                    L_mac(L_sum, 4681, st->cbGainHistory[i], pOverflow);
            }
            cbGainMean = pv_round(L_sum, pOverflow);              /* Q1 */
        }

        /* cbGainMix = bgMix*cbGainMix + (1-bgMix)*cbGainMean; */
        /* L_sum in Q15 */
        L_sum = L_mult(bgMix, cbGainMix, pOverflow);
        L_sum = L_mac(L_sum, 8192, cbGainMean, pOverflow);
        L_sum = L_msu(L_sum, bgMix, cbGainMean, pOverflow);
        cbGainMix = pv_round(L_shl(L_sum, 2, pOverflow), pOverflow);  /* Q1 */
    }

    st->hangCount += 1;

    return (cbGainMix);
}
Пример #4
0
/*
------------------------------------------------------------------------------
 FUNCTION NAME: code_2i40_11bits
------------------------------------------------------------------------------
 INPUT AND OUTPUT DEFINITIONS

 Inputs:
    x,  target vector, array of type Word16
    h,  impulse response of weighted synthesis filter, array of type Word16
    T0, Pitch lag, variable of type Word16
    pitch_sharp, Last quantized pitch gain, variable of type Word16

 Outputs:
    code[], Innovative codebook, array of type Word16
    y[],    filtered fixed codebook excitation, array of type Word16
    sign,   Signs of 2 pulses, pointer of type Word16 *
    pOverflow  Flag set when overflow occurs, pointer of type Flag *

 Returns:
    index

 Global Variables Used:
    None

 Local Variables Needed:
    None

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

     Searches a 11 bit algebraic codebook containing 2 pulses
     in a frame of 40 samples.

     The code length is 40, containing 2 nonzero pulses: i0...i1.
     All pulses can have two possible amplitudes: +1 or -1.
     Pulse i0 can have 2x8=16 possible positions, pulse i1 can have
     4x8=32 positions.

        i0 :  1, 6, 11, 16, 21, 26, 31, 36.
              3, 8, 13, 18, 23, 28, 33, 38.
        i1 :  0, 5, 10, 15, 20, 25, 30, 35.
              1, 6, 11, 16, 21, 26, 31, 36.
              2, 7, 12, 17, 22, 27, 32, 37.
              4, 9, 14, 19, 24, 29, 34, 39.

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

 None

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

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

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


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

------------------------------------------------------------------------------
*/
Word16 code_2i40_11bits(
    Word16 x[],         /* i : target vector                                 */
    Word16 h[],         /* i : impulse response of weighted synthesis filter */
    /*     h[-L_subfr..-1] must be set to zero.          */
    Word16 T0,          /* i : Pitch lag                                     */
    Word16 pitch_sharp, /* i : Last quantized pitch gain                     */
    Word16 code[],      /* o : Innovative codebook                           */
    Word16 y[],         /* o : filtered fixed codebook excitation            */
    Word16 * sign,      /* o : Signs of 2 pulses                             */
    Flag   * pOverflow  /* o : Flag set when overflow occurs                 */
)
{
    Word16 codvec[NB_PULSE];
    Word16 dn[L_CODE];
    Word16 dn2[L_CODE];
    Word16 dn_sign[L_CODE];

    Word16 rr[L_CODE][L_CODE];

    Word16 i;
    Word16 index;
    Word16 sharp;
    Word16 tempWord;

    sharp = pitch_sharp << 1;

    if (T0 < L_CODE)
    {
        for (i = T0; i < L_CODE; i++)
        {
            tempWord =
                mult(
                    h[i - T0],
                    sharp,
                    pOverflow);

            h[i] =
                add_16(
                    h[i],
                    tempWord,
                    pOverflow);
        }

    }

    cor_h_x(
        h,
        x,
        dn,
        1,
        pOverflow);

    set_sign(
        dn,
        dn_sign,
        dn2,
        8); /* dn2[] not used in this codebook search */

    cor_h(
        h,
        dn_sign,
        rr,
        pOverflow);

    search_2i40(
        dn,
        rr,
        codvec,
        pOverflow);

    /* function result */

    index =
        build_code(
            codvec,
            dn_sign,
            code,
            h,
            y,
            sign,
            pOverflow);

    /*
    * Compute innovation vector gain.
    * Include fixed-gain pitch contribution into code[].
    */

    if (T0 < L_CODE)
    {
        for (i = T0; i < L_CODE; i++)
        {
            tempWord =
                mult(
                    code[i - T0],
                    sharp,
                    pOverflow);

            code[i] =
                add_16(
                    code[i],
                    tempWord,
                    pOverflow);
        }
    }

    return index;
}
Пример #5
0
void cbsearch(Word16 x[],        /* i : target vector, Q0                     */
              Word16 h[],        /* i : impulse response of weighted synthesis*/
              /*     filter h[-L_subfr..-1] must be set to */
              /*     zero. Q12                             */
              Word16 T0,         /* i : Pitch lag                             */
              Word16 pitch_sharp,/* i : Last quantized pitch gain, Q14        */
              Word16 gain_pit,   /* i : Pitch gain, Q14                       */
              Word16 res2[],     /* i : Long term prediction residual, Q0     */
              Word16 code[],     /* o : Innovative codebook, Q13              */
              Word16 y[],        /* o : filtered fixed codebook excitation    */
              /*     Q12                                   */
              Word16 **anap,     /* o : Signs of the pulses                   */
              enum Mode mode,    /* i : coder mode                            */
              Word16 subNr,      /* i : subframe number                       */
              CommonAmrTbls* common_amr_tbls, /* ptr to struct of tables    */
              Flag  *pOverflow)  /* o : Flag set when overflow occurs         */
{
    Word16 index;
    Word16 i;
    Word16 temp;
    Word16 pit_sharpTmp;

    /* For MR74, the pre and post CB pitch sharpening is included in the
     * codebook search routine, while for MR122 is it not.
     */

    if ((mode == MR475) || (mode == MR515))
    {
        /* MR475, MR515 */
        *(*anap)++ =
            code_2i40_9bits(
                subNr,
                x,
                h,
                T0,
                pitch_sharp,
                code,
                y,
                &index,
                common_amr_tbls->startPos_ptr,
                pOverflow);

        *(*anap)++ = index;    /* sign index */
    }
    else if (mode == MR59)
    {   /* MR59 */
        *(*anap)++ =
            code_2i40_11bits(
                x,
                h,
                T0,
                pitch_sharp,
                code,
                y,
                &index,
                pOverflow);

        *(*anap)++ = index;    /* sign index */
    }
    else if (mode == MR67)
    {   /* MR67 */
        *(*anap)++ =
            code_3i40_14bits(
                x,
                h,
                T0,
                pitch_sharp,
                code,
                y,
                &index,
                pOverflow);

        *(*anap)++ = index;    /* sign index */
    }
    else if ((mode == MR74) || (mode == MR795))
    {   /* MR74, MR795 */
        *(*anap)++ =
            code_4i40_17bits(
                x,
                h,
                T0,
                pitch_sharp,
                code,
                y,
                &index,
                common_amr_tbls->gray_ptr,
                pOverflow);

        *(*anap)++ = index;    /* sign index */
    }
    else if (mode == MR102)
    {   /* MR102 */
        /*-------------------------------------------------------------*
         * - include pitch contribution into impulse resp. h1[]        *
         *-------------------------------------------------------------*/
        /* pit_sharpTmp = pit_sharp;                     */
        /* if (pit_sharpTmp > 1.0) pit_sharpTmp = 1.0;   */

        pit_sharpTmp =
            shl(
                pitch_sharp,
                1,
                pOverflow);

        for (i = T0; i < L_SUBFR; i++)
        {
            temp =
                mult(
                    h[i - T0],
                    pit_sharpTmp,
                    pOverflow);

            h[i] =
                add_16(
                    h[i],
                    temp,
                    pOverflow);
        }

        /*--------------------------------------------------------------*
         * - Innovative codebook search (find index and gain)           *
         *--------------------------------------------------------------*/
        code_8i40_31bits(
            x,
            res2,
            h,
            code,
            y,
            *anap,
            pOverflow);

        *anap += 7;

        /*-------------------------------------------------------*
         * - Add the pitch contribution to code[].               *
         *-------------------------------------------------------*/
        for (i = T0; i < L_SUBFR; i++)
        {
            temp =
                mult(
                    code[i - T0],
                    pit_sharpTmp,
                    pOverflow);

            code[i] =
                add_16(
                    code[i],
                    temp,
                    pOverflow);
        }
    }
    else
    {  /* MR122 */
        /*-------------------------------------------------------------*
         * - include pitch contribution into impulse resp. h1[]        *
         *-------------------------------------------------------------*/

        /* pit_sharpTmp = gain_pit;                      */
        /* if (pit_sharpTmp > 1.0) pit_sharpTmp = 1.0;   */

        pit_sharpTmp = shl(gain_pit, 1, pOverflow);

        for (i = T0; i < L_SUBFR; i++)
        {
            temp = ((Word32)h[i - T0] * pit_sharpTmp) >> 15;
            /*
                     mult(
                            h[i - T0],
                            ,
                            pOverflow);
            */
            h[i] =
                add_16(
                    h[i],
                    temp,
                    pOverflow);
        }
        /*--------------------------------------------------------------*
         * - Innovative codebook search (find index and gain)           *
         *--------------------------------------------------------------*/

        code_10i40_35bits(
            x,
            res2,
            h,
            code,
            y,
            *anap,
            common_amr_tbls->gray_ptr,
            pOverflow);

        *anap += 10;

        /*-------------------------------------------------------*
         * - Add the pitch contribution to code[].               *
         *-------------------------------------------------------*/
        for (i = T0; i < L_SUBFR; i++)
        {
            temp =
                mult(
                    code[i - T0],
                    pit_sharpTmp,
                    pOverflow);

            code[i] =
                add_16(
                    code[i],
                    temp,
                    pOverflow);
        }
    }

}
Пример #6
0
static Word16
MR795_gain_code_quant_mod(  /* o  : index of quantization.            */
    Word16 gain_pit,        /* i  : pitch gain,                   Q14 */
    Word16 exp_gcode0,      /* i  : predicted CB gain (exponent), Q0  */
    Word16 gcode0,          /* i  : predicted CB gain (norm.),    Q14 */
    Word16 frac_en[],       /* i  : energy coefficients (4),
                                    fraction part,                Q15 */
    Word16 exp_en[],        /* i  : energy coefficients (4),
                                    eponent part,                 Q0  */
    Word16 alpha,           /* i  : gain adaptor factor (>0),     Q15 */
    Word16 gain_cod_unq,    /* i  : Code gain (unquantized)           */
    /*      (scaling: Q10 - exp_gcode0)       */
    Word16 *gain_cod,       /* i/o: Code gain (pre-/quantized),   Q1  */
    Word16 *qua_ener_MR122, /* o  : quantized energy error,       Q10 */
    /*      (for MR122 MA predictor update)   */
    Word16 *qua_ener,       /* o  : quantized energy error,       Q10 */
    /*      (for other MA predictor update)   */
    const Word16* qua_gain_code_ptr, /* i : ptr to read-only ptr      */
    Flag   *pOverflow       /* o  : overflow indicator                */
)
{
    const Word16 *p;
    Word16 i;
    Word16 index;
    Word16 tmp;
    Word16 one_alpha;
    Word16 exp;
    Word16 e_max;

    Word16 g2_pitch;
    Word16 g_code;
    Word16 g2_code_h;
    Word16 g2_code_l;
    Word16 d2_code_h;
    Word16 d2_code_l;
    Word16 coeff[5];
    Word16 coeff_lo[5];
    Word16 exp_coeff[5];
    Word32 L_tmp;
    Word32 L_t0;
    Word32 L_t1;
    Word32 dist_min;
    Word16 gain_code;

    /*
      Steps in calculation of the error criterion (dist):
      ---------------------------------------------------

      underlined = constant; alp = FLP value of alpha, alpha = FIP
      ----------


        ExEn = gp^2 * LtpEn + 2.0*gp*gc[i] * XC + gc[i]^2 * InnEn;
               ------------   ------         --             -----

        aExEn= alp * ExEn
             = alp*gp^2*LtpEn + 2.0*alp*gp*XC* gc[i] + alp*InnEn* gc[i]^2
               --------------   -------------          ---------

             =         t[1]   +              t[2]    +          t[3]

        dist = d1 + d2;

          d1 = (1.0 - alp) * InnEn * (gcu - gc[i])^2 = t[4]
               -------------------    ---

          d2 =        alp  * (ResEn - 2.0 * sqrt(ResEn*ExEn) + ExEn);
                      ---     -----   ---        -----

             =        alp  * (sqrt(ExEn) - sqrt(ResEn))^2
                      ---                  -----------

             =               (sqrt(aExEn) - sqrt(alp*ResEn))^2
                                            ---------------

             =               (sqrt(aExEn) -       t[0]     )^2
                                                  ----

     */

    /*
     * calculate scalings of the constant terms
     */
    gain_code = shl(*gain_cod, (10 - exp_gcode0), pOverflow);   /* Q1  -> Q11 (-ec0) */
    g2_pitch = mult(gain_pit, gain_pit, pOverflow);               /* Q14 -> Q13        */
    /* 0 < alpha <= 0.5 => 0.5 <= 1-alpha < 1, i.e one_alpha is normalized  */
    one_alpha = add_16((32767 - alpha), 1, pOverflow);   /* 32768 - alpha */


    /*  alpha <= 0.5 -> mult. by 2 to keep precision; compensate in exponent */
    L_t1 = L_mult(alpha, frac_en[1], pOverflow);
    L_t1 = L_shl(L_t1, 1, pOverflow);
    tmp = (Word16)(L_t1 >> 16);

    /* directly store in 32 bit variable because no further mult. required */
    L_t1 = L_mult(tmp, g2_pitch, pOverflow);
    exp_coeff[1] = exp_en[1] - 15;


    tmp = (Word16)(L_shl(L_mult(alpha, frac_en[2], pOverflow), 1, pOverflow) >> 16);
    coeff[2] = mult(tmp, gain_pit, pOverflow);
    exp = exp_gcode0 - 10;
    exp_coeff[2] = add_16(exp_en[2], exp, pOverflow);


    /* alpha <= 0.5 -> mult. by 2 to keep precision; compensate in exponent */
    coeff[3] = (Word16)(L_shl(L_mult(alpha, frac_en[3], pOverflow), 1, pOverflow) >> 16);
    exp = shl(exp_gcode0, 1, pOverflow) - 7;
    exp_coeff[3] = add_16(exp_en[3], exp, pOverflow);


    coeff[4] = mult(one_alpha, frac_en[3], pOverflow);
    exp_coeff[4] = add_16(exp_coeff[3], 1, pOverflow);


    L_tmp = L_mult(alpha, frac_en[0], pOverflow);
    /* sqrt_l returns normalized value and 2*exponent
       -> result = val >> (exp/2)
       exp_coeff holds 2*exponent for c[0]            */
    /* directly store in 32 bit variable because no further mult. required */
    L_t0 = sqrt_l_exp(L_tmp, &exp, pOverflow);  /* normalization included in sqrt_l_exp */
    exp += 47;
    exp_coeff[0] = exp_en[0] - exp;

    /*
     * Determine the maximum exponent occuring in the distance calculation
     * and adjust all fractions accordingly (including a safety margin)
     *
     */

    /* find max(e[1..4],e[0]+31) */
    e_max = exp_coeff[0] + 31;
    for (i = 1; i <= 4; i++)
    {
        if (exp_coeff[i] > e_max)
        {
            e_max = exp_coeff[i];
        }
    }

    /* scale c[1]         (requires no further multiplication) */
    tmp = e_max - exp_coeff[1];
    L_t1 = L_shr(L_t1, tmp, pOverflow);

    /* scale c[2..4] (used in Mpy_32_16 in the quantizer loop) */
    for (i = 2; i <= 4; i++)
    {
        tmp = e_max - exp_coeff[i];
        L_tmp = ((Word32)coeff[i] << 16);
        L_tmp = L_shr(L_tmp, tmp, pOverflow);
        L_Extract(L_tmp, &coeff[i], &coeff_lo[i], pOverflow);
    }

    /* scale c[0]         (requires no further multiplication) */
    exp = e_max - 31;              /* new exponent */
    tmp = exp - exp_coeff[0];
    L_t0 = L_shr(L_t0, shr(tmp, 1, pOverflow), pOverflow);
    /* perform correction by 1/sqrt(2) if exponent difference is odd */
    if ((tmp & 0x1) != 0)
    {
        L_Extract(L_t0, &coeff[0], &coeff_lo[0], pOverflow);
        L_t0 = Mpy_32_16(coeff[0], coeff_lo[0],
                         23170, pOverflow);                    /* 23170 Q15 = 1/sqrt(2)*/
    }

    /* search the quantizer table for the lowest value
       of the search criterion                           */
    dist_min = MAX_32;
    index = 0;
    p = &qua_gain_code_ptr[0];

    for (i = 0; i < NB_QUA_CODE; i++)
    {
        g_code = *p++;                   /* this is g_fac (Q11)  */
        p++;                             /* skip log2(g_fac)     */
        p++;                             /* skip 20*log10(g_fac) */
        g_code = mult(g_code, gcode0, pOverflow);

        /* only continue if    gc[i]            < 2.0*gc
           which is equiv. to  g_code (Q10-ec0) < gain_code (Q11-ec0) */

        if (g_code >= gain_code)
        {
            break;
        }

        L_tmp = L_mult(g_code, g_code, pOverflow);
        L_Extract(L_tmp, &g2_code_h, &g2_code_l, pOverflow);

        tmp = sub(g_code, gain_cod_unq, pOverflow);
        L_tmp = L_mult(tmp, tmp, pOverflow);
        L_Extract(L_tmp, &d2_code_h, &d2_code_l, pOverflow);

        /* t2, t3, t4 */
        L_tmp = Mac_32_16(L_t1, coeff[2], coeff_lo[2], g_code, pOverflow);
        L_tmp = Mac_32(L_tmp,    coeff[3], coeff_lo[3], g2_code_h, g2_code_l, pOverflow);

        L_tmp = sqrt_l_exp(L_tmp, &exp, pOverflow);
        L_tmp = L_shr(L_tmp, shr(exp, 1, pOverflow), pOverflow);

        /* d2 */
        tmp = pv_round(L_sub(L_tmp, L_t0, pOverflow), pOverflow);
        L_tmp = L_mult(tmp, tmp, pOverflow);

        /* dist */
        L_tmp = Mac_32(L_tmp, coeff[4], coeff_lo[4], d2_code_h, d2_code_l, pOverflow);

        /* store table index if distance measure for this
            index is lower than the minimum seen so far   */
        if (L_tmp < dist_min)
        {
            dist_min = L_tmp;
            index = i;
        }
    }

    /*------------------------------------------------------------------*
     *  read quantized gains and new values for MA predictor memories   *
     *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~   *
     *------------------------------------------------------------------*/

    /* Read the quantized gains */
    p = &qua_gain_code_ptr[(index<<2) - index];
    g_code = *p++;
    *qua_ener_MR122 = *p++;
    *qua_ener = *p;

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

    L_tmp = L_mult(g_code, gcode0, pOverflow);
    L_tmp = L_shr(L_tmp, 9 - exp_gcode0, pOverflow);
    *gain_cod = (Word16)(L_tmp >> 16);

    return index;
}
Пример #7
0
static void
MR795_gain_code_quant3(
    Word16 exp_gcode0,        /* i  : predicted CB gain (exponent), Q0  */
    Word16 gcode0,            /* i  : predicted CB gain (norm.),    Q14 */
    Word16 g_pitch_cand[],    /* i  : Pitch gain candidates (3),    Q14 */
    Word16 g_pitch_cind[],    /* i  : Pitch gain cand. indices (3), Q0  */
    Word16 frac_coeff[],      /* i  : coefficients (5),             Q15 */
    Word16 exp_coeff[],       /* i  : energy coefficients (5),      Q0  */
    /*      coefficients from calc_filt_ener()*/
    Word16 *gain_pit,         /* o  : Pitch gain,                   Q14 */
    Word16 *gain_pit_ind,     /* o  : Pitch gain index,             Q0  */
    Word16 *gain_cod,         /* o  : Code gain,                    Q1  */
    Word16 *gain_cod_ind,     /* o  : Code gain index,              Q0  */
    Word16 *qua_ener_MR122,   /* o  : quantized energy error,       Q10 */
    /*      (for MR122 MA predictor update)   */
    Word16 *qua_ener,         /* o  : quantized energy error,       Q10 */
    /*      (for other MA predictor update)   */
    const Word16* qua_gain_code_ptr, /* i : ptr to read-only table      */
    Flag   *pOverflow         /* o  : overflow indicator                */
)
{
    const Word16 *p;
    Word16 i;
    Word16 j;
    Word16 cod_ind;
    Word16 pit_ind;
    Word16 e_max;
    Word16 exp_code;
    Word16 g_pitch;
    Word16 g2_pitch;
    Word16 g_code;
    Word16 g2_code_h;
    Word16 g2_code_l;
    Word16 g_pit_cod_h;
    Word16 g_pit_cod_l;
    Word16 coeff[5];
    Word16 coeff_lo[5];
    Word16 exp_max[5];
    Word32 L_tmp;
    Word32 L_tmp0;
    Word32 dist_min;

    /*
     * The error energy (sum) to be minimized consists of five terms, t[0..4].
     *
     *                      t[0] =    gp^2  * <y1 y1>
     *                      t[1] = -2*gp    * <xn y1>
     *                      t[2] =    gc^2  * <y2 y2>
     *                      t[3] = -2*gc    * <xn y2>
     *                      t[4] =  2*gp*gc * <y1 y2>
     *
     */

    /* determine the scaling exponent for g_code: ec = ec0 - 10 */
    exp_code = exp_gcode0 - 10;

    /* calculate exp_max[i] = s[i]-1 */
    exp_max[0] = exp_coeff[0] - 13;
    exp_max[1] = exp_coeff[1] - 14;
    exp_max[2] = exp_coeff[2] + shl(exp_code, 1, pOverflow) + 15;
    exp_max[3] = exp_coeff[3] + exp_code;
    exp_max[4] = exp_coeff[4] + (exp_code + 1);


    /*-------------------------------------------------------------------*
     *  Find maximum exponent:                                           *
     *  ~~~~~~~~~~~~~~~~~~~~~~                                           *
     *                                                                   *
     *  For the sum operation, all terms must have the same scaling;     *
     *  that scaling should be low enough to prevent overflow. There-    *
     *  fore, the maximum scale is determined and all coefficients are   *
     *  re-scaled:                                                       *
     *                                                                   *
     *    e_max = max(exp_max[i]) + 1;                                   *
     *    e = exp_max[i]-e_max;         e <= 0!                          *
     *    c[i] = c[i]*2^e                                                *
     *-------------------------------------------------------------------*/

    e_max = exp_max[0];
    for (i = 1; i < 5; i++)     /* implemented flattened */
    {
        if (exp_max[i] > e_max)
        {
            e_max = exp_max[i];
        }
    }

    e_max = add_16(e_max, 1, pOverflow);      /* To avoid overflow */

    for (i = 0; i < 5; i++)
    {
        j = e_max - exp_max[i];
        L_tmp = ((Word32)frac_coeff[i] << 16);
        L_tmp = L_shr(L_tmp, j, pOverflow);
        L_Extract(L_tmp, &coeff[i], &coeff_lo[i], pOverflow);
    }


    /*-------------------------------------------------------------------*
     *  Codebook search:                                                 *
     *  ~~~~~~~~~~~~~~~~                                                 *
     *                                                                   *
     *  For each of the candiates LTP gains in g_pitch_cand[], the terms *
     *  t[0..4] are calculated from the values in the table (and the     *
     *  pitch gain candidate) and summed up; the result is the mean      *
     *  squared error for the LPT/CB gain pair. The index for the mini-  *
     *  mum MSE is stored and finally used to retrieve the quantized CB  *
     *  gain                                                             *
     *-------------------------------------------------------------------*/

    /* start with "infinite" MSE */
    dist_min = MAX_32;
    cod_ind = 0;
    pit_ind = 0;

    /* loop through LTP gain candidates */
    for (j = 0; j < 3; j++)
    {
        /* pre-calculate terms only dependent on pitch gain */
        g_pitch = g_pitch_cand[j];
        g2_pitch = mult(g_pitch, g_pitch, pOverflow);
        L_tmp0 = Mpy_32_16(coeff[0], coeff_lo[0], g2_pitch, pOverflow);
        L_tmp0 = Mac_32_16(L_tmp0, coeff[1], coeff_lo[1], g_pitch, pOverflow);

        p = &qua_gain_code_ptr[0];
        for (i = 0; i < NB_QUA_CODE; i++)
        {
            g_code = *p++;                   /* this is g_fac        Q11 */
            p++;                             /* skip log2(g_fac)         */
            p++;                             /* skip 20*log10(g_fac)     */

            g_code = mult(g_code, gcode0, pOverflow);

            L_tmp = L_mult(g_code, g_code, pOverflow);
            L_Extract(L_tmp, &g2_code_h, &g2_code_l, pOverflow);

            L_tmp = L_mult(g_code, g_pitch, pOverflow);
            L_Extract(L_tmp, &g_pit_cod_h, &g_pit_cod_l, pOverflow);

            L_tmp = Mac_32(L_tmp0, coeff[2], coeff_lo[2],
                           g2_code_h, g2_code_l, pOverflow);
            L_tmp = Mac_32_16(L_tmp, coeff[3], coeff_lo[3],
                              g_code, pOverflow);
            L_tmp = Mac_32(L_tmp, coeff[4], coeff_lo[4],
                           g_pit_cod_h, g_pit_cod_l, pOverflow);

            /* store table index if MSE for this index is lower
               than the minimum MSE seen so far; also store the
               pitch gain for this (so far) lowest MSE          */
            if (L_tmp < dist_min)
            {
                dist_min = L_tmp;
                cod_ind = i;
                pit_ind = j;
            }
        }
    }

    /*------------------------------------------------------------------*
     *  read quantized gains and new values for MA predictor memories   *
     *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~   *
     *------------------------------------------------------------------*/

    /* Read the quantized gains */
    p = &qua_gain_code_ptr[(cod_ind<<2) - cod_ind];

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

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

    L_tmp = L_mult(g_code, gcode0, pOverflow);
    L_tmp = L_shr(L_tmp, 9 - exp_gcode0, pOverflow);
    *gain_cod = (Word16)(L_tmp >> 16);
    *gain_cod_ind = cod_ind;
    *gain_pit = g_pitch_cand[pit_ind];
    *gain_pit_ind = g_pitch_cind[pit_ind];
}
Пример #8
0
Word16
Qua_gain(                   /* o  : index of quantization.                 */
    enum Mode mode,         /* i  : AMR mode                               */
    Word16 exp_gcode0,      /* i  : predicted CB gain (exponent),      Q0  */
    Word16 frac_gcode0,     /* i  : predicted CB gain (fraction),      Q15 */
    Word16 frac_coeff[],    /* i  : energy coeff. (5), fraction part,  Q15 */
    Word16 exp_coeff[],     /* i  : energy coeff. (5), exponent part,  Q0  */
    /*      (frac_coeff and exp_coeff computed in  */
    /*       calc_filt_energies())                 */
    Word16 gp_limit,        /* i  : pitch gain limit                       */
    Word16 *gain_pit,       /* o  : Pitch gain,                        Q14 */
    Word16 *gain_cod,       /* o  : Code gain,                         Q1  */
    Word16 *qua_ener_MR122, /* o  : quantized energy error,            Q10 */
    /*      (for MR122 MA predictor update)        */
    Word16 *qua_ener,       /* o  : quantized energy error,            Q10 */
    /*      (for other MA predictor update)        */
    CommonAmrTbls* common_amr_tbls, /* i : ptr to struct of tables ptrs    */
    Flag   *pOverflow       /* o  : overflow indicator                     */
)
{
    const Word16 *p;
    Word16 i;
    Word16 j;
    Word16 index = 0;
    Word16 gcode0;
    Word16 e_max;
    Word16 temp;
    Word16 exp_code;
    Word16 g_pitch;
    Word16 g2_pitch;
    Word16 g_code;
    Word16 g2_code;
    Word16 g_pit_cod;
    Word16 coeff[5];
    Word16 coeff_lo[5];
    Word16 exp_max[5];
    Word32 L_tmp;
    Word32 L_tmp2;
    Word32 dist_min;
    const Word16 *table_gain;
    Word16 table_len;

    if (mode == MR102 || mode == MR74 || mode == MR67)
    {
        table_len = VQ_SIZE_HIGHRATES;
        table_gain = common_amr_tbls->table_gain_highrates_ptr;
    }
    else
    {
        table_len = VQ_SIZE_LOWRATES;
        table_gain = common_amr_tbls->table_gain_lowrates_ptr;
    }

    /*-------------------------------------------------------------------*
     *  predicted codebook gain                                          *
     *  ~~~~~~~~~~~~~~~~~~~~~~~                                          *
     *  gc0     = 2^exp_gcode0 + 2^frac_gcode0                           *
     *                                                                   *
     *  gcode0 (Q14) = 2^14*2^frac_gcode0 = gc0 * 2^(14-exp_gcode0)      *
     *-------------------------------------------------------------------*/

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

    /*-------------------------------------------------------------------*
     *  Scaling considerations:                                          *
     *  ~~~~~~~~~~~~~~~~~~~~~~~                                          *
     *-------------------------------------------------------------------*/

    /*
     * The error energy (sum) to be minimized consists of five terms, t[0..4].
     *
     *                      t[0] =    gp^2  * <y1 y1>
     *                      t[1] = -2*gp    * <xn y1>
     *                      t[2] =    gc^2  * <y2 y2>
     *                      t[3] = -2*gc    * <xn y2>
     *                      t[4] =  2*gp*gc * <y1 y2>
     *
     */

    /* determine the scaling exponent for g_code: ec = ec0 - 11 */
    exp_code = exp_gcode0 - 11;

    /* calculate exp_max[i] = s[i]-1 */
    exp_max[0] = exp_coeff[0] - 13;
    exp_max[1] = exp_coeff[1] - 14;

    temp = shl(exp_code, 1, pOverflow);
    temp += 15;
    exp_max[2] = add_16(exp_coeff[2], temp, pOverflow);

    exp_max[3] = add_16(exp_coeff[3], exp_code, pOverflow);

    temp = exp_code + 1;
    exp_max[4] = add_16(exp_coeff[4], temp, pOverflow);


    /*-------------------------------------------------------------------*
     *  Find maximum exponent:                                           *
     *  ~~~~~~~~~~~~~~~~~~~~~~                                           *
     *                                                                   *
     *  For the sum operation, all terms must have the same scaling;     *
     *  that scaling should be low enough to prevent overflow. There-    *
     *  fore, the maximum scale is determined and all coefficients are   *
     *  re-scaled:                                                       *
     *                                                                   *
     *    e_max = max(exp_max[i]) + 1;                                   *
     *    e = exp_max[i]-e_max;         e <= 0!                          *
     *    c[i] = c[i]*2^e                                                *
     *-------------------------------------------------------------------*/

    e_max = exp_max[0];
    for (i = 1; i < 5; i++)
    {
        if (exp_max[i] > e_max)
        {
            e_max = exp_max[i];
        }
    }

    e_max++;

    for (i = 0; i < 5; i++)
    {
        j = e_max - exp_max[i];
        L_tmp = ((Word32)frac_coeff[i] << 16);
        L_tmp = L_shr(L_tmp, j, pOverflow);
        L_Extract(L_tmp, &coeff[i], &coeff_lo[i], pOverflow);
    }


    /*-------------------------------------------------------------------*
     *  Codebook search:                                                 *
     *  ~~~~~~~~~~~~~~~~                                                 *
     *                                                                   *
     *  For each pair (g_pitch, g_fac) in the table calculate the        *
     *  terms t[0..4] and sum them up; the result is the mean squared    *
     *  error for the quantized gains from the table. The index for the  *
     *  minimum MSE is stored and finally used to retrieve the quantized *
     *  gains                                                            *
     *-------------------------------------------------------------------*/

    /* start with "infinite" MSE */
    dist_min = MAX_32;

    p = &table_gain[0];

    for (i = 0; i < table_len; i++)
    {
        g_pitch = *p++;
        g_code = *p++;                   /* this is g_fac        */
        p++;                             /* skip log2(g_fac)     */
        p++;                             /* skip 20*log10(g_fac) */

        if (g_pitch <= gp_limit)
        {
            g_code = mult(g_code, gcode0, pOverflow);
            g2_pitch = mult(g_pitch, g_pitch, pOverflow);
            g2_code = mult(g_code, g_code, pOverflow);
            g_pit_cod = mult(g_code, g_pitch, pOverflow);

            L_tmp = Mpy_32_16(coeff[0], coeff_lo[0], g2_pitch, pOverflow);
            L_tmp2 = Mpy_32_16(coeff[1], coeff_lo[1], g_pitch, pOverflow);
            L_tmp = L_add(L_tmp, L_tmp2, pOverflow);

            L_tmp2 = Mpy_32_16(coeff[2], coeff_lo[2], g2_code, pOverflow);
            L_tmp = L_add(L_tmp, L_tmp2, pOverflow);

            L_tmp2 =  Mpy_32_16(coeff[3], coeff_lo[3], g_code, pOverflow);
            L_tmp = L_add(L_tmp, L_tmp2, pOverflow);

            L_tmp2 = Mpy_32_16(coeff[4], coeff_lo[4], g_pit_cod, pOverflow);
            L_tmp = L_add(L_tmp, L_tmp2, pOverflow);

            /* store table index if MSE for this index is lower
               than the minimum MSE seen so far */
            if (L_tmp < dist_min)
            {
                dist_min = L_tmp;
                index = i;
            }
        }
    }

    /*------------------------------------------------------------------*
     *  read quantized gains and new values for MA predictor memories   *
     *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~   *
     *------------------------------------------------------------------*/

    /* Read the quantized gains */
    p = &table_gain[shl(index, 2, pOverflow)];
    *gain_pit = *p++;
    g_code = *p++;
    *qua_ener_MR122 = *p++;
    *qua_ener = *p;

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

    L_tmp = L_mult(g_code, gcode0, pOverflow);
    temp  = 10 - exp_gcode0;
    L_tmp = L_shr(L_tmp, temp, pOverflow);

    *gain_cod = (Word16)(L_tmp >> 16);

    return index;
}
Пример #9
0
    Word16 code_2i40_9bits(
        Word16 subNr,       /* i : subframe number                          */
        Word16 x[],         /* i : target vector                            */
        Word16 h[],         /* i : impulse response of weighted synthesis   */
        /*     filter h[-L_subfr..-1] must be set to 0. */
        Word16 T0,          /* i : Pitch lag                                */
        Word16 pitch_sharp, /* i : Last quantized pitch gain                */
        Word16 code[],      /* o : Innovative codebook                      */
        Word16 y[],         /* o : filtered fixed codebook excitation       */
        Word16 * sign,      /* o : Signs of 2 pulses                        */
        const Word16* startPos_ptr, /* ptr to read-only table              */
        Flag   * pOverflow  /* o : Flag set when overflow occurs            */
    )
    {
        Word16 codvec[NB_PULSE];
        Word16 dn[L_CODE];
        Word16 dn2[L_CODE];
        Word16 dn_sign[L_CODE];
        Word16 rr[L_CODE][L_CODE];

        register Word16 i;

        Word16 index;
        Word16 sharp;
        Word16 temp;
        Word32 L_temp;

        L_temp = ((Word32) pitch_sharp) << 1;

        /* Check for overflow condition */
        if (L_temp != (Word32)((Word16) L_temp))
        {
            *(pOverflow) = 1;
            sharp = (pitch_sharp > 0) ? MAX_16 : MIN_16;
        }
        else
        {
            sharp = (Word16) L_temp;
        }

        if (T0 < L_CODE)
        {
            for (i = T0; i < L_CODE; i++)
            {
                temp =
                    mult(
                        *(h + i - T0),
                        sharp,
                        pOverflow);

                *(h + i) =
                    add_16(
                        *(h + i),
                        temp,
                        pOverflow);
            }
        }

        cor_h_x(
            h,
            x,
            dn,
            1,
            pOverflow);

        /* dn2[] not used in this codebook search */

        set_sign(
            dn,
            dn_sign,
            dn2,
            8);

        cor_h(
            h,
            dn_sign,
            rr,
            pOverflow);

        search_2i40(
            subNr,
            dn,
            rr,
            startPos_ptr,
            codvec,
            pOverflow);

        index =
            build_code(
                subNr,
                codvec,
                dn_sign,
                code,
                h,
                y,
                sign,
                pOverflow);

        /*-----------------------------------------------------------------*
         * Compute innovation vector gain.                                 *
         * Include fixed-gain pitch contribution into code[].              *
         *-----------------------------------------------------------------*/

        if (T0 < L_CODE)
        {
            for (i = T0; i < L_CODE; i++)
            {
                temp =
                    mult(
                        *(code + i - T0),
                        sharp,
                        pOverflow);

                *(code + i) =
                    add_16(
                        *(code + i),
                        temp,
                        pOverflow);
            }
        }

        return(index);
    }