📄 g7231_util_lbc.c
字号:
#include "typedef.h"
#include "G7231_basop.h"
#include "G7231_cst_lbc.h"
#include "G7231_tab_lbc.h"
#include "G7231_lbccodec.h"
#include "G7231_coder.h"
#include "G7231_decod.h"
#include "G7231_util_lbc.h"
#include "intrindefs.h"
void G7231Rem_Dc( Word16 *Dpnt )
{
int i ;
Word32 Acc0,Acc1 ;
if ( G7231UseHp ) {
for ( i = 0 ; i < G7231Frame ; i ++ ) {
/* Do the Fir and scale by 2 */
Acc0 = G7231L_mult( Dpnt[i], (Word16) 0x4000 ) ;
Acc0 = G7231L_mac ( Acc0, G7231CodStat.HpfZdl, (Word16) 0xc000 ) ;
G7231CodStat.HpfZdl = Dpnt[i] ;
/* Do the Iir part */
Acc1 = G7231L_mls( G7231CodStat.HpfPdl, (Word16) 0x7f00 ) ;
Acc0 = G7231L_add( Acc0, Acc1 ) ;
G7231CodStat.HpfPdl = Acc0 ;
Dpnt[i] = G7231round(Acc0) ;
}
}
else {
for ( i = 0 ; i < G7231Frame ; i ++ )
Dpnt[i] = G7231shr( Dpnt[i], (Word16) 1 ) ;
}
return;
}
Word16 G7231Vec_Norm( Word16 *Vect, Word16 Len )
{
int i ;
Word16 Acc0,Acc1 ;
Word16 Exp ;
Word16 Rez ;
Word32 Temp ;
static short G7231ShiftTable[16] = {
0x0001 ,
0x0002 ,
0x0004 ,
0x0008 ,
0x0010 ,
0x0020 ,
0x0040 ,
0x0080 ,
0x0100 ,
0x0200 ,
0x0400 ,
0x0800 ,
0x1000 ,
0x2000 ,
0x4000 ,
0x7fff
} ;
/* Find absolute maximum */
Acc1 = (Word16) 0 ;
for ( i = 0 ; i < Len ; i ++ ) {
Acc0 = G7231abs_s( Vect[i] ) ;
if ( Acc0 > Acc1 )
Acc1 = Acc0 ;
}
/* Get the shift count */
Rez = G7231norm_s( Acc1 ) ;
Exp = G7231ShiftTable[Rez] ;
/* Normalize all the vector */
for ( i = 0 ; i < Len ; i ++ ) {
Temp = G7231L_mult( Exp, Vect[i] ) ;
Temp = G7231L_shr( Temp, 4 ) ;
Vect[i] = G7231extract_l( Temp ) ;
}
Rez = G7231sub( Rez, (Word16) 3) ;
return Rez ;
}
void G7231Mem_Shift( Word16 *PrevDat, Word16 *DataBuff )
{
int i ;
Word16 Dpnt[G7231Frame+G7231LpcFrame-G7231SubFrLen] ;
/* Form Buffer */
for ( i = 0 ; i < G7231LpcFrame-G7231SubFrLen ; i ++ )
Dpnt[i] = PrevDat[i] ;
for ( i = 0 ; i < G7231Frame ; i ++ )
Dpnt[i+G7231LpcFrame-G7231SubFrLen] = DataBuff[i] ;
/* Update PrevDat */
for ( i = 0 ; i < G7231LpcFrame-G7231SubFrLen ; i ++ )
PrevDat[i] = Dpnt[G7231Frame+i] ;
/* Update DataBuff */
for ( i = 0 ; i < G7231Frame ; i ++ )
DataBuff[i] = Dpnt[(G7231LpcFrame-G7231SubFrLen)/2+i] ;
return;
}
void G7231Line_Pack( G7231LINEDEF *Line, char *Vout, Word16 Ftyp )
{
int i ;
int BitCount ;
Word16 BitStream[192] ;
Word16 *Bsp = BitStream ;
Word32 Temp ;
/* Clear the output vector */
for ( i = 0 ; i < 24 ; i ++ )
Vout[i] = 0 ;
/*
* Add the coder rate info and frame type info to the 2 msb
* of the first word of the frame.
* The signaling is as follows:
* Ftyp WrkRate => X1X0
* 1 Rate63 00 : High Rate
* 1 Rate53 01 : Low Rate
* 2 x 10 : Silence Insertion Descriptor frame
* 0 x 11 : Used only for simulation of
* untransmitted silence frames
*/
switch (Ftyp) {
case 0 : {
Temp = 0x00000003L;
break;
}
case 2 : {
Temp = 0x00000002L;
break;
}
default : {
if ( G7231CodStat.WrkRate == Rate63 )
Temp = 0x00000000L ;
else
Temp = 0x00000001L ;
break;
}
}
/* Serialize Control info */
Bsp = G7231Par2Ser( Temp, Bsp, 2 ) ;
/* Check for Speech/NonSpeech case */
if ( Ftyp == 1 ) {
/* 24 bit LspId */
Temp = (*Line).LspId ;
Bsp = G7231Par2Ser( Temp, Bsp, 24 ) ;
/*
* Do the part common to both rates
*/
/* Adaptive code book lags */
Temp = (Word32) (*Line).Olp[0] - (Word32) G7231PitchMin ;
Bsp = G7231Par2Ser( Temp, Bsp, 7 ) ;
Temp = (Word32) (*Line).Sfs[1].AcLg ;
Bsp = G7231Par2Ser( Temp, Bsp, 2 ) ;
Temp = (Word32) (*Line).Olp[1] - (Word32) G7231PitchMin ;
Bsp = G7231Par2Ser( Temp, Bsp, 7 ) ;
Temp = (Word32) (*Line).Sfs[3].AcLg ;
Bsp = G7231Par2Ser( Temp, Bsp, 2 ) ;
/* Write combined 12 bit index of all the gains */
for ( i = 0 ; i < G7231SubFrames ; i ++ ) {
Temp = (*Line).Sfs[i].AcGn*G7231NumOfGainLev + (*Line).Sfs[i].Mamp ;
if ( G7231CodStat.WrkRate == Rate63 )
Temp += (Word32) (*Line).Sfs[i].Tran << 11 ;
Bsp = G7231Par2Ser( Temp, Bsp, 12 ) ;
}
/* Write all the Grid indices */
for ( i = 0 ; i < G7231SubFrames ; i ++ )
*Bsp ++ = (*Line).Sfs[i].Grid ;
/* High rate only part */
if ( G7231CodStat.WrkRate == Rate63 ) {
/* Write the reserved bit as 0 */
*Bsp ++ = (Word16) 0 ;
/* Write 13 bit combined position index */
Temp = (*Line).Sfs[0].Ppos >> 16 ;
Temp = Temp * 9 + ( (*Line).Sfs[1].Ppos >> 14) ;
Temp *= 90 ;
Temp += ((*Line).Sfs[2].Ppos >> 16) * 9 + ( (*Line).Sfs[3].Ppos >> 14 ) ;
Bsp = G7231Par2Ser( Temp, Bsp, 13 ) ;
/* Write all the pulse positions */
Temp = (*Line).Sfs[0].Ppos & 0x0000ffffL ;
Bsp = G7231Par2Ser( Temp, Bsp, 16 ) ;
Temp = (*Line).Sfs[1].Ppos & 0x00003fffL ;
Bsp = G7231Par2Ser( Temp, Bsp, 14 ) ;
Temp = (*Line).Sfs[2].Ppos & 0x0000ffffL ;
Bsp = G7231Par2Ser( Temp, Bsp, 16 ) ;
Temp = (*Line).Sfs[3].Ppos & 0x00003fffL ;
Bsp = G7231Par2Ser( Temp, Bsp, 14 ) ;
/* Write pulse amplitudes */
Temp = (Word32) (*Line).Sfs[0].Pamp ;
Bsp = G7231Par2Ser( Temp, Bsp, 6 ) ;
Temp = (Word32) (*Line).Sfs[1].Pamp ;
Bsp = G7231Par2Ser( Temp, Bsp, 5 ) ;
Temp = (Word32) (*Line).Sfs[2].Pamp ;
Bsp = G7231Par2Ser( Temp, Bsp, 6 ) ;
Temp = (Word32) (*Line).Sfs[3].Pamp ;
Bsp = G7231Par2Ser( Temp, Bsp, 5 ) ;
}
/* Low rate only part */
else {
/* Write 12 bits of positions */
for ( i = 0 ; i < G7231SubFrames ; i ++ ) {
Temp = (*Line).Sfs[i].Ppos ;
Bsp = G7231Par2Ser( Temp, Bsp, 12 ) ;
}
/* Write 4 bit Pamps */
for ( i = 0 ; i < G7231SubFrames ; i ++ ) {
Temp = (*Line).Sfs[i].Pamp ;
Bsp = G7231Par2Ser( Temp, Bsp, 4 ) ;
}
}
}
else if(Ftyp == 2) { /* SID frame */
/* 24 bit LspId */
Temp = (*Line).LspId ;
Bsp = G7231Par2Ser( Temp, Bsp, 24 ) ;
/* Do Sid frame gain */
Temp = (Word32)(*Line).Sfs[0].Mamp ;
Bsp = G7231Par2Ser( Temp, Bsp, 6 ) ;
}
/* Write out active frames */
if ( Ftyp == 1 ) {
if ( G7231CodStat.WrkRate == Rate63 )
BitCount = 192 ;
else
BitCount = 160 ;
}
/* Non active frames */
else if ( Ftyp == 2 )
BitCount = 32 ;
else
BitCount = 2;
for ( i = 0 ; i < BitCount ; i ++ )
Vout[i>>3] ^= BitStream[i] << (i & 0x0007) ;
return;
}
Word16* G7231Par2Ser( Word32 Inp, Word16 *Pnt, int BitNum )
{
int i ;
Word16 Temp ;
for ( i = 0 ; i < BitNum ; i ++ ) {
Temp = (Word16) Inp & (Word16)0x0001 ;
Inp >>= 1 ;
*Pnt ++ = Temp ;
}
return Pnt ;
}
G7231LINEDEF G7231Line_Unpk( char *Vinp, Word16 *Ftyp, Word16 Crc )
{
int i ;
Word16 BitStream[192] ;
Word16 *Bsp = BitStream ;
G7231LINEDEF Line ;
Word32 Temp ;
Word16 Info;
Word16 Bound_AcGn;
Line.Crc = Crc;
if(Crc != 0) return Line;
/* Unpack the byte info to BitStream vector */
for ( i = 0 ; i < 192 ; i ++ )
BitStream[i] = ( Vinp[i>>3] >> (i & (Word16)0x0007) ) & (Word16)1 ;
/* Decode the frame type and rate info */
Info = (Word16)G7231Ser2Par( &Bsp, 2 ) ;
if ( Info == 3 ) {
*Ftyp = 0;
Line.LspId = 0L; /* Dummy : to avoid Borland C3.1 warning */
return Line;
}
/* Decode the LspId */
Line.LspId = G7231Ser2Par( &Bsp, 24 ) ;
if ( Info == 2 ) {
/* Decode the Noise Gain */
Line.Sfs[0].Mamp = (Word16)G7231Ser2Par( &Bsp, 6);
*Ftyp = 2;
return Line ;
}
/*
* Decode the common information to both rates
*/
*Ftyp = 1;
/* Decode the bit-rate */
G7231DecStat.WrkRate = (Info == 0) ? Rate63 : Rate53;
/* Decode the adaptive codebook lags */
Temp = G7231Ser2Par( &Bsp, 7 ) ;
/* Test if forbidden code */
if( Temp <= 123) {
Line.Olp[0] = (Word16) Temp + (Word16)G7231PitchMin ;
}
else {
/* transmission error */
Line.Crc = 1;
return Line ;
}
Line.Sfs[1].AcLg = (Word16) G7231Ser2Par( &Bsp, 2 ) ;
Temp = G7231Ser2Par( &Bsp, 7 ) ;
/* Test if forbidden code */
if( Temp <= 123) {
Line.Olp[1] = (Word16) Temp + (Word16)G7231PitchMin ;
}
else {
/* transmission error */
Line.Crc = 1;
return Line ;
}
Line.Sfs[3].AcLg = (Word16) G7231Ser2Par( &Bsp, 2 ) ;
Line.Sfs[0].AcLg = 1 ;
Line.Sfs[2].AcLg = 1 ;
/* Decode the combined gains accordingly to the rate */
for ( i = 0 ; i < G7231SubFrames ; i ++ ) {
Temp = G7231Ser2Par( &Bsp, 12 ) ;
Line.Sfs[i].Tran = 0 ;
Bound_AcGn = G7231NbFilt170 ;
if ( (G7231DecStat.WrkRate == Rate63) && (Line.Olp[i>>1] < (G7231SubFrLen-2) ) ) {
Line.Sfs[i].Tran = (Word16)(Temp >> 11) ;
Temp &= 0x000007ffL ;
Bound_AcGn = G7231NbFilt085 ;
}
Line.Sfs[i].AcGn = (Word16)(Temp / (Word16)G7231NumOfGainLev) ;
if(Line.Sfs[i].AcGn < Bound_AcGn ) {
Line.Sfs[i].Mamp = (Word16)(Temp % (Word16)G7231NumOfGainLev) ;
}
else {
/* error detected */
Line.Crc = 1;
return Line ;
}
}
/* Decode the grids */
for ( i = 0 ; i < G7231SubFrames ; i ++ )
Line.Sfs[i].Grid = *Bsp ++ ;
if (Info == 0) {
/* Skip the reserved bit */
Bsp ++ ;
/* Decode 13 bit combined position index */
Temp = G7231Ser2Par( &Bsp, 13 ) ;
Line.Sfs[0].Ppos = ( Temp/90 ) / 9 ;
Line.Sfs[1].Ppos = ( Temp/90 ) % 9 ;
Line.Sfs[2].Ppos = ( Temp%90 ) / 9 ;
Line.Sfs[3].Ppos = ( Temp%90 ) % 9 ;
/* Decode all the pulse positions */
Line.Sfs[0].Ppos = ( Line.Sfs[0].Ppos << 16 ) + G7231Ser2Par( &Bsp, 16 ) ;
Line.Sfs[1].Ppos = ( Line.Sfs[1].Ppos << 14 ) + G7231Ser2Par( &Bsp, 14 ) ;
Line.Sfs[2].Ppos = ( Line.Sfs[2].Ppos << 16 ) + G7231Ser2Par( &Bsp, 16 ) ;
Line.Sfs[3].Ppos = ( Line.Sfs[3].Ppos << 14 ) + G7231Ser2Par( &Bsp, 14 ) ;
/* Decode pulse amplitudes */
Line.Sfs[0].Pamp = (Word16)G7231Ser2Par( &Bsp, 6 ) ;
Line.Sfs[1].Pamp = (Word16)G7231Ser2Par( &Bsp, 5 ) ;
Line.Sfs[2].Pamp = (Word16)G7231Ser2Par( &Bsp, 6 ) ;
Line.Sfs[3].Pamp = (Word16)G7231Ser2Par( &Bsp, 5 ) ;
}
else {
/* Decode the positions */
for ( i = 0 ; i < G7231SubFrames ; i ++ )
Line.Sfs[i].Ppos = G7231Ser2Par( &Bsp, 12 ) ;
/* Decode the amplitudes */
for ( i = 0 ; i < G7231SubFrames ; i ++ )
Line.Sfs[i].Pamp = (Word16)G7231Ser2Par( &Bsp, 4 ) ;
}
return Line ;
}
Word32 G7231Ser2Par( Word16 **Pnt, int Count )
{
int i ;
Word32 Rez = 0L ;
for ( i = 0 ; i < Count ; i ++ ) {
Rez += (Word32) **Pnt << i ;
(*Pnt) ++ ;
}
return Rez ;
}
Word32 G7231Comp_En( Word16 *Dpnt )
{
int i ;
Word32 Rez ;
Word16 Temp[G7231SubFrLen] ;
for ( i = 0 ; i < G7231SubFrLen ; i ++ )
Temp[i] = G7231shr( Dpnt[i], (Word16) 2 ) ;
Rez = (Word32) 0 ;
for ( i = 0 ; i < G7231SubFrLen ; i ++ )
Rez = G7231L_mac( Rez, Temp[i], Temp[i] ) ;
return Rez ;
}
Word16 G7231Sqrt_lbc( Word32 Num )
{
int i ;
Word16 Rez = (Word16) 0 ;
Word16 Exp = (Word16) 0x4000 ;
Word32 Acc ;
for ( i = 0 ; i < 14 ; i ++ ) {
Acc = G7231L_mult( G7231add(Rez, Exp), G7231add(Rez, Exp) ) ;
if ( Num >= Acc )
Rez = G7231add( Rez, Exp ) ;
Exp = G7231shr( Exp, (Word16) 1 ) ;
}
return Rez ;
}
Word16 G7231Rand_lbc( Word16 *p )
{
Word32 Temp ;
Temp = G7231L_deposit_l( *p ) ;
Temp &= (Word32) 0x0000ffff ;
Temp = Temp*(Word32)521 + (Word32) 259 ;
*p = G7231extract_l( Temp ) ;
return G7231extract_l( Temp ) ;
}
void G7231Scale( Word16 *Tv, Word32 Sen )
{
int i ;
Word32 Acc0,Acc1 ;
Word16 Exp,SfGain ;
Acc0 = Sen ;
Acc1 = G7231Comp_En( Tv ) ;
/* Normalize both */
if ( (Acc1 != (Word32) 0) && (Acc0 != (Word32) 0 ) ) {
Exp = G7231norm_l( Acc1 ) ;
Acc1 = G7231L_shl( Acc1, Exp ) ;
SfGain = G7231norm_l( Acc0 ) ;
Acc0 = G7231L_shl( Acc0, SfGain ) ;
Acc0 = G7231L_shr( Acc0, (Word16) 1 ) ;
Exp = G7231sub( Exp, SfGain ) ;
Exp = G7231add( Exp, (Word16) 1 ) ;
Exp = G7231sub( (Word16) 6, Exp ) ;
if ( Exp < (Word16) 0 )
Exp = (Word16) 0 ;
SfGain = G7231extract_h( Acc1 ) ;
SfGain = G7231div_l( Acc0, SfGain ) ;
Acc0 = G7231L_deposit_h( SfGain ) ;
Acc0 = G7231L_shr( Acc0, Exp ) ;
SfGain = G7231Sqrt_lbc( Acc0 ) ;
}
else
SfGain = 0x1000 ;
/* Filter the data */
for ( i = 0 ; i < G7231SubFrLen ; i ++ ) {
/* Update gain */
Acc0 = G7231L_deposit_h( G7231DecStat.Gain ) ;
Acc0 = G7231L_msu( Acc0, G7231DecStat.Gain, (Word16) 0x0800 ) ;
Acc0 = G7231L_mac( Acc0, SfGain, (Word16) 0x0800 ) ;
G7231DecStat.Gain = G7231round( Acc0 ) ;
Exp = G7231add( G7231DecStat.Gain, G7231shr( G7231DecStat.Gain, (Word16) 4) ) ;
Acc0 = G7231L_mult( Tv[i], Exp ) ;
Acc0 = G7231L_shl( Acc0, (Word16) 4 ) ;
Tv[i] = G7231round( Acc0 ) ;
}
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -