📄 lpc2.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 + -