📄 sp_dec.c
字号:
/* initialize states */
memcpy( aState, a, M <<2 );
/* backward Levinson recursion */
for ( i = M - 1; i >= 0; i-- )
{
if ( labs( aState[i] ) >= 4096 )
{
goto ExitRefl;
}
refl[i] = aState[i] << 3;
temp = ( refl[i] * refl[i] ) << 1;
acc = ( MAX_32 - temp );
normShift=0;
if (acc != 0)
{
temp = acc;
while (!(temp & 0x40000000))
{
normShift++;
temp = temp << 1;
}
}
else
{
normShift = 0;
}
scale = 15 - normShift;
acc = ( acc << normShift );
temp = ( acc + ( Word32 )0x00008000L );
if ( temp > 0 )
{
normProd = temp >> 16;
mult = 0x20000000L / normProd;
}
else
mult = 16384;
for ( j = 0; j < i; j++ )
{
acc = aState[j] << 16;
acc -= ( refl[i] * aState[i - j - 1] ) << 1;
temp = ( acc + ( Word32 )0x00008000L ) >> 16;
temp = ( mult * temp ) << 1;
if ( scale > 0 )
{
if ( ( temp & ( ( Word32 )1 << ( scale - 1 ) ) ) != 0 )
{
temp = ( temp >> scale ) + 1;
}
else
temp = ( temp >> scale );
}
else
temp = ( temp >> scale );
if ( labs( temp ) > 32767 )
{
goto ExitRefl;
}
bState[j] = temp;
}
memcpy( aState, bState, i <<2 );
}
return;
ExitRefl:
memset( refl, 0, M <<2 );
}
/************************************************************************************
* Log2_norm
*
*
* Parameters:
* x I: input value
* exp I: exponent
* exponent O: Integer part of Log2. (range: 0<=val<=30)
* fraction O: Fractional part of Log2. (range: 0<=val<1)
*
* Function:
* Computes log2
*
* Computes log2(L_x, exp), where L_x is positive and
* normalized, and exp is the normalisation exponent
* If L_x is negative or zero, the result is 0.
*
* The function Log2(L_x) is approximated by a table and linear
* interpolation. The following steps are used to compute Log2(L_x)
*
* exponent = 30-normExponent
* i = bit25-b31 of L_x; 32<=i<=63 (because of normalization).
* a = bit10-b24
* i -=32
* fraction = table[i]<<16 - (table[i] - table[i+1]) * a * 2
*
* Returns:
* void
*************************************************************************************/
static void Log2_norm( Word32 x, Word32 exp, Word32 *exponent, Word32 *
fraction )
{
Word32 y, i, a;
if ( x <= 0 )
{
*exponent = 0;
*fraction = 0;
return;
}
/* Extract b25-b31 */
i = x >> 25;
i = i - 32;
/* Extract b10-b24 of fraction */
a = x >> 9;
a = a & 0xFFFE; /* 2a */
/* fraction */
y = ( log2_table[i] << 16 ) - a * ( log2_table[i] - log2_table[i + 1] );
*fraction = y >> 16;
*exponent = 30 - exp;
return;
}
/************************************************************************************
* Log2
*
*
* Parameters:
* x I: input value
* exponent O: Integer part of Log2. (range: 0<=val<=30)
* fraction O: Fractional part of Log2. (range: 0<=val<1)
*
* Function:
* Computes log2(L_x)
* If x is negative or zero, the result is 0.
*
* Returns:
* void
*************************************************************************************/
static void Log2( Word32 x, Word32 *exponent, Word32 *fraction )
{
int tmp, exp=0;
if (x != 0)
{
tmp = x;
while (!((tmp & 0x80000000) ^ ((tmp & 0x40000000) << 1)))
{
exp++;
tmp = tmp << 1;
}
}
Log2_norm( x <<exp, exp, exponent, fraction );
}
/************************************************************************************
* Pow2
*
*
* Parameters:
* exponent I: Integer part. (range: 0<=val<=30)
* fraction O: Fractional part. (range: 0.0<=val<1.0)
*
* Function:
* pow(2.0, exponent.fraction)
*
* The function Pow2(L_x) is approximated by a table and linear interpolation.
*
* i = bit10-b15 of fraction, 0 <= i <= 31
* a = biT0-b9 of fraction
* x = table[i]<<16 - (table[i] - table[i+1]) * a * 2
* x = L_x >> (30-exponent) (with rounding)
*
* Returns:
* result (range: 0<=val<=0x7fffffff)
**************************************************************************************/
static Word32 Pow2( Word32 exponent, Word32 fraction )
{
Word32 i, a, tmp, x, exp;
i = fraction >> 10;
a = ( fraction << 5 ) & 0x7fff;
x = pow2_table[i] << 16;
tmp = pow2_table[i] - pow2_table[i + 1];
x -= ( tmp * a ) << 1;
if ( exponent >= -1 )
{
exp = ( 30 - exponent );
if ( ( x & ( ( Word32 )1 << ( exp - 1 ) ) ) != 0 )
{
x = ( x >> exp ) + 1;
}
else
x = x >> exp;
}
else
x = 0;
return( x );
}
/************************************************************************************
* Build_CN_code
*
*
* Parameters:
* seed B: Old CN generator shift register state
* cod O: Generated CN fixed codebook vector
*
* Function:
* Generate CN fixed codebook vector
*
* Returns:
* void
************************************************************************************/
static void Build_CN_code( Word32 *seed, Word32 cod[] )
{
Word32 i, j, k;
memset( cod, 0, L_SUBFR <<2 );
for ( k = 0; k < 10; k++ )
{
i = pseudonoise( seed, 2 ); /* generate pulse position */
i = ( i * 20 ) >> 1;
i = ( i + k );
j = pseudonoise( seed, 1 ); /* generate sign */
if ( j > 0 )
{
cod[i] = 4096;
}
else
{
cod[i] = -4096;
}
}
return;
}
/*************************************************************************************
* Build_CN_param
*
*
* Parameters:
* seed B: Old CN generator shift register state
* nParam I: number of params
* paramSizeTable I: size of params
* parm O: CN Generated params
*
* Function:
* Generate parameters for comfort noise generation
*
* Returns:
* void
*************************************************************************************/
static void Build_CN_param( Word16 *seed, enum Mode mode, Word16 parm[] )
{
Word32 i;
const Word32 *p;
*seed = ( Word16 )( ( *seed * 31821 ) + 13849L );
p = &window_200_40[ * seed & 0x7F];
switch ( mode )
{
case MR122:
for ( i = 0; i < PRMNO_MR122; i++ )
{
parm[i] = ( Word16 )( *p++ & ~( 0xFFFF << bitno_MR122[i] ) );
}
break;
case MR102:
for ( i = 0; i < PRMNO_MR102; i++ )
{
parm[i] = ( Word16 )( *p++ & ~( 0xFFFF << bitno_MR102[i] ) );
}
break;
case MR795:
for ( i = 0; i < PRMNO_MR795; i++ )
{
parm[i] = ( Word16 )( *p++ & ~( 0xFFFF << bitno_MR795[i] ) );
}
break;
case MR74:
for ( i = 0; i < PRMNO_MR74; i++ )
{
parm[i] = ( Word16 )( *p++ & ~( 0xFFFF << bitno_MR74[i] ) );
}
break;
case MR67:
for ( i = 0; i < PRMNO_MR67; i++ )
{
parm[i] = ( Word16 )( *p++ & ~( 0xFFFF << bitno_MR67[i] ) );
}
break;
case MR59:
for ( i = 0; i < PRMNO_MR59; i++ )
{
parm[i] = ( Word16 )( *p++ & ~( 0xFFFF << bitno_MR59[i] ) );
}
break;
case MR515:
for ( i = 0; i < PRMNO_MR515; i++ )
{
parm[i] = ( Word16 )( *p++ & ~( 0xFFFF << bitno_MR515[i] ) );
}
break;
case MR475:
for ( i = 0; i < PRMNO_MR475; i++ )
{
parm[i] = ( Word16 )( *p++ & ~( 0xFFFF << bitno_MR475[i] ) );
}
break;
}
}
/************************************************************************************
* Syn_filt
*
*
* Parameters:
* a I: prediction coefficients [M+1]
* x I: input signal
* y O: output signal
* lg I: size of filtering
* mem B: memory associated with this filtering
* update I: 0=no update, 1=update of memory.
*
* Function:
* Perform synthesis filtering through 1/A(z).
*
* Returns:
* void
************************************************************************************/
static Word32 Syn_filt( Word32 a[], Word32 x[], Word32 y[], Word32 lg, Word32 mem[]
, Word32 update )
{/*合成滤波器重构语音*/
Word32 tmp[50]; /* malloc is slow */
Word32 s, a0, overflow = 0;
Word32 *yy, *yy_limit;
/* Copy mem[] to yy[] */
memcpy( tmp, mem, 40 );
yy = tmp + M;
yy_limit = yy + lg;
a0 = a[0];
/* Do the filtering. */
while ( yy < yy_limit )
{
s = *x++ * a0;
s -= yy[-1] * a[1];
s -= yy[-2] * a[2];
s -= yy[-3] * a[3];
s -= yy[-4] * a[4];
s -= yy[-5] * a[5];
s -= yy[-6] * a[6];
s -= yy[-7] * a[7];
s -= yy[-8] * a[8];
s -= yy[-9] * a[9];
s -= yy[-10] * a[10];
if ( labs( s ) < 0x7ffffff )
*yy = ( s + 0x800L ) >> 12;
else if ( s > 0 )
{
*yy = 32767;
overflow = 1;
}
else
{
*yy = -32768;
overflow = 1;
}
yy++;
}
memcpy( y, &tmp[M], lg <<2 );
/* Update of memory if update==1 */
if ( update )
{
memcpy( mem, &y[lg - M], 40 );
}
return overflow;
}
/*************************************************************************************
* Syn_filt_overflow
*
*
* Parameters:
* a I: prediction coefficients [M+1]
* x I: input signal
* y O: output signal
* lg I: size of filtering
* mem B: memory associated with this filtering
* update I: 0=no update, 1=update of memory.
*
* Function:
* Perform synthesis filtering through 1/A(z).
* Saturate after every multiplication.
* Returns:
* void
*************************************************************************************/
static void Syn_filt_overflow( Word32 a[], Word32 x[], Word32 y[], Word32 lg, Word32 mem[]
, Word32 update )
{
Word32 tmp[50]; /* malloc is slow */
Word32 i, j, s, a0;
Word32 *yy;
/* Copy mem[] to yy[] */
memcpy( tmp, mem, 40 );
yy = tmp + M;
a0 = a[0];
/* Do the filtering. */
for ( i = 0; i < lg; i++ )
{
s = x[i] * a0;
for ( j = 1; j <= M; j++ )
{
s -= a[j] * yy[ - j];
if (s > 1073741823)
{
s = 1073741823;
}
else if ( s < -1073741824)
{
s = -1073741824;
}
}
if ( labs( s ) < 0x7FFE800 )
*yy = ( s + 0x800L ) >> 12;
else if ( s > 0 )
{
*yy = 32767;
}
else
{
*yy = -32768;
}
yy++;
}
memcpy( y, &tmp[M], lg <<2 );
/* Update of memory if update==1 */
if ( update )
{
memcpy( mem, &y[lg - M], 40 );
}
return;
}
/************************************************************************************
* dtx_dec
*
*
* Parameters:
* st B: DTX state struct
* mem_syn I: AMR decoder state
* lsfState B: LSF state struct
* pred_state->past_qua_en O: table of past quantized energies
* pred_state->past_qua_en_MR122 O: table of past quantized energies MR122
* averState->hangVar O:
* averState->hangCount O: hangover variable
* new_state I: new DTX state
* mode I: AMR mode
* parm I: vector of synthesis parameters
* synth O: synthesised speech
* A_t O: decoded LP filter in 4 subframes
*
* Function:
* DTX
*
* Returns:
* void
*************************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -