📄 lsp.c
字号:
for ( j = 0 ; j < BandInfoTable[k][1] ; j ++ )
Tmp[j] = mult_r( Wvect[BandInfoTable[k][0]+j],
LspQntPnt[j] ) ;
Acc0 = (Word32) 0 ;
for ( j = 0 ; j < BandInfoTable[k][1] ; j ++ )
Acc0 = L_mac( Acc0, Tv[BandInfoTable[k][0]+j], Tmp[j] ) ;
Acc0 = L_shl( Acc0, (Word16) 1 ) ;
for ( j = 0 ; j < BandInfoTable[k][1] ; j ++ )
Acc0 = L_msu( Acc0, LspQntPnt[j], Tmp[j] ) ;
LspQntPnt += BandInfoTable[k][1] ;
/*
* Compare the metric to the previous maximum and select the
* new index
*/
if ( Acc0 > Acc1 ) {
Acc1 = Acc0 ;
Indx = (Word32) i ;
}
}
/*
* Pack the result with the optimum index for this band
*/
Rez = L_shl( Rez, (Word16) LspCbBits ) ;
Rez = L_add( Rez, Indx ) ;
}
return Rez ;
}
/*
**
** Function: Lsp_Inq()
**
** Description: Performs inverse vector quantization of the
** LSP frequencies. The LSP vector is divided
** into 3 sub-vectors, or bands, of dimension 3,
** 3, and 4. Each band is inverse quantized
** separately using a different VQ table. Each
** table has 256 entries, so each VQ index is 8
** bits. (Only the LSP vector for subframe 3 is
** quantized per frame.)
**
** Links to text: Sections 2.6, 3.2
**
** Arguments:
**
** Word16 *Lsp Empty buffer
** Word16 PrevLsp[] Quantized LSP frequencies from the previous frame
** (10 words)
** Word32 LspId 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].
** Word16 Crc Frame erasure indicator
**
** Outputs:
**
** Word16 Lsp[] Quantized LSP frequencies for current frame (10
** words)
**
** Return value: None
**
*/
void Lsp_Inq( Word16 *Lsp, Word16 *PrevLsp, Word32 LspId, Word16 Crc )
{
int i,j ;
Word16 *LspQntPnt ;
Word16 Scon ;
Word16 Lprd ;
Word16 Tmp ;
Flag Test ;
/*
* Check for frame erasure. If a frame erasure has occurred, the
* resulting VQ table entries are zero. In addition, a different
* fixed predictor and minimum frequency separation are used.
*/
if ( Crc == (Word16) 0 ) {
Scon = (Word16) 0x0100 ;
Lprd = LspPrd0 ;
}
else {
LspId = (Word32) 0 ;
Scon = (Word16) 0x0200 ;
Lprd = LspPrd1 ;
}
/*
* Inverse quantize the 10th-order LSP vector. Each band is done
* separately.
*/
for ( i = LspQntBands-1; i >= 0 ; i -- ) {
/*
* Get the VQ table entry corresponding to the transmitted index
*/
Tmp = (Word16) ( LspId & (Word32) 0x000000ff ) ;
LspId >>= 8 ;
LspQntPnt = BandQntTable[i] ;
for ( j = 0 ; j < BandInfoTable[i][1] ; j ++ )
Lsp[BandInfoTable[i][0] + j] =
LspQntPnt[Tmp*BandInfoTable[i][1] + j] ;
}
/*
* Subtract the DC component from the previous frame's quantized
* vector
*/
for ( j = 0 ; j < LpcOrder ; j ++ )
PrevLsp[j] = sub(PrevLsp[j], LspDcTable[j] ) ;
/*
* Generate the prediction vector using a fixed first-order
* predictor based on the previous frame's (DC-free) quantized
* vector
*/
for ( j = 0 ; j < LpcOrder ; j ++ ) {
Tmp = mult_r( PrevLsp[j], Lprd ) ;
Lsp[j] = add( Lsp[j], Tmp ) ;
}
/*
* Add the DC component back to the previous quantized vector,
* which is needed in later routines
*/
for ( j = 0 ; j < LpcOrder ; j ++ ) {
PrevLsp[j] = add( PrevLsp[j], LspDcTable[j] ) ;
Lsp[j] = add( Lsp[j], LspDcTable[j] ) ;
}
/*
* Perform a stability test on the quantized LSP frequencies. This
* test checks that the frequencies are ordered, with a minimum
* separation between each. If the test fails, the frequencies are
* iteratively modified until the test passes. If after 10
* iterations the test has not passed, the previous frame's
* quantized LSP vector is used.
*/
for ( i = 0 ; i < LpcOrder ; i ++ ) {
/* Check the first frequency */
if ( Lsp[0] < (Word16) 0x180 )
Lsp[0] = (Word16) 0x180 ;
/* Check the last frequency */
if ( Lsp[LpcOrder-1] > (Word16) 0x7e00 )
Lsp[LpcOrder-1] = (Word16) 0x7e00 ;
/* Perform the modification */
for ( j = 1 ; j < LpcOrder ; j ++ ) {
Tmp = add( Scon, Lsp[j-1] ) ;
Tmp = sub( Tmp, Lsp[j] ) ;
if ( Tmp > (Word16) 0 ) {
Tmp = shr( Tmp, (Word16) 1 ) ;
Lsp[j-1] = sub( Lsp[j-1], Tmp ) ;
Lsp[j] = add( Lsp[j], Tmp ) ;
}
}
Test = False ;
/*
* Test the modified frequencies for stability. Break out of
* the loop if the frequencies are stable.
*/
for ( j = 1 ; j < LpcOrder ; j ++ ) {
Tmp = add( Lsp[j-1], Scon ) ;
Tmp = sub( Tmp, (Word16) 4 ) ;
Tmp = sub( Tmp, Lsp[j] ) ;
if ( Tmp > (Word16) 0 )
Test = True ;
}
if ( Test == False )
break ;
}
/*
* Return the result of the stability check. True = not stable,
* False = stable.
*/
if ( Test == True) {
for ( j = 0 ; j < LpcOrder ; j ++ )
Lsp[j] = PrevLsp[j] ;
}
return;
}
/*
**
** Function: Lsp_Int()
**
** Description: Computes the quantized LPC coefficients for a
** frame. First the quantized LSP frequencies
** for all subframes are computed by linear
** interpolation. These frequencies are then
** transformed to quantized LPC coefficients.
**
** Links to text: Sections 2.7, 3.3
**
** Arguments:
**
** Word16 *QntLpc Empty buffer
** Word16 CurrLsp[] Quantized LSP frequencies for the current frame,
** subframe 3 (10 words)
** Word16 PrevLsp[] Quantized LSP frequencies for the previous frame,
** subframe 3 (10 words)
**
** Outputs:
**
** Word16 QntLpc[] Quantized LPC coefficients for current frame, all
** subframes (40 words)
**
** Return value: None
**
*/
void Lsp_Int( Word16 *QntLpc, Word16 *CurrLsp, Word16 *PrevLsp )
{
int i,j ;
Word16 Tmp ;
Word16 *Dpnt ;
Word32 Acc0 ;
/*
* Initialize the interpolation factor
*/
Tmp = (Word16) (MIN_16 / SubFrames ) ;
Dpnt = QntLpc ;
/*
* Do for all subframes
*/
for ( i = 0 ; i < SubFrames ; i ++ ) {
/*
* Compute the quantized LSP frequencies by linear interpolation
* of the frequencies from subframe 3 of the current and
* previous frames
*/
for ( j = 0 ; j < LpcOrder ; j ++ ) {
Acc0 = L_deposit_h( PrevLsp[j] ) ;
Acc0 = L_mac( Acc0, Tmp, PrevLsp[j] ) ;
Acc0 = L_msu( Acc0, Tmp, CurrLsp[j] ) ;
Dpnt[j] = round( Acc0 ) ;
}
/*
* Convert the quantized LSP frequencies to quantized LPC
* coefficients
*/
LsptoA( Dpnt ) ;
Dpnt += LpcOrder ;
/* Update the interpolation factor */
Tmp = add( Tmp, (Word16) (MIN_16 / SubFrames ) ) ;
}
}
/*
**
** Function: LsptoA()
**
** Description: Converts LSP frequencies to LPC coefficients
** for a subframe. Sum and difference
** polynomials are computed from the LSP
** frequencies (which are the roots of these
** polynomials). The LPC coefficients are then
** computed by adding the sum and difference
** polynomials.
**
** Links to text: Sections 2.7, 3.3
**
** Arguments:
**
** Word16 Lsp[] LSP frequencies (10 words)
**
** Outputs:
**
** Word16 Lsp[] LPC coefficients (10 words)
**
** Return value: None
**
*/
void LsptoA( Word16 *Lsp )
{
int i,j ;
Word32 Acc0,Acc1 ;
Word16 Tmp ;
Word32 P[LpcOrder/2+1] ;
Word32 Q[LpcOrder/2+1] ;
/*
* Compute the cosines of the LSP frequencies by table lookup and
* linear interpolation
*/
for ( i = 0 ; i < LpcOrder ; i ++ ) {
/*
* Do the table lookup using bits [15:7] of the LSP frequency
*/
j = (int) shr( Lsp[i], (Word16) 7 ) ;
Acc0 = L_deposit_h( CosineTable[j] ) ;
/*
* Do the linear interpolations using bits [6:0] of the LSP
* frequency
*/
Tmp = sub(CosineTable[j+1], CosineTable[j] ) ;
Acc0 = L_mac( Acc0, Tmp, add( shl( (Word16)(Lsp[i] & 0x007f) ,
(Word16)8 ), (Word16) 0x0080 ) ) ;
Acc0 = L_shl( Acc0, (Word16) 1 ) ;
Lsp[i] = negate( round( Acc0 ) ) ;
}
/*
* Compute the sum and difference polynomials with the real roots
* removed. These are computed by polynomial multiplication as
* follows. Let the sum polynomial be P(z). Define the elementary
* polynomials P_i(z) = 1 - 2cos(w_i) z^{-1} + z^{-2}, for 1<=i<=
* 5, where {w_i} are the LSP frequencies corresponding to the sum
* polynomial. Then P(z) = P_1(z)P_2(z)...P_5(z). Similarly
* the difference polynomial Q(z) = Q_1(z)Q_2(z)...Q_5(z).
*/
/*
* Initialize the arrays with the coefficients of the product
* P_1(z)P_2(z) and Q_1(z)Q_2(z). Scale by 1/8.
*/
P[0] = (Word32) 0x10000000L ;
P[1] = L_mult( Lsp[0], (Word16) 0x2000 ) ;
P[1] = L_mac( P[1], Lsp[2], (Word16) 0x2000 ) ;
P[2] = L_mult( Lsp[0], Lsp[2] ) ;
P[2] = L_shr( P[2], (Word16) 1 ) ;
P[2] = L_add( P[2], (Word32) 0x20000000L ) ;
Q[0] = (Word32) 0x10000000L ;
Q[1] = L_mult( Lsp[1], (Word16) 0x2000 ) ;
Q[1] = L_mac( Q[1], Lsp[3], (Word16) 0x2000 ) ;
Q[2] = L_mult( Lsp[1], Lsp[3] ) ;
Q[2] = L_shr( Q[2], (Word16) 1 ) ;
Q[2] = L_add( Q[2], (Word32) 0x20000000L ) ;
/*
* Compute the intermediate polynomials P_1(z)P_2(z)...P_i(z) and
* Q_1(z)Q_2(z)...Q_i(z), for i = 2, 3, 4. Each intermediate
* polynomial is symmetric, so only the coefficients up to i+1 need
* by computed. Scale by 1/2 each iteration for a total of 1/8.
*/
for ( i = 2 ; i < LpcOrder/2 ; i ++ ) {
/* Compute coefficient (i+1) */
Acc0 = P[i] ;
Acc0 = L_mls( Acc0, Lsp[2*i+0] ) ;
Acc0 = L_add( Acc0, P[i-1] ) ;
P[i+1] = Acc0 ;
Acc1 = Q[i] ;
Acc1 = L_mls( Acc1, Lsp[2*i+1] ) ;
Acc1 = L_add( Acc1, Q[i-1] ) ;
Q[i+1] = Acc1 ;
/* Compute coefficients i, i-1, ..., 2 */
for ( j = i ; j >= 2 ; j -- ) {
Acc0 = P[j-1] ;
Acc0 = L_mls( Acc0, Lsp[2*i+0] ) ;
Acc0 = L_add( Acc0, L_shr(P[j], (Word16) 1 ) ) ;
Acc0 = L_add( Acc0, L_shr(P[j-2], (Word16) 1 ) ) ;
P[j] = Acc0 ;
Acc1 = Q[j-1] ;
Acc1 = L_mls( Acc1, Lsp[2*i+1] ) ;
Acc1 = L_add( Acc1, L_shr(Q[j], (Word16) 1 ) ) ;
Acc1 = L_add( Acc1, L_shr(Q[j-2], (Word16) 1 ) ) ;
Q[j] = Acc1 ;
}
/* Compute coefficients 1, 0 */
P[0] = L_shr( P[0], (Word16) 1 ) ;
Q[0] = L_shr( Q[0], (Word16) 1 ) ;
Acc0 = L_deposit_h( Lsp[2*i+0] ) ;
Acc0 = L_shr( Acc0, (Word16) i ) ;
Acc0 = L_add( Acc0, P[1] ) ;
Acc0 = L_shr( Acc0, (Word16) 1 ) ;
P[1] = Acc0 ;
Acc1 = L_deposit_h( Lsp[2*i+1] ) ;
Acc1 = L_shr( Acc1, (Word16) i ) ;
Acc1 = L_add( Acc1, Q[1] ) ;
Acc1 = L_shr( Acc1, (Word16) 1 ) ;
Q[1] = Acc1 ;
}
/*
* Convert the sum and difference polynomials to LPC coefficients
* The LPC polynomial is the sum of the sum and difference
* polynomials with the real zeros factored in: A(z) = 1/2 {P(z) (1
* + z^{-1}) + Q(z) (1 - z^{-1})}. The LPC coefficients are scaled
* here by 16; the overall scale factor for the LPC coefficients
* returned by this function is therefore 1/4.
*/
for ( i = 0 ; i < LpcOrder/2 ; i ++ ) {
Acc0 = P[i] ;
Acc0 = L_add( Acc0, P[i+1] ) ;
Acc0 = L_sub( Acc0, Q[i] ) ;
Acc0 = L_add( Acc0, Q[i+1] ) ;
Acc0 = L_shl( Acc0, (Word16) 3 ) ;
Lsp[i] = negate( round( Acc0 ) ) ;
Acc1 = P[i] ;
Acc1 = L_add( Acc1, P[i+1] ) ;
Acc1 = L_add( Acc1, Q[i] ) ;
Acc1 = L_sub( Acc1, Q[i+1] ) ;
Acc1 = L_shl( Acc1, (Word16) 3 ) ;
Lsp[LpcOrder-1-i] = negate( round( Acc1 ) ) ;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -