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

📄 decoder.cpp

📁 G711语音压缩源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//#include "stdafx.h"
#include <math.h>
#include <memory.h>
#include <float.h>

#include "LanAudio.h"
#include "Global.h"

unsigned char linear2alaw(_int16	pcm_val);
_int16 alaw2linear(unsigned char  a_val);
unsigned char linear2ulaw(_int16	pcm_val);
_int16 ulaw2linear(unsigned char	u_val);
unsigned char alaw2ulaw(unsigned char	aval);
unsigned char ulaw2alaw(unsigned char	uval);

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CLanAudioDecoder::CLanAudioDecoder(BOOL bPostFilter,EAudioCodec nCodec)
{
	UsePf = bPostFilter;
    Init_Decod();
    Init_Dec_Cng();
//	OutputDebugString("Audio Decoder Inited\n");
	m_nCodec = nCodec;
	m_bMute = FALSE;
}

CLanAudioDecoder::~CLanAudioDecoder()
{
}
int CLanAudioDecoder::DecodeG711(unsigned char * input,short* decode)
{
	unsigned char * org_input = input;
	short* org_decode = decode;

	if(m_bMute)
		for(int i = 0; i < G711_Frame; i++){
			*decode = 0;
			decode ++;
		}
	else{ 
		if(m_nCodec==G711_A)
			for(int i = 0; i < G711_Frame; i++){
				*decode = alaw2linear(*input);
				input ++;
				decode ++;
			}
		else
			for(int i = 0; i < G711_Frame; i++){
				*decode = ulaw2linear(*input);
				input ++;
				decode ++;
			}
	}

	input = org_input;
	decode = org_decode;
	return(G711_Frame);
}

int CLanAudioDecoder::DecodeG723(short * iFrame, char * cCode)
{
	int i, iInfo, iSize;

    short Crc = (short) 0;
    Decod(DataBuff, cCode, Crc);

    for (i = 0; i < Frame; i ++)
    {
        if (DataBuff[i] < (float)-32767.5)
            iFrame[i] = -32768L;
        else if (DataBuff[i] > (float)32766.5)
            iFrame[i] = 32767;
        else
        {
            if (DataBuff[i] < 0)
                iFrame[i] = (short) (DataBuff[i]-(float)0.5);
            else
                iFrame[i] = (short) (DataBuff[i]+(float)0.5);
        }
    }

    iInfo = cCode[0] & 0x0003;

    /* Check frame type and rate information */
    switch (iInfo) 
	{
        case 0x0002 : {  /* SID frame */
            iSize = 4;
            break;
        }

        case 0x0003 : {  /* untransmitted silence frame */
            iSize = 1;
            break;
        }

        case 0x0001 : {  /* active frame, low rate */
            iSize = 20;
            break;
        }

        default : {      /* active frame, high rate */
            iSize = 24;
        }
    }
	return iSize;
}

int CLanAudioDecoder::Decode(short * iFrame, char * cCode)
{
	switch (m_nCodec){
	case G711_A:
	case G711_U:
		return(DecodeG711((unsigned char *)cCode,iFrame));
		break;
	case G723:
		return(DecodeG723(iFrame,cCode));
		break;
	default:
		return(0);
		break;
	}
}

/*
**
** 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  CLanAudioDecoder::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:        Init_Dec_Cng()
**
** Description:     Initialize Dec_Cng static variables
**
** Links to text:
**
** Arguments:       None
**
** Outputs:         None
**
** Return value:    None
**
*/
void CLanAudioDecoder::Init_Dec_Cng(void)
{
    int i;

    DecCng.PastFtyp = 1;
    DecCng.SidGain = (float)0.0;
    for (i=0; i<LpcOrder; i++)
        DecCng.LspSid[i] = LspDcTable[i];
    DecCng.RandSeed = 12345;
    return;
}

/*
**
** 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
**  short Vinp[]       Encoded frame (22/26 bytes)
**

** Outputs:
**
**  float  DataBuff[]   Decoded frame (480 bytes)
**
** Return value:
**
**  BOOL            Always TRUE
**
*/

BOOL  CLanAudioDecoder::Decod(float *DataBuff, char *Vinp, short 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];

    short   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 != (short) 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 TRUE;
}

/*
**
** Function:           Dec_Cng()
**
** Description:        Receives Ftyp
**                     0  :  for untransmitted frames
**                     2  :  for SID frames
**                     Decodes SID frames
**                     Computes current frame excitation
**                     Computes current frame LSPs
**
** Links to text:
**
** Arguments:
**
**  short  Ftyp       Type of silence frame
**  LINEDEF *Line      Coded parameters
**  float   *DataExc   Current frame excitation
**  float   *QntLpc    Interpolated frame LPC coefficients
**
** Outputs:
**
**  float   *DataExc
**  float   *QntLpc
**
** Return value:       None
**
*/
void CLanAudioDecoder::Dec_Cng(short Ftyp, LINEDEF *Line, float *DataExc, float *QntLpc)
{
    short temp;
    int i;

    if (Ftyp == 2) {
        /*
         * SID Frame decoding
         */

        DecCng.SidGain = Dec_SidGain((short) Line->Sfs[0].Mamp);

        /* Inverse quantization of the LSP */
        Lsp_Inq(DecCng.LspSid, DecStat.PrevLsp, Line->LspId, 0);
    }
    else {

        /*
         * non SID Frame
         */
        if (DecCng.PastFtyp == 1) {
            /*
             * Case of 1st SID frame erased : quantize-decode
             * energy estimate stored in DecCng.SidGain
             * scaling factor in DecCng.CurGain
             */
            temp = Qua_SidGain(&DecCng.SidGain, 0);
            DecCng.SidGain = Dec_SidGain(temp);
        }
    }

    if (DecCng.PastFtyp == 1) {
        DecCng.CurGain = DecCng.SidGain;
    }
    else {
        DecCng.CurGain =   (float) 0.875 * DecCng.CurGain
                         + (float) 0.125 * DecCng.SidGain;
    }
    Calc_Exc_Rand(DecCng.CurGain, DecStat.PrevExc, DataExc,
                    &DecCng.RandSeed, Line);

    /* Interpolate the Lsp vectors */

⌨️ 快捷键说明

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