www.pudn.com > p_voice.rar > DECOD2.C


/* 
** 
** File:        "decod2.c" 
** 
** Description:     Top-level source code for G.723.1 dual-rate decoder 
** 
** Functions:       Init_Decod() 
**                  Decod() 
** 
** 
*/ 
 
/* 
    ITU-T G.723.1 Floating Point Speech Coder ANSI C Source Code.  Version 5.1F 
 
    Original fixed-point code copyright (c) 1995, 
    AudioCodes, DSP Group, France Telecom, Universite de Sherbrooke. 
    All rights reserved. 
 
    Floating-point code copyright (c) 1995, 
    Intel Corporation and France Telecom (CNET). 
    All rights reserved. 
*/ 
 
 
#include  
#include  
#include  
 
#include "typedef2.h" 
#include "cst2.h" 
#include "tab2.h" 
#include "lbccode2.h" 
#include "decod2.h" 
#include "util2.h" 
#include "lpc2.h" 
#include "lsp2.h" 
#include "exc2.h" 
#include "deccng2.h" 
 
 
/* 
   The following structure contains all the static decoder 
      variables. 
*/ 
 
DECSTATDEF  DecStat; 
 
/* 
** 
** Function:        Init_Decod() 
** 
** Description:     Initializes non-zero state variables 
**          for the decoder. 
** 
** Links to text:   Section 3.11 
** 
** Arguments:       None 
** 
** Outputs:     None 
** 
** Return value:    None 
** 
*/ 
void  Init_Decod(void) 
{ 
    int i; 
 
    /* Initialize decoder data structure with zeros */ 
    memset(&DecStat,0,sizeof(DECSTATDEF)); 
 
    /* Initialize the previously decoded LSP vector to the DC vector */ 
    for (i = 0; i < LpcOrder; i++) 
        DecStat.PrevLsp[i] = LspDcTable[i]; 
 
    DecStat.Gain = (FLOAT)1.0; 
} 
 
/* 
** 
** Function:        Decod() 
** 
** Description:     Implements G.723.1 dual-rate decoder for  a frame 
**          of speech 
** 
** Links to text:   Section 3 
** 
** Arguments: 
** 
**  FLOAT  *DataBuff    Empty buffer 
**  Word16 Vinp[]       Encoded frame (22/26 bytes) 
** 
 
** Outputs: 
** 
**  FLOAT  DataBuff[]   Decoded frame (480 bytes) 
** 
** Return value: 
** 
**  Flag            Always True 
** 
*/ 
 
Flag  Decod(FLOAT *DataBuff, char *Vinp, Word16 Crc) 
{ 
    int      i, j, g; 
 
    FLOAT    Senr; 
    FLOAT    QntLpc[SubFrames*LpcOrder]; 
    FLOAT    AcbkCont[SubFrLen]; 
 
    FLOAT    LspVect[LpcOrder]; 
    FLOAT    Temp[PitchMax+Frame]; 
    FLOAT   *Dpnt; 
 
    LINEDEF  Line; 
    PFDEF    Pf[SubFrames]; 
 
    Word16   Ftyp; 
 
    /* 
     * Decode the packed bitstream for the frame.  (Text: Section 4; 
     * pars of sectio,d 2.17, 2.18) 
     */ 
    Line = Line_Unpk(Vinp, &Ftyp, Crc); 
 
    if (Line.Crc != (Word16) 0) { 
        if(DecCng.PastFtyp == 1) 
            Ftyp = 1;  /* active */ 
        else 
            Ftyp = 0;  /* untransmitted */ 
    } 
 
    if (Ftyp != 1) { 
 
        /* Silence frame : do noise generation */ 
        Dec_Cng(Ftyp, &Line, DataBuff, QntLpc); 
    } 
    else { 
 
        /* 
         * Update the frame erasure count (Text: Section 3.10) 
         */ 
        if (Line.Crc != 0) 
            DecStat.Ecount++; 
        else 
            DecStat.Ecount = 0; 
 
        if (DecStat.Ecount >  ErrMaxNum) 
            DecStat.Ecount = ErrMaxNum; 
 
        /* 
         * Decode the LSP vector for subframe 3.  (Text: Section 3.2) 
         */ 
        Lsp_Inq(LspVect, DecStat.PrevLsp, Line.LspId, Line.Crc); 
 
        /* 
         * Interpolate the LSP vectors for subframes 0--2.  Convert the 
         * LSP vectors to LPC coefficients.  (Text: Section 3.3) 
         */ 
        Lsp_Int(QntLpc, LspVect, DecStat.PrevLsp); 
 
        /* Copy the LSP vector for the next frame */ 
        for ( i = 0 ; i < LpcOrder ; i ++ ) 
            DecStat.PrevLsp[i] = LspVect[i]; 
 
        /* 
         * In case of no erasure, update the interpolation gain memory. 
         * Otherwise compute the interpolation gain (Text: Section 3.10) 
         */ 
        if (DecStat.Ecount == 0) { 
            g = (Line.Sfs[SubFrames-2].Mamp + Line.Sfs[SubFrames-1].Mamp) >> 1; 
            DecStat.InterGain = FcbkGainTable[g]; 
        } 
        else 
            DecStat.InterGain = DecStat.InterGain*(FLOAT)0.75; 
 
        /* 
         * Generate the excitation for the frame 
         */ 
        for (i = 0; i < PitchMax; i++) 
            Temp[i] = DecStat.PrevExc[i]; 
 
        Dpnt = &Temp[PitchMax]; 
 
        if (DecStat.Ecount == 0) { 
 
            for (i = 0; i < SubFrames; i++) { 
 
                /* Generate the fixed codebook excitation for a 
                   subframe. (Text: Section 3.5) */ 
                Fcbk_Unpk(Dpnt, Line.Sfs[i], Line.Olp[i>>1], i); 
 
                /* Generate the adaptive codebook excitation for a 
                   subframe. (Text: Section 3.4) */ 
                Decod_Acbk(AcbkCont, &Temp[SubFrLen*i], Line.Olp[i>>1], 
                           Line.Sfs[i].AcLg, Line.Sfs[i].AcGn); 
 
                /* Add the adaptive and fixed codebook contributions to 
                   generate the total excitation. */ 
 
                for (j = 0; j < SubFrLen; j++) 
                    Dpnt[j] = Dpnt[j] + AcbkCont[j]; 
 
                Dpnt += SubFrLen; 
            } 
 
            /* Save the excitation */ 
            for (j = 0; j < Frame; j++) 
                DataBuff[j] = Temp[PitchMax+j]; 
 
            /* Compute interpolation index. (Text: Section 3.10) */ 
            /* Use DecCng.SidGain to store                       */ 
            /* excitation energy estimation                      */ 
            DecStat.InterIndx = Comp_Info(Temp, Line.Olp[SubFrames/2-1], 
                                          &DecCng.SidGain); 
 
            /* Compute pitch post filter coefficients.  (Text: Section 3.6) */ 
            if (UsePf) 
                for (i = 0; i < SubFrames; i++) 
                    Pf[i] = Comp_Lpf(Temp, Line.Olp[i>>1], i); 
 
            /* Reload the original excitation */ 
            for (j = 0; j < PitchMax; j++) 
                Temp[j] = DecStat.PrevExc[j]; 
            for (j = 0; j < Frame; j++) 
                Temp[PitchMax+j] = DataBuff[j]; 
 
            /* Clip newly generated samples in Temp array */ 
            for (j = 0; j < Frame; j++) { 
                if (Temp[PitchMax+j] < (FLOAT)-32767.5) 
                    Temp[PitchMax+j] = (FLOAT)-32768.0; 
                else if (Temp[PitchMax+j] > (FLOAT)32766.5) 
                    Temp[PitchMax+j] = (FLOAT)32767.0; 
            } 
 
            /* Perform pitch post filtering for the frame.  (Text: Section 
               3.6) */ 
            if (UsePf) 
                for (i = 0; i < SubFrames; i++) 
                    Filt_Lpf(DataBuff, Temp, Pf[i], i); 
 
            /* Save Lsps --> LspSid */ 
            for (i=0; i < LpcOrder; i++) 
                DecCng.LspSid[i] = DecStat.PrevLsp[i]; 
        } 
        else { 
            /* If a frame erasure has occurred, regenerate the 
               signal for the frame. (Text: Section 3.10) */ 
            Regen(DataBuff, Temp, DecStat.InterIndx, DecStat.InterGain, 
                  DecStat.Ecount, &DecStat.Rseed); 
        } 
 
        /* Update the previous excitation for the next frame */ 
        for (j = 0; j < PitchMax; j++) 
            DecStat.PrevExc[j] = Temp[Frame+j]; 
 
        /* Resets random generator for CNG */ 
        DecCng.RandSeed = 12345; 
    } 
 
    /* Save Ftyp information for next frame */ 
    DecCng.PastFtyp = Ftyp; 
 
    /* 
     * Synthesize the speech for the frame 
     */ 
    Dpnt = DataBuff; 
    for (i = 0; i < SubFrames; i++) { 
 
        /* Compute the synthesized speech signal for a subframe. 
         * (Text: Section 3.7) 
         */ 
        Synt(Dpnt, &QntLpc[i*LpcOrder]); 
 
        if (UsePf) { 
 
            /* Do the formant post filter. (Text: Section 3.8) */ 
            Senr = Spf( Dpnt, &QntLpc[i*LpcOrder] ) ; 
 
            /* Do the gain scaling unit.  (Text: Section 3.9) */ 
            Scale(Dpnt, Senr); 
        } 
 
        Dpnt += SubFrLen; 
    } 
 
    return (Flag) True; 
}