📄 lsp2.cpp
字号:
//#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 + -