⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 g7231_util_cng.c

📁 G723.1语音压缩解压在tms320c54系列上的实现代码,本人已在CCS上仿真通过. 包含全部源代码,主函数请自已写(本人的就不奉送了:
💻 C
字号:

#include "typedef.h"
#include "G7231_cst_lbc.h"
#include "G7231_tab_lbc.h"
#include "G7231_util_lbc.h"
#include "G7231_exc_lbc.h"
#include "G7231_basop.h"
#include "G7231_util_cng.h"
#include "intrindefs.h"

static Word16 G7231random_number(Word16 number_max_p1, Word16 *nRandom);

void G7231Calc_Exc_Rand_En(Word16 curGain, Word16 *PrevExc, Word16 *DataExc,
                                      Word16 *nRandom, G7231LINEDEF *Line)
{
    int i, i_subfr, iblk;
    Word16 temp, temp2;
    Word16 j;
    Word16 TabPos[2*G7231NbPulsBlk], TabSign[2*G7231NbPulsBlk];
    Word16 *ptr_TabPos, *ptr_TabSign;
    Word16 *ptr1, *curExc;
    Word16 sh1, x1, x2, inter_exc, delta, b0;
    Word32 L_acc, L_c, L_temp;
    Word16 tmp[G7231SubFrLen/G7231Sgrid];
    Word16 offset[G7231SubFrames];
    Word16 tempExc[G7231SubFrLenD];

 /*
  * generate LTP codes
  */
    Line->Olp[0] = G7231random_number(21, nRandom) + (Word16)123;
    Line->Olp[1] = G7231random_number(21, nRandom) + (Word16)123;
    for(i_subfr=0; i_subfr<G7231SubFrames; i_subfr++) 
    {  /* in [1, NbFilt] */
        Line->Sfs[i_subfr].AcGn = G7231random_number(G7231NbFilt, nRandom) + (Word16)1;
    }
    Line->Sfs[0].AcLg = 1;
    Line->Sfs[1].AcLg = 0;
    Line->Sfs[2].AcLg = 1;
    Line->Sfs[3].AcLg = 3;


 /*
  * Random innovation :
  * Selection of the grids, signs and pulse positions
  */

    /* Signs and Grids */
    ptr_TabSign = TabSign;
    ptr1 = offset;
    for(iblk=0; iblk<G7231SubFrames/2; iblk++) {
        temp    = G7231random_number((1 << (G7231NbPulsBlk+2)), nRandom);
        *ptr1++ = temp & (Word16)0x0001;
        temp    = G7231shr(temp, 1);
        *ptr1++ = G7231add( (Word16) G7231SubFrLen, (Word16) (temp & 0x0001) );
        for(i=0; i<G7231NbPulsBlk; i++) {
            *ptr_TabSign++= G7231shl(G7231sub((temp & (Word16)0x0002), 1), 14);
            temp = G7231shr(temp, 1);
        }
    }

    /* Positions */
    ptr_TabPos  = TabPos;
    for(i_subfr=0; i_subfr<G7231SubFrames; i_subfr++) {

        for(i=0; i<(G7231SubFrLen/G7231Sgrid); i++) tmp[i] = (Word16)i;
        temp = (G7231SubFrLen/G7231Sgrid);
        for(i=0; i<G7231Nb_puls[i_subfr]; i++) {
            j = G7231random_number(temp, nRandom);
            *ptr_TabPos++ = G7231add(G7231shl(tmp[(int)j],1), offset[i_subfr]);
            temp = G7231sub(temp, 1);
            tmp[(int)j] = tmp[(int)temp];
        }
    }

 /*
  * Compute fixed codebook gains
  */

    ptr_TabPos = TabPos;
    ptr_TabSign = TabSign;
    curExc = DataExc;
    i_subfr = 0;
    for(iblk=0; iblk<G7231SubFrames/2; iblk++) {

        /* decode LTP only */
        G7231Decod_Acbk_En(curExc, &PrevExc[0], Line->Olp[iblk],
                    Line->Sfs[i_subfr].AcLg, Line->Sfs[i_subfr].AcGn);
        G7231Decod_Acbk_En(&curExc[G7231SubFrLen], &PrevExc[G7231SubFrLen], Line->Olp[iblk],
            Line->Sfs[i_subfr+1].AcLg, Line->Sfs[i_subfr+1].AcGn);

        temp2 = 0;
        for(i=0; i<G7231SubFrLenD; i++) {
            temp = G7231abs_s(curExc[i]);
            if(temp > temp2) temp2 = temp;
        }
        if(temp2 == 0) sh1 = 0;
        else {
            sh1 = G7231sub(4,G7231norm_s(temp2)); /* 4 bits of margin  */
            if(sh1 < -2) sh1 = -2;
        }

        L_temp = 0L;
        for(i=0; i<G7231SubFrLenD; i++) {
            temp  = G7231shr(curExc[i], sh1); /* left if sh1 < 0 */
            L_temp = G7231L_mac(L_temp, temp, temp);
            tempExc[i] = temp;
        }  /* ener_ltp x 2**(-2sh1+1) */

        L_acc = 0L;
        for(i=0; i<G7231NbPulsBlk; i++) {
            L_acc = G7231L_mac(L_acc, tempExc[(int)ptr_TabPos[i]], ptr_TabSign[i]);
        }
        inter_exc = G7231extract_h(G7231L_shl(L_acc, 1)); /* inter_exc x 2-sh1 */

        /* compute SubFrLenD x curGain**2 x 2**(-2sh1+1)    */
        /* curGain input = 2**5 curGain                     */
        L_acc = G7231L_mult(curGain, G7231SubFrLen);
        L_acc = G7231L_shr(L_acc, 6);
        temp  = G7231extract_l(L_acc);   /* SubFrLen x curGain : avoids overflows */
        L_acc = G7231L_mult(temp, curGain);
        temp = G7231shl(sh1, 1);
        temp = G7231add(temp, 4);
        L_acc = G7231L_shr(L_acc, temp); /* SubFrLenD x curGain**2 x 2**(-2sh1+1) */

        /* c = (ener_ltp - SubFrLenD x curGain**2)/nb_pulses_blk */
        /* compute L_c = c >> 2sh1-1                                */
        L_acc = G7231L_sub(L_temp, L_acc);
        /* x 1/nb_pulses_blk */
        L_c  = G7231L_mls(L_acc, G7231InvNbPulsBlk);

/*
 * Solve EQ(X) = X**2 + 2 b0 X + c
 */
        /* delta = b0 x b0 - c */
        b0 = G7231mult_r(inter_exc, G7231InvNbPulsBlk);   /* b0 >> sh1 */
        L_acc = G7231L_msu(L_c, b0, b0);             /* (c - b0**2) >> 2sh1-1 */
        L_acc = G7231L_negate(L_acc);                /* delta x 2**(-2sh1+1) */

        /* Case delta <= 0 */
        if(L_acc <= 0) {  /* delta <= 0 */
            x1 = G7231negate(b0);        /* sh1 */
        }

        /* Case delta > 0 */
        else {
            delta = G7231Sqrt_lbc(L_acc);  /* >> sh1 */
            x1 = G7231sub(delta, b0);      /* x1 >> sh1 */
            x2 = G7231add(b0, delta);      /* (-x2) >> sh1 */
            if(G7231abs_s(x2) < G7231abs_s(x1)) {
                x1 = G7231negate(x2);
            }
        }

        /* Update DataExc */
        sh1 = G7231add(sh1, 1);
        temp = G7231shl(x1, sh1);
        if(temp > (2*G7231Gexc_Max)) temp = (2*G7231Gexc_Max);
        if(temp < -(2*G7231Gexc_Max)) temp = -(2*G7231Gexc_Max);
        for(i=0; i<G7231NbPulsBlk; i++) {
            j = *ptr_TabPos++;
            curExc[(int)j] = G7231add(curExc[(int)j], G7231mult(temp,
                                                (*ptr_TabSign++)) );
        }

        /* update PrevExc */
        ptr1 = PrevExc;
        for(i=G7231SubFrLenD; i<G7231PitchMax; i++)   *ptr1++ = PrevExc[i];
        for(i=0; i<G7231SubFrLenD; i++)  *ptr1++ = curExc[i];

        curExc += G7231SubFrLenD;
        i_subfr += 2;

    } /* end of loop on LTP blocks */

    return;
}


void G7231Calc_Exc_Rand_De(Word16 curGain, Word16 *PrevExc, Word16 *DataExc,
                                      Word16 *nRandom, G7231LINEDEF *Line)
{
    int i, i_subfr, iblk;
    Word16 temp, temp2;
    Word16 j;
    Word16 TabPos[2*G7231NbPulsBlk], TabSign[2*G7231NbPulsBlk];
    Word16 *ptr_TabPos, *ptr_TabSign;
    Word16 *ptr1, *curExc;
    Word16 sh1, x1, x2, inter_exc, delta, b0;
    Word32 L_acc, L_c, L_temp;
    Word16 tmp[G7231SubFrLen/G7231Sgrid];
    Word16 offset[G7231SubFrames];
    Word16 tempExc[G7231SubFrLenD];

 /*
  * generate LTP codes
  */
    Line->Olp[0] = G7231random_number(21, nRandom) + (Word16)123;
    Line->Olp[1] = G7231random_number(21, nRandom) + (Word16)123;
    for(i_subfr=0; i_subfr<G7231SubFrames; i_subfr++) 
    {  /* in [1, NbFilt] */
        Line->Sfs[i_subfr].AcGn = G7231random_number(G7231NbFilt, nRandom) + (Word16)1;
    }
    Line->Sfs[0].AcLg = 1;
    Line->Sfs[1].AcLg = 0;
    Line->Sfs[2].AcLg = 1;
    Line->Sfs[3].AcLg = 3;


 /*
  * Random innovation :
  * Selection of the grids, signs and pulse positions
  */

    /* Signs and Grids */
    ptr_TabSign = TabSign;
    ptr1 = offset;
    for(iblk=0; iblk<G7231SubFrames/2; iblk++) {
        temp    = G7231random_number((1 << (G7231NbPulsBlk+2)), nRandom);
        *ptr1++ = temp & (Word16)0x0001;
        temp    = G7231shr(temp, 1);
        *ptr1++ = G7231add( (Word16) G7231SubFrLen, (Word16) (temp & 0x0001) );
        for(i=0; i<G7231NbPulsBlk; i++) {
            *ptr_TabSign++= G7231shl(G7231sub((temp & (Word16)0x0002), 1), 14);
            temp = G7231shr(temp, 1);
        }
    }

    /* Positions */
    ptr_TabPos  = TabPos;
    for(i_subfr=0; i_subfr<G7231SubFrames; i_subfr++) {

        for(i=0; i<(G7231SubFrLen/G7231Sgrid); i++) tmp[i] = (Word16)i;
        temp = (G7231SubFrLen/G7231Sgrid);
        for(i=0; i<G7231Nb_puls[i_subfr]; i++) {
            j = G7231random_number(temp, nRandom);
            *ptr_TabPos++ = G7231add(G7231shl(tmp[(int)j],1), offset[i_subfr]);
            temp = G7231sub(temp, 1);
            tmp[(int)j] = tmp[(int)temp];
        }
    }

 /*
  * Compute fixed codebook gains
  */

    ptr_TabPos = TabPos;
    ptr_TabSign = TabSign;
    curExc = DataExc;
    i_subfr = 0;
    for(iblk=0; iblk<G7231SubFrames/2; iblk++) {

        /* decode LTP only */
        G7231Decod_Acbk_De(curExc, &PrevExc[0], Line->Olp[iblk],
                    Line->Sfs[i_subfr].AcLg, Line->Sfs[i_subfr].AcGn);
        G7231Decod_Acbk_De(&curExc[G7231SubFrLen], &PrevExc[G7231SubFrLen], Line->Olp[iblk],
            Line->Sfs[i_subfr+1].AcLg, Line->Sfs[i_subfr+1].AcGn);

        temp2 = 0;
        for(i=0; i<G7231SubFrLenD; i++) {
            temp = G7231abs_s(curExc[i]);
            if(temp > temp2) temp2 = temp;
        }
        if(temp2 == 0) sh1 = 0;
        else {
            sh1 = G7231sub(4,G7231norm_s(temp2)); /* 4 bits of margin  */
            if(sh1 < -2) sh1 = -2;
        }

        L_temp = 0L;
        for(i=0; i<G7231SubFrLenD; i++) {
            temp  = G7231shr(curExc[i], sh1); /* left if sh1 < 0 */
            L_temp = G7231L_mac(L_temp, temp, temp);
            tempExc[i] = temp;
        }  /* ener_ltp x 2**(-2sh1+1) */

        L_acc = 0L;
        for(i=0; i<G7231NbPulsBlk; i++) {
            L_acc = G7231L_mac(L_acc, tempExc[(int)ptr_TabPos[i]], ptr_TabSign[i]);
        }
        inter_exc = G7231extract_h(G7231L_shl(L_acc, 1)); /* inter_exc x 2-sh1 */

        /* compute SubFrLenD x curGain**2 x 2**(-2sh1+1)    */
        /* curGain input = 2**5 curGain                     */
        L_acc = G7231L_mult(curGain, G7231SubFrLen);
        L_acc = G7231L_shr(L_acc, 6);
        temp  = G7231extract_l(L_acc);   /* SubFrLen x curGain : avoids overflows */
        L_acc = G7231L_mult(temp, curGain);
        temp = G7231shl(sh1, 1);
        temp = G7231add(temp, 4);
        L_acc = G7231L_shr(L_acc, temp); /* SubFrLenD x curGain**2 x 2**(-2sh1+1) */

        /* c = (ener_ltp - SubFrLenD x curGain**2)/nb_pulses_blk */
        /* compute L_c = c >> 2sh1-1                                */
        L_acc = G7231L_sub(L_temp, L_acc);
        /* x 1/nb_pulses_blk */
        L_c  = G7231L_mls(L_acc, G7231InvNbPulsBlk);

/*
 * Solve EQ(X) = X**2 + 2 b0 X + c
 */
        /* delta = b0 x b0 - c */
        b0 = G7231mult_r(inter_exc, G7231InvNbPulsBlk);   /* b0 >> sh1 */
        L_acc = G7231L_msu(L_c, b0, b0);             /* (c - b0**2) >> 2sh1-1 */
        L_acc = G7231L_negate(L_acc);                /* delta x 2**(-2sh1+1) */

        /* Case delta <= 0 */
        if(L_acc <= 0) {  /* delta <= 0 */
            x1 = G7231negate(b0);        /* sh1 */
        }

        /* Case delta > 0 */
        else {
            delta = G7231Sqrt_lbc(L_acc);  /* >> sh1 */
            x1 = G7231sub(delta, b0);      /* x1 >> sh1 */
            x2 = G7231add(b0, delta);      /* (-x2) >> sh1 */
            if(G7231abs_s(x2) < G7231abs_s(x1)) {
                x1 = G7231negate(x2);
            }
        }

        /* Update DataExc */
        sh1 = G7231add(sh1, 1);
        temp = G7231shl(x1, sh1);
        if(temp > (2*G7231Gexc_Max)) temp = (2*G7231Gexc_Max);
        if(temp < -(2*G7231Gexc_Max)) temp = -(2*G7231Gexc_Max);
        for(i=0; i<G7231NbPulsBlk; i++) {
            j = *ptr_TabPos++;
            curExc[(int)j] = G7231add(curExc[(int)j], G7231mult(temp,
                                                (*ptr_TabSign++)) );
        }

        /* update PrevExc */
        ptr1 = PrevExc;
        for(i=G7231SubFrLenD; i<G7231PitchMax; i++)   *ptr1++ = PrevExc[i];
        for(i=0; i<G7231SubFrLenD; i++)  *ptr1++ = curExc[i];

        curExc += G7231SubFrLenD;
        i_subfr += 2;

    } /* end of loop on LTP blocks */

    return;
}

Word16 G7231random_number(Word16 np1, Word16 *nRandom)
{
    Word16 temp;

    temp = G7231Rand_lbc(nRandom) & (Word16)0x7FFF;
    temp = G7231mult(temp, np1);
    return(temp);
}

Word16 G7231Qua_SidGain(Word16 *Ener, Word16 *shEner, Word16 nq)
{
    Word16 temp, iseg, iseg_p1;
    Word16 j, j2, k, exp;
    Word32 L_x, L_y;
    Word16 sh1;
    Word32 L_acc;
    int i;

    if(nq == 0) {
         /* Quantize energy saved for frame erasure case                */
         /* L_x = 2 x average_ener                                      */
         temp = G7231shl(*shEner, 1);
         temp = G7231sub(16, temp);
         L_acc = G7231L_deposit_l(*Ener);
         L_acc = G7231L_shl(L_acc, temp); /* may overflow, and >> if temp < 0 */
         L_x = G7231L_mls(L_acc, G7231fact[0]);
    }

    else {
         sh1 = shEner[0];
         for(i=1; i<nq; i++) {
             if(shEner[i] < sh1) sh1 = shEner[i];
         }
         for(i=0, L_x=0L; i<nq; i++) {
             temp = G7231sub(shEner[i], sh1);
             temp = G7231shr(Ener[i], temp);
             temp = G7231mult_r(G7231fact[nq], temp);
             L_x = G7231L_add(L_x, G7231L_deposit_l(temp));
         }
         temp = G7231sub(15, sh1);
         L_x = G7231L_shl(L_x, temp);
    }

    /* Quantize L_x */
    if(L_x >= G7231L_bseg[2]) return(63);

    /* Compute segment number iseg */
    if(L_x >= G7231L_bseg[1]) {
        iseg = 2;
        exp = 4;
    }
    else {
        exp  = 3;
        if(L_x >= G7231L_bseg[0]) iseg = 1;
        else iseg = 0;
    }

    iseg_p1 = G7231add(iseg,1);
    j = G7231shl(1, exp);
    k = G7231shr(j,1);

    /* Binary search in segment iseg */
    for(i=0; i<exp; i++) {
        temp = G7231add(G7231base[iseg], G7231shl(j, iseg_p1));
        L_y = G7231L_mult(temp, temp);
        if(L_x >= L_y) j = G7231add(j, k);
        else j = G7231sub(j, k);
        k = G7231shr(k, 1);
    }

    temp = G7231add(G7231base[iseg], G7231shl(j, iseg_p1));
    L_y = G7231L_mult(temp, temp);
    L_y = G7231L_sub(L_y, L_x);
    if(L_y <= 0L) {
        j2    = G7231add(j, 1);
        temp  = G7231add(G7231base[iseg], G7231shl(j2, iseg_p1));
        L_acc = G7231L_mult(temp, temp);
        L_acc = G7231L_sub(L_x, L_acc);
        if(L_y > L_acc) temp = G7231add(G7231shl(iseg,4), j);
        else temp = G7231add(G7231shl(iseg,4), j2);
    }
    else {
        j2    = G7231sub(j, 1);
        temp  = G7231add(G7231base[iseg], G7231shl(j2, iseg_p1));
        L_acc = G7231L_mult(temp, temp);
        L_acc = G7231L_sub(L_x, L_acc);
        if(L_y < L_acc) temp = G7231add(G7231shl(iseg,4), j);
        else temp = G7231add(G7231shl(iseg,4), j2);
    }
    return(temp);
}

Word16 G7231Dec_SidGain(Word16 iGain)
{
    Word16 i, iseg;
    Word16 temp;

    iseg = G7231shr(iGain, 4);
    if(iseg == 3) iseg = 2;
    i = G7231sub(iGain, G7231shl(iseg, 4));
    temp = G7231add(iseg, 1);
    temp = G7231shl(i, temp);
    temp = G7231add(temp, G7231base[iseg]);  /* SidGain */
    temp = G7231shl(temp, 5); /* << 5 */
    return(temp);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -