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

📄 lsp2.cpp

📁 G711语音压缩源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//#include "stdafx.h"

#include <math.h>
#include <memory.h>

#include "LanAudio.h"
#include "Global.h"
/*
**
** File:    lsp2.c
**
** Description: Functions that implement line spectral pair
**      (LSP) operations.
**
** Functions:
**
**  Converting between linear predictive coding (LPC) coefficients
**  and LSP frequencies:
**
**      AtoLsp()
**      LsptoA()
**
**  Vector quantization (VQ) of LSP frequencies:
**
**      Lsp_Qnt()
**      Lsp_Svq()
**      Lsp_Inq()
**
**  Interpolation of LSP frequencies:
**
**      Lsp_Int()
*/

/*
**
** Function:        Polynomial
**
** Description:     Sub-function of AtoLsp().  Evaluates the polynomial once.
*/

float Polynomial(float *Lpq, int CosPtr)
{
    float  Ret;
    int    j;

    Ret = (float)0.0;
    for (j=0; j<=LpcOrder/2; j++)
        Ret += Lpq[LpcOrder-2*j]*CosineTable[(CosPtr*j) % CosineTableSize];

    return(Ret);
}


/*
**
** Function:            AtoLsp()
**
** Description:     Transforms 10 LPC coefficients to the 10
**          corresponding LSP frequencies for a subframe.
**          This transformation is done once per frame,
**          for subframe 3 only.  The transform algorithm
**          generates sum and difference polynomials from
**          the LPC coefficients.  It then evaluates the
**          sum and difference polynomials at uniform
**          intervals of pi/256 along the unit circle.
**          Intervals where a sign change occurs are
**          interpolated to find the zeros of the
**          polynomials, which are the LSP frequencies.
**
** Links to text:   Section 2.5
**
** Arguments:
**
**  float  *LspVect     Empty Buffer
**  float  Lpc[]        Unquantized LPC coefficients (10 words)
**  float  PrevLsp[]    LSP frequencies from the previous frame (10 words)
**
** Outputs:
**
**  float  LspVect[]    LSP frequencies for the current frame (10 words)
**
** Return value:        None
**
**/
void  AtoLsp(float *LspVect, float *Lpc, float *PrevLsp)
{
    int    i,j,k;
    int    LspCnt;
    float  Lpq[LpcOrder+2];
    float  PrevVal,CurrVal,AbsPrev,AbsCurr;

    /*
     * Perform a bandwidth expansion on the LPC coefficients.  This
     * scales the poles of the LPC synthesis filter by a factor of
     * 0.994.
     */

    for (i=0; i < LpcOrder; i++)
        LspVect[i] = Lpc[i]*BandExpTable[i];

    /* This loop computes the coefficients of P(z) and Q(z).  The long
     * division (to remove the real zeros) is done recursively.
     */

    Lpq[0] = Lpq[1] = (float)1.0;

    for (i=0; i < LpcOrder/2; i++)
    {
        Lpq[2*i+2] = -Lpq[2*i+0] - LspVect[i] - LspVect[LpcOrder-1-i];
        Lpq[2*i+3] =  Lpq[2*i+1] - LspVect[i] + LspVect[LpcOrder-1-i];
    }
    Lpq[LpcOrder+0] *= (float)0.5;
    Lpq[LpcOrder+1] *= (float)0.5;

    /* Do first evaluation */

    k = 0;
    LspCnt = 0;
    PrevVal = Polynomial(Lpq,0);

    /*
     * Search loop.  Evaluate P(z) and Q(z) at uniform intervals of
     * pi/256 along the unit circle.  Check for zero crossings.  The
     * zeros of P(w) and Q(w) alternate, so only one of them need by
     * evaluated at any given step.
     */

    for (i=1; i < CosineTableSize/2; i++)
    {
        /* Evaluate the polynomial */

        CurrVal = Polynomial(&Lpq[k],i);

        /* Test for sign change indicating a zero crossing */

        if (CurrVal*PrevVal < 0)
        {
            AbsPrev = (float)::fabs(PrevVal);
            AbsCurr = (float)::fabs(CurrVal);

            LspVect[LspCnt++] = (i-1 + AbsPrev/(AbsPrev+AbsCurr));

            /* Check if all found */

            if (LspCnt == LpcOrder)
                break;

            /* Switch the pointer, evaluate again */

            k ^= 1;
            CurrVal = Polynomial(&Lpq[k],i);
        }
        PrevVal = CurrVal;
    }

    /*
     *  Check if all 10 zeros were found.  If not, ignore the results of
     *  the search and use the previous frame's LSP frequencies instead.
     */

    if (LspCnt != LpcOrder)
    {
        for (j=0; j < LpcOrder; j++)
            LspVect[j] = PrevLsp[j];
    }
    return;
}


/*
**
** Function:            Lsp_Qnt()
**
** Description:     Vector quantizes the LSP frequencies.  The LSP
**          vector is divided into 3 sub-vectors, or
**          bands, of dimension 3, 3, and 4.  Each band is
**          quantized separately using a different VQ
**          table.  Each table has 256 entries, so the
**          quantization generates three indices of 8 bits
**          each.  (Only the LSP vector for subframe 3 is
**          quantized per frame.)
**
** Links to text:   Section 2.5
**
** Arguments:
**
**  float CurrLsp[]    Unquantized LSP frequencies (10) for the current frame
**  float PrevLsp[]    LSP frequencies (10) from the previous frame
**
** Outputs:            Quantized LSP frequencies (10) for the current frame
**
** Return value:
**
**  int  Long word packed with the 3 VQ indices.  Band 0
**          corresponds to bits [23:16], band 1 corresponds
**          to bits [15:8], and band 2 corresponds to bits [7:0].
**          (Bit 0 is the least significant.)
**
*/
int Lsp_Qnt(float *CurrLsp, float *PrevLsp)
{
    int   i;

    float Wvect[LpcOrder];
    float Min,Tmp;

    /*
     * Compute the VQ weighting vector.  The weights assign greater
     * precision to those frequencies that are closer together.
     */

    /* Compute the end differences */

    Wvect[0] = ((float)1.0)/(CurrLsp[1] - CurrLsp[0]);
    Wvect[LpcOrder-1] = ((float)1.0)/(CurrLsp[LpcOrder-1] - CurrLsp[LpcOrder-2]);

    /* Compute the rest of the differences */

    for (i=1; i < LpcOrder-1; i++)
    {
        Min = CurrLsp[i+1] - CurrLsp[i];
        Tmp = CurrLsp[i] - CurrLsp[i-1];

        if (Tmp < Min)
            Min = Tmp;

        if (Min > (float)0.0)
            Wvect[i] = ((float)1.0)/Min;
        else
            Wvect[i] = (float)1.0;
    }

    /* Generate the prediction vector and subtract it.  Use a constant
     * first-order predictor based on the previous (DC-free) LSP vector.
     */

    for (i=0; i < LpcOrder; i++)
        CurrLsp[i] = (CurrLsp[i] - LspDcTable[i]) -
                        LspPred0*(PrevLsp[i] - LspDcTable[i]);

    /* Do the vector quantization for all three bands */

    return Lsp_Svq(CurrLsp, Wvect);
}


/*
**
** Function:            Lsp_Svq()
**
** Description:     Performs the search of the VQ tables to find
**          the optimum LSP indices for all three bands.
**          For each band, the search finds the index which
**          minimizes the weighted squared error between
**          the table entry and the target.
**
** Links to text:   Section 2.5
**
** Arguments:
**
**  float  Tv[]     VQ target vector (10 words)
**  float  Wvect[]      VQ weight vector (10 words)
**
** Outputs:         None
**
** Return value:
**
**  int  Long word packed with the 3 VQ indices.  Band 0
**          corresponds to bits [23:16], band 1 corresponds
**          to bits [15:8], and band 2 corresponds to bits [7:0].
**
*/
/*int  Lsp_Svq(float *Lsp, float *Wvect)
{
    int  i,j,k;

    int Rez;
    int Indx;
    int    Start,Dim;
    float  Tmp[LpcOrder];
    float *LspQntPnt;
    float  Max,Err;

    /*  Initialize the return value  */

  /*  Rez = (int) 0;

    /*  Quantize each band separately  */

//    for (k=0; k < LspQntBands; k++)
/*    for (k=0; k < 2; k++)
    {

        /*
         * Search over the entire VQ table to find the index that
         * minimizes the error.
         */

        /* Initialize the search */

  /*      Max = (float)-1.0;
        Indx = 0;
        LspQntPnt = BandQntTable[k];
        Start = BandInfoTable[k][0];
        Dim = BandInfoTable[k][1];

        for (i=0; i < LspCbSize; i++)
        {
            /* Generate weighted vector */

    /*        for (j=0; j<Dim; j++)
                Tmp[j] = Wvect[Start+j]*LspQntPnt[j];

            /* Compute the Error */

//            Err = ((float)2.0)*DotProd(&Lsp[Start],Tmp,Dim) - DotProd(LspQntPnt,Tmp,Dim);
   /*         Err = ((float)2.0)*DotProd3s(&Lsp[Start],Tmp) - 
                    DotProd3s(LspQntPnt,Tmp);
            LspQntPnt += BandInfoTable[k][1];

            if (Err > Max)
            {
                Max = Err;
                Indx = (int) i;
            }
        }
        Rez = (Rez << 8) | Indx;
    }

//    for (k=0; k < LspQntBands; k++)
    for (k=2; k < 3; k++)
    {

        /*
         * Search over the entire VQ table to find the index that
         * minimizes the error.
         */

        /* Initialize the search */

   /*     Max = (float)-1.0;
        Indx = 0;
        LspQntPnt = BandQntTable[k];
        Start = BandInfoTable[k][0];
        Dim = BandInfoTable[k][1];

        for (i=0; i < LspCbSize; i++)
        {
            /* Generate weighted vector */

    /*        for (j=0; j<Dim; j++)
                Tmp[j] = Wvect[Start+j]*LspQntPnt[j];

            /* Compute the Error */

//            Err = ((float)2.0)*DotProd(&Lsp[Start],Tmp,Dim) - DotProd(LspQntPnt,Tmp,Dim);
   /*         Err = ((float)2.0)*DotProd4s(&Lsp[Start],Tmp) -
                    DotProd4s(LspQntPnt,Tmp);
            LspQntPnt += BandInfoTable[k][1];

            if (Err > Max)
            {
                Max = Err;
                Indx = (int) i;
            }
        }
        Rez = (Rez << 8) | Indx;
    }
    return Rez;
}  */

int  Lsp_Svq(float *Lsp, float *Wvect)
{
    int  i,j,k;

    int Rez;
    int Indx;
    int    Start,Dim;
    float  Tmp[LpcOrder];
    float *LspQntPnt;
    float  Max,Err;

    /*  Initialize the return value  */

    Rez = (int) 0;

    /*  Quantize each band separately  */

//    for (k=0; k < LspQntBands; k++)
    for (k=0; k < 2; k++)
    {

        /*
         * Search over the entire VQ table to find the index that
         * minimizes the error.
         */

        /* Initialize the search */

        Max = 0;
        Indx = 0;

⌨️ 快捷键说明

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