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

📄 g7231_cod_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_basop.h"
#include "G7231_lsp.h"
#include "G7231_lpc.h"
#include "G7231_util_cng.h"
#include "G7231_cod_cng.h"
#include "G7231_vad.h"
#include "G7231_coder.h"
#include "intrindefs.h"

static void G7231ComputePastAvFilter(Word16 *Coeff);
static void G7231CalcRC(Word16 *Coeff, Word16 *RC, Word16 *shRC);
static Flag G7231LpcDiff(Word16 *RC, Word16 shRC, Word16 *Acf, Word16 alpha);

G7231CODCNGDEF G7231CodCng;

void G7231Init_Cod_Cng(void)
{
    int i;

    G7231CodCng.CurGain = 0;

    for(i=0; i< G7231SizAcf; i++) G7231CodCng.Acf[i] = 0;

    for(i=0; i <= G7231NbAvAcf; i++) G7231CodCng.ShAcf[i] = 40;

    for(i=0; i < G7231LpcOrder; i++) G7231CodCng.SidLpc[i] = 0;

    G7231CodCng.PastFtyp = 1;

    G7231CodCng.RandSeed = 12345;

    return;
}

void G7231Cod_Cng(Word16 *DataExc, Word16 *Ftyp, G7231LINEDEF *Line, Word16 *QntLpc)
{


    Word16 curCoeff[G7231LpcOrder];
    Word16 curQGain;
    Word16 temp;
    int i;

    for(i=G7231NbAvGain-1; i>=1; i--) {
        G7231CodCng.Ener[i] = G7231CodCng.Ener[i-1];
    }

    G7231CodCng.Ener[0] = G7231Durbin(curCoeff, &G7231CodCng.Acf[1], G7231CodCng.Acf[0], &temp);

    if(G7231CodCng.PastFtyp == 1) {
        *Ftyp = 2;
        G7231CodCng.NbEner = 1;
        curQGain = G7231Qua_SidGain(G7231CodCng.Ener, G7231CodCng.ShAcf, G7231CodCng.NbEner);
    }

    else {
        G7231CodCng.NbEner++;
        if(G7231CodCng.NbEner > G7231NbAvGain) G7231CodCng.NbEner = G7231NbAvGain;
        curQGain = G7231Qua_SidGain(G7231CodCng.Ener, G7231CodCng.ShAcf, G7231CodCng.NbEner);

        if(G7231LpcDiff(G7231CodCng.RC, G7231CodCng.ShRC, G7231CodCng.Acf, *G7231CodCng.Ener) == 0) 
        {
            *Ftyp = 2;
        }
        else {
            temp = G7231abs_s(G7231sub(curQGain, G7231CodCng.IRef));
            if(temp > G7231ThreshGain) {
                *Ftyp = 2;
            }
            else {
                *Ftyp = 0;
            }
        }
    }

    if(*Ftyp == 2) {

        G7231ComputePastAvFilter(G7231CodCng.SidLpc) ;

        if ( !G7231VadStat.Aen ) {
            for(i=0; i<G7231LpcOrder; i++) G7231VadStat.NLpc[i] = G7231CodCng.SidLpc[i];
        }

        G7231CalcRC(G7231CodCng.SidLpc , G7231CodCng.RC, &G7231CodCng.ShRC);

        if(G7231LpcDiff(G7231CodCng.RC, G7231CodCng.ShRC, G7231CodCng.Acf, *G7231CodCng.Ener) == 0){
            for(i=0; i<G7231LpcOrder; i++) {
                G7231CodCng.SidLpc[i] = curCoeff[i];
            }
            G7231CalcRC(curCoeff, G7231CodCng.RC, &G7231CodCng.ShRC);
        }

        G7231AtoLsp(G7231CodCng.LspSid, G7231CodCng.SidLpc, G7231CodStat.PrevLsp);
        Line->LspId = G7231Lsp_Qnt(G7231CodCng.LspSid, G7231CodStat.PrevLsp);
        G7231Lsp_Inq(G7231CodCng.LspSid, G7231CodStat.PrevLsp, Line->LspId, 0);

        Line->Sfs[0].Mamp = curQGain;
        G7231CodCng.IRef = curQGain;
        G7231CodCng.SidGain = G7231Dec_SidGain(G7231CodCng.IRef);

    } 

    if(G7231CodCng.PastFtyp == 1) {
        G7231CodCng.CurGain = G7231CodCng.SidGain;
    }
    else {
          G7231CodCng.CurGain = G7231extract_h(G7231L_add( G7231L_mult(G7231CodCng.CurGain,0x7000),
                    G7231L_mult(G7231CodCng.SidGain,0x1000) ) ) ;
    }
    G7231Calc_Exc_Rand_En(G7231CodCng.CurGain, G7231CodStat.PrevExc, DataExc,
                                                &G7231CodCng.RandSeed, Line);

    G7231Lsp_Int(QntLpc, G7231CodCng.LspSid, G7231CodStat.PrevLsp);
    for (i=0; i < G7231LpcOrder ; i++) {
        G7231CodStat.PrevLsp[i] = G7231CodCng.LspSid[i];
    }

    G7231CodCng.PastFtyp = *Ftyp;
    return;
}

void G7231Update_Acf(Word16 *Acf_sf, Word16 *ShAcf_sf)
{

    int i, i_subfr;
    Word16 *ptr1, *ptr2;
    Word32 L_temp[G7231LpcOrderP1];
    Word16 sh1, temp;
    Word32 L_acc0;

    ptr2 = G7231CodCng.Acf + G7231SizAcf;
    ptr1 = ptr2 - G7231LpcOrderP1;
    for(i=G7231LpcOrderP1; i<G7231SizAcf; i++) *(--ptr2) = *(--ptr1);
    for(i=G7231NbAvAcf; i>=1; i--) G7231CodCng.ShAcf[i] = G7231CodCng.ShAcf[i-1];

    sh1 = ShAcf_sf[0];
    for(i_subfr=1; i_subfr<G7231SubFrames; i_subfr++) {
        if(ShAcf_sf[i_subfr] < sh1) sh1 = ShAcf_sf[i_subfr];
    }
    sh1 = G7231add(sh1, 14);  

    for(i=0; i<= G7231LpcOrder; i++) L_temp[i] = 0;

    ptr2 = Acf_sf;
    for(i_subfr=0; i_subfr<G7231SubFrames; i_subfr++) {
        temp = G7231sub(sh1, ShAcf_sf[i_subfr]);
        for(i=0; i <= G7231LpcOrder; i++) {
            L_acc0 = G7231L_deposit_l(*ptr2++);
            L_acc0 = G7231L_shl(L_acc0, temp);  
            L_temp[i] = G7231L_add(L_temp[i], L_acc0);
        }
    }
    temp = G7231norm_l(L_temp[0]);
    temp = G7231sub(16, temp);
    if(temp < 0) temp = 0;
    for(i=0; i <= G7231LpcOrder; i++) {
        G7231CodCng.Acf[i] = G7231extract_l(G7231L_shr(L_temp[i],temp));
    }

    G7231CodCng.ShAcf[0] = G7231sub(sh1, temp);

    return;
}

void G7231ComputePastAvFilter(Word16 *Coeff)
{
    int i, j;
    Word16 *ptr_Acf;
    Word32 L_sumAcf[G7231LpcOrderP1];
    Word16 Corr[G7231LpcOrder], Err;
    Word16 sh1, temp;
    Word32 L_acc0;

    sh1 = G7231CodCng.ShAcf[1];
    for(i=2; i <= G7231NbAvAcf; i ++) {
        temp = G7231CodCng.ShAcf[i];
        if(temp < sh1) sh1 = temp;
    }
    sh1 = G7231add(sh1, 14);     

    for(j=0; j <= G7231LpcOrder; j++) L_sumAcf[j] = 0;

    ptr_Acf = G7231CodCng.Acf + G7231LpcOrderP1;
    for(i=1; i <= G7231NbAvAcf; i ++) {
        temp = G7231sub(sh1, G7231CodCng.ShAcf[i]);
        for(j=0; j <= G7231LpcOrder; j++) {
            L_acc0 = G7231L_deposit_l(*ptr_Acf++);
            L_acc0 = G7231L_shl(L_acc0, temp); 
            L_sumAcf[j] = G7231L_add(L_sumAcf[j], L_acc0);
        }
    }

    temp = G7231norm_l(L_sumAcf[0]);
    temp = G7231sub(16, temp);
    if(temp < 0) temp = 0;
    Err = G7231extract_l(G7231L_shr(L_sumAcf[0],temp));
    for(i=1; i<G7231LpcOrderP1; i++) {
        Corr[i-1] = G7231extract_l(G7231L_shr(L_sumAcf[i],temp));
    }

    G7231Durbin(Coeff, Corr, Err, &temp);

    return;
}

void G7231CalcRC(Word16 *Coeff, Word16 *RC, Word16 *ShRC)
{
    int i, j;
    Word16 sh1;
    Word32 L_acc;

    L_acc = 0L;
    for(j=0; j<G7231LpcOrder; j++) {
        L_acc = G7231L_mac(L_acc, Coeff[j], Coeff[j]);
    }
    L_acc = G7231L_shr(L_acc, 1);
    L_acc = G7231L_add(L_acc, 0x04000000L);  
    sh1 = G7231norm_l(L_acc) - (Word16)2;   
                                
    L_acc = G7231L_shl(L_acc, sh1); 
    RC[0] = G7231round(L_acc);

    for(i=1; i<=G7231LpcOrder; i++) {
        L_acc = G7231L_mult( (Word16) 0xE000, Coeff[i-1]);   
        for(j=0; j<G7231LpcOrder-i; j++) {
            L_acc = G7231L_mac(L_acc, Coeff[j], Coeff[j+i]);
        }
        L_acc = G7231L_shl(L_acc, sh1);
        RC[i] = G7231round(L_acc);
    }
    *ShRC = sh1;
    return;
}

Flag G7231LpcDiff(Word16 *RC, Word16 ShRC, Word16 *ptrAcf, Word16 alpha)
{
    Word32 L_temp0, L_temp1;
    Word16 temp;
    int i;
    Flag diff;

    L_temp0 = 0L;
    for(i=0; i<=G7231LpcOrder; i++) {
        temp = G7231shr(ptrAcf[i], 2);  /* + 2 margin bits */
        L_temp0 = G7231L_mac(L_temp0, RC[i], temp);
    }

    temp = G7231mult_r(alpha, G7231FracThresh);
    L_temp1 = G7231L_add((Word32)temp, (Word32)alpha);
    temp = G7231add(ShRC, 9);  /* 9 = Lpc_justif. * 2 - 15 - 2 */
    L_temp1 = G7231L_shl(L_temp1, temp);

    if(L_temp0 < L_temp1) diff = 1;
    else diff = 0;
    return(diff);
}

⌨️ 快捷键说明

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