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

📄 lpc2.cpp

📁 G711语音压缩源码
💻 CPP
字号:
//#include "stdafx.h"
#include <math.h>
#include <memory.h>


#include "LanAudio.h"
#include "Global.h"
/*
**
** File:    lpc2.c
**
** Description: Functions that implement linear predictive coding
**      (LPC) operations.
**
** Functions:
**
**  Computing LPC coefficients:
**
**      Comp_Lpc()
**      Durbin()
**
**  Perceptual noise weighting:
**
**      Wght_Lpc()
**      Error_Wght()
**
**  Computing combined impulse response:
**
**      Comp_Ir()
**
**  Computing ringing response:
**
**      Sub_Ring()
**      Upd_Ring()
**
**  Synthesizing speech:
**
**      Synt()
**      Spf()
*/

/*
**
** Function:        Durbin()
**
** Description:     Implements the Levinson-Durbin algorithm for a
**          subframe.  The Levinson-Durbin algorithm
**          recursively computes the minimum mean-squared
**          error (MMSE) linear prediction filter based on the
**          estimated autocorrelation coefficients.
**
** Links to text:   Section 2.4
**
** Arguments:
**
**  float *Lpc Empty buffer
**  float Corr[]   First- through tenth-order autocorrelations (10 words)
**  float Err  Zeroth-order autocorrelation, or energy
**
** Outputs:
**
**  float Lpc[]    LPC coefficients (10 words)
**
** Return value:    None
**
*/
float  Durbin(float *Lpc, float *Corr, float Err, float *Pk2)
{
    int    i,j;
    float  Temp[LpcOrder];
    float  Pk,Tmp0;

    /*  Initialize the LPC vector  */

    for (i=0; i < LpcOrder; i++)
        Lpc[i] = (float)0.0;

    /*  Compute the partial correlation (parcor) coefficient  */

    for (i=0; i < LpcOrder; i++)
    {
        Tmp0 = Corr[i];
        for (j=0; j<i; j++)
            Tmp0 -= Lpc[j]*Corr[i-j-1];

        if (::fabs(Tmp0) >= Err) {
            *Pk2 = (float)0.99;
            break;
        }

        Lpc[i] = Pk = Tmp0/Err;
        Err -= Tmp0*Pk;

        /*
         * Sine detector
         */
        if ( i == 1 )
            *Pk2 = -Pk;

        for (j=0; j < i; j++)
            Temp[j] = Lpc[j];

        for (j=0; j < i; j++)
            Lpc[j] = Lpc[j] - Pk*Temp[i-j-1];
    }
    return Err;
}


/*
**
** Function:        Wght_Lpc()
**
** Description:     Computes the formant perceptual weighting
**          filter coefficients for a frame.  These
**          coefficients are geometrically scaled versions
**          of the unquantized LPC coefficients.
**
** Links to text:   Section 2.8
**
** Arguments:
**
**  float  *PerLpc      Empty Buffer
**  float  UnqLpc[]     Unquantized LPC coefficients (40 words)
**
** Outputs:
**
**
**  float  PerLpc[]     Perceptual weighting filter coefficients
**              (80 words)
**
** Return value:    None
**
*/
void  Wght_Lpc(float *PerLpc, float *UnqLpc)
{
    int  i,j;

    for (i=0; i < SubFrames; i++)
    {
        /*
         * Compute the jth FIR coefficient by multiplying the jth LPC
         * coefficient by (0.9)^j. Compute the jth IIR coefficient by
         * multiplying the jth LPC coefficient by (0.5)^j.
         */

        for (j=0; j < LpcOrder; j++)
        {
            PerLpc[j]          = UnqLpc[j]*PerFiltZeroTable[j];
            PerLpc[j+LpcOrder] = UnqLpc[j]*PerFiltPoleTable[j];
        }
        PerLpc += 2*LpcOrder;
        UnqLpc += LpcOrder;
    }
}


/*
**
** Function:        Comp_Ir()
**
** Description:     Computes the combined impulse response of the
**          formant perceptual weighting filter, harmonic
**          noise shaping filter, and synthesis filter for
**          a subframe.
**
** Links to text:   Section 2.12
**
** Arguments:
**
**  float  *ImpResp     Empty Buffer
**  float  QntLpc[]     Quantized LPC coefficients (10 words)
**  float  PerLpc[]     Perceptual filter coefficients (20 words)
**  PWDEF  Pw           Harmonic noise shaping filter parameters
**
** Outputs:
**
**  float  ImpResp[]    Combined impulse response (60 words)
**
** Return value:    None
**
*/
void  Comp_Ir(float *ImpResp, float *QntLpc, float *PerLpc, PWDEF Pw)
{
    int    i,j;

    float  FirDl[LpcOrder];
    float  IirDl[LpcOrder];
    float  Temp[PitchMax+SubFrLen];
    float  Acc0,Acc1;

    /*
     * Clear all memory.  Impulse response calculation requires
     * an all-zero initial state.
     */

    /* Perceptual weighting filter */

    for (i=0; i < LpcOrder; i++)
        FirDl[i] = IirDl[i] = (float)0.0;

    /* Harmonic noise shaping filter */

    for (i=0; i < PitchMax+SubFrLen; i++)
        Temp[i] = (float)0.0;

    /*  Input a single impulse  */

    Acc0 = (float)1.0;

    /*  Do for all elements in a subframe  */

    for (i=0; i < SubFrLen; i++)
    {
        /*  Synthesis filter  */

//        Acc1 = Acc0 = Acc0 + DotProd(QntLpc,FirDl,LpcOrder);
        Acc1 = Acc0 = Acc0 + DotProd10s(QntLpc,FirDl);

        /*  Perceptual weighting filter  */

        /*  FIR part */

//        Acc0 -= DotProd(PerLpc,FirDl,LpcOrder);
        Acc0 -= DotProd10s(PerLpc,FirDl);
        for (j=LpcOrder-1; j > 0; j--)
            FirDl[j] = FirDl[j-1];

        FirDl[0] = Acc1;

        /*  IIR part */

//        Acc0 += DotProd(&PerLpc[LpcOrder],IirDl,LpcOrder);
        Acc0 += DotProd10s(&PerLpc[LpcOrder],IirDl);
        for (j=LpcOrder-1; j > 0; j--)
            IirDl[j] = IirDl[j-1];

        Temp[PitchMax+i] = IirDl[0] = Acc0;

        /*  Harmonic noise shaping filter  */

        ImpResp[i] = Acc0 - Pw.Gain*Temp[PitchMax-Pw.Indx+i];

        Acc0 = (float)0.0;
    }
}





⌨️ 快捷键说明

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