📄 lsp2.c
字号:
/*
**
** 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()
*/
/*
ITU-T G.723.1 Floating Point Speech Coder ANSI C Source Code. Version 5.1F
Original fixed-point code copyright (c) 1995,
AudioCodes, DSP Group, France Telecom, Universite de Sherbrooke.
All rights reserved.
Floating-point code copyright (c) 1995,
Intel Corporation and France Telecom (CNET).
All rights reserved.
*/
#include <stdio.h>
#include <math.h>
#include "typedef2.h"
#include "cst2.h"
#include "tab2.h"
#include "util2.h"
#include "lsp2.h"
/*
**
** 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:
**
** Word32 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.)
**
*/
Word32 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:
**
** Word32 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].
**
*/
Word32 Lsp_Svq(FLOAT *Lsp, FLOAT *Wvect)
{
int i,j,k;
Word32 Rez;
Word32 Indx;
int Start,Dim;
FLOAT Tmp[LpcOrder];
FLOAT *LspQntPnt;
FLOAT Max,Err;
/* Initialize the return value */
Rez = (Word32) 0;
/* Quantize each band separately */
for (k=0; k < LspQntBands; 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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -