mirror of
https://github.com/xiph/opus.git
synced 2025-05-19 01:48:30 +00:00
SILK fixes following last codec WG meeting
decoder: - fixed incorrect scaling of filter states for the smallest quantization step sizes - NLSF2A now limits the prediction gain of LPC filters encoder: - increased damping of LTP coefficients in LTP analysis - increased white noise fraction in noise shaping LPC analysis - introduced maximum total prediction gain. Used by Burg's method to exit early if prediction gain is exceeded. This improves packet loss robustness and numerical robustness in Burg's method - Prefiltered signal is now in int32 Q10 domain, from int16 Q0 - Increased max number of iterations in CBR gain control loop from 5 to 6 - Removed useless code from LTP scaling control - Optimization: smarter LPC loop unrolling - Switched default win32 compile mode to be floating-point resampler: - made resampler have constant delay of 0.75 ms; removed delay compensation from silk code. - removed obsolete table entries (~850 Bytes) - increased downsampling filter order from 16 to 18/24/36 (depending on frequency ratio) - reoptimized filter coefficients
This commit is contained in:
parent
6619a73637
commit
bf75c8ec4d
71 changed files with 961 additions and 1005 deletions
15
silk/CNG.c
15
silk/CNG.c
|
@ -54,7 +54,7 @@ static inline void silk_CNG_exc(
|
||||||
idx = ( opus_int )( silk_RSHIFT( seed, 24 ) & exc_mask );
|
idx = ( opus_int )( silk_RSHIFT( seed, 24 ) & exc_mask );
|
||||||
silk_assert( idx >= 0 );
|
silk_assert( idx >= 0 );
|
||||||
silk_assert( idx <= CNG_BUF_MASK_MAX );
|
silk_assert( idx <= CNG_BUF_MASK_MAX );
|
||||||
residual_Q10[ i ] = ( opus_int16 )silk_SAT16( silk_SMULWW( exc_buf_Q10[ idx ], Gain_Q16 ) );
|
residual_Q10[ i ] = (opus_int16)silk_SAT16( silk_SMULWW( exc_buf_Q10[ idx ], Gain_Q16 ) );
|
||||||
}
|
}
|
||||||
*rand_seed = seed;
|
*rand_seed = seed;
|
||||||
}
|
}
|
||||||
|
@ -83,7 +83,7 @@ void silk_CNG(
|
||||||
opus_int length /* I Length of residual */
|
opus_int length /* I Length of residual */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
opus_int i, j, subfr;
|
opus_int i, subfr;
|
||||||
opus_int32 sum_Q6, max_Gain_Q16;
|
opus_int32 sum_Q6, max_Gain_Q16;
|
||||||
opus_int16 A_Q12[ MAX_LPC_ORDER ];
|
opus_int16 A_Q12[ MAX_LPC_ORDER ];
|
||||||
opus_int32 CNG_sig_Q10[ MAX_FRAME_LENGTH + MAX_LPC_ORDER ];
|
opus_int32 CNG_sig_Q10[ MAX_FRAME_LENGTH + MAX_LPC_ORDER ];
|
||||||
|
@ -133,7 +133,7 @@ void silk_CNG(
|
||||||
/* Generate CNG signal, by synthesis filtering */
|
/* Generate CNG signal, by synthesis filtering */
|
||||||
silk_memcpy( CNG_sig_Q10, psCNG->CNG_synth_state, MAX_LPC_ORDER * sizeof( opus_int32 ) );
|
silk_memcpy( CNG_sig_Q10, psCNG->CNG_synth_state, MAX_LPC_ORDER * sizeof( opus_int32 ) );
|
||||||
for( i = 0; i < length; i++ ) {
|
for( i = 0; i < length; i++ ) {
|
||||||
/* Partially unrolled */
|
silk_assert( psDec->LPC_order == 10 || psDec->LPC_order == 16 );
|
||||||
sum_Q6 = silk_SMULWB( CNG_sig_Q10[ MAX_LPC_ORDER + i - 1 ], A_Q12[ 0 ] );
|
sum_Q6 = silk_SMULWB( CNG_sig_Q10[ MAX_LPC_ORDER + i - 1 ], A_Q12[ 0 ] );
|
||||||
sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 2 ], A_Q12[ 1 ] );
|
sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 2 ], A_Q12[ 1 ] );
|
||||||
sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 3 ], A_Q12[ 2 ] );
|
sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 3 ], A_Q12[ 2 ] );
|
||||||
|
@ -144,8 +144,13 @@ void silk_CNG(
|
||||||
sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 8 ], A_Q12[ 7 ] );
|
sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 8 ], A_Q12[ 7 ] );
|
||||||
sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 9 ], A_Q12[ 8 ] );
|
sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 9 ], A_Q12[ 8 ] );
|
||||||
sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 10 ], A_Q12[ 9 ] );
|
sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 10 ], A_Q12[ 9 ] );
|
||||||
for( j = 10; j < psDec->LPC_order; j++ ) {
|
if( psDec->LPC_order == 16 ) {
|
||||||
sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - j - 1 ], A_Q12[ j ] );
|
sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 11 ], A_Q12[ 10 ] );
|
||||||
|
sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 12 ], A_Q12[ 11 ] );
|
||||||
|
sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 13 ], A_Q12[ 12 ] );
|
||||||
|
sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 14 ], A_Q12[ 13 ] );
|
||||||
|
sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 15 ], A_Q12[ 14 ] );
|
||||||
|
sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 16 ], A_Q12[ 15 ] );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update states */
|
/* Update states */
|
||||||
|
|
|
@ -77,7 +77,7 @@ void silk_LPC_analysis_filter(
|
||||||
out32 = silk_RSHIFT_ROUND( out32_Q12, 12 );
|
out32 = silk_RSHIFT_ROUND( out32_Q12, 12 );
|
||||||
|
|
||||||
/* Saturate output */
|
/* Saturate output */
|
||||||
out[ ix ] = ( opus_int16 )silk_SAT16( out32 );
|
out[ ix ] = (opus_int16)silk_SAT16( out32 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set first d output samples to zero */
|
/* Set first d output samples to zero */
|
||||||
|
|
|
@ -38,24 +38,22 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
/* Compute inverse of LPC prediction gain, and */
|
/* Compute inverse of LPC prediction gain, and */
|
||||||
/* test if LPC coefficients are stable (all poles within unit circle) */
|
/* test if LPC coefficients are stable (all poles within unit circle) */
|
||||||
static opus_int LPC_inverse_pred_gain_QA( /* O Returns 1 if unstable, otherwise 0 */
|
static opus_int32 LPC_inverse_pred_gain_QA( /* O Returns inverse prediction gain in energy domain, Q30 */
|
||||||
opus_int32 *invGain_Q30, /* O Inverse prediction gain, Q30 energy domain */
|
opus_int32 A_QA[ 2 ][ SILK_MAX_ORDER_LPC ], /* I Prediction coefficients */
|
||||||
opus_int32 A_QA[ 2 ][ SILK_MAX_ORDER_LPC ], /* I Prediction coefficients */
|
const opus_int order /* I Prediction order */
|
||||||
const opus_int order /* I Prediction order */
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
opus_int k, n, mult2Q;
|
opus_int k, n, mult2Q;
|
||||||
opus_int32 rc_Q31, rc_mult1_Q30, rc_mult2, tmp_QA;
|
opus_int32 invGain_Q30, rc_Q31, rc_mult1_Q30, rc_mult2, tmp_QA;
|
||||||
opus_int32 *Aold_QA, *Anew_QA;
|
opus_int32 *Aold_QA, *Anew_QA;
|
||||||
|
|
||||||
Anew_QA = A_QA[ order & 1 ];
|
Anew_QA = A_QA[ order & 1 ];
|
||||||
|
|
||||||
*invGain_Q30 = ( 1 << 30 );
|
invGain_Q30 = 1 << 30;
|
||||||
for( k = order - 1; k > 0; k-- ) {
|
for( k = order - 1; k > 0; k-- ) {
|
||||||
/* Check for stability */
|
/* Check for stability */
|
||||||
if( ( Anew_QA[ k ] > A_LIMIT ) || ( Anew_QA[ k ] < -A_LIMIT ) ) {
|
if( ( Anew_QA[ k ] > A_LIMIT ) || ( Anew_QA[ k ] < -A_LIMIT ) ) {
|
||||||
*invGain_Q30 = 0;
|
return 0;
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set RC equal to negated AR coef */
|
/* Set RC equal to negated AR coef */
|
||||||
|
@ -72,9 +70,9 @@ static opus_int LPC_inverse_pred_gain_QA( /* O Returns 1 if
|
||||||
|
|
||||||
/* Update inverse gain */
|
/* Update inverse gain */
|
||||||
/* invGain_Q30 range: [ 0 : 2^30 ] */
|
/* invGain_Q30 range: [ 0 : 2^30 ] */
|
||||||
*invGain_Q30 = silk_LSHIFT( silk_SMMUL( *invGain_Q30, rc_mult1_Q30 ), 2 );
|
invGain_Q30 = silk_LSHIFT( silk_SMMUL( invGain_Q30, rc_mult1_Q30 ), 2 );
|
||||||
silk_assert( *invGain_Q30 >= 0 );
|
silk_assert( invGain_Q30 >= 0 );
|
||||||
silk_assert( *invGain_Q30 <= ( 1 << 30 ) );
|
silk_assert( invGain_Q30 <= ( 1 << 30 ) );
|
||||||
|
|
||||||
/* Swap pointers */
|
/* Swap pointers */
|
||||||
Aold_QA = Anew_QA;
|
Aold_QA = Anew_QA;
|
||||||
|
@ -89,8 +87,7 @@ static opus_int LPC_inverse_pred_gain_QA( /* O Returns 1 if
|
||||||
|
|
||||||
/* Check for stability */
|
/* Check for stability */
|
||||||
if( ( Anew_QA[ 0 ] > A_LIMIT ) || ( Anew_QA[ 0 ] < -A_LIMIT ) ) {
|
if( ( Anew_QA[ 0 ] > A_LIMIT ) || ( Anew_QA[ 0 ] < -A_LIMIT ) ) {
|
||||||
*invGain_Q30 = 0;
|
return 0;
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set RC equal to negated AR coef */
|
/* Set RC equal to negated AR coef */
|
||||||
|
@ -101,16 +98,15 @@ static opus_int LPC_inverse_pred_gain_QA( /* O Returns 1 if
|
||||||
|
|
||||||
/* Update inverse gain */
|
/* Update inverse gain */
|
||||||
/* Range: [ 0 : 2^30 ] */
|
/* Range: [ 0 : 2^30 ] */
|
||||||
*invGain_Q30 = silk_LSHIFT( silk_SMMUL( *invGain_Q30, rc_mult1_Q30 ), 2 );
|
invGain_Q30 = silk_LSHIFT( silk_SMMUL( invGain_Q30, rc_mult1_Q30 ), 2 );
|
||||||
silk_assert( *invGain_Q30 >= 0 );
|
silk_assert( invGain_Q30 >= 0 );
|
||||||
silk_assert( *invGain_Q30 <= 1<<30 );
|
silk_assert( invGain_Q30 <= 1<<30 );
|
||||||
|
|
||||||
return 0;
|
return invGain_Q30;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For input in Q12 domain */
|
/* For input in Q12 domain */
|
||||||
opus_int silk_LPC_inverse_pred_gain( /* O Returns 1 if unstable, otherwise 0 */
|
opus_int32 silk_LPC_inverse_pred_gain( /* O Returns inverse prediction gain in energy domain, Q30 */
|
||||||
opus_int32 *invGain_Q30, /* O Inverse prediction gain, Q30 energy domain */
|
|
||||||
const opus_int16 *A_Q12, /* I Prediction coefficients, Q12 [order] */
|
const opus_int16 *A_Q12, /* I Prediction coefficients, Q12 [order] */
|
||||||
const opus_int order /* I Prediction order */
|
const opus_int order /* I Prediction order */
|
||||||
)
|
)
|
||||||
|
@ -118,30 +114,27 @@ opus_int silk_LPC_inverse_pred_gain( /* O Returns 1 if unstable
|
||||||
opus_int k;
|
opus_int k;
|
||||||
opus_int32 Atmp_QA[ 2 ][ SILK_MAX_ORDER_LPC ];
|
opus_int32 Atmp_QA[ 2 ][ SILK_MAX_ORDER_LPC ];
|
||||||
opus_int32 *Anew_QA;
|
opus_int32 *Anew_QA;
|
||||||
opus_int32 DC_resp=0;
|
opus_int32 DC_resp = 0;
|
||||||
|
|
||||||
Anew_QA = Atmp_QA[ order & 1 ];
|
Anew_QA = Atmp_QA[ order & 1 ];
|
||||||
|
|
||||||
/* Increase Q domain of the AR coefficients */
|
/* Increase Q domain of the AR coefficients */
|
||||||
for( k = 0; k < order; k++ ) {
|
for( k = 0; k < order; k++ ) {
|
||||||
DC_resp += (opus_int32)A_Q12[ k ];
|
DC_resp += (opus_int32)A_Q12[ k ];
|
||||||
Anew_QA[ k ] = silk_LSHIFT( (opus_int32)A_Q12[ k ], QA - 12 );
|
Anew_QA[ k ] = silk_LSHIFT32( (opus_int32)A_Q12[ k ], QA - 12 );
|
||||||
}
|
}
|
||||||
/* If the DC is unstable, we don't even need to do the full calculations */
|
/* If the DC is unstable, we don't even need to do the full calculations */
|
||||||
if( DC_resp >= 4096 ) {
|
if( DC_resp >= 4096 ) {
|
||||||
*invGain_Q30 = 0;
|
return 0;
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
return LPC_inverse_pred_gain_QA( invGain_Q30, Atmp_QA, order );
|
return LPC_inverse_pred_gain_QA( Atmp_QA, order );
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FIXED_POINT
|
#ifdef FIXED_POINT
|
||||||
|
|
||||||
/* For input in Q24 domain */
|
/* For input in Q24 domain */
|
||||||
/* This function is only used by the fixed-point build */
|
opus_int32 silk_LPC_inverse_pred_gain_Q24( /* O Returns inverse prediction gain in energy domain, Q30 */
|
||||||
opus_int silk_LPC_inverse_pred_gain_Q24( /* O Returns 1 if unstable, otherwise 0 */
|
const opus_int32 *A_Q24, /* I Prediction coefficients [order] */
|
||||||
opus_int32 *invGain_Q30, /* O Inverse prediction gain, Q30 energy domain */
|
|
||||||
const opus_int32 *A_Q24, /* I Prediction coefficients, Q24 [order] */
|
|
||||||
const opus_int order /* I Prediction order */
|
const opus_int order /* I Prediction order */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
@ -153,9 +146,9 @@ opus_int silk_LPC_inverse_pred_gain_Q24( /* O Returns 1 if unstabl
|
||||||
|
|
||||||
/* Increase Q domain of the AR coefficients */
|
/* Increase Q domain of the AR coefficients */
|
||||||
for( k = 0; k < order; k++ ) {
|
for( k = 0; k < order; k++ ) {
|
||||||
Anew_QA[ k ] = silk_RSHIFT( A_Q24[ k ], 24 - QA );
|
Anew_QA[ k ] = silk_RSHIFT32( A_Q24[ k ], 24 - QA );
|
||||||
}
|
}
|
||||||
|
|
||||||
return LPC_inverse_pred_gain_QA( invGain_Q30, Atmp_QA, order );
|
return LPC_inverse_pred_gain_QA( Atmp_QA, order );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -91,24 +91,24 @@ static inline opus_int64 silk_SUB64(opus_int64 a, opus_int64 b){
|
||||||
static inline opus_int16 silk_ADD_SAT16( opus_int16 a16, opus_int16 b16 ) {
|
static inline opus_int16 silk_ADD_SAT16( opus_int16 a16, opus_int16 b16 ) {
|
||||||
opus_int16 res;
|
opus_int16 res;
|
||||||
res = (opus_int16)silk_SAT16( silk_ADD32( (opus_int32)(a16), (b16) ) );
|
res = (opus_int16)silk_SAT16( silk_ADD32( (opus_int32)(a16), (b16) ) );
|
||||||
silk_assert( res == silk_SAT16( ( opus_int32 )a16 + ( opus_int32 )b16 ) );
|
silk_assert( res == silk_SAT16( (opus_int32)a16 + (opus_int32)b16 ) );
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_ADD_SAT32
|
#undef silk_ADD_SAT32
|
||||||
static inline opus_int32 silk_ADD_SAT32(opus_int32 a32, opus_int32 b32){
|
static inline opus_int32 silk_ADD_SAT32(opus_int32 a32, opus_int32 b32){
|
||||||
opus_int32 res;
|
opus_int32 res;
|
||||||
res = ((((a32) + (b32)) & 0x80000000) == 0 ? \
|
res = ((((a32) + (b32)) & 0x80000000) == 0 ? \
|
||||||
((((a32) & (b32)) & 0x80000000) != 0 ? silk_int32_MIN : (a32)+(b32)) : \
|
((((a32) & (b32)) & 0x80000000) != 0 ? silk_int32_MIN : (a32)+(b32)) : \
|
||||||
((((a32) | (b32)) & 0x80000000) == 0 ? silk_int32_MAX : (a32)+(b32)) );
|
((((a32) | (b32)) & 0x80000000) == 0 ? silk_int32_MAX : (a32)+(b32)) );
|
||||||
silk_assert( res == silk_SAT32( ( opus_int64 )a32 + ( opus_int64 )b32 ) );
|
silk_assert( res == silk_SAT32( (opus_int64)a32 + (opus_int64)b32 ) );
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_ADD_SAT64
|
#undef silk_ADD_SAT64
|
||||||
static inline opus_int64 silk_ADD_SAT64( opus_int64 a64, opus_int64 b64 ) {
|
static inline opus_int64 silk_ADD_SAT64( opus_int64 a64, opus_int64 b64 ) {
|
||||||
opus_int64 res;
|
opus_int64 res;
|
||||||
res = ((((a64) + (b64)) & 0x8000000000000000LL) == 0 ? \
|
res = ((((a64) + (b64)) & 0x8000000000000000LL) == 0 ? \
|
||||||
((((a64) & (b64)) & 0x8000000000000000LL) != 0 ? silk_int64_MIN : (a64)+(b64)) : \
|
((((a64) & (b64)) & 0x8000000000000000LL) != 0 ? silk_int64_MIN : (a64)+(b64)) : \
|
||||||
((((a64) | (b64)) & 0x8000000000000000LL) == 0 ? silk_int64_MAX : (a64)+(b64)) );
|
((((a64) | (b64)) & 0x8000000000000000LL) == 0 ? silk_int64_MAX : (a64)+(b64)) );
|
||||||
if( res != a64 + b64 ) {
|
if( res != a64 + b64 ) {
|
||||||
|
@ -126,24 +126,24 @@ static inline opus_int64 silk_ADD_SAT64( opus_int64 a64, opus_int64 b64 ) {
|
||||||
static inline opus_int16 silk_SUB_SAT16( opus_int16 a16, opus_int16 b16 ) {
|
static inline opus_int16 silk_SUB_SAT16( opus_int16 a16, opus_int16 b16 ) {
|
||||||
opus_int16 res;
|
opus_int16 res;
|
||||||
res = (opus_int16)silk_SAT16( silk_SUB32( (opus_int32)(a16), (b16) ) );
|
res = (opus_int16)silk_SAT16( silk_SUB32( (opus_int32)(a16), (b16) ) );
|
||||||
silk_assert( res == silk_SAT16( ( opus_int32 )a16 - ( opus_int32 )b16 ) );
|
silk_assert( res == silk_SAT16( (opus_int32)a16 - (opus_int32)b16 ) );
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_SUB_SAT32
|
#undef silk_SUB_SAT32
|
||||||
static inline opus_int32 silk_SUB_SAT32( opus_int32 a32, opus_int32 b32 ) {
|
static inline opus_int32 silk_SUB_SAT32( opus_int32 a32, opus_int32 b32 ) {
|
||||||
opus_int32 res;
|
opus_int32 res;
|
||||||
res = ((((a32)-(b32)) & 0x80000000) == 0 ? \
|
res = ((((a32)-(b32)) & 0x80000000) == 0 ? \
|
||||||
(( (a32) & ((b32)^0x80000000) & 0x80000000) ? silk_int32_MIN : (a32)-(b32)) : \
|
(( (a32) & ((b32)^0x80000000) & 0x80000000) ? silk_int32_MIN : (a32)-(b32)) : \
|
||||||
((((a32)^0x80000000) & (b32) & 0x80000000) ? silk_int32_MAX : (a32)-(b32)) );
|
((((a32)^0x80000000) & (b32) & 0x80000000) ? silk_int32_MAX : (a32)-(b32)) );
|
||||||
silk_assert( res == silk_SAT32( ( opus_int64 )a32 - ( opus_int64 )b32 ) );
|
silk_assert( res == silk_SAT32( (opus_int64)a32 - (opus_int64)b32 ) );
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_SUB_SAT64
|
#undef silk_SUB_SAT64
|
||||||
static inline opus_int64 silk_SUB_SAT64( opus_int64 a64, opus_int64 b64 ) {
|
static inline opus_int64 silk_SUB_SAT64( opus_int64 a64, opus_int64 b64 ) {
|
||||||
opus_int64 res;
|
opus_int64 res;
|
||||||
res = ((((a64)-(b64)) & 0x8000000000000000LL) == 0 ? \
|
res = ((((a64)-(b64)) & 0x8000000000000000LL) == 0 ? \
|
||||||
(( (a64) & ((b64)^0x8000000000000000LL) & 0x8000000000000000LL) ? silk_int64_MIN : (a64)-(b64)) : \
|
(( (a64) & ((b64)^0x8000000000000000LL) & 0x8000000000000000LL) ? silk_int64_MIN : (a64)-(b64)) : \
|
||||||
((((a64)^0x8000000000000000LL) & (b64) & 0x8000000000000000LL) ? silk_int64_MAX : (a64)-(b64)) );
|
((((a64)^0x8000000000000000LL) & (b64) & 0x8000000000000000LL) ? silk_int64_MAX : (a64)-(b64)) );
|
||||||
|
|
||||||
|
|
|
@ -83,7 +83,7 @@ void silk_NLSF2A(
|
||||||
opus_int32 P[ SILK_MAX_ORDER_LPC / 2 + 1 ], Q[ SILK_MAX_ORDER_LPC / 2 + 1 ];
|
opus_int32 P[ SILK_MAX_ORDER_LPC / 2 + 1 ], Q[ SILK_MAX_ORDER_LPC / 2 + 1 ];
|
||||||
opus_int32 Ptmp, Qtmp, f_int, f_frac, cos_val, delta;
|
opus_int32 Ptmp, Qtmp, f_int, f_frac, cos_val, delta;
|
||||||
opus_int32 a32_QA1[ SILK_MAX_ORDER_LPC ];
|
opus_int32 a32_QA1[ SILK_MAX_ORDER_LPC ];
|
||||||
opus_int32 maxabs, absval, idx=0, sc_Q16, invGain_Q30;
|
opus_int32 maxabs, absval, idx=0, sc_Q16;
|
||||||
|
|
||||||
silk_assert( LSF_COS_TAB_SZ_FIX == 128 );
|
silk_assert( LSF_COS_TAB_SZ_FIX == 128 );
|
||||||
silk_assert( d==10||d==16 );
|
silk_assert( d==10||d==16 );
|
||||||
|
@ -162,8 +162,8 @@ void silk_NLSF2A(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for( i = 1; i < MAX_LPC_STABILIZE_ITERATIONS; i++ ) {
|
for( i = 1; i <= MAX_LPC_STABILIZE_ITERATIONS; i++ ) {
|
||||||
if( silk_LPC_inverse_pred_gain( &invGain_Q30, a_Q12, d ) == 1 ) {
|
if( silk_LPC_inverse_pred_gain( a_Q12, d ) < SILK_FIX_CONST( 1.0 / MAX_PREDICTION_POWER_GAIN, 30 ) ) {
|
||||||
/* Prediction coefficients are (too close to) unstable; apply bandwidth expansion */
|
/* Prediction coefficients are (too close to) unstable; apply bandwidth expansion */
|
||||||
/* on the unscaled coefficients, convert to Q12 and measure again */
|
/* on the unscaled coefficients, convert to Q12 and measure again */
|
||||||
silk_bwexpander_32( a32_QA1, d, 65536 - silk_SMULBB( 9 + i, i ) ); /* 10_Q16 = 0.00015 */
|
silk_bwexpander_32( a32_QA1, d, 65536 - silk_SMULBB( 9 + i, i ) ); /* 10_Q16 = 0.00015 */
|
||||||
|
@ -175,7 +175,7 @@ void silk_NLSF2A(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( i == MAX_LPC_STABILIZE_ITERATIONS ) {
|
if( i > MAX_LPC_STABILIZE_ITERATIONS ) {
|
||||||
/* Reached the last iteration, set coefficients to zero */
|
/* Reached the last iteration, set coefficients to zero */
|
||||||
for( k = 0; k < d; k++ ) {
|
for( k = 0; k < d; k++ ) {
|
||||||
a_Q12[ k ] = 0;
|
a_Q12[ k ] = 0;
|
||||||
|
|
|
@ -51,11 +51,11 @@ void silk_NLSF_VQ(
|
||||||
sum_error_Q26 = 0;
|
sum_error_Q26 = 0;
|
||||||
for( m = 0; m < LPC_order; m += 2 ) {
|
for( m = 0; m < LPC_order; m += 2 ) {
|
||||||
/* Compute weighted squared quantization error for index m */
|
/* Compute weighted squared quantization error for index m */
|
||||||
diff_Q15 = silk_SUB_LSHIFT32( in_Q15[ m ], ( opus_int32 )*pCB_Q8++, 7 ); /* range: [ -32767 : 32767 ]*/
|
diff_Q15 = silk_SUB_LSHIFT32( in_Q15[ m ], (opus_int32)*pCB_Q8++, 7 ); /* range: [ -32767 : 32767 ]*/
|
||||||
sum_error_Q30 = silk_SMULBB( diff_Q15, diff_Q15 );
|
sum_error_Q30 = silk_SMULBB( diff_Q15, diff_Q15 );
|
||||||
|
|
||||||
/* Compute weighted squared quantization error for index m + 1 */
|
/* Compute weighted squared quantization error for index m + 1 */
|
||||||
diff_Q15 = silk_SUB_LSHIFT32( in_Q15[m + 1], ( opus_int32 )*pCB_Q8++, 7 ); /* range: [ -32767 : 32767 ]*/
|
diff_Q15 = silk_SUB_LSHIFT32( in_Q15[m + 1], (opus_int32)*pCB_Q8++, 7 ); /* range: [ -32767 : 32767 ]*/
|
||||||
sum_error_Q30 = silk_SMLABB( sum_error_Q30, diff_Q15, diff_Q15 );
|
sum_error_Q30 = silk_SMLABB( sum_error_Q30, diff_Q15, diff_Q15 );
|
||||||
|
|
||||||
sum_error_Q26 = silk_ADD_RSHIFT32( sum_error_Q26, sum_error_Q30, 4 );
|
sum_error_Q26 = silk_ADD_RSHIFT32( sum_error_Q26, sum_error_Q30, 4 );
|
||||||
|
|
|
@ -77,7 +77,7 @@ void silk_NLSF_decode(
|
||||||
/* Decode first stage */
|
/* Decode first stage */
|
||||||
pCB_element = &psNLSF_CB->CB1_NLSF_Q8[ NLSFIndices[ 0 ] * psNLSF_CB->order ];
|
pCB_element = &psNLSF_CB->CB1_NLSF_Q8[ NLSFIndices[ 0 ] * psNLSF_CB->order ];
|
||||||
for( i = 0; i < psNLSF_CB->order; i++ ) {
|
for( i = 0; i < psNLSF_CB->order; i++ ) {
|
||||||
pNLSF_Q15[ i ] = silk_LSHIFT( ( opus_int16 )pCB_element[ i ], 7 );
|
pNLSF_Q15[ i ] = silk_LSHIFT( (opus_int16)pCB_element[ i ], 7 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unpack entropy table indices and predictor for current CB1 index */
|
/* Unpack entropy table indices and predictor for current CB1 index */
|
||||||
|
@ -91,8 +91,8 @@ void silk_NLSF_decode(
|
||||||
|
|
||||||
/* Apply inverse square-rooted weights and add to output */
|
/* Apply inverse square-rooted weights and add to output */
|
||||||
for( i = 0; i < psNLSF_CB->order; i++ ) {
|
for( i = 0; i < psNLSF_CB->order; i++ ) {
|
||||||
W_tmp_Q9 = silk_SQRT_APPROX( silk_LSHIFT( ( opus_int32 )W_tmp_QW[ i ], 18 - NLSF_W_Q ) );
|
W_tmp_Q9 = silk_SQRT_APPROX( silk_LSHIFT( (opus_int32)W_tmp_QW[ i ], 18 - NLSF_W_Q ) );
|
||||||
NLSF_Q15_tmp = silk_ADD32( pNLSF_Q15[ i ], silk_DIV32_16( silk_LSHIFT( ( opus_int32 )res_Q10[ i ], 14 ), W_tmp_Q9 ) );
|
NLSF_Q15_tmp = silk_ADD32( pNLSF_Q15[ i ], silk_DIV32_16( silk_LSHIFT( (opus_int32)res_Q10[ i ], 14 ), W_tmp_Q9 ) );
|
||||||
pNLSF_Q15[ i ] = (opus_int16)silk_LIMIT( NLSF_Q15_tmp, 0, 32767 );
|
pNLSF_Q15[ i ] = (opus_int16)silk_LIMIT( NLSF_Q15_tmp, 0, 32767 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,7 @@ opus_int32 silk_NLSF_encode( /* O Returns
|
||||||
/* Residual after first stage */
|
/* Residual after first stage */
|
||||||
pCB_element = &psNLSF_CB->CB1_NLSF_Q8[ ind1 * psNLSF_CB->order ];
|
pCB_element = &psNLSF_CB->CB1_NLSF_Q8[ ind1 * psNLSF_CB->order ];
|
||||||
for( i = 0; i < psNLSF_CB->order; i++ ) {
|
for( i = 0; i < psNLSF_CB->order; i++ ) {
|
||||||
NLSF_tmp_Q15[ i ] = silk_LSHIFT16( ( opus_int16 )pCB_element[ i ], 7 );
|
NLSF_tmp_Q15[ i ] = silk_LSHIFT16( (opus_int16)pCB_element[ i ], 7 );
|
||||||
res_Q15[ i ] = pNLSF_Q15[ i ] - NLSF_tmp_Q15[ i ];
|
res_Q15[ i ] = pNLSF_Q15[ i ] - NLSF_tmp_Q15[ i ];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,13 +88,13 @@ opus_int32 silk_NLSF_encode( /* O Returns
|
||||||
|
|
||||||
/* Apply square-rooted weights */
|
/* Apply square-rooted weights */
|
||||||
for( i = 0; i < psNLSF_CB->order; i++ ) {
|
for( i = 0; i < psNLSF_CB->order; i++ ) {
|
||||||
W_tmp_Q9 = silk_SQRT_APPROX( silk_LSHIFT( ( opus_int32 )W_tmp_QW[ i ], 18 - NLSF_W_Q ) );
|
W_tmp_Q9 = silk_SQRT_APPROX( silk_LSHIFT( (opus_int32)W_tmp_QW[ i ], 18 - NLSF_W_Q ) );
|
||||||
res_Q10[ i ] = ( opus_int16 )silk_RSHIFT( silk_SMULBB( res_Q15[ i ], W_tmp_Q9 ), 14 );
|
res_Q10[ i ] = (opus_int16)silk_RSHIFT( silk_SMULBB( res_Q15[ i ], W_tmp_Q9 ), 14 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Modify input weights accordingly */
|
/* Modify input weights accordingly */
|
||||||
for( i = 0; i < psNLSF_CB->order; i++ ) {
|
for( i = 0; i < psNLSF_CB->order; i++ ) {
|
||||||
W_adj_Q5[ i ] = silk_DIV32_16( silk_LSHIFT( ( opus_int32 )pW_QW[ i ], 5 ), W_tmp_QW[ i ] );
|
W_adj_Q5[ i ] = silk_DIV32_16( silk_LSHIFT( (opus_int32)pW_QW[ i ], 5 ), W_tmp_QW[ i ] );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unpack entropy table indices and predictor for current CB1 index */
|
/* Unpack entropy table indices and predictor for current CB1 index */
|
||||||
|
@ -118,7 +118,7 @@ opus_int32 silk_NLSF_encode( /* O Returns
|
||||||
/* Find the lowest rate-distortion error */
|
/* Find the lowest rate-distortion error */
|
||||||
silk_insertion_sort_increasing( RD_Q25, &bestIndex, nSurvivors, 1 );
|
silk_insertion_sort_increasing( RD_Q25, &bestIndex, nSurvivors, 1 );
|
||||||
|
|
||||||
NLSFIndices[ 0 ] = ( opus_int8 )tempIndices1[ bestIndex ];
|
NLSFIndices[ 0 ] = (opus_int8)tempIndices1[ bestIndex ];
|
||||||
silk_memcpy( &NLSFIndices[ 1 ], &tempIndices2[ bestIndex * MAX_LPC_ORDER ], psNLSF_CB->order * sizeof( opus_int8 ) );
|
silk_memcpy( &NLSFIndices[ 1 ], &tempIndices2[ bestIndex * MAX_LPC_ORDER ], psNLSF_CB->order * sizeof( opus_int8 ) );
|
||||||
|
|
||||||
/* Decode */
|
/* Decode */
|
||||||
|
|
99
silk/NSQ.c
99
silk/NSQ.c
|
@ -34,10 +34,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
static inline void silk_nsq_scale_states(
|
static inline void silk_nsq_scale_states(
|
||||||
const silk_encoder_state *psEncC, /* I Encoder State */
|
const silk_encoder_state *psEncC, /* I Encoder State */
|
||||||
silk_nsq_state *NSQ, /* I/O NSQ state */
|
silk_nsq_state *NSQ, /* I/O NSQ state */
|
||||||
const opus_int16 x[], /* I input in Q0 */
|
const opus_int32 x_Q10[], /* I input in Q0 */
|
||||||
opus_int32 x_sc_Q10[], /* O input scaled with 1/Gain */
|
opus_int32 x_sc_Q10[], /* O input scaled with 1/Gain */
|
||||||
const opus_int16 sLTP[], /* I re-whitened LTP state in Q0 */
|
const opus_int16 sLTP[], /* I re-whitened LTP state in Q0 */
|
||||||
opus_int32 sLTP_Q16[], /* O LTP state matching scaled input */
|
opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */
|
||||||
opus_int subfr, /* I subframe number */
|
opus_int subfr, /* I subframe number */
|
||||||
const opus_int LTP_scale_Q14, /* I */
|
const opus_int LTP_scale_Q14, /* I */
|
||||||
const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */
|
const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */
|
||||||
|
@ -51,7 +51,7 @@ static inline void silk_noise_shape_quantizer(
|
||||||
const opus_int32 x_sc_Q10[], /* I */
|
const opus_int32 x_sc_Q10[], /* I */
|
||||||
opus_int8 pulses[], /* O */
|
opus_int8 pulses[], /* O */
|
||||||
opus_int16 xq[], /* O */
|
opus_int16 xq[], /* O */
|
||||||
opus_int32 sLTP_Q16[], /* I/O LTP state */
|
opus_int32 sLTP_Q15[], /* I/O LTP state */
|
||||||
const opus_int16 a_Q12[], /* I Short term prediction coefs */
|
const opus_int16 a_Q12[], /* I Short term prediction coefs */
|
||||||
const opus_int16 b_Q14[], /* I Long term prediction coefs */
|
const opus_int16 b_Q14[], /* I Long term prediction coefs */
|
||||||
const opus_int16 AR_shp_Q13[], /* I Noise shaping AR coefs */
|
const opus_int16 AR_shp_Q13[], /* I Noise shaping AR coefs */
|
||||||
|
@ -71,7 +71,7 @@ void silk_NSQ(
|
||||||
const silk_encoder_state *psEncC, /* I/O Encoder State */
|
const silk_encoder_state *psEncC, /* I/O Encoder State */
|
||||||
silk_nsq_state *NSQ, /* I/O NSQ state */
|
silk_nsq_state *NSQ, /* I/O NSQ state */
|
||||||
SideInfoIndices *psIndices, /* I/O Quantization Indices */
|
SideInfoIndices *psIndices, /* I/O Quantization Indices */
|
||||||
const opus_int16 x[], /* I Prefiltered input signal */
|
const opus_int32 x_Q10[], /* I Prefiltered input signal */
|
||||||
opus_int8 pulses[], /* O Quantized pulse signal */
|
opus_int8 pulses[], /* O Quantized pulse signal */
|
||||||
const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
|
const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
|
||||||
const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
|
const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
|
||||||
|
@ -85,14 +85,14 @@ void silk_NSQ(
|
||||||
const opus_int LTP_scale_Q14 /* I LTP state scaling */
|
const opus_int LTP_scale_Q14 /* I LTP state scaling */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
opus_int k, lag, start_idx, LSF_interpolation_flag;
|
opus_int k, lag, start_idx, LSF_interpolation_flag;
|
||||||
const opus_int16 *A_Q12, *B_Q14, *AR_shp_Q13;
|
const opus_int16 *A_Q12, *B_Q14, *AR_shp_Q13;
|
||||||
opus_int16 *pxq;
|
opus_int16 *pxq;
|
||||||
opus_int32 sLTP_Q16[ 2 * MAX_FRAME_LENGTH ];
|
opus_int32 sLTP_Q15[ 2 * MAX_FRAME_LENGTH ];
|
||||||
opus_int16 sLTP[ 2 * MAX_FRAME_LENGTH ];
|
opus_int16 sLTP[ 2 * MAX_FRAME_LENGTH ];
|
||||||
opus_int32 HarmShapeFIRPacked_Q14;
|
opus_int32 HarmShapeFIRPacked_Q14;
|
||||||
opus_int offset_Q10;
|
opus_int offset_Q10;
|
||||||
opus_int32 x_sc_Q10[ MAX_FRAME_LENGTH / MAX_NB_SUBFR ];
|
opus_int32 x_sc_Q10[ MAX_SUB_FRAME_LENGTH ];
|
||||||
|
|
||||||
NSQ->rand_seed = psIndices->Seed;
|
NSQ->rand_seed = psIndices->Seed;
|
||||||
|
|
||||||
|
@ -109,7 +109,7 @@ void silk_NSQ(
|
||||||
LSF_interpolation_flag = 1;
|
LSF_interpolation_flag = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup pointers to start of sub frame */
|
/* Set up pointers to start of sub frame */
|
||||||
NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length;
|
NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length;
|
||||||
NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;
|
NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;
|
||||||
pxq = &NSQ->xq[ psEncC->ltp_mem_length ];
|
pxq = &NSQ->xq[ psEncC->ltp_mem_length ];
|
||||||
|
@ -121,7 +121,7 @@ void silk_NSQ(
|
||||||
/* Noise shape parameters */
|
/* Noise shape parameters */
|
||||||
silk_assert( HarmShapeGain_Q14[ k ] >= 0 );
|
silk_assert( HarmShapeGain_Q14[ k ] >= 0 );
|
||||||
HarmShapeFIRPacked_Q14 = silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 );
|
HarmShapeFIRPacked_Q14 = silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 );
|
||||||
HarmShapeFIRPacked_Q14 |= silk_LSHIFT( ( opus_int32 )silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 );
|
HarmShapeFIRPacked_Q14 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 );
|
||||||
|
|
||||||
NSQ->rewhite_flag = 0;
|
NSQ->rewhite_flag = 0;
|
||||||
if( psIndices->signalType == TYPE_VOICED ) {
|
if( psIndices->signalType == TYPE_VOICED ) {
|
||||||
|
@ -142,13 +142,13 @@ void silk_NSQ(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
silk_nsq_scale_states( psEncC, NSQ, x, x_sc_Q10, sLTP, sLTP_Q16, k, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType );
|
silk_nsq_scale_states( psEncC, NSQ, x_Q10, x_sc_Q10, sLTP, sLTP_Q15, k, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType );
|
||||||
|
|
||||||
silk_noise_shape_quantizer( NSQ, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q16, A_Q12, B_Q14,
|
silk_noise_shape_quantizer( NSQ, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15, A_Q12, B_Q14,
|
||||||
AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ], Lambda_Q10,
|
AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ], Lambda_Q10,
|
||||||
offset_Q10, psEncC->subfr_length, psEncC->shapingLPCOrder, psEncC->predictLPCOrder );
|
offset_Q10, psEncC->subfr_length, psEncC->shapingLPCOrder, psEncC->predictLPCOrder );
|
||||||
|
|
||||||
x += psEncC->subfr_length;
|
x_Q10 += psEncC->subfr_length;
|
||||||
pulses += psEncC->subfr_length;
|
pulses += psEncC->subfr_length;
|
||||||
pxq += psEncC->subfr_length;
|
pxq += psEncC->subfr_length;
|
||||||
}
|
}
|
||||||
|
@ -170,7 +170,7 @@ static inline void silk_noise_shape_quantizer(
|
||||||
const opus_int32 x_sc_Q10[], /* I */
|
const opus_int32 x_sc_Q10[], /* I */
|
||||||
opus_int8 pulses[], /* O */
|
opus_int8 pulses[], /* O */
|
||||||
opus_int16 xq[], /* O */
|
opus_int16 xq[], /* O */
|
||||||
opus_int32 sLTP_Q16[], /* I/O LTP state */
|
opus_int32 sLTP_Q15[], /* I/O LTP state */
|
||||||
const opus_int16 a_Q12[], /* I Short term prediction coefs */
|
const opus_int16 a_Q12[], /* I Short term prediction coefs */
|
||||||
const opus_int16 b_Q14[], /* I Long term prediction coefs */
|
const opus_int16 b_Q14[], /* I Long term prediction coefs */
|
||||||
const opus_int16 AR_shp_Q13[], /* I Noise shaping AR coefs */
|
const opus_int16 AR_shp_Q13[], /* I Noise shaping AR coefs */
|
||||||
|
@ -187,16 +187,16 @@ static inline void silk_noise_shape_quantizer(
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
opus_int i, j;
|
opus_int i, j;
|
||||||
opus_int32 LTP_pred_Q14, LPC_pred_Q10, n_AR_Q10, n_LTP_Q14;
|
opus_int32 LTP_pred_Q13, LPC_pred_Q10, n_AR_Q10, n_LTP_Q14;
|
||||||
opus_int32 n_LF_Q10, r_Q10, rr_Q10, q1_Q10, q2_Q10, rd1_Q10, rd2_Q10;
|
opus_int32 n_LF_Q10, r_Q10, rr_Q10, q1_Q10, q2_Q10, rd1_Q10, rd2_Q10;
|
||||||
opus_int32 dither, exc_Q10, LPC_exc_Q10, xq_Q10;
|
opus_int32 dither, exc_Q10, LPC_exc_Q10, xq_Q10;
|
||||||
opus_int32 tmp1, tmp2, sLF_AR_shp_Q10;
|
opus_int32 tmp1, tmp2, sLF_AR_shp_Q10;
|
||||||
opus_int32 *psLPC_Q14, *shp_lag_ptr, *pred_lag_ptr;
|
opus_int32 *psLPC_Q14, *shp_lag_ptr, *pred_lag_ptr;
|
||||||
|
|
||||||
shp_lag_ptr = &NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ];
|
shp_lag_ptr = &NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ];
|
||||||
pred_lag_ptr = &sLTP_Q16[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ];
|
pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ];
|
||||||
|
|
||||||
/* Setup short term AR state */
|
/* Set up short term AR state */
|
||||||
psLPC_Q14 = &NSQ->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 ];
|
psLPC_Q14 = &NSQ->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 ];
|
||||||
|
|
||||||
for( i = 0; i < length; i++ ) {
|
for( i = 0; i < length; i++ ) {
|
||||||
|
@ -207,11 +207,7 @@ static inline void silk_noise_shape_quantizer(
|
||||||
dither = silk_RSHIFT( NSQ->rand_seed, 31 );
|
dither = silk_RSHIFT( NSQ->rand_seed, 31 );
|
||||||
|
|
||||||
/* Short-term prediction */
|
/* Short-term prediction */
|
||||||
silk_assert( ( predictLPCOrder & 1 ) == 0 ); /* check that order is even */
|
silk_assert( predictLPCOrder == 10 || predictLPCOrder == 16 );
|
||||||
silk_assert( ( (opus_int64)a_Q12 & 3 ) == 0 ); /* check that array starts at 4-byte aligned address */
|
|
||||||
silk_assert( predictLPCOrder >= 10 ); /* check that unrolling works */
|
|
||||||
|
|
||||||
/* Partially unrolled */
|
|
||||||
LPC_pred_Q10 = silk_SMULWB( psLPC_Q14[ 0 ], a_Q12[ 0 ] );
|
LPC_pred_Q10 = silk_SMULWB( psLPC_Q14[ 0 ], a_Q12[ 0 ] );
|
||||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -1 ], a_Q12[ 1 ] );
|
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -1 ], a_Q12[ 1 ] );
|
||||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -2 ], a_Q12[ 2 ] );
|
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -2 ], a_Q12[ 2 ] );
|
||||||
|
@ -222,21 +218,26 @@ static inline void silk_noise_shape_quantizer(
|
||||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -7 ], a_Q12[ 7 ] );
|
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -7 ], a_Q12[ 7 ] );
|
||||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -8 ], a_Q12[ 8 ] );
|
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -8 ], a_Q12[ 8 ] );
|
||||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -9 ], a_Q12[ 9 ] );
|
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -9 ], a_Q12[ 9 ] );
|
||||||
for( j = 10; j < predictLPCOrder; j ++ ) {
|
if( predictLPCOrder == 16 ) {
|
||||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -j ], a_Q12[ j ] );
|
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -10 ], a_Q12[ 10 ] );
|
||||||
|
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -11 ], a_Q12[ 11 ] );
|
||||||
|
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -12 ], a_Q12[ 12 ] );
|
||||||
|
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -13 ], a_Q12[ 13 ] );
|
||||||
|
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -14 ], a_Q12[ 14 ] );
|
||||||
|
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -15 ], a_Q12[ 15 ] );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Long-term prediction */
|
/* Long-term prediction */
|
||||||
if( signalType == TYPE_VOICED ) {
|
if( signalType == TYPE_VOICED ) {
|
||||||
/* Unrolled loop */
|
/* Unrolled loop */
|
||||||
LTP_pred_Q14 = silk_SMULWB( pred_lag_ptr[ 0 ], b_Q14[ 0 ] );
|
LTP_pred_Q13 = silk_SMULWB( pred_lag_ptr[ 0 ], b_Q14[ 0 ] );
|
||||||
LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -1 ], b_Q14[ 1 ] );
|
LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -1 ], b_Q14[ 1 ] );
|
||||||
LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -2 ], b_Q14[ 2 ] );
|
LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -2 ], b_Q14[ 2 ] );
|
||||||
LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -3 ], b_Q14[ 3 ] );
|
LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -3 ], b_Q14[ 3 ] );
|
||||||
LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], b_Q14[ 4 ] );
|
LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -4 ], b_Q14[ 4 ] );
|
||||||
pred_lag_ptr++;
|
pred_lag_ptr++;
|
||||||
} else {
|
} else {
|
||||||
LTP_pred_Q14 = 0;
|
LTP_pred_Q13 = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Noise shape feedback */
|
/* Noise shape feedback */
|
||||||
|
@ -268,11 +269,11 @@ static inline void silk_noise_shape_quantizer(
|
||||||
if( lag > 0 ) {
|
if( lag > 0 ) {
|
||||||
/* Symmetric, packed FIR coefficients */
|
/* Symmetric, packed FIR coefficients */
|
||||||
n_LTP_Q14 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 );
|
n_LTP_Q14 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 );
|
||||||
n_LTP_Q14 = silk_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 );
|
n_LTP_Q14 = silk_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 );
|
||||||
n_LTP_Q14 = silk_LSHIFT( n_LTP_Q14, 6 );
|
n_LTP_Q14 = silk_LSHIFT( n_LTP_Q14, 6 );
|
||||||
shp_lag_ptr++;
|
shp_lag_ptr++;
|
||||||
|
|
||||||
tmp1 = silk_SUB32( LTP_pred_Q14, n_LTP_Q14 ); /* Add Q14 stuff */
|
tmp1 = silk_SUB32( LTP_pred_Q13 << 1, n_LTP_Q14 ); /* Add Q14 stuff */
|
||||||
tmp1 = silk_RSHIFT( tmp1, 4 ); /* convert to Q10 */
|
tmp1 = silk_RSHIFT( tmp1, 4 ); /* convert to Q10 */
|
||||||
tmp1 = silk_ADD32( tmp1, LPC_pred_Q10 ); /* add Q10 stuff */
|
tmp1 = silk_ADD32( tmp1, LPC_pred_Q10 ); /* add Q10 stuff */
|
||||||
tmp1 = silk_SUB32( tmp1, n_AR_Q10 ); /* subtract Q10 stuff */
|
tmp1 = silk_SUB32( tmp1, n_AR_Q10 ); /* subtract Q10 stuff */
|
||||||
|
@ -324,18 +325,19 @@ static inline void silk_noise_shape_quantizer(
|
||||||
q1_Q10 = q2_Q10;
|
q1_Q10 = q2_Q10;
|
||||||
}
|
}
|
||||||
|
|
||||||
pulses[ i ] = ( opus_int8 )silk_RSHIFT_ROUND( q1_Q10, 10 );
|
pulses[ i ] = (opus_int8)silk_RSHIFT_ROUND( q1_Q10, 10 );
|
||||||
|
|
||||||
/* Excitation */
|
/* Excitation */
|
||||||
exc_Q10 = q1_Q10 ^ dither;
|
exc_Q10 = q1_Q10 ^ dither;
|
||||||
|
|
||||||
/* Add predictions */
|
/* Add predictions */
|
||||||
LPC_exc_Q10 = silk_ADD32( exc_Q10, silk_RSHIFT_ROUND( LTP_pred_Q14, 4 ) );
|
LPC_exc_Q10 = silk_ADD32( exc_Q10, silk_RSHIFT_ROUND( LTP_pred_Q13, 3 ) );
|
||||||
xq_Q10 = silk_ADD32( LPC_exc_Q10, LPC_pred_Q10 );
|
xq_Q10 = silk_ADD32( LPC_exc_Q10, LPC_pred_Q10 );
|
||||||
|
|
||||||
/* Scale XQ back to normal level before saving */
|
/* Scale XQ back to normal level before saving */
|
||||||
xq[ i ] = ( opus_int16 )silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( xq_Q10, Gain_Q16 ), 10 ) );
|
xq[ i ] = ( opus_int16 )silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( xq_Q10, Gain_Q16 ), 10 ) );
|
||||||
|
|
||||||
|
/* DEBUG_STORE_DATA( enc.pcm, &xq[i], sizeof( opus_int16 ) ) */
|
||||||
/* Update states */
|
/* Update states */
|
||||||
psLPC_Q14++;
|
psLPC_Q14++;
|
||||||
*psLPC_Q14 = silk_LSHIFT( xq_Q10, 4 );
|
*psLPC_Q14 = silk_LSHIFT( xq_Q10, 4 );
|
||||||
|
@ -343,7 +345,7 @@ static inline void silk_noise_shape_quantizer(
|
||||||
NSQ->sLF_AR_shp_Q12 = silk_LSHIFT( sLF_AR_shp_Q10, 2 );
|
NSQ->sLF_AR_shp_Q12 = silk_LSHIFT( sLF_AR_shp_Q10, 2 );
|
||||||
|
|
||||||
NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx ] = silk_SUB32( sLF_AR_shp_Q10, n_LF_Q10 );
|
NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx ] = silk_SUB32( sLF_AR_shp_Q10, n_LF_Q10 );
|
||||||
sLTP_Q16[ NSQ->sLTP_buf_idx ] = silk_LSHIFT( LPC_exc_Q10, 6 );
|
sLTP_Q15[ NSQ->sLTP_buf_idx ] = silk_LSHIFT( LPC_exc_Q10, 5 );
|
||||||
NSQ->sLTP_shp_buf_idx++;
|
NSQ->sLTP_shp_buf_idx++;
|
||||||
NSQ->sLTP_buf_idx++;
|
NSQ->sLTP_buf_idx++;
|
||||||
|
|
||||||
|
@ -358,10 +360,10 @@ static inline void silk_noise_shape_quantizer(
|
||||||
static inline void silk_nsq_scale_states(
|
static inline void silk_nsq_scale_states(
|
||||||
const silk_encoder_state *psEncC, /* I Encoder State */
|
const silk_encoder_state *psEncC, /* I Encoder State */
|
||||||
silk_nsq_state *NSQ, /* I/O NSQ state */
|
silk_nsq_state *NSQ, /* I/O NSQ state */
|
||||||
const opus_int16 x[], /* I input in Q0 */
|
const opus_int32 x_Q10[], /* I input in Q0 */
|
||||||
opus_int32 x_sc_Q10[], /* O input scaled with 1/Gain */
|
opus_int32 x_sc_Q10[], /* O input scaled with 1/Gain */
|
||||||
const opus_int16 sLTP[], /* I re-whitened LTP state in Q0 */
|
const opus_int16 sLTP[], /* I re-whitened LTP state in Q0 */
|
||||||
opus_int32 sLTP_Q16[], /* O LTP state matching scaled input */
|
opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */
|
||||||
opus_int subfr, /* I subframe number */
|
opus_int subfr, /* I subframe number */
|
||||||
const opus_int LTP_scale_Q14, /* I */
|
const opus_int LTP_scale_Q14, /* I */
|
||||||
const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */
|
const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */
|
||||||
|
@ -370,22 +372,21 @@ static inline void silk_nsq_scale_states(
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
opus_int i, lag;
|
opus_int i, lag;
|
||||||
opus_int32 inv_gain_Q16, gain_adj_Q16, inv_gain_Q32;
|
opus_int32 inv_gain_Q16, gain_adj_Q16, inv_gain_Q31;
|
||||||
|
|
||||||
inv_gain_Q16 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 32 );
|
inv_gain_Q16 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 32 );
|
||||||
inv_gain_Q16 = silk_min( inv_gain_Q16, silk_int16_MAX );
|
|
||||||
lag = pitchL[ subfr ];
|
lag = pitchL[ subfr ];
|
||||||
|
|
||||||
/* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */
|
/* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */
|
||||||
if( NSQ->rewhite_flag ) {
|
if( NSQ->rewhite_flag ) {
|
||||||
inv_gain_Q32 = silk_LSHIFT( inv_gain_Q16, 16 );
|
inv_gain_Q31 = silk_LSHIFT( inv_gain_Q16, 15 );
|
||||||
if( subfr == 0 ) {
|
if( subfr == 0 ) {
|
||||||
/* Do LTP downscaling */
|
/* Do LTP downscaling */
|
||||||
inv_gain_Q32 = silk_LSHIFT( silk_SMULWB( inv_gain_Q32, LTP_scale_Q14 ), 2 );
|
inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, LTP_scale_Q14 ), 2 );
|
||||||
}
|
}
|
||||||
for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {
|
for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {
|
||||||
silk_assert( i < MAX_FRAME_LENGTH );
|
silk_assert( i < MAX_FRAME_LENGTH );
|
||||||
sLTP_Q16[ i ] = silk_SMULWB( inv_gain_Q32, sLTP[ i ] );
|
sLTP_Q15[ i ] = silk_SMULWB( inv_gain_Q31, sLTP[ i ] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -401,7 +402,7 @@ static inline void silk_nsq_scale_states(
|
||||||
/* Scale long-term prediction state */
|
/* Scale long-term prediction state */
|
||||||
if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) {
|
if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) {
|
||||||
for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {
|
for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {
|
||||||
sLTP_Q16[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q16[ i ] );
|
sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -418,10 +419,10 @@ static inline void silk_nsq_scale_states(
|
||||||
|
|
||||||
/* Scale input */
|
/* Scale input */
|
||||||
for( i = 0; i < psEncC->subfr_length; i++ ) {
|
for( i = 0; i < psEncC->subfr_length; i++ ) {
|
||||||
x_sc_Q10[ i ] = silk_RSHIFT( silk_SMULBB( x[ i ], ( opus_int16 )inv_gain_Q16 ), 6 );
|
x_sc_Q10[ i ] = silk_SMULWW( x_Q10[ i ], inv_gain_Q16 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* save inv_gain */
|
/* Save inv_gain */
|
||||||
silk_assert( inv_gain_Q16 != 0 );
|
silk_assert( inv_gain_Q16 != 0 );
|
||||||
NSQ->prev_inv_gain_Q16 = inv_gain_Q16;
|
NSQ->prev_inv_gain_Q16 = inv_gain_Q16;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
opus_int32 sLPC_Q14[ MAX_FRAME_LENGTH / MAX_NB_SUBFR + NSQ_LPC_BUF_LENGTH ];
|
opus_int32 sLPC_Q14[ MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH ];
|
||||||
opus_int32 RandState[ DECISION_DELAY ];
|
opus_int32 RandState[ DECISION_DELAY ];
|
||||||
opus_int32 Q_Q10[ DECISION_DELAY ];
|
opus_int32 Q_Q10[ DECISION_DELAY ];
|
||||||
opus_int32 Xq_Q10[ DECISION_DELAY ];
|
opus_int32 Xq_Q10[ DECISION_DELAY ];
|
||||||
|
@ -58,10 +58,10 @@ static inline void silk_nsq_del_dec_scale_states(
|
||||||
const silk_encoder_state *psEncC, /* I Encoder State */
|
const silk_encoder_state *psEncC, /* I Encoder State */
|
||||||
silk_nsq_state *NSQ, /* I/O NSQ state */
|
silk_nsq_state *NSQ, /* I/O NSQ state */
|
||||||
NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
|
NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
|
||||||
const opus_int16 x[], /* I Input in Q0 */
|
const opus_int32 x_Q10[], /* I Input in Q0 */
|
||||||
opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */
|
opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */
|
||||||
const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */
|
const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */
|
||||||
opus_int32 sLTP_Q16[], /* O LTP state matching scaled input */
|
opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */
|
||||||
opus_int subfr, /* I Subframe number */
|
opus_int subfr, /* I Subframe number */
|
||||||
opus_int nStatesDelayedDecision, /* I Number of del dec states */
|
opus_int nStatesDelayedDecision, /* I Number of del dec states */
|
||||||
const opus_int LTP_scale_Q14, /* I LTP state scaling */
|
const opus_int LTP_scale_Q14, /* I LTP state scaling */
|
||||||
|
@ -81,7 +81,7 @@ static inline void silk_noise_shape_quantizer_del_dec(
|
||||||
const opus_int32 x_Q10[], /* I */
|
const opus_int32 x_Q10[], /* I */
|
||||||
opus_int8 pulses[], /* O */
|
opus_int8 pulses[], /* O */
|
||||||
opus_int16 xq[], /* O */
|
opus_int16 xq[], /* O */
|
||||||
opus_int32 sLTP_Q16[], /* I/O LTP filter state */
|
opus_int32 sLTP_Q15[], /* I/O LTP filter state */
|
||||||
opus_int32 delayedGain_Q16[], /* I/O Gain delay buffer */
|
opus_int32 delayedGain_Q16[], /* I/O Gain delay buffer */
|
||||||
const opus_int16 a_Q12[], /* I Short term prediction coefs */
|
const opus_int16 a_Q12[], /* I Short term prediction coefs */
|
||||||
const opus_int16 b_Q14[], /* I Long term prediction coefs */
|
const opus_int16 b_Q14[], /* I Long term prediction coefs */
|
||||||
|
@ -107,7 +107,7 @@ void silk_NSQ_del_dec(
|
||||||
const silk_encoder_state *psEncC, /* I/O Encoder State */
|
const silk_encoder_state *psEncC, /* I/O Encoder State */
|
||||||
silk_nsq_state *NSQ, /* I/O NSQ state */
|
silk_nsq_state *NSQ, /* I/O NSQ state */
|
||||||
SideInfoIndices *psIndices, /* I/O Quantization Indices */
|
SideInfoIndices *psIndices, /* I/O Quantization Indices */
|
||||||
const opus_int16 x[], /* I Prefiltered input signal */
|
const opus_int32 x_Q10[], /* I Prefiltered input signal */
|
||||||
opus_int8 pulses[], /* O Quantized pulse signal */
|
opus_int8 pulses[], /* O Quantized pulse signal */
|
||||||
const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
|
const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
|
||||||
const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
|
const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
|
||||||
|
@ -121,19 +121,19 @@ void silk_NSQ_del_dec(
|
||||||
const opus_int LTP_scale_Q14 /* I LTP state scaling */
|
const opus_int LTP_scale_Q14 /* I LTP state scaling */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
opus_int i, k, lag, start_idx, LSF_interpolation_flag, Winner_ind, subfr;
|
opus_int i, k, lag, start_idx, LSF_interpolation_flag, Winner_ind, subfr;
|
||||||
opus_int last_smple_idx, smpl_buf_idx, decisionDelay;
|
opus_int last_smple_idx, smpl_buf_idx, decisionDelay;
|
||||||
const opus_int16 *A_Q12, *B_Q14, *AR_shp_Q13;
|
const opus_int16 *A_Q12, *B_Q14, *AR_shp_Q13;
|
||||||
opus_int16 *pxq;
|
opus_int16 *pxq;
|
||||||
opus_int32 sLTP_Q16[ 2 * MAX_FRAME_LENGTH ];
|
opus_int32 sLTP_Q15[ 2 * MAX_FRAME_LENGTH ];
|
||||||
opus_int16 sLTP[ 2 * MAX_FRAME_LENGTH ];
|
opus_int16 sLTP[ 2 * MAX_FRAME_LENGTH ];
|
||||||
opus_int32 HarmShapeFIRPacked_Q14;
|
opus_int32 HarmShapeFIRPacked_Q14;
|
||||||
opus_int offset_Q10;
|
opus_int offset_Q10;
|
||||||
opus_int32 RDmin_Q10;
|
opus_int32 RDmin_Q10;
|
||||||
opus_int32 x_sc_Q10[ MAX_SUB_FRAME_LENGTH ];
|
opus_int32 x_sc_Q10[ MAX_SUB_FRAME_LENGTH ];
|
||||||
opus_int32 delayedGain_Q16[ DECISION_DELAY ];
|
opus_int32 delayedGain_Q16[ DECISION_DELAY ];
|
||||||
NSQ_del_dec_struct psDelDec[ MAX_DEL_DEC_STATES ];
|
NSQ_del_dec_struct psDelDec[ MAX_DEL_DEC_STATES ];
|
||||||
NSQ_del_dec_struct *psDD;
|
NSQ_del_dec_struct *psDD;
|
||||||
|
|
||||||
/* Set unvoiced lag to the previous one, overwrite later for voiced */
|
/* Set unvoiced lag to the previous one, overwrite later for voiced */
|
||||||
lag = NSQ->lagPrev;
|
lag = NSQ->lagPrev;
|
||||||
|
@ -175,7 +175,7 @@ void silk_NSQ_del_dec(
|
||||||
LSF_interpolation_flag = 1;
|
LSF_interpolation_flag = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup pointers to start of sub frame */
|
/* Set up pointers to start of sub frame */
|
||||||
pxq = &NSQ->xq[ psEncC->ltp_mem_length ];
|
pxq = &NSQ->xq[ psEncC->ltp_mem_length ];
|
||||||
NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length;
|
NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length;
|
||||||
NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;
|
NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;
|
||||||
|
@ -188,7 +188,7 @@ void silk_NSQ_del_dec(
|
||||||
/* Noise shape parameters */
|
/* Noise shape parameters */
|
||||||
silk_assert( HarmShapeGain_Q14[ k ] >= 0 );
|
silk_assert( HarmShapeGain_Q14[ k ] >= 0 );
|
||||||
HarmShapeFIRPacked_Q14 = silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 );
|
HarmShapeFIRPacked_Q14 = silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 );
|
||||||
HarmShapeFIRPacked_Q14 |= silk_LSHIFT( ( opus_int32 )silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 );
|
HarmShapeFIRPacked_Q14 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 );
|
||||||
|
|
||||||
NSQ->rewhite_flag = 0;
|
NSQ->rewhite_flag = 0;
|
||||||
if( psIndices->signalType == TYPE_VOICED ) {
|
if( psIndices->signalType == TYPE_VOICED ) {
|
||||||
|
@ -220,8 +220,8 @@ void silk_NSQ_del_dec(
|
||||||
last_smple_idx = smpl_buf_idx + decisionDelay;
|
last_smple_idx = smpl_buf_idx + decisionDelay;
|
||||||
for( i = 0; i < decisionDelay; i++ ) {
|
for( i = 0; i < decisionDelay; i++ ) {
|
||||||
last_smple_idx = ( last_smple_idx - 1 ) & DECISION_DELAY_MASK;
|
last_smple_idx = ( last_smple_idx - 1 ) & DECISION_DELAY_MASK;
|
||||||
pulses[ i - decisionDelay ] = ( opus_int8 )silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );
|
pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );
|
||||||
pxq[ i - decisionDelay ] = ( opus_int16 )silk_SAT16( silk_RSHIFT_ROUND(
|
pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(
|
||||||
silk_SMULWW( psDD->Xq_Q10[ last_smple_idx ], Gains_Q16[ 1 ] ), 10 ) );
|
silk_SMULWW( psDD->Xq_Q10[ last_smple_idx ], Gains_Q16[ 1 ] ), 10 ) );
|
||||||
NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q10[ last_smple_idx ];
|
NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q10[ last_smple_idx ];
|
||||||
}
|
}
|
||||||
|
@ -241,15 +241,15 @@ void silk_NSQ_del_dec(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
silk_nsq_del_dec_scale_states( psEncC, NSQ, psDelDec, x, x_sc_Q10, sLTP, sLTP_Q16, k,
|
silk_nsq_del_dec_scale_states( psEncC, NSQ, psDelDec, x_Q10, x_sc_Q10, sLTP, sLTP_Q15, k,
|
||||||
psEncC->nStatesDelayedDecision, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType, decisionDelay );
|
psEncC->nStatesDelayedDecision, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType, decisionDelay );
|
||||||
|
|
||||||
silk_noise_shape_quantizer_del_dec( NSQ, psDelDec, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q16,
|
silk_noise_shape_quantizer_del_dec( NSQ, psDelDec, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15,
|
||||||
delayedGain_Q16, A_Q12, B_Q14, AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ],
|
delayedGain_Q16, A_Q12, B_Q14, AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ],
|
||||||
Gains_Q16[ k ], Lambda_Q10, offset_Q10, psEncC->subfr_length, subfr++, psEncC->shapingLPCOrder,
|
Gains_Q16[ k ], Lambda_Q10, offset_Q10, psEncC->subfr_length, subfr++, psEncC->shapingLPCOrder,
|
||||||
psEncC->predictLPCOrder, psEncC->warping_Q16, psEncC->nStatesDelayedDecision, &smpl_buf_idx, decisionDelay );
|
psEncC->predictLPCOrder, psEncC->warping_Q16, psEncC->nStatesDelayedDecision, &smpl_buf_idx, decisionDelay );
|
||||||
|
|
||||||
x += psEncC->subfr_length;
|
x_Q10 += psEncC->subfr_length;
|
||||||
pulses += psEncC->subfr_length;
|
pulses += psEncC->subfr_length;
|
||||||
pxq += psEncC->subfr_length;
|
pxq += psEncC->subfr_length;
|
||||||
}
|
}
|
||||||
|
@ -270,8 +270,8 @@ void silk_NSQ_del_dec(
|
||||||
last_smple_idx = smpl_buf_idx + decisionDelay;
|
last_smple_idx = smpl_buf_idx + decisionDelay;
|
||||||
for( i = 0; i < decisionDelay; i++ ) {
|
for( i = 0; i < decisionDelay; i++ ) {
|
||||||
last_smple_idx = ( last_smple_idx - 1 ) & DECISION_DELAY_MASK;
|
last_smple_idx = ( last_smple_idx - 1 ) & DECISION_DELAY_MASK;
|
||||||
pulses[ i - decisionDelay ] = ( opus_int8 )silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );
|
pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );
|
||||||
pxq[ i - decisionDelay ] = ( opus_int16 )silk_SAT16( silk_RSHIFT_ROUND(
|
pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(
|
||||||
silk_SMULWW( psDD->Xq_Q10[ last_smple_idx ], Gains_Q16[ psEncC->nb_subfr - 1 ] ), 10 ) );
|
silk_SMULWW( psDD->Xq_Q10[ last_smple_idx ], Gains_Q16[ psEncC->nb_subfr - 1 ] ), 10 ) );
|
||||||
NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q10[ last_smple_idx ];
|
NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q10[ last_smple_idx ];
|
||||||
}
|
}
|
||||||
|
@ -282,7 +282,8 @@ void silk_NSQ_del_dec(
|
||||||
NSQ->sLF_AR_shp_Q12 = psDD->LF_AR_Q12;
|
NSQ->sLF_AR_shp_Q12 = psDD->LF_AR_Q12;
|
||||||
NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ];
|
NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ];
|
||||||
|
|
||||||
/* Save quantized speech and noise shaping signals */
|
/* Save quantized speech signal */
|
||||||
|
/* DEBUG_STORE_DATA( enc.pcm, &NSQ->xq[psEncC->ltp_mem_length], psEncC->frame_length * sizeof( opus_int16 ) ) */
|
||||||
silk_memmove( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) );
|
silk_memmove( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) );
|
||||||
silk_memmove( NSQ->sLTP_shp_Q10, &NSQ->sLTP_shp_Q10[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) );
|
silk_memmove( NSQ->sLTP_shp_Q10, &NSQ->sLTP_shp_Q10[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) );
|
||||||
}
|
}
|
||||||
|
@ -297,7 +298,7 @@ static inline void silk_noise_shape_quantizer_del_dec(
|
||||||
const opus_int32 x_Q10[], /* I */
|
const opus_int32 x_Q10[], /* I */
|
||||||
opus_int8 pulses[], /* O */
|
opus_int8 pulses[], /* O */
|
||||||
opus_int16 xq[], /* O */
|
opus_int16 xq[], /* O */
|
||||||
opus_int32 sLTP_Q16[], /* I/O LTP filter state */
|
opus_int32 sLTP_Q15[], /* I/O LTP filter state */
|
||||||
opus_int32 delayedGain_Q16[], /* I/O Gain delay buffer */
|
opus_int32 delayedGain_Q16[], /* I/O Gain delay buffer */
|
||||||
const opus_int16 a_Q12[], /* I Short term prediction coefs */
|
const opus_int16 a_Q12[], /* I Short term prediction coefs */
|
||||||
const opus_int16 b_Q14[], /* I Long term prediction coefs */
|
const opus_int16 b_Q14[], /* I Long term prediction coefs */
|
||||||
|
@ -321,7 +322,7 @@ static inline void silk_noise_shape_quantizer_del_dec(
|
||||||
{
|
{
|
||||||
opus_int i, j, k, Winner_ind, RDmin_ind, RDmax_ind, last_smple_idx;
|
opus_int i, j, k, Winner_ind, RDmin_ind, RDmax_ind, last_smple_idx;
|
||||||
opus_int32 Winner_rand_state;
|
opus_int32 Winner_rand_state;
|
||||||
opus_int32 LTP_pred_Q14, LPC_pred_Q10, n_AR_Q10, n_LTP_Q14, LTP_Q10;
|
opus_int32 LTP_pred_Q13, LPC_pred_Q10, n_AR_Q10, n_LTP_Q14, LTP_Q10;
|
||||||
opus_int32 n_LF_Q10, r_Q10, rr_Q10, rd1_Q10, rd2_Q10, RDmin_Q10, RDmax_Q10;
|
opus_int32 n_LF_Q10, r_Q10, rr_Q10, rd1_Q10, rd2_Q10, RDmin_Q10, RDmax_Q10;
|
||||||
opus_int32 q1_Q10, q2_Q10, dither, exc_Q10, LPC_exc_Q10, xq_Q10;
|
opus_int32 q1_Q10, q2_Q10, dither, exc_Q10, LPC_exc_Q10, xq_Q10;
|
||||||
opus_int32 tmp1, tmp2, sLF_AR_shp_Q10;
|
opus_int32 tmp1, tmp2, sLF_AR_shp_Q10;
|
||||||
|
@ -333,7 +334,7 @@ static inline void silk_noise_shape_quantizer_del_dec(
|
||||||
silk_assert( nStatesDelayedDecision > 0 );
|
silk_assert( nStatesDelayedDecision > 0 );
|
||||||
|
|
||||||
shp_lag_ptr = &NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ];
|
shp_lag_ptr = &NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ];
|
||||||
pred_lag_ptr = &sLTP_Q16[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ];
|
pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ];
|
||||||
|
|
||||||
for( i = 0; i < length; i++ ) {
|
for( i = 0; i < length; i++ ) {
|
||||||
/* Perform common calculations used in all states */
|
/* Perform common calculations used in all states */
|
||||||
|
@ -341,25 +342,25 @@ static inline void silk_noise_shape_quantizer_del_dec(
|
||||||
/* Long-term prediction */
|
/* Long-term prediction */
|
||||||
if( signalType == TYPE_VOICED ) {
|
if( signalType == TYPE_VOICED ) {
|
||||||
/* Unrolled loop */
|
/* Unrolled loop */
|
||||||
LTP_pred_Q14 = silk_SMULWB( pred_lag_ptr[ 0 ], b_Q14[ 0 ] );
|
LTP_pred_Q13 = silk_SMULWB( pred_lag_ptr[ 0 ], b_Q14[ 0 ] );
|
||||||
LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -1 ], b_Q14[ 1 ] );
|
LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -1 ], b_Q14[ 1 ] );
|
||||||
LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -2 ], b_Q14[ 2 ] );
|
LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -2 ], b_Q14[ 2 ] );
|
||||||
LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -3 ], b_Q14[ 3 ] );
|
LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -3 ], b_Q14[ 3 ] );
|
||||||
LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], b_Q14[ 4 ] );
|
LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -4 ], b_Q14[ 4 ] );
|
||||||
pred_lag_ptr++;
|
pred_lag_ptr++;
|
||||||
} else {
|
} else {
|
||||||
LTP_pred_Q14 = 0;
|
LTP_pred_Q13 = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Long-term shaping */
|
/* Long-term shaping */
|
||||||
if( lag > 0 ) {
|
if( lag > 0 ) {
|
||||||
/* Symmetric, packed FIR coefficients */
|
/* Symmetric, packed FIR coefficients */
|
||||||
n_LTP_Q14 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 );
|
n_LTP_Q14 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 );
|
||||||
n_LTP_Q14 = silk_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 );
|
n_LTP_Q14 = silk_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 );
|
||||||
n_LTP_Q14 = silk_LSHIFT( n_LTP_Q14, 6 );
|
n_LTP_Q14 = silk_LSHIFT( n_LTP_Q14, 6 );
|
||||||
shp_lag_ptr++;
|
shp_lag_ptr++;
|
||||||
|
|
||||||
LTP_Q10 = silk_RSHIFT( silk_SUB32( LTP_pred_Q14, n_LTP_Q14 ), 4 );
|
LTP_Q10 = silk_RSHIFT( silk_SUB32( LTP_pred_Q13 << 1, n_LTP_Q14 ), 4 );
|
||||||
} else {
|
} else {
|
||||||
LTP_Q10 = 0;
|
LTP_Q10 = 0;
|
||||||
}
|
}
|
||||||
|
@ -380,10 +381,7 @@ static inline void silk_noise_shape_quantizer_del_dec(
|
||||||
/* Pointer used in short term prediction and shaping */
|
/* Pointer used in short term prediction and shaping */
|
||||||
psLPC_Q14 = &psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 + i ];
|
psLPC_Q14 = &psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 + i ];
|
||||||
/* Short-term prediction */
|
/* Short-term prediction */
|
||||||
silk_assert( predictLPCOrder >= 10 ); /* check that unrolling works */
|
silk_assert( predictLPCOrder == 10 || predictLPCOrder == 16 );
|
||||||
silk_assert( ( predictLPCOrder & 1 ) == 0 ); /* check that order is even */
|
|
||||||
silk_assert( ( (opus_int64)a_Q12 & 3 ) == 0 ); /* check that array starts at 4-byte aligned address */
|
|
||||||
/* Partially unrolled */
|
|
||||||
LPC_pred_Q10 = silk_SMULWB( psLPC_Q14[ 0 ], a_Q12[ 0 ] );
|
LPC_pred_Q10 = silk_SMULWB( psLPC_Q14[ 0 ], a_Q12[ 0 ] );
|
||||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -1 ], a_Q12[ 1 ] );
|
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -1 ], a_Q12[ 1 ] );
|
||||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -2 ], a_Q12[ 2 ] );
|
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -2 ], a_Q12[ 2 ] );
|
||||||
|
@ -394,8 +392,13 @@ static inline void silk_noise_shape_quantizer_del_dec(
|
||||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -7 ], a_Q12[ 7 ] );
|
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -7 ], a_Q12[ 7 ] );
|
||||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -8 ], a_Q12[ 8 ] );
|
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -8 ], a_Q12[ 8 ] );
|
||||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -9 ], a_Q12[ 9 ] );
|
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -9 ], a_Q12[ 9 ] );
|
||||||
for( j = 10; j < predictLPCOrder; j ++ ) {
|
if( predictLPCOrder == 16 ) {
|
||||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -j ], a_Q12[ j ] );
|
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -10 ], a_Q12[ 10 ] );
|
||||||
|
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -11 ], a_Q12[ 11 ] );
|
||||||
|
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -12 ], a_Q12[ 12 ] );
|
||||||
|
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -13 ], a_Q12[ 13 ] );
|
||||||
|
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -14 ], a_Q12[ 14 ] );
|
||||||
|
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -15 ], a_Q12[ 15 ] );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Noise shape feedback */
|
/* Noise shape feedback */
|
||||||
|
@ -486,7 +489,7 @@ static inline void silk_noise_shape_quantizer_del_dec(
|
||||||
exc_Q10 = psSS[ 0 ].Q_Q10 ^ dither;
|
exc_Q10 = psSS[ 0 ].Q_Q10 ^ dither;
|
||||||
|
|
||||||
/* Add predictions */
|
/* Add predictions */
|
||||||
LPC_exc_Q10 = exc_Q10 + silk_RSHIFT_ROUND( LTP_pred_Q14, 4 );
|
LPC_exc_Q10 = exc_Q10 + silk_RSHIFT_ROUND( LTP_pred_Q13, 3 );
|
||||||
xq_Q10 = silk_ADD32( LPC_exc_Q10, LPC_pred_Q10 );
|
xq_Q10 = silk_ADD32( LPC_exc_Q10, LPC_pred_Q10 );
|
||||||
|
|
||||||
/* Update states */
|
/* Update states */
|
||||||
|
@ -502,7 +505,7 @@ static inline void silk_noise_shape_quantizer_del_dec(
|
||||||
exc_Q10 = psSS[ 1 ].Q_Q10 ^ dither;
|
exc_Q10 = psSS[ 1 ].Q_Q10 ^ dither;
|
||||||
|
|
||||||
/* Add predictions */
|
/* Add predictions */
|
||||||
LPC_exc_Q10 = exc_Q10 + silk_RSHIFT_ROUND( LTP_pred_Q14, 4 );
|
LPC_exc_Q10 = exc_Q10 + silk_RSHIFT_ROUND( LTP_pred_Q13, 3 );
|
||||||
xq_Q10 = silk_ADD32( LPC_exc_Q10, LPC_pred_Q10 );
|
xq_Q10 = silk_ADD32( LPC_exc_Q10, LPC_pred_Q10 );
|
||||||
|
|
||||||
/* Update states */
|
/* Update states */
|
||||||
|
@ -564,11 +567,11 @@ static inline void silk_noise_shape_quantizer_del_dec(
|
||||||
/* Write samples from winner to output and long-term filter states */
|
/* Write samples from winner to output and long-term filter states */
|
||||||
psDD = &psDelDec[ Winner_ind ];
|
psDD = &psDelDec[ Winner_ind ];
|
||||||
if( subfr > 0 || i >= decisionDelay ) {
|
if( subfr > 0 || i >= decisionDelay ) {
|
||||||
pulses[ i - decisionDelay ] = ( opus_int8 )silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );
|
pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );
|
||||||
xq[ i - decisionDelay ] = ( opus_int16 )silk_SAT16( silk_RSHIFT_ROUND(
|
xq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(
|
||||||
silk_SMULWW( psDD->Xq_Q10[ last_smple_idx ], delayedGain_Q16[ last_smple_idx ] ), 10 ) );
|
silk_SMULWW( psDD->Xq_Q10[ last_smple_idx ], delayedGain_Q16[ last_smple_idx ] ), 10 ) );
|
||||||
NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx - decisionDelay ] = psDD->Shape_Q10[ last_smple_idx ];
|
NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx - decisionDelay ] = psDD->Shape_Q10[ last_smple_idx ];
|
||||||
sLTP_Q16[ NSQ->sLTP_buf_idx - decisionDelay ] = psDD->Pred_Q16[ last_smple_idx ];
|
sLTP_Q15[ NSQ->sLTP_buf_idx - decisionDelay ] = psDD->Pred_Q16[ last_smple_idx ] >> 1;
|
||||||
}
|
}
|
||||||
NSQ->sLTP_shp_buf_idx++;
|
NSQ->sLTP_shp_buf_idx++;
|
||||||
NSQ->sLTP_buf_idx++;
|
NSQ->sLTP_buf_idx++;
|
||||||
|
@ -600,10 +603,10 @@ static inline void silk_nsq_del_dec_scale_states(
|
||||||
const silk_encoder_state *psEncC, /* I Encoder State */
|
const silk_encoder_state *psEncC, /* I Encoder State */
|
||||||
silk_nsq_state *NSQ, /* I/O NSQ state */
|
silk_nsq_state *NSQ, /* I/O NSQ state */
|
||||||
NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
|
NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
|
||||||
const opus_int16 x[], /* I Input in Q0 */
|
const opus_int32 x_Q10[], /* I Input in Q0 */
|
||||||
opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */
|
opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */
|
||||||
const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */
|
const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */
|
||||||
opus_int32 sLTP_Q16[], /* O LTP state matching scaled input */
|
opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */
|
||||||
opus_int subfr, /* I Subframe number */
|
opus_int subfr, /* I Subframe number */
|
||||||
opus_int nStatesDelayedDecision, /* I Number of del dec states */
|
opus_int nStatesDelayedDecision, /* I Number of del dec states */
|
||||||
const opus_int LTP_scale_Q14, /* I LTP state scaling */
|
const opus_int LTP_scale_Q14, /* I LTP state scaling */
|
||||||
|
@ -614,23 +617,22 @@ static inline void silk_nsq_del_dec_scale_states(
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
opus_int i, k, lag;
|
opus_int i, k, lag;
|
||||||
opus_int32 inv_gain_Q16, gain_adj_Q16, inv_gain_Q32;
|
opus_int32 inv_gain_Q16, gain_adj_Q16, inv_gain_Q31;
|
||||||
NSQ_del_dec_struct *psDD;
|
NSQ_del_dec_struct *psDD;
|
||||||
|
|
||||||
inv_gain_Q16 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 32 );
|
inv_gain_Q16 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 32 );
|
||||||
inv_gain_Q16 = silk_min( inv_gain_Q16, silk_int16_MAX );
|
|
||||||
lag = pitchL[ subfr ];
|
lag = pitchL[ subfr ];
|
||||||
|
|
||||||
/* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */
|
/* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */
|
||||||
if( NSQ->rewhite_flag ) {
|
if( NSQ->rewhite_flag ) {
|
||||||
inv_gain_Q32 = silk_LSHIFT( inv_gain_Q16, 16 );
|
inv_gain_Q31 = silk_LSHIFT( inv_gain_Q16, 15 );
|
||||||
if( subfr == 0 ) {
|
if( subfr == 0 ) {
|
||||||
/* Do LTP downscaling */
|
/* Do LTP downscaling */
|
||||||
inv_gain_Q32 = silk_LSHIFT( silk_SMULWB( inv_gain_Q32, LTP_scale_Q14 ), 2 );
|
inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, LTP_scale_Q14 ), 2 );
|
||||||
}
|
}
|
||||||
for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {
|
for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {
|
||||||
silk_assert( i < MAX_FRAME_LENGTH );
|
silk_assert( i < MAX_FRAME_LENGTH );
|
||||||
sLTP_Q16[ i ] = silk_SMULWB( inv_gain_Q32, sLTP[ i ] );
|
sLTP_Q15[ i ] = silk_SMULWB( inv_gain_Q31, sLTP[ i ] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -646,7 +648,7 @@ static inline void silk_nsq_del_dec_scale_states(
|
||||||
/* Scale long-term prediction state */
|
/* Scale long-term prediction state */
|
||||||
if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) {
|
if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) {
|
||||||
for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx - decisionDelay; i++ ) {
|
for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx - decisionDelay; i++ ) {
|
||||||
sLTP_Q16[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q16[ i ] );
|
sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -672,7 +674,7 @@ static inline void silk_nsq_del_dec_scale_states(
|
||||||
|
|
||||||
/* Scale input */
|
/* Scale input */
|
||||||
for( i = 0; i < psEncC->subfr_length; i++ ) {
|
for( i = 0; i < psEncC->subfr_length; i++ ) {
|
||||||
x_sc_Q10[ i ] = silk_RSHIFT( silk_SMULBB( x[ i ], ( opus_int16 )inv_gain_Q16 ), 6 );
|
x_sc_Q10[ i ] = silk_SMULWW( x_Q10[ i ], inv_gain_Q16 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* save inv_gain */
|
/* save inv_gain */
|
||||||
|
|
14
silk/PLC.c
14
silk/PLC.c
|
@ -192,7 +192,7 @@ static inline void silk_PLC_conceal(
|
||||||
exc_buf_ptr = exc_buf;
|
exc_buf_ptr = exc_buf;
|
||||||
for( k = 0; k < 2; k++ ) {
|
for( k = 0; k < 2; k++ ) {
|
||||||
for( i = 0; i < psPLC->subfr_length; i++ ) {
|
for( i = 0; i < psPLC->subfr_length; i++ ) {
|
||||||
exc_buf_ptr[ i ] = ( opus_int16 )silk_RSHIFT(
|
exc_buf_ptr[ i ] = (opus_int16)silk_RSHIFT(
|
||||||
silk_SMULWW( psDec->exc_Q10[ i + ( k + psPLC->nb_subfr - 2 ) * psPLC->subfr_length ], psPLC->prevGain_Q16[ k ] ), 10 );
|
silk_SMULWW( psDec->exc_Q10[ i + ( k + psPLC->nb_subfr - 2 ) * psPLC->subfr_length ], psPLC->prevGain_Q16[ k ] ), 10 );
|
||||||
}
|
}
|
||||||
exc_buf_ptr += psPLC->subfr_length;
|
exc_buf_ptr += psPLC->subfr_length;
|
||||||
|
@ -209,11 +209,11 @@ static inline void silk_PLC_conceal(
|
||||||
rand_ptr = &psDec->exc_Q10[ silk_max_int( 0, psPLC->nb_subfr * psPLC->subfr_length - RAND_BUF_SIZE ) ];
|
rand_ptr = &psDec->exc_Q10[ silk_max_int( 0, psPLC->nb_subfr * psPLC->subfr_length - RAND_BUF_SIZE ) ];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup Gain to random noise component */
|
/* Set up Gain to random noise component */
|
||||||
B_Q14 = psPLC->LTPCoef_Q14;
|
B_Q14 = psPLC->LTPCoef_Q14;
|
||||||
rand_scale_Q14 = psPLC->randScale_Q14;
|
rand_scale_Q14 = psPLC->randScale_Q14;
|
||||||
|
|
||||||
/* Setup attenuation gains */
|
/* Set up attenuation gains */
|
||||||
harm_Gain_Q15 = HARM_ATT_Q15[ silk_min_int( NB_ATT - 1, psDec->lossCnt ) ];
|
harm_Gain_Q15 = HARM_ATT_Q15[ silk_min_int( NB_ATT - 1, psDec->lossCnt ) ];
|
||||||
if( psDec->prevSignalType == TYPE_VOICED ) {
|
if( psDec->prevSignalType == TYPE_VOICED ) {
|
||||||
rand_Gain_Q15 = PLC_RAND_ATTENUATE_V_Q15[ silk_min_int( NB_ATT - 1, psDec->lossCnt ) ];
|
rand_Gain_Q15 = PLC_RAND_ATTENUATE_V_Q15[ silk_min_int( NB_ATT - 1, psDec->lossCnt ) ];
|
||||||
|
@ -237,12 +237,12 @@ static inline void silk_PLC_conceal(
|
||||||
rand_scale_Q14 -= B_Q14[ i ];
|
rand_scale_Q14 -= B_Q14[ i ];
|
||||||
}
|
}
|
||||||
rand_scale_Q14 = silk_max_16( 3277, rand_scale_Q14 ); /* 0.2 */
|
rand_scale_Q14 = silk_max_16( 3277, rand_scale_Q14 ); /* 0.2 */
|
||||||
rand_scale_Q14 = ( opus_int16 )silk_RSHIFT( silk_SMULBB( rand_scale_Q14, psPLC->prevLTP_scale_Q14 ), 14 );
|
rand_scale_Q14 = (opus_int16)silk_RSHIFT( silk_SMULBB( rand_scale_Q14, psPLC->prevLTP_scale_Q14 ), 14 );
|
||||||
} else {
|
} else {
|
||||||
/* Reduce random noise for unvoiced frames with high LPC gain */
|
/* Reduce random noise for unvoiced frames with high LPC gain */
|
||||||
opus_int32 invGain_Q30, down_scale_Q30;
|
opus_int32 invGain_Q30, down_scale_Q30;
|
||||||
|
|
||||||
silk_LPC_inverse_pred_gain( &invGain_Q30, psPLC->prevLPC_Q12, psDec->LPC_order );
|
invGain_Q30 = silk_LPC_inverse_pred_gain( psPLC->prevLPC_Q12, psDec->LPC_order );
|
||||||
|
|
||||||
down_scale_Q30 = silk_min_32( silk_RSHIFT( 1 << 30, LOG2_INV_LPC_GAIN_HIGH_THRES ), invGain_Q30 );
|
down_scale_Q30 = silk_min_32( silk_RSHIFT( 1 << 30, LOG2_INV_LPC_GAIN_HIGH_THRES ), invGain_Q30 );
|
||||||
down_scale_Q30 = silk_max_32( silk_RSHIFT( 1 << 30, LOG2_INV_LPC_GAIN_LOW_THRES ), down_scale_Q30 );
|
down_scale_Q30 = silk_max_32( silk_RSHIFT( 1 << 30, LOG2_INV_LPC_GAIN_LOW_THRES ), down_scale_Q30 );
|
||||||
|
@ -272,7 +272,7 @@ static inline void silk_PLC_conceal(
|
||||||
/* LTP synthesis filtering */
|
/* LTP synthesis filtering */
|
||||||
/***************************/
|
/***************************/
|
||||||
for( k = 0; k < psDec->nb_subfr; k++ ) {
|
for( k = 0; k < psDec->nb_subfr; k++ ) {
|
||||||
/* Setup pointer */
|
/* Set up pointer */
|
||||||
pred_lag_ptr = &sLTP_Q14[ sLTP_buf_idx - lag + LTP_ORDER / 2 ];
|
pred_lag_ptr = &sLTP_Q14[ sLTP_buf_idx - lag + LTP_ORDER / 2 ];
|
||||||
for( i = 0; i < psDec->subfr_length; i++ ) {
|
for( i = 0; i < psDec->subfr_length; i++ ) {
|
||||||
/* Unrolled loop */
|
/* Unrolled loop */
|
||||||
|
@ -334,7 +334,7 @@ static inline void silk_PLC_conceal(
|
||||||
sLPC_Q14_ptr[ MAX_LPC_ORDER + i ] = silk_ADD_LSHIFT32( sLPC_Q14_ptr[ MAX_LPC_ORDER + i ], LPC_pred_Q10, 4 );
|
sLPC_Q14_ptr[ MAX_LPC_ORDER + i ] = silk_ADD_LSHIFT32( sLPC_Q14_ptr[ MAX_LPC_ORDER + i ], LPC_pred_Q10, 4 );
|
||||||
|
|
||||||
/* Scale with Gain */
|
/* Scale with Gain */
|
||||||
frame[ i ] = ( opus_int16 )silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( sLPC_Q14_ptr[ MAX_LPC_ORDER + i ], psPLC->prevGain_Q16[ 1 ] ), 14 ) );
|
frame[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( sLPC_Q14_ptr[ MAX_LPC_ORDER + i ], psPLC->prevGain_Q16[ 1 ] ), 14 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save LPC state */
|
/* Save LPC state */
|
||||||
|
|
|
@ -25,8 +25,8 @@ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
#ifndef SILK_PLC_FIX_H
|
#ifndef SILK_PLC_H
|
||||||
#define SILK_PLC_FIX_H
|
#define SILK_PLC_H
|
||||||
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
|
||||||
|
|
|
@ -52,19 +52,20 @@ extern "C"
|
||||||
* Initialize/reset the resampler state for a given pair of input/output sampling rates
|
* Initialize/reset the resampler state for a given pair of input/output sampling rates
|
||||||
*/
|
*/
|
||||||
opus_int silk_resampler_init(
|
opus_int silk_resampler_init(
|
||||||
silk_resampler_state_struct *S, /* I/O Resampler state */
|
silk_resampler_state_struct *S, /* I/O Resampler state */
|
||||||
opus_int32 Fs_Hz_in, /* I Input sampling rate (Hz) */
|
opus_int32 Fs_Hz_in, /* I Input sampling rate (Hz) */
|
||||||
opus_int32 Fs_Hz_out /* I Output sampling rate (Hz) */
|
opus_int32 Fs_Hz_out, /* I Output sampling rate (Hz) */
|
||||||
|
opus_int forEnc /* I If 1: encoder; if 0: decoder */
|
||||||
);
|
);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Resampler: convert from one sampling rate to another
|
* Resampler: convert from one sampling rate to another
|
||||||
*/
|
*/
|
||||||
opus_int silk_resampler(
|
opus_int silk_resampler(
|
||||||
silk_resampler_state_struct *S, /* I/O Resampler state */
|
silk_resampler_state_struct *S, /* I/O Resampler state */
|
||||||
opus_int16 out[], /* O Output signal */
|
opus_int16 out[], /* O Output signal */
|
||||||
const opus_int16 in[], /* I Input signal */
|
const opus_int16 in[], /* I Input signal */
|
||||||
opus_int32 inLen /* I Number of input samples */
|
opus_int32 inLen /* I Number of input samples */
|
||||||
);
|
);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -127,15 +128,14 @@ void silk_bwexpander_32(
|
||||||
|
|
||||||
/* Compute inverse of LPC prediction gain, and */
|
/* Compute inverse of LPC prediction gain, and */
|
||||||
/* test if LPC coefficients are stable (all poles within unit circle) */
|
/* test if LPC coefficients are stable (all poles within unit circle) */
|
||||||
opus_int silk_LPC_inverse_pred_gain( /* O Returns 1 if unstable, otherwise 0 */
|
opus_int32 silk_LPC_inverse_pred_gain( /* O Returns inverse prediction gain in energy domain, Q30 */
|
||||||
opus_int32 *invGain_Q30, /* O Inverse prediction gain, Q30 energy domain */
|
|
||||||
const opus_int16 *A_Q12, /* I Prediction coefficients, Q12 [order] */
|
const opus_int16 *A_Q12, /* I Prediction coefficients, Q12 [order] */
|
||||||
const opus_int order /* I Prediction order */
|
const opus_int order /* I Prediction order */
|
||||||
);
|
);
|
||||||
|
|
||||||
opus_int silk_LPC_inverse_pred_gain_Q24( /* O Returns 1 if unstable, otherwise 0 */
|
/* For input in Q24 domain */
|
||||||
opus_int32 *invGain_Q30, /* O Inverse prediction gain, Q30 energy domain */
|
opus_int32 silk_LPC_inverse_pred_gain_Q24( /* O Returns inverse prediction gain in energy domain, Q30 */
|
||||||
const opus_int32 *A_Q24, /* I Prediction coefficients, Q24 [order] */
|
const opus_int32 *A_Q24, /* I Prediction coefficients [order] */
|
||||||
const opus_int order /* I Prediction order */
|
const opus_int order /* I Prediction order */
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -313,9 +313,9 @@ void silk_burg_modified(
|
||||||
opus_int *res_nrg_Q, /* O Residual energy Q value */
|
opus_int *res_nrg_Q, /* O Residual energy Q value */
|
||||||
opus_int32 A_Q16[], /* O Prediction coefficients (length order) */
|
opus_int32 A_Q16[], /* O Prediction coefficients (length order) */
|
||||||
const opus_int16 x[], /* I Input signal, length: nb_subfr * ( D + subfr_length ) */
|
const opus_int16 x[], /* I Input signal, length: nb_subfr * ( D + subfr_length ) */
|
||||||
|
const opus_int32 minInvGain_Q30, /* I Inverse of max prediction gain */
|
||||||
const opus_int subfr_length, /* I Input signal subframe length (incl. D preceeding samples) */
|
const opus_int subfr_length, /* I Input signal subframe length (incl. D preceeding samples) */
|
||||||
const opus_int nb_subfr, /* I Number of subframes stacked in x */
|
const opus_int nb_subfr, /* I Number of subframes stacked in x */
|
||||||
const opus_int32 WhiteNoiseFrac_Q32, /* I Fraction added to zero-lag autocorrelation */
|
|
||||||
const opus_int D /* I Order */
|
const opus_int D /* I Order */
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -388,9 +388,9 @@ static inline opus_int32 silk_ROR32( opus_int32 a32, opus_int rot )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Useful Macros that can be adjusted to other platforms */
|
/* Useful Macros that can be adjusted to other platforms */
|
||||||
#define silk_memcpy(a, b, c) memcpy((a), (b), (c)) /* Dest, Src, ByteCount */
|
#define silk_memcpy(dest, src, size) memcpy((dest), (src), (size))
|
||||||
#define silk_memset(a, b, c) memset((a), (b), (c)) /* Dest, value, ByteCount */
|
#define silk_memset(dest, src, size) memset((dest), (src), (size))
|
||||||
#define silk_memmove(a, b, c) memmove((a), (b), (c)) /* Dest, Src, ByteCount */
|
#define silk_memmove(dest, src, size) memmove((dest), (src), (size))
|
||||||
|
|
||||||
/* Fixed point macros */
|
/* Fixed point macros */
|
||||||
|
|
||||||
|
|
|
@ -204,7 +204,7 @@ opus_int silk_VAD_GetSA_Q8( /* O Return v
|
||||||
sumSquared = silk_DIV32_16( sumSquared, VAD_N_BANDS ); /* Q14 */
|
sumSquared = silk_DIV32_16( sumSquared, VAD_N_BANDS ); /* Q14 */
|
||||||
|
|
||||||
/* Root-mean-square approximation, scale to dBs, and write to output pointer */
|
/* Root-mean-square approximation, scale to dBs, and write to output pointer */
|
||||||
pSNR_dB_Q7 = ( opus_int16 )( 3 * silk_SQRT_APPROX( sumSquared ) ); /* Q7 */
|
pSNR_dB_Q7 = (opus_int16)( 3 * silk_SQRT_APPROX( sumSquared ) ); /* Q7 */
|
||||||
|
|
||||||
/*********************************/
|
/*********************************/
|
||||||
/* Speech Probability Estimation */
|
/* Speech Probability Estimation */
|
||||||
|
|
|
@ -38,13 +38,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "tuning_parameters.h"
|
#include "tuning_parameters.h"
|
||||||
#include "pitch_est_defines.h"
|
#include "pitch_est_defines.h"
|
||||||
|
|
||||||
static const opus_int enc_delay_matrix[3][5] = {
|
|
||||||
/*SILK API 8 12 16 24 48 */
|
|
||||||
/* 8 */ {5, 0, 3, 4, 8},
|
|
||||||
/*12 */ {0, 6, 0, 0, 0},
|
|
||||||
/*16 */ {4, 5, 11, 5, 18}
|
|
||||||
};
|
|
||||||
|
|
||||||
opus_int silk_setup_resamplers(
|
opus_int silk_setup_resamplers(
|
||||||
silk_encoder_state_Fxx *psEnc, /* I/O */
|
silk_encoder_state_Fxx *psEnc, /* I/O */
|
||||||
opus_int fs_kHz /* I */
|
opus_int fs_kHz /* I */
|
||||||
|
@ -150,7 +143,7 @@ opus_int silk_setup_resamplers(
|
||||||
{
|
{
|
||||||
if( psEnc->sCmn.fs_kHz == 0 ) {
|
if( psEnc->sCmn.fs_kHz == 0 ) {
|
||||||
/* Initialize the resampler for enc_API.c preparing resampling from API_fs_Hz to fs_kHz */
|
/* Initialize the resampler for enc_API.c preparing resampling from API_fs_Hz to fs_kHz */
|
||||||
ret += silk_resampler_init( &psEnc->sCmn.resampler_state, psEnc->sCmn.API_fs_Hz, fs_kHz * 1000 );
|
ret += silk_resampler_init( &psEnc->sCmn.resampler_state, psEnc->sCmn.API_fs_Hz, fs_kHz * 1000, 1 );
|
||||||
} else {
|
} else {
|
||||||
/* Allocate worst case space for temporary upsampling, 8 to 48 kHz, so a factor 6 */
|
/* Allocate worst case space for temporary upsampling, 8 to 48 kHz, so a factor 6 */
|
||||||
opus_int16 x_buf_API_fs_Hz[ ( 2 * MAX_FRAME_LENGTH_MS + LA_SHAPE_MS ) * MAX_API_FS_KHZ ];
|
opus_int16 x_buf_API_fs_Hz[ ( 2 * MAX_FRAME_LENGTH_MS + LA_SHAPE_MS ) * MAX_API_FS_KHZ ];
|
||||||
|
@ -168,7 +161,7 @@ opus_int silk_setup_resamplers(
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Initialize resampler for temporary resampling of x_buf data to API_fs_Hz */
|
/* Initialize resampler for temporary resampling of x_buf data to API_fs_Hz */
|
||||||
ret += silk_resampler_init( &temp_resampler_state, silk_SMULBB( psEnc->sCmn.fs_kHz, 1000 ), psEnc->sCmn.API_fs_Hz );
|
ret += silk_resampler_init( &temp_resampler_state, silk_SMULBB( psEnc->sCmn.fs_kHz, 1000 ), psEnc->sCmn.API_fs_Hz, 0 );
|
||||||
|
|
||||||
/* Temporary resampling of x_buf data to API_fs_Hz */
|
/* Temporary resampling of x_buf data to API_fs_Hz */
|
||||||
ret += silk_resampler( &temp_resampler_state, x_buf_API_fs_Hz, x_bufFIX, nSamples_temp );
|
ret += silk_resampler( &temp_resampler_state, x_buf_API_fs_Hz, x_bufFIX, nSamples_temp );
|
||||||
|
@ -177,7 +170,7 @@ opus_int silk_setup_resamplers(
|
||||||
nSamples_temp = silk_DIV32_16( nSamples_temp * psEnc->sCmn.API_fs_Hz, silk_SMULBB( psEnc->sCmn.fs_kHz, 1000 ) );
|
nSamples_temp = silk_DIV32_16( nSamples_temp * psEnc->sCmn.API_fs_Hz, silk_SMULBB( psEnc->sCmn.fs_kHz, 1000 ) );
|
||||||
|
|
||||||
/* Initialize the resampler for enc_API.c preparing resampling from API_fs_Hz to fs_kHz */
|
/* Initialize the resampler for enc_API.c preparing resampling from API_fs_Hz to fs_kHz */
|
||||||
ret += silk_resampler_init( &psEnc->sCmn.resampler_state, psEnc->sCmn.API_fs_Hz, silk_SMULBB( fs_kHz, 1000 ) );
|
ret += silk_resampler_init( &psEnc->sCmn.resampler_state, psEnc->sCmn.API_fs_Hz, silk_SMULBB( fs_kHz, 1000 ), 1 );
|
||||||
|
|
||||||
/* Correct resampler state by resampling buffered data from API_fs_Hz to fs_kHz */
|
/* Correct resampler state by resampling buffered data from API_fs_Hz to fs_kHz */
|
||||||
ret += silk_resampler( &psEnc->sCmn.resampler_state, x_bufFIX, x_buf_API_fs_Hz, nSamples_temp );
|
ret += silk_resampler( &psEnc->sCmn.resampler_state, x_bufFIX, x_buf_API_fs_Hz, nSamples_temp );
|
||||||
|
@ -234,9 +227,6 @@ opus_int silk_setup_fs(
|
||||||
psEnc->sCmn.TargetRate_bps = 0; /* trigger new SNR computation */
|
psEnc->sCmn.TargetRate_bps = 0; /* trigger new SNR computation */
|
||||||
}
|
}
|
||||||
|
|
||||||
psEnc->sCmn.delay = enc_delay_matrix[rateID(fs_kHz*1000)][rateID(psEnc->sCmn.API_fs_Hz)];
|
|
||||||
silk_assert(psEnc->sCmn.delay <= MAX_ENCODER_DELAY);
|
|
||||||
|
|
||||||
/* Set internal sampling frequency */
|
/* Set internal sampling frequency */
|
||||||
silk_assert( fs_kHz == 8 || fs_kHz == 12 || fs_kHz == 16 );
|
silk_assert( fs_kHz == 8 || fs_kHz == 12 || fs_kHz == 16 );
|
||||||
silk_assert( psEnc->sCmn.nb_subfr == 2 || psEnc->sCmn.nb_subfr == 4 );
|
silk_assert( psEnc->sCmn.nb_subfr == 2 || psEnc->sCmn.nb_subfr == 4 );
|
||||||
|
@ -336,7 +326,7 @@ opus_int silk_setup_complexity(
|
||||||
psEncC->shapingLPCOrder = 10;
|
psEncC->shapingLPCOrder = 10;
|
||||||
psEncC->la_shape = 5 * psEncC->fs_kHz;
|
psEncC->la_shape = 5 * psEncC->fs_kHz;
|
||||||
psEncC->nStatesDelayedDecision = 1;
|
psEncC->nStatesDelayedDecision = 1;
|
||||||
psEncC->useInterpolatedNLSFs = 1;
|
psEncC->useInterpolatedNLSFs = 0;
|
||||||
psEncC->LTPQuantLowComplexity = 0;
|
psEncC->LTPQuantLowComplexity = 0;
|
||||||
psEncC->NLSF_MSVQ_Survivors = 4;
|
psEncC->NLSF_MSVQ_Survivors = 4;
|
||||||
psEncC->warping_Q16 = 0;
|
psEncC->warping_Q16 = 0;
|
||||||
|
@ -347,7 +337,7 @@ opus_int silk_setup_complexity(
|
||||||
psEncC->shapingLPCOrder = 12;
|
psEncC->shapingLPCOrder = 12;
|
||||||
psEncC->la_shape = 5 * psEncC->fs_kHz;
|
psEncC->la_shape = 5 * psEncC->fs_kHz;
|
||||||
psEncC->nStatesDelayedDecision = 2;
|
psEncC->nStatesDelayedDecision = 2;
|
||||||
psEncC->useInterpolatedNLSFs = 0;
|
psEncC->useInterpolatedNLSFs = 1;
|
||||||
psEncC->LTPQuantLowComplexity = 0;
|
psEncC->LTPQuantLowComplexity = 0;
|
||||||
psEncC->NLSF_MSVQ_Survivors = 8;
|
psEncC->NLSF_MSVQ_Survivors = 8;
|
||||||
psEncC->warping_Q16 = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 );
|
psEncC->warping_Q16 = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 );
|
||||||
|
@ -358,7 +348,7 @@ opus_int silk_setup_complexity(
|
||||||
psEncC->shapingLPCOrder = 14;
|
psEncC->shapingLPCOrder = 14;
|
||||||
psEncC->la_shape = 5 * psEncC->fs_kHz;
|
psEncC->la_shape = 5 * psEncC->fs_kHz;
|
||||||
psEncC->nStatesDelayedDecision = 3;
|
psEncC->nStatesDelayedDecision = 3;
|
||||||
psEncC->useInterpolatedNLSFs = 0;
|
psEncC->useInterpolatedNLSFs = 1;
|
||||||
psEncC->LTPQuantLowComplexity = 0;
|
psEncC->LTPQuantLowComplexity = 0;
|
||||||
psEncC->NLSF_MSVQ_Survivors = 16;
|
psEncC->NLSF_MSVQ_Survivors = 16;
|
||||||
psEncC->warping_Q16 = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 );
|
psEncC->warping_Q16 = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 );
|
||||||
|
|
|
@ -83,9 +83,9 @@ opus_int silk_Decode( /* O Returns error co
|
||||||
opus_int32 *nSamplesOut /* O Number of samples decoded */
|
opus_int32 *nSamplesOut /* O Number of samples decoded */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
opus_int i, n, delay, decode_only_middle = 0, ret = SILK_NO_ERROR;
|
opus_int i, n, decode_only_middle = 0, ret = SILK_NO_ERROR;
|
||||||
opus_int32 nSamplesOutDec, LBRR_symbol;
|
opus_int32 nSamplesOutDec, LBRR_symbol;
|
||||||
opus_int16 samplesOut1_tmp[ 2 ][ MAX_FS_KHZ * MAX_FRAME_LENGTH_MS + 2 + MAX_DECODER_DELAY ];
|
opus_int16 samplesOut1_tmp[ 2 ][ MAX_FS_KHZ * MAX_FRAME_LENGTH_MS + 2 ];
|
||||||
opus_int16 samplesOut2_tmp[ MAX_API_FS_KHZ * MAX_FRAME_LENGTH_MS ];
|
opus_int16 samplesOut2_tmp[ MAX_API_FS_KHZ * MAX_FRAME_LENGTH_MS ];
|
||||||
opus_int32 MS_pred_Q13[ 2 ] = { 0 };
|
opus_int32 MS_pred_Q13[ 2 ] = { 0 };
|
||||||
opus_int16 *resample_out_ptr;
|
opus_int16 *resample_out_ptr;
|
||||||
|
@ -139,13 +139,10 @@ opus_int silk_Decode( /* O Returns error co
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delay = channel_state[ 0 ].delay;
|
|
||||||
|
|
||||||
if( decControl->nChannelsAPI == 2 && decControl->nChannelsInternal == 2 && ( psDec->nChannelsAPI == 1 || psDec->nChannelsInternal == 1 ) ) {
|
if( decControl->nChannelsAPI == 2 && decControl->nChannelsInternal == 2 && ( psDec->nChannelsAPI == 1 || psDec->nChannelsInternal == 1 ) ) {
|
||||||
silk_memset( psDec->sStereo.pred_prev_Q13, 0, sizeof( psDec->sStereo.pred_prev_Q13 ) );
|
silk_memset( psDec->sStereo.pred_prev_Q13, 0, sizeof( psDec->sStereo.pred_prev_Q13 ) );
|
||||||
silk_memset( psDec->sStereo.sSide, 0, sizeof( psDec->sStereo.sSide ) );
|
silk_memset( psDec->sStereo.sSide, 0, sizeof( psDec->sStereo.sSide ) );
|
||||||
silk_memcpy( &channel_state[ 1 ].resampler_state, &channel_state[ 0 ].resampler_state, sizeof( silk_resampler_state_struct ) );
|
silk_memcpy( &channel_state[ 1 ].resampler_state, &channel_state[ 0 ].resampler_state, sizeof( silk_resampler_state_struct ) );
|
||||||
silk_memcpy( &channel_state[ 1 ].delayBuf, &channel_state[ 0 ].delayBuf, sizeof(channel_state[ 0 ].delayBuf));
|
|
||||||
}
|
}
|
||||||
psDec->nChannelsAPI = decControl->nChannelsAPI;
|
psDec->nChannelsAPI = decControl->nChannelsAPI;
|
||||||
psDec->nChannelsInternal = decControl->nChannelsInternal;
|
psDec->nChannelsInternal = decControl->nChannelsInternal;
|
||||||
|
@ -264,20 +261,20 @@ opus_int silk_Decode( /* O Returns error co
|
||||||
} else {
|
} else {
|
||||||
condCoding = CODE_CONDITIONALLY;
|
condCoding = CODE_CONDITIONALLY;
|
||||||
}
|
}
|
||||||
ret += silk_decode_frame( &channel_state[ n ], psRangeDec, &samplesOut1_tmp[ n ][ 2 + delay ], &nSamplesOutDec, lostFlag, condCoding);
|
ret += silk_decode_frame( &channel_state[ n ], psRangeDec, &samplesOut1_tmp[ n ][ 2 ], &nSamplesOutDec, lostFlag, condCoding);
|
||||||
} else {
|
} else {
|
||||||
silk_memset( &samplesOut1_tmp[ n ][ 2 + delay ], 0, nSamplesOutDec * sizeof( opus_int16 ) );
|
silk_memset( &samplesOut1_tmp[ n ][ 2 ], 0, nSamplesOutDec * sizeof( opus_int16 ) );
|
||||||
}
|
}
|
||||||
channel_state[ n ].nFramesDecoded++;
|
channel_state[ n ].nFramesDecoded++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( decControl->nChannelsAPI == 2 && decControl->nChannelsInternal == 2 ) {
|
if( decControl->nChannelsAPI == 2 && decControl->nChannelsInternal == 2 ) {
|
||||||
/* Convert Mid/Side to Left/Right */
|
/* Convert Mid/Side to Left/Right */
|
||||||
silk_stereo_MS_to_LR( &psDec->sStereo, &samplesOut1_tmp[ 0 ][ delay ], &samplesOut1_tmp[ 1 ][ delay ], MS_pred_Q13, channel_state[ 0 ].fs_kHz, nSamplesOutDec );
|
silk_stereo_MS_to_LR( &psDec->sStereo, samplesOut1_tmp[ 0 ], samplesOut1_tmp[ 1 ], MS_pred_Q13, channel_state[ 0 ].fs_kHz, nSamplesOutDec );
|
||||||
} else {
|
} else {
|
||||||
/* Buffering */
|
/* Buffering */
|
||||||
silk_memcpy( &samplesOut1_tmp[ 0 ][ delay ], psDec->sStereo.sMid, 2 * sizeof( opus_int16 ) );
|
silk_memcpy( samplesOut1_tmp[ 0 ], psDec->sStereo.sMid, 2 * sizeof( opus_int16 ) );
|
||||||
silk_memcpy( psDec->sStereo.sMid, &samplesOut1_tmp[ 0 ][ nSamplesOutDec + delay ], 2 * sizeof( opus_int16 ) );
|
silk_memcpy( psDec->sStereo.sMid, &samplesOut1_tmp[ 0 ][ nSamplesOutDec ], 2 * sizeof( opus_int16 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Number of output samples */
|
/* Number of output samples */
|
||||||
|
@ -292,10 +289,8 @@ opus_int silk_Decode( /* O Returns error co
|
||||||
|
|
||||||
for( n = 0; n < silk_min( decControl->nChannelsAPI, decControl->nChannelsInternal ); n++ ) {
|
for( n = 0; n < silk_min( decControl->nChannelsAPI, decControl->nChannelsInternal ); n++ ) {
|
||||||
|
|
||||||
silk_memcpy(&samplesOut1_tmp[ n ][ 1 ], &channel_state[ n ].delayBuf[ MAX_DECODER_DELAY - delay ], delay * sizeof(opus_int16));
|
|
||||||
/* Resample decoded signal to API_sampleRate */
|
/* Resample decoded signal to API_sampleRate */
|
||||||
ret += silk_resampler( &channel_state[ n ].resampler_state, resample_out_ptr, &samplesOut1_tmp[ n ][ 1 ], nSamplesOutDec );
|
ret += silk_resampler( &channel_state[ n ].resampler_state, resample_out_ptr, &samplesOut1_tmp[ n ][ 1 ], nSamplesOutDec );
|
||||||
silk_memcpy(channel_state[ n ].delayBuf, &samplesOut1_tmp[ n ][ 1 + nSamplesOutDec + delay - MAX_DECODER_DELAY ], MAX_DECODER_DELAY * sizeof(opus_int16));
|
|
||||||
|
|
||||||
/* Interleave if stereo output and stereo stream */
|
/* Interleave if stereo output and stereo stream */
|
||||||
if( decControl->nChannelsAPI == 2 && decControl->nChannelsInternal == 2 ) {
|
if( decControl->nChannelsAPI == 2 && decControl->nChannelsInternal == 2 ) {
|
||||||
|
|
|
@ -41,11 +41,11 @@ void silk_decode_core(
|
||||||
const opus_int pulses[ MAX_FRAME_LENGTH ] /* I Pulse signal */
|
const opus_int pulses[ MAX_FRAME_LENGTH ] /* I Pulse signal */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
opus_int i, j, k, lag = 0, start_idx, sLTP_buf_idx, NLSF_interpolation_flag, signalType;
|
opus_int i, k, lag = 0, start_idx, sLTP_buf_idx, NLSF_interpolation_flag, signalType;
|
||||||
opus_int16 *A_Q12, *B_Q14, *pxq, A_Q12_tmp[ MAX_LPC_ORDER ];
|
opus_int16 *A_Q12, *B_Q14, *pxq, A_Q12_tmp[ MAX_LPC_ORDER ];
|
||||||
opus_int16 sLTP[ MAX_FRAME_LENGTH ];
|
opus_int16 sLTP[ MAX_FRAME_LENGTH ];
|
||||||
opus_int32 sLTP_Q16[ 2 * MAX_FRAME_LENGTH ];
|
opus_int32 sLTP_Q15[ 2 * MAX_FRAME_LENGTH ];
|
||||||
opus_int32 LTP_pred_Q14, LPC_pred_Q10, Gain_Q10, inv_gain_Q16, inv_gain_Q32, gain_adj_Q16, rand_seed, offset_Q10;
|
opus_int32 LTP_pred_Q13, LPC_pred_Q10, Gain_Q10, inv_gain_Q16, inv_gain_Q31, gain_adj_Q16, rand_seed, offset_Q10;
|
||||||
opus_int32 *pred_lag_ptr, *pexc_Q10, *pres_Q10;
|
opus_int32 *pred_lag_ptr, *pexc_Q10, *pres_Q10;
|
||||||
opus_int32 res_Q10[ MAX_SUB_FRAME_LENGTH ];
|
opus_int32 res_Q10[ MAX_SUB_FRAME_LENGTH ];
|
||||||
opus_int32 sLPC_Q14[ MAX_SUB_FRAME_LENGTH + MAX_LPC_ORDER ];
|
opus_int32 sLPC_Q14[ MAX_SUB_FRAME_LENGTH + MAX_LPC_ORDER ];
|
||||||
|
@ -64,7 +64,7 @@ void silk_decode_core(
|
||||||
rand_seed = psDec->indices.Seed;
|
rand_seed = psDec->indices.Seed;
|
||||||
for( i = 0; i < psDec->frame_length; i++ ) {
|
for( i = 0; i < psDec->frame_length; i++ ) {
|
||||||
rand_seed = silk_RAND( rand_seed );
|
rand_seed = silk_RAND( rand_seed );
|
||||||
psDec->exc_Q10[ i ] = silk_LSHIFT( ( opus_int32 )pulses[ i ], 10 );
|
psDec->exc_Q10[ i ] = silk_LSHIFT( (opus_int32)pulses[ i ], 10 );
|
||||||
if( psDec->exc_Q10[ i ] > 0 ) {
|
if( psDec->exc_Q10[ i ] > 0 ) {
|
||||||
psDec->exc_Q10[ i ] -= QUANT_LEVEL_ADJUST_Q10;
|
psDec->exc_Q10[ i ] -= QUANT_LEVEL_ADJUST_Q10;
|
||||||
} else
|
} else
|
||||||
|
@ -95,7 +95,6 @@ void silk_decode_core(
|
||||||
|
|
||||||
Gain_Q10 = silk_RSHIFT( psDecCtrl->Gains_Q16[ k ], 6 );
|
Gain_Q10 = silk_RSHIFT( psDecCtrl->Gains_Q16[ k ], 6 );
|
||||||
inv_gain_Q16 = silk_INVERSE32_varQ( psDecCtrl->Gains_Q16[ k ], 32 );
|
inv_gain_Q16 = silk_INVERSE32_varQ( psDecCtrl->Gains_Q16[ k ], 32 );
|
||||||
inv_gain_Q16 = silk_min( inv_gain_Q16, silk_int16_MAX );
|
|
||||||
|
|
||||||
/* Calculate Gain adjustment factor */
|
/* Calculate Gain adjustment factor */
|
||||||
gain_adj_Q16 = 1 << 16;
|
gain_adj_Q16 = 1 << 16;
|
||||||
|
@ -141,19 +140,19 @@ void silk_decode_core(
|
||||||
A_Q12, psDec->ltp_mem_length - start_idx, psDec->LPC_order );
|
A_Q12, psDec->ltp_mem_length - start_idx, psDec->LPC_order );
|
||||||
|
|
||||||
/* After rewhitening the LTP state is unscaled */
|
/* After rewhitening the LTP state is unscaled */
|
||||||
inv_gain_Q32 = silk_LSHIFT( inv_gain_Q16, 16 );
|
inv_gain_Q31 = silk_LSHIFT( inv_gain_Q16, 15 );
|
||||||
if( k == 0 ) {
|
if( k == 0 ) {
|
||||||
/* Do LTP downscaling to reduce inter-packet dependency */
|
/* Do LTP downscaling to reduce inter-packet dependency */
|
||||||
inv_gain_Q32 = silk_LSHIFT( silk_SMULWB( inv_gain_Q32, psDecCtrl->LTP_scale_Q14 ), 2 );
|
inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, psDecCtrl->LTP_scale_Q14 ), 2 );
|
||||||
}
|
}
|
||||||
for( i = 0; i < lag + LTP_ORDER/2; i++ ) {
|
for( i = 0; i < lag + LTP_ORDER/2; i++ ) {
|
||||||
sLTP_Q16[ sLTP_buf_idx - i - 1 ] = silk_SMULWB( inv_gain_Q32, sLTP[ psDec->ltp_mem_length - i - 1 ] );
|
sLTP_Q15[ sLTP_buf_idx - i - 1 ] = silk_SMULWB( inv_gain_Q31, sLTP[ psDec->ltp_mem_length - i - 1 ] );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Update LTP state when Gain changes */
|
/* Update LTP state when Gain changes */
|
||||||
if( gain_adj_Q16 != 1 << 16 ) {
|
if( gain_adj_Q16 != 1 << 16 ) {
|
||||||
for( i = 0; i < lag + LTP_ORDER/2; i++ ) {
|
for( i = 0; i < lag + LTP_ORDER/2; i++ ) {
|
||||||
sLTP_Q16[ sLTP_buf_idx - i - 1 ] = silk_SMULWW( gain_adj_Q16, sLTP_Q16[ sLTP_buf_idx - i - 1 ] );
|
sLTP_Q15[ sLTP_buf_idx - i - 1 ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ sLTP_buf_idx - i - 1 ] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -161,22 +160,22 @@ void silk_decode_core(
|
||||||
|
|
||||||
/* Long-term prediction */
|
/* Long-term prediction */
|
||||||
if( signalType == TYPE_VOICED ) {
|
if( signalType == TYPE_VOICED ) {
|
||||||
/* Setup pointer */
|
/* Set up pointer */
|
||||||
pred_lag_ptr = &sLTP_Q16[ sLTP_buf_idx - lag + LTP_ORDER / 2 ];
|
pred_lag_ptr = &sLTP_Q15[ sLTP_buf_idx - lag + LTP_ORDER / 2 ];
|
||||||
for( i = 0; i < psDec->subfr_length; i++ ) {
|
for( i = 0; i < psDec->subfr_length; i++ ) {
|
||||||
/* Unrolled loop */
|
/* Unrolled loop */
|
||||||
LTP_pred_Q14 = silk_SMULWB( pred_lag_ptr[ 0 ], B_Q14[ 0 ] );
|
LTP_pred_Q13 = silk_SMULWB( pred_lag_ptr[ 0 ], B_Q14[ 0 ] );
|
||||||
LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -1 ], B_Q14[ 1 ] );
|
LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -1 ], B_Q14[ 1 ] );
|
||||||
LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -2 ], B_Q14[ 2 ] );
|
LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -2 ], B_Q14[ 2 ] );
|
||||||
LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -3 ], B_Q14[ 3 ] );
|
LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -3 ], B_Q14[ 3 ] );
|
||||||
LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], B_Q14[ 4 ] );
|
LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -4 ], B_Q14[ 4 ] );
|
||||||
pred_lag_ptr++;
|
pred_lag_ptr++;
|
||||||
|
|
||||||
/* Generate LPC excitation */
|
/* Generate LPC excitation */
|
||||||
pres_Q10[ i ] = silk_ADD32( pexc_Q10[ i ], silk_RSHIFT_ROUND( LTP_pred_Q14, 4 ) );
|
pres_Q10[ i ] = silk_ADD32( pexc_Q10[ i ], silk_RSHIFT_ROUND( LTP_pred_Q13, 3 ) );
|
||||||
|
|
||||||
/* Update states */
|
/* Update states */
|
||||||
sLTP_Q16[ sLTP_buf_idx ] = silk_LSHIFT( pres_Q10[ i ], 6 );
|
sLTP_Q15[ sLTP_buf_idx ] = silk_LSHIFT( pres_Q10[ i ], 5 );
|
||||||
sLTP_buf_idx++;
|
sLTP_buf_idx++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -184,7 +183,8 @@ void silk_decode_core(
|
||||||
}
|
}
|
||||||
|
|
||||||
for( i = 0; i < psDec->subfr_length; i++ ) {
|
for( i = 0; i < psDec->subfr_length; i++ ) {
|
||||||
/* Partially unrolled */
|
/* Short-term prediction */
|
||||||
|
silk_assert( psDec->LPC_order == 10 || psDec->LPC_order == 16 );
|
||||||
LPC_pred_Q10 = silk_SMULWB( sLPC_Q14[ MAX_LPC_ORDER + i - 1 ], A_Q12_tmp[ 0 ] );
|
LPC_pred_Q10 = silk_SMULWB( sLPC_Q14[ MAX_LPC_ORDER + i - 1 ], A_Q12_tmp[ 0 ] );
|
||||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 2 ], A_Q12_tmp[ 1 ] );
|
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 2 ], A_Q12_tmp[ 1 ] );
|
||||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 3 ], A_Q12_tmp[ 2 ] );
|
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 3 ], A_Q12_tmp[ 2 ] );
|
||||||
|
@ -195,17 +195,23 @@ void silk_decode_core(
|
||||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 8 ], A_Q12_tmp[ 7 ] );
|
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 8 ], A_Q12_tmp[ 7 ] );
|
||||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 9 ], A_Q12_tmp[ 8 ] );
|
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 9 ], A_Q12_tmp[ 8 ] );
|
||||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 10 ], A_Q12_tmp[ 9 ] );
|
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 10 ], A_Q12_tmp[ 9 ] );
|
||||||
for( j = 10; j < psDec->LPC_order; j++ ) {
|
if( psDec->LPC_order == 16 ) {
|
||||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - j - 1 ], A_Q12_tmp[ j ] );
|
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 11 ], A_Q12_tmp[ 10 ] );
|
||||||
|
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 12 ], A_Q12_tmp[ 11 ] );
|
||||||
|
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 13 ], A_Q12_tmp[ 12 ] );
|
||||||
|
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 14 ], A_Q12_tmp[ 13 ] );
|
||||||
|
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 15 ], A_Q12_tmp[ 14 ] );
|
||||||
|
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 16 ], A_Q12_tmp[ 15 ] );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add prediction to LPC excitation */
|
/* Add prediction to LPC excitation */
|
||||||
sLPC_Q14[ MAX_LPC_ORDER + i ] = silk_LSHIFT( silk_ADD32( pres_Q10[ i ], LPC_pred_Q10 ), 4 );
|
sLPC_Q14[ MAX_LPC_ORDER + i ] = silk_LSHIFT( silk_ADD32( pres_Q10[ i ], LPC_pred_Q10 ), 4 );
|
||||||
|
|
||||||
/* Scale with Gain */
|
/* Scale with Gain */
|
||||||
pxq[ i ] = ( opus_int16 )silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( sLPC_Q14[ MAX_LPC_ORDER + i ], Gain_Q10 ), 8 ) );
|
pxq[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( sLPC_Q14[ MAX_LPC_ORDER + i ], Gain_Q10 ), 8 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* DEBUG_STORE_DATA( dec.pcm, pxq, psDec->subfr_length * sizeof( opus_int16 ) ) */
|
||||||
/* Update LPC filter state */
|
/* Update LPC filter state */
|
||||||
silk_memcpy( sLPC_Q14, &sLPC_Q14[ psDec->subfr_length ], MAX_LPC_ORDER * sizeof( opus_int32 ) );
|
silk_memcpy( sLPC_Q14, &sLPC_Q14[ psDec->subfr_length ], MAX_LPC_ORDER * sizeof( opus_int32 ) );
|
||||||
pexc_Q10 += psDec->subfr_length;
|
pexc_Q10 += psDec->subfr_length;
|
||||||
|
|
|
@ -72,8 +72,7 @@ void silk_decode_parameters(
|
||||||
silk_NLSF2A( psDecCtrl->PredCoef_Q12[ 0 ], pNLSF0_Q15, psDec->LPC_order );
|
silk_NLSF2A( psDecCtrl->PredCoef_Q12[ 0 ], pNLSF0_Q15, psDec->LPC_order );
|
||||||
} else {
|
} else {
|
||||||
/* Copy LPC coefficients for first half from second half */
|
/* Copy LPC coefficients for first half from second half */
|
||||||
silk_memcpy( psDecCtrl->PredCoef_Q12[ 0 ], psDecCtrl->PredCoef_Q12[ 1 ],
|
silk_memcpy( psDecCtrl->PredCoef_Q12[ 0 ], psDecCtrl->PredCoef_Q12[ 1 ], psDec->LPC_order * sizeof( opus_int16 ) );
|
||||||
psDec->LPC_order * sizeof( opus_int16 ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
silk_memcpy( psDec->prevNLSF_Q15, pNLSF_Q15, psDec->LPC_order * sizeof( opus_int16 ) );
|
silk_memcpy( psDec->prevNLSF_Q15, pNLSF_Q15, psDec->LPC_order * sizeof( opus_int16 ) );
|
||||||
|
|
|
@ -31,13 +31,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
|
||||||
static const int dec_delay_matrix[3][5] = {
|
|
||||||
/*SILK API 8 12 16 24 48 */
|
|
||||||
/* 8 */ {3, 0, 2, 0, 0},
|
|
||||||
/*12 */ {0, 8, 5, 7, 5},
|
|
||||||
/*16 */ {0, 0, 8, 5, 5}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Set decoder sampling rate */
|
/* Set decoder sampling rate */
|
||||||
opus_int silk_decoder_set_fs(
|
opus_int silk_decoder_set_fs(
|
||||||
silk_decoder_state *psDec, /* I/O Decoder state pointer */
|
silk_decoder_state *psDec, /* I/O Decoder state pointer */
|
||||||
|
@ -60,13 +53,9 @@ opus_int silk_decoder_set_fs(
|
||||||
opus_int16 temp_buf[ MAX_FRAME_LENGTH_MS * MAX_API_FS_KHZ ];
|
opus_int16 temp_buf[ MAX_FRAME_LENGTH_MS * MAX_API_FS_KHZ ];
|
||||||
silk_resampler_state_struct temp_resampler_state;
|
silk_resampler_state_struct temp_resampler_state;
|
||||||
|
|
||||||
/* New delay value */
|
|
||||||
psDec->delay = dec_delay_matrix[ rateID( silk_SMULBB( fs_kHz, 1000 ) ) ][ rateID( fs_API_Hz ) ];
|
|
||||||
silk_assert( psDec->delay <= MAX_DECODER_DELAY );
|
|
||||||
|
|
||||||
if( psDec->fs_kHz != fs_kHz && psDec->fs_kHz > 0 ) {
|
if( psDec->fs_kHz != fs_kHz && psDec->fs_kHz > 0 ) {
|
||||||
/* Initialize resampler for temporary resampling of outBuf data to the new internal sampling rate */
|
/* Initialize resampler for temporary resampling of outBuf data to the new internal sampling rate */
|
||||||
ret += silk_resampler_init( &temp_resampler_state, silk_SMULBB( psDec->fs_kHz, 1000 ), silk_SMULBB( fs_kHz, 1000 ) );
|
ret += silk_resampler_init( &temp_resampler_state, silk_SMULBB( psDec->fs_kHz, 1000 ), silk_SMULBB( fs_kHz, 1000 ), 0 );
|
||||||
|
|
||||||
/* Temporary resampling of outBuf data to the new internal sampling rate */
|
/* Temporary resampling of outBuf data to the new internal sampling rate */
|
||||||
silk_memcpy( temp_buf, psDec->outBuf, psDec->frame_length * sizeof( opus_int16 ) );
|
silk_memcpy( temp_buf, psDec->outBuf, psDec->frame_length * sizeof( opus_int16 ) );
|
||||||
|
@ -74,7 +63,7 @@ opus_int silk_decoder_set_fs(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize the resampler for dec_API.c preparing resampling from fs_kHz to API_fs_Hz */
|
/* Initialize the resampler for dec_API.c preparing resampling from fs_kHz to API_fs_Hz */
|
||||||
ret += silk_resampler_init( &psDec->resampler_state, silk_SMULBB( fs_kHz, 1000 ), fs_API_Hz );
|
ret += silk_resampler_init( &psDec->resampler_state, silk_SMULBB( fs_kHz, 1000 ), fs_API_Hz, 0 );
|
||||||
|
|
||||||
/* Correct resampler state by resampling buffered data from fs_kHz to API_fs_Hz */
|
/* Correct resampler state by resampling buffered data from fs_kHz to API_fs_Hz */
|
||||||
ret += silk_resampler( &psDec->resampler_state, temp_buf, psDec->outBuf, frame_length );
|
ret += silk_resampler( &psDec->resampler_state, temp_buf, psDec->outBuf, frame_length );
|
||||||
|
|
|
@ -91,9 +91,6 @@ extern "C"
|
||||||
#define MAX_FRAME_LENGTH_MS ( SUB_FRAME_LENGTH_MS * MAX_NB_SUBFR )
|
#define MAX_FRAME_LENGTH_MS ( SUB_FRAME_LENGTH_MS * MAX_NB_SUBFR )
|
||||||
#define MAX_FRAME_LENGTH ( MAX_FRAME_LENGTH_MS * MAX_FS_KHZ )
|
#define MAX_FRAME_LENGTH ( MAX_FRAME_LENGTH_MS * MAX_FS_KHZ )
|
||||||
|
|
||||||
#define MAX_ENCODER_DELAY 18
|
|
||||||
#define MAX_DECODER_DELAY 8
|
|
||||||
|
|
||||||
/* Milliseconds of lookahead for pitch analysis */
|
/* Milliseconds of lookahead for pitch analysis */
|
||||||
#define LA_PITCH_MS 2
|
#define LA_PITCH_MS 2
|
||||||
#define LA_PITCH_MAX ( LA_PITCH_MS * MAX_FS_KHZ )
|
#define LA_PITCH_MAX ( LA_PITCH_MS * MAX_FS_KHZ )
|
||||||
|
@ -133,7 +130,9 @@ extern "C"
|
||||||
#define QUANT_LEVEL_ADJUST_Q10 80
|
#define QUANT_LEVEL_ADJUST_Q10 80
|
||||||
|
|
||||||
/* Maximum numbers of iterations used to stabilize a LPC vector */
|
/* Maximum numbers of iterations used to stabilize a LPC vector */
|
||||||
#define MAX_LPC_STABILIZE_ITERATIONS 20
|
#define MAX_LPC_STABILIZE_ITERATIONS 30
|
||||||
|
#define MAX_PREDICTION_POWER_GAIN 1e4f
|
||||||
|
#define MAX_PREDICTION_POWER_GAIN_AFTER_RESET 1e2f
|
||||||
|
|
||||||
#define MAX_LPC_ORDER 16
|
#define MAX_LPC_ORDER 16
|
||||||
#define MIN_LPC_ORDER 10
|
#define MIN_LPC_ORDER 10
|
||||||
|
|
|
@ -140,10 +140,10 @@ opus_int silk_Encode( /* O Returns error co
|
||||||
opus_int n, i, nBits, flags, tmp_payloadSize_ms = 0, tmp_complexity = 0, ret = 0;
|
opus_int n, i, nBits, flags, tmp_payloadSize_ms = 0, tmp_complexity = 0, ret = 0;
|
||||||
opus_int nSamplesToBuffer, nBlocksOf10ms, nSamplesFromInput = 0;
|
opus_int nSamplesToBuffer, nBlocksOf10ms, nSamplesFromInput = 0;
|
||||||
opus_int speech_act_thr_for_switch_Q8;
|
opus_int speech_act_thr_for_switch_Q8;
|
||||||
opus_int32 TargetRate_bps, MStargetRates_bps[ 2 ], channelRate_bps, LBRR_symbol;
|
opus_int32 TargetRate_bps, MStargetRates_bps[ 2 ], channelRate_bps, LBRR_symbol, sum;
|
||||||
silk_encoder *psEnc = ( silk_encoder * )encState;
|
silk_encoder *psEnc = ( silk_encoder * )encState;
|
||||||
opus_int16 buf[ MAX_FRAME_LENGTH_MS * MAX_API_FS_KHZ + MAX_ENCODER_DELAY];
|
opus_int16 buf[ MAX_FRAME_LENGTH_MS * MAX_API_FS_KHZ ];
|
||||||
opus_int transition, delay, curr_block, tot_blocks;
|
opus_int transition, curr_block, tot_blocks;
|
||||||
|
|
||||||
psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded = psEnc->state_Fxx[ 1 ].sCmn.nFramesEncoded = 0;
|
psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded = psEnc->state_Fxx[ 1 ].sCmn.nFramesEncoded = 0;
|
||||||
|
|
||||||
|
@ -233,7 +233,6 @@ opus_int silk_Encode( /* O Returns error co
|
||||||
}
|
}
|
||||||
silk_assert( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 0 ].sCmn.fs_kHz == psEnc->state_Fxx[ 1 ].sCmn.fs_kHz );
|
silk_assert( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 0 ].sCmn.fs_kHz == psEnc->state_Fxx[ 1 ].sCmn.fs_kHz );
|
||||||
|
|
||||||
delay = psEnc->state_Fxx[ 0 ].sCmn.delay;
|
|
||||||
/* Input buffering/resampling and encoding */
|
/* Input buffering/resampling and encoding */
|
||||||
while( 1 ) {
|
while( 1 ) {
|
||||||
nSamplesToBuffer = psEnc->state_Fxx[ 0 ].sCmn.frame_length - psEnc->state_Fxx[ 0 ].sCmn.inputBufIx;
|
nSamplesToBuffer = psEnc->state_Fxx[ 0 ].sCmn.frame_length - psEnc->state_Fxx[ 0 ].sCmn.inputBufIx;
|
||||||
|
@ -243,15 +242,12 @@ opus_int silk_Encode( /* O Returns error co
|
||||||
if( encControl->nChannelsAPI == 2 && encControl->nChannelsInternal == 2 ) {
|
if( encControl->nChannelsAPI == 2 && encControl->nChannelsInternal == 2 ) {
|
||||||
opus_int id = psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded;
|
opus_int id = psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded;
|
||||||
for( n = 0; n < nSamplesFromInput; n++ ) {
|
for( n = 0; n < nSamplesFromInput; n++ ) {
|
||||||
buf[ n+delay ] = samplesIn[ 2 * n ];
|
buf[ n ] = samplesIn[ 2 * n ];
|
||||||
}
|
}
|
||||||
silk_memcpy(buf, &psEnc->state_Fxx[ 0 ].sCmn.delayBuf[ MAX_ENCODER_DELAY - delay ], delay * sizeof(opus_int16));
|
|
||||||
/* Making sure to start both resamplers from the same state when switching from mono to stereo */
|
/* Making sure to start both resamplers from the same state when switching from mono to stereo */
|
||||||
if(psEnc->nPrevChannelsInternal == 1 && id==0) {
|
if( psEnc->nPrevChannelsInternal == 1 && id==0 ) {
|
||||||
silk_memcpy( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state, &psEnc->state_Fxx[ 0 ].sCmn.resampler_state, sizeof(psEnc->state_Fxx[ 1 ].sCmn.resampler_state));
|
silk_memcpy( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state, &psEnc->state_Fxx[ 0 ].sCmn.resampler_state, sizeof(psEnc->state_Fxx[ 1 ].sCmn.resampler_state));
|
||||||
silk_memcpy( &psEnc->state_Fxx[ 1 ].sCmn.delayBuf, &psEnc->state_Fxx[ 0 ].sCmn.delayBuf, MAX_ENCODER_DELAY*sizeof(opus_int16));
|
|
||||||
}
|
}
|
||||||
silk_memcpy(psEnc->state_Fxx[ 0 ].sCmn.delayBuf, buf + nSamplesFromInput + delay - MAX_ENCODER_DELAY, MAX_ENCODER_DELAY*sizeof(opus_int16));
|
|
||||||
|
|
||||||
ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state,
|
ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state,
|
||||||
&psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );
|
&psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );
|
||||||
|
@ -260,25 +256,18 @@ opus_int silk_Encode( /* O Returns error co
|
||||||
nSamplesToBuffer = psEnc->state_Fxx[ 1 ].sCmn.frame_length - psEnc->state_Fxx[ 1 ].sCmn.inputBufIx;
|
nSamplesToBuffer = psEnc->state_Fxx[ 1 ].sCmn.frame_length - psEnc->state_Fxx[ 1 ].sCmn.inputBufIx;
|
||||||
nSamplesToBuffer = silk_min( nSamplesToBuffer, 10 * nBlocksOf10ms * psEnc->state_Fxx[ 1 ].sCmn.fs_kHz );
|
nSamplesToBuffer = silk_min( nSamplesToBuffer, 10 * nBlocksOf10ms * psEnc->state_Fxx[ 1 ].sCmn.fs_kHz );
|
||||||
for( n = 0; n < nSamplesFromInput; n++ ) {
|
for( n = 0; n < nSamplesFromInput; n++ ) {
|
||||||
buf[ n + delay ] = samplesIn[ 2 * n + 1 ];
|
buf[ n ] = samplesIn[ 2 * n + 1 ];
|
||||||
}
|
}
|
||||||
silk_memcpy(buf, &psEnc->state_Fxx[ 1 ].sCmn.delayBuf[ MAX_ENCODER_DELAY - delay ], delay * sizeof(opus_int16));
|
|
||||||
ret += silk_resampler( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state,
|
ret += silk_resampler( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state,
|
||||||
&psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ psEnc->state_Fxx[ 1 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );
|
&psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ psEnc->state_Fxx[ 1 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );
|
||||||
silk_memcpy(psEnc->state_Fxx[ 1 ].sCmn.delayBuf, buf + nSamplesFromInput + delay - MAX_ENCODER_DELAY, MAX_ENCODER_DELAY*sizeof(opus_int16));
|
|
||||||
|
|
||||||
psEnc->state_Fxx[ 1 ].sCmn.inputBufIx += nSamplesToBuffer;
|
psEnc->state_Fxx[ 1 ].sCmn.inputBufIx += nSamplesToBuffer;
|
||||||
} else if( encControl->nChannelsAPI == 2 && encControl->nChannelsInternal == 1 ) {
|
} else if( encControl->nChannelsAPI == 2 && encControl->nChannelsInternal == 1 ) {
|
||||||
/* Combine left and right channels before resampling */
|
/* Combine left and right channels before resampling */
|
||||||
for( n = 0; n < nSamplesFromInput; n++ ) {
|
for( n = 0; n < nSamplesFromInput; n++ ) {
|
||||||
buf[ n + delay ] = (opus_int16)silk_RSHIFT_ROUND( samplesIn[ 2 * n ] + samplesIn[ 2 * n + 1 ], 1 );
|
sum = samplesIn[ 2 * n ] + samplesIn[ 2 * n + 1 ];
|
||||||
|
buf[ n ] = (opus_int16)silk_RSHIFT_ROUND( sum, 1 );
|
||||||
}
|
}
|
||||||
if(psEnc->nPrevChannelsInternal == 2 && psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded==0) {
|
|
||||||
for( n = 0; n<MAX_ENCODER_DELAY; n++ ) {
|
|
||||||
psEnc->state_Fxx[ 0 ].sCmn.delayBuf[ n ] = silk_RSHIFT(psEnc->state_Fxx[ 0 ].sCmn.delayBuf[ n ]+(opus_int32)psEnc->state_Fxx[ 1 ].sCmn.delayBuf[ n ], 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
silk_memcpy(buf, &psEnc->state_Fxx[ 0 ].sCmn.delayBuf[ MAX_ENCODER_DELAY - delay ], delay * sizeof(opus_int16));
|
|
||||||
ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state,
|
ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state,
|
||||||
&psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );
|
&psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );
|
||||||
/* On the first mono frame, average the results for the two resampler states */
|
/* On the first mono frame, average the results for the two resampler states */
|
||||||
|
@ -291,15 +280,12 @@ opus_int silk_Encode( /* O Returns error co
|
||||||
+ psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ psEnc->state_Fxx[ 1 ].sCmn.inputBufIx+n+2 ], 1);
|
+ psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ psEnc->state_Fxx[ 1 ].sCmn.inputBufIx+n+2 ], 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
silk_memcpy(psEnc->state_Fxx[ 0 ].sCmn.delayBuf, buf + nSamplesFromInput + delay - MAX_ENCODER_DELAY, MAX_ENCODER_DELAY*sizeof(opus_int16));
|
|
||||||
psEnc->state_Fxx[ 0 ].sCmn.inputBufIx += nSamplesToBuffer;
|
psEnc->state_Fxx[ 0 ].sCmn.inputBufIx += nSamplesToBuffer;
|
||||||
} else {
|
} else {
|
||||||
silk_assert( encControl->nChannelsAPI == 1 && encControl->nChannelsInternal == 1 );
|
silk_assert( encControl->nChannelsAPI == 1 && encControl->nChannelsInternal == 1 );
|
||||||
silk_memcpy(buf + delay, samplesIn, nSamplesFromInput*sizeof(opus_int16));
|
silk_memcpy(buf, samplesIn, nSamplesFromInput*sizeof(opus_int16));
|
||||||
silk_memcpy(buf, &psEnc->state_Fxx[ 0 ].sCmn.delayBuf[ MAX_ENCODER_DELAY - delay ], delay * sizeof(opus_int16));
|
|
||||||
ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state,
|
ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state,
|
||||||
&psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );
|
&psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );
|
||||||
silk_memcpy(psEnc->state_Fxx[ 0 ].sCmn.delayBuf, buf + nSamplesFromInput + delay - MAX_ENCODER_DELAY, MAX_ENCODER_DELAY*sizeof(opus_int16));
|
|
||||||
psEnc->state_Fxx[ 0 ].sCmn.inputBufIx += nSamplesToBuffer;
|
psEnc->state_Fxx[ 0 ].sCmn.inputBufIx += nSamplesToBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,7 @@ void silk_LTP_analysis_filter_FIX(
|
||||||
LTP_est = silk_RSHIFT_ROUND( LTP_est, 14 ); /* round and -> Q0*/
|
LTP_est = silk_RSHIFT_ROUND( LTP_est, 14 ); /* round and -> Q0*/
|
||||||
|
|
||||||
/* Subtract long-term prediction */
|
/* Subtract long-term prediction */
|
||||||
LTP_res_ptr[ i ] = ( opus_int16 )silk_SAT16( ( opus_int32 )x_ptr[ i ] - LTP_est );
|
LTP_res_ptr[ i ] = (opus_int16)silk_SAT16( (opus_int32)x_ptr[ i ] - LTP_est );
|
||||||
|
|
||||||
/* Scale residual */
|
/* Scale residual */
|
||||||
LTP_res_ptr[ i ] = silk_SMULWB( invGains_Q16[ k ], LTP_res_ptr[ i ] );
|
LTP_res_ptr[ i ] = silk_SMULWB( invGains_Q16[ k ], LTP_res_ptr[ i ] );
|
||||||
|
|
|
@ -40,16 +40,11 @@ void silk_LTP_scale_ctrl_FIX(
|
||||||
{
|
{
|
||||||
opus_int round_loss;
|
opus_int round_loss;
|
||||||
|
|
||||||
/* 1st order high-pass filter */
|
|
||||||
psEnc->HPLTPredCodGain_Q7 = silk_max_int( psEncCtrl->LTPredCodGain_Q7 - silk_RSHIFT( psEnc->prevLTPredCodGain_Q7, 1 ), 0 )
|
|
||||||
+ silk_RSHIFT( psEnc->HPLTPredCodGain_Q7, 1 );
|
|
||||||
psEnc->prevLTPredCodGain_Q7 = psEncCtrl->LTPredCodGain_Q7;
|
|
||||||
|
|
||||||
/* Only scale if first frame in packet */
|
|
||||||
if( condCoding == CODE_INDEPENDENTLY ) {
|
if( condCoding == CODE_INDEPENDENTLY ) {
|
||||||
round_loss = psEnc->sCmn.PacketLoss_perc + psEnc->sCmn.nFramesPerPacket - 1;
|
/* Only scale if first frame in packet */
|
||||||
|
round_loss = psEnc->sCmn.PacketLoss_perc + psEnc->sCmn.nFramesPerPacket;
|
||||||
psEnc->sCmn.indices.LTP_scaleIndex = (opus_int8)silk_LIMIT(
|
psEnc->sCmn.indices.LTP_scaleIndex = (opus_int8)silk_LIMIT(
|
||||||
silk_SMULWB( silk_SMULBB( round_loss, psEnc->HPLTPredCodGain_Q7 ), SILK_FIX_CONST( 0.1, 9 ) ), 0, 2 );
|
silk_SMULWB( silk_SMULBB( round_loss, psEncCtrl->LTPredCodGain_Q7 ), SILK_FIX_CONST( 0.1, 9 ) ), 0, 2 );
|
||||||
} else {
|
} else {
|
||||||
/* Default is minimum scaling */
|
/* Default is minimum scaling */
|
||||||
psEnc->sCmn.indices.LTP_scaleIndex = 0;
|
psEnc->sCmn.indices.LTP_scaleIndex = 0;
|
||||||
|
|
|
@ -30,9 +30,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "SigProc_FIX.h"
|
#include "SigProc_FIX.h"
|
||||||
|
#include "define.h"
|
||||||
|
#include "tuning_parameters.h"
|
||||||
|
|
||||||
#define MAX_FRAME_SIZE 384 /* subfr_length * nb_subfr = ( 0.005 * 16000 + 16 ) * 4 = 384 */
|
#define MAX_FRAME_SIZE 384 /* subfr_length * nb_subfr = ( 0.005 * 16000 + 16 ) * 4 = 384 */
|
||||||
#define MAX_NB_SUBFR 4
|
|
||||||
|
|
||||||
#define QA 25
|
#define QA 25
|
||||||
#define N_BITS_HEAD_ROOM 2
|
#define N_BITS_HEAD_ROOM 2
|
||||||
|
@ -45,26 +46,22 @@ void silk_burg_modified(
|
||||||
opus_int *res_nrg_Q, /* O Residual energy Q value */
|
opus_int *res_nrg_Q, /* O Residual energy Q value */
|
||||||
opus_int32 A_Q16[], /* O Prediction coefficients (length order) */
|
opus_int32 A_Q16[], /* O Prediction coefficients (length order) */
|
||||||
const opus_int16 x[], /* I Input signal, length: nb_subfr * ( D + subfr_length ) */
|
const opus_int16 x[], /* I Input signal, length: nb_subfr * ( D + subfr_length ) */
|
||||||
|
const opus_int32 minInvGain_Q30, /* I Inverse of max prediction gain */
|
||||||
const opus_int subfr_length, /* I Input signal subframe length (incl. D preceeding samples) */
|
const opus_int subfr_length, /* I Input signal subframe length (incl. D preceeding samples) */
|
||||||
const opus_int nb_subfr, /* I Number of subframes stacked in x */
|
const opus_int nb_subfr, /* I Number of subframes stacked in x */
|
||||||
const opus_int32 WhiteNoiseFrac_Q32, /* I Fraction added to zero-lag autocorrelation */
|
|
||||||
const opus_int D /* I Order */
|
const opus_int D /* I Order */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
opus_int k, n, s, lz, rshifts, rshifts_extra;
|
opus_int k, n, s, lz, rshifts, rshifts_extra, reached_max_gain;
|
||||||
opus_int32 C0, num, nrg, rc_Q31, Atmp_QA, Atmp1, tmp1, tmp2, x1, x2;
|
opus_int32 C0, num, nrg, rc_Q31, invGain_Q30, Atmp_QA, Atmp1, tmp1, tmp2, x1, x2;
|
||||||
const opus_int16 *x_ptr;
|
const opus_int16 *x_ptr;
|
||||||
|
|
||||||
opus_int32 C_first_row[ SILK_MAX_ORDER_LPC ];
|
opus_int32 C_first_row[ SILK_MAX_ORDER_LPC ];
|
||||||
opus_int32 C_last_row[ SILK_MAX_ORDER_LPC ];
|
opus_int32 C_last_row[ SILK_MAX_ORDER_LPC ];
|
||||||
opus_int32 Af_QA[ SILK_MAX_ORDER_LPC ];
|
opus_int32 Af_QA[ SILK_MAX_ORDER_LPC ];
|
||||||
|
|
||||||
opus_int32 CAf[ SILK_MAX_ORDER_LPC + 1 ];
|
opus_int32 CAf[ SILK_MAX_ORDER_LPC + 1 ];
|
||||||
opus_int32 CAb[ SILK_MAX_ORDER_LPC + 1 ];
|
opus_int32 CAb[ SILK_MAX_ORDER_LPC + 1 ];
|
||||||
|
|
||||||
silk_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE );
|
silk_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE );
|
||||||
silk_assert( nb_subfr <= MAX_NB_SUBFR );
|
|
||||||
|
|
||||||
|
|
||||||
/* Compute autocorrelations, added over subframes */
|
/* Compute autocorrelations, added over subframes */
|
||||||
silk_sum_sqr_shift( &C0, &rshifts, x, nb_subfr * subfr_length );
|
silk_sum_sqr_shift( &C0, &rshifts, x, nb_subfr * subfr_length );
|
||||||
|
@ -84,6 +81,7 @@ void silk_burg_modified(
|
||||||
}
|
}
|
||||||
rshifts += rshifts_extra;
|
rshifts += rshifts_extra;
|
||||||
}
|
}
|
||||||
|
CAb[ 0 ] = CAf[ 0 ] = C0 + silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ) + 1; /* Q(-rshifts) */
|
||||||
silk_memset( C_first_row, 0, SILK_MAX_ORDER_LPC * sizeof( opus_int32 ) );
|
silk_memset( C_first_row, 0, SILK_MAX_ORDER_LPC * sizeof( opus_int32 ) );
|
||||||
if( rshifts > 0 ) {
|
if( rshifts > 0 ) {
|
||||||
for( s = 0; s < nb_subfr; s++ ) {
|
for( s = 0; s < nb_subfr; s++ ) {
|
||||||
|
@ -105,8 +103,10 @@ void silk_burg_modified(
|
||||||
silk_memcpy( C_last_row, C_first_row, SILK_MAX_ORDER_LPC * sizeof( opus_int32 ) );
|
silk_memcpy( C_last_row, C_first_row, SILK_MAX_ORDER_LPC * sizeof( opus_int32 ) );
|
||||||
|
|
||||||
/* Initialize */
|
/* Initialize */
|
||||||
CAb[ 0 ] = CAf[ 0 ] = C0 + silk_SMMUL( WhiteNoiseFrac_Q32, C0 ) + 1; /* Q(-rshifts)*/
|
CAb[ 0 ] = CAf[ 0 ] = C0 + silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ) + 1; /* Q(-rshifts) */
|
||||||
|
|
||||||
|
invGain_Q30 = 1 << 30;
|
||||||
|
reached_max_gain = 0;
|
||||||
for( n = 0; n < D; n++ ) {
|
for( n = 0; n < D; n++ ) {
|
||||||
/* Update first row of correlation matrix (without first element) */
|
/* Update first row of correlation matrix (without first element) */
|
||||||
/* Update last row of correlation matrix (without last element, stored in reversed order) */
|
/* Update last row of correlation matrix (without last element, stored in reversed order) */
|
||||||
|
@ -115,108 +115,155 @@ void silk_burg_modified(
|
||||||
if( rshifts > -2 ) {
|
if( rshifts > -2 ) {
|
||||||
for( s = 0; s < nb_subfr; s++ ) {
|
for( s = 0; s < nb_subfr; s++ ) {
|
||||||
x_ptr = x + s * subfr_length;
|
x_ptr = x + s * subfr_length;
|
||||||
x1 = -silk_LSHIFT32( (opus_int32)x_ptr[ n ], 16 - rshifts ); /* Q(16-rshifts)*/
|
x1 = -silk_LSHIFT32( (opus_int32)x_ptr[ n ], 16 - rshifts ); /* Q(16-rshifts) */
|
||||||
x2 = -silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], 16 - rshifts ); /* Q(16-rshifts)*/
|
x2 = -silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], 16 - rshifts ); /* Q(16-rshifts) */
|
||||||
tmp1 = silk_LSHIFT32( (opus_int32)x_ptr[ n ], QA - 16 ); /* Q(QA-16)*/
|
tmp1 = silk_LSHIFT32( (opus_int32)x_ptr[ n ], QA - 16 ); /* Q(QA-16) */
|
||||||
tmp2 = silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], QA - 16 ); /* Q(QA-16)*/
|
tmp2 = silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], QA - 16 ); /* Q(QA-16) */
|
||||||
for( k = 0; k < n; k++ ) {
|
for( k = 0; k < n; k++ ) {
|
||||||
C_first_row[ k ] = silk_SMLAWB( C_first_row[ k ], x1, x_ptr[ n - k - 1 ] ); /* Q( -rshifts )*/
|
C_first_row[ k ] = silk_SMLAWB( C_first_row[ k ], x1, x_ptr[ n - k - 1 ] ); /* Q( -rshifts ) */
|
||||||
C_last_row[ k ] = silk_SMLAWB( C_last_row[ k ], x2, x_ptr[ subfr_length - n + k ] ); /* Q( -rshifts )*/
|
C_last_row[ k ] = silk_SMLAWB( C_last_row[ k ], x2, x_ptr[ subfr_length - n + k ] ); /* Q( -rshifts ) */
|
||||||
Atmp_QA = Af_QA[ k ];
|
Atmp_QA = Af_QA[ k ];
|
||||||
tmp1 = silk_SMLAWB( tmp1, Atmp_QA, x_ptr[ n - k - 1 ] ); /* Q(QA-16)*/
|
tmp1 = silk_SMLAWB( tmp1, Atmp_QA, x_ptr[ n - k - 1 ] ); /* Q(QA-16) */
|
||||||
tmp2 = silk_SMLAWB( tmp2, Atmp_QA, x_ptr[ subfr_length - n + k ] ); /* Q(QA-16)*/
|
tmp2 = silk_SMLAWB( tmp2, Atmp_QA, x_ptr[ subfr_length - n + k ] ); /* Q(QA-16) */
|
||||||
}
|
}
|
||||||
tmp1 = silk_LSHIFT32( -tmp1, 32 - QA - rshifts ); /* Q(16-rshifts)*/
|
tmp1 = silk_LSHIFT32( -tmp1, 32 - QA - rshifts ); /* Q(16-rshifts) */
|
||||||
tmp2 = silk_LSHIFT32( -tmp2, 32 - QA - rshifts ); /* Q(16-rshifts)*/
|
tmp2 = silk_LSHIFT32( -tmp2, 32 - QA - rshifts ); /* Q(16-rshifts) */
|
||||||
for( k = 0; k <= n; k++ ) {
|
for( k = 0; k <= n; k++ ) {
|
||||||
CAf[ k ] = silk_SMLAWB( CAf[ k ], tmp1, x_ptr[ n - k ] ); /* Q( -rshift )*/
|
CAf[ k ] = silk_SMLAWB( CAf[ k ], tmp1, x_ptr[ n - k ] ); /* Q( -rshift ) */
|
||||||
CAb[ k ] = silk_SMLAWB( CAb[ k ], tmp2, x_ptr[ subfr_length - n + k - 1 ] ); /* Q( -rshift )*/
|
CAb[ k ] = silk_SMLAWB( CAb[ k ], tmp2, x_ptr[ subfr_length - n + k - 1 ] ); /* Q( -rshift ) */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for( s = 0; s < nb_subfr; s++ ) {
|
for( s = 0; s < nb_subfr; s++ ) {
|
||||||
x_ptr = x + s * subfr_length;
|
x_ptr = x + s * subfr_length;
|
||||||
x1 = -silk_LSHIFT32( (opus_int32)x_ptr[ n ], -rshifts ); /* Q( -rshifts )*/
|
x1 = -silk_LSHIFT32( (opus_int32)x_ptr[ n ], -rshifts ); /* Q( -rshifts ) */
|
||||||
x2 = -silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], -rshifts ); /* Q( -rshifts )*/
|
x2 = -silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], -rshifts ); /* Q( -rshifts ) */
|
||||||
tmp1 = silk_LSHIFT32( (opus_int32)x_ptr[ n ], 17 ); /* Q17*/
|
tmp1 = silk_LSHIFT32( (opus_int32)x_ptr[ n ], 17 ); /* Q17 */
|
||||||
tmp2 = silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], 17 ); /* Q17*/
|
tmp2 = silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], 17 ); /* Q17 */
|
||||||
for( k = 0; k < n; k++ ) {
|
for( k = 0; k < n; k++ ) {
|
||||||
C_first_row[ k ] = silk_MLA( C_first_row[ k ], x1, x_ptr[ n - k - 1 ] ); /* Q( -rshifts )*/
|
C_first_row[ k ] = silk_MLA( C_first_row[ k ], x1, x_ptr[ n - k - 1 ] ); /* Q( -rshifts ) */
|
||||||
C_last_row[ k ] = silk_MLA( C_last_row[ k ], x2, x_ptr[ subfr_length - n + k ] ); /* Q( -rshifts )*/
|
C_last_row[ k ] = silk_MLA( C_last_row[ k ], x2, x_ptr[ subfr_length - n + k ] ); /* Q( -rshifts ) */
|
||||||
Atmp1 = silk_RSHIFT_ROUND( Af_QA[ k ], QA - 17 ); /* Q17*/
|
Atmp1 = silk_RSHIFT_ROUND( Af_QA[ k ], QA - 17 ); /* Q17 */
|
||||||
tmp1 = silk_MLA( tmp1, x_ptr[ n - k - 1 ], Atmp1 ); /* Q17*/
|
tmp1 = silk_MLA( tmp1, x_ptr[ n - k - 1 ], Atmp1 ); /* Q17 */
|
||||||
tmp2 = silk_MLA( tmp2, x_ptr[ subfr_length - n + k ], Atmp1 ); /* Q17*/
|
tmp2 = silk_MLA( tmp2, x_ptr[ subfr_length - n + k ], Atmp1 ); /* Q17 */
|
||||||
}
|
}
|
||||||
tmp1 = -tmp1; /* Q17*/
|
tmp1 = -tmp1; /* Q17 */
|
||||||
tmp2 = -tmp2; /* Q17*/
|
tmp2 = -tmp2; /* Q17 */
|
||||||
for( k = 0; k <= n; k++ ) {
|
for( k = 0; k <= n; k++ ) {
|
||||||
CAf[ k ] = silk_SMLAWW( CAf[ k ], tmp1,
|
CAf[ k ] = silk_SMLAWW( CAf[ k ], tmp1,
|
||||||
silk_LSHIFT32( (opus_int32)x_ptr[ n - k ], -rshifts - 1 ) ); /* Q( -rshift )*/
|
silk_LSHIFT32( (opus_int32)x_ptr[ n - k ], -rshifts - 1 ) ); /* Q( -rshift ) */
|
||||||
CAb[ k ] = silk_SMLAWW( CAb[ k ], tmp2,
|
CAb[ k ] = silk_SMLAWW( CAb[ k ], tmp2,
|
||||||
silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n + k - 1 ], -rshifts - 1 ) ); /* Q( -rshift )*/
|
silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n + k - 1 ], -rshifts - 1 ) ); /* Q( -rshift ) */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate nominator and denominator for the next order reflection (parcor) coefficient */
|
/* Calculate nominator and denominator for the next order reflection (parcor) coefficient */
|
||||||
tmp1 = C_first_row[ n ]; /* Q( -rshifts )*/
|
tmp1 = C_first_row[ n ]; /* Q( -rshifts ) */
|
||||||
tmp2 = C_last_row[ n ]; /* Q( -rshifts )*/
|
tmp2 = C_last_row[ n ]; /* Q( -rshifts ) */
|
||||||
num = 0; /* Q( -rshifts )*/
|
num = 0; /* Q( -rshifts ) */
|
||||||
nrg = silk_ADD32( CAb[ 0 ], CAf[ 0 ] ); /* Q( 1-rshifts )*/
|
nrg = silk_ADD32( CAb[ 0 ], CAf[ 0 ] ); /* Q( 1-rshifts ) */
|
||||||
for( k = 0; k < n; k++ ) {
|
for( k = 0; k < n; k++ ) {
|
||||||
Atmp_QA = Af_QA[ k ];
|
Atmp_QA = Af_QA[ k ];
|
||||||
lz = silk_CLZ32( silk_abs( Atmp_QA ) ) - 1;
|
lz = silk_CLZ32( silk_abs( Atmp_QA ) ) - 1;
|
||||||
lz = silk_min( 32 - QA, lz );
|
lz = silk_min( 32 - QA, lz );
|
||||||
Atmp1 = silk_LSHIFT32( Atmp_QA, lz ); /* Q( QA + lz )*/
|
Atmp1 = silk_LSHIFT32( Atmp_QA, lz ); /* Q( QA + lz ) */
|
||||||
|
|
||||||
tmp1 = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( C_last_row[ n - k - 1 ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts )*/
|
tmp1 = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( C_last_row[ n - k - 1 ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts ) */
|
||||||
tmp2 = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( C_first_row[ n - k - 1 ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts )*/
|
tmp2 = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( C_first_row[ n - k - 1 ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts ) */
|
||||||
num = silk_ADD_LSHIFT32( num, silk_SMMUL( CAb[ n - k ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts )*/
|
num = silk_ADD_LSHIFT32( num, silk_SMMUL( CAb[ n - k ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts ) */
|
||||||
nrg = silk_ADD_LSHIFT32( nrg, silk_SMMUL( silk_ADD32( CAb[ k + 1 ], CAf[ k + 1 ] ),
|
nrg = silk_ADD_LSHIFT32( nrg, silk_SMMUL( silk_ADD32( CAb[ k + 1 ], CAf[ k + 1 ] ),
|
||||||
Atmp1 ), 32 - QA - lz ); /* Q( 1-rshifts )*/
|
Atmp1 ), 32 - QA - lz ); /* Q( 1-rshifts ) */
|
||||||
}
|
}
|
||||||
CAf[ n + 1 ] = tmp1; /* Q( -rshifts )*/
|
CAf[ n + 1 ] = tmp1; /* Q( -rshifts ) */
|
||||||
CAb[ n + 1 ] = tmp2; /* Q( -rshifts )*/
|
CAb[ n + 1 ] = tmp2; /* Q( -rshifts ) */
|
||||||
num = silk_ADD32( num, tmp2 ); /* Q( -rshifts )*/
|
num = silk_ADD32( num, tmp2 ); /* Q( -rshifts ) */
|
||||||
num = silk_LSHIFT32( -num, 1 ); /* Q( 1-rshifts )*/
|
num = silk_LSHIFT32( -num, 1 ); /* Q( 1-rshifts ) */
|
||||||
|
|
||||||
/* Calculate the next order reflection (parcor) coefficient */
|
/* Calculate the next order reflection (parcor) coefficient */
|
||||||
if( silk_abs( num ) < nrg ) {
|
if( silk_abs( num ) < nrg ) {
|
||||||
rc_Q31 = silk_DIV32_varQ( num, nrg, 31 );
|
rc_Q31 = silk_DIV32_varQ( num, nrg, 31 );
|
||||||
} else {
|
} else {
|
||||||
/* Negative energy or ratio too high; set remaining coefficients to zero and exit loop */
|
rc_Q31 = ( num > 0 ) ? silk_int32_MAX : silk_int32_MIN;
|
||||||
silk_memset( &Af_QA[ n ], 0, ( D - n ) * sizeof( opus_int32 ) );
|
}
|
||||||
silk_assert( 0 );
|
|
||||||
break;
|
/* Update inverse prediction gain */
|
||||||
|
tmp1 = ( (opus_int32)1 << 30 ) - silk_SMMUL( rc_Q31, rc_Q31 );
|
||||||
|
tmp1 = silk_LSHIFT( silk_SMMUL( invGain_Q30, tmp1 ), 2 );
|
||||||
|
if( tmp1 <= minInvGain_Q30 ) {
|
||||||
|
/* Max prediction gain exceeded; set reflection coefficient such that max prediction gain is exactly hit */
|
||||||
|
tmp2 = ( 1 << 30 ) - silk_DIV32_varQ( minInvGain_Q30, invGain_Q30, 30 ); /* Q30 */
|
||||||
|
rc_Q31 = silk_SQRT_APPROX( tmp2 ); /* Q15 */
|
||||||
|
/* Newton-Raphson iteration */
|
||||||
|
rc_Q31 = silk_RSHIFT32( rc_Q31 + silk_DIV32( tmp2, rc_Q31 ), 1 ); /* Q15 */
|
||||||
|
rc_Q31 = silk_LSHIFT32( rc_Q31, 16 ); /* Q31 */
|
||||||
|
if( num < 0 ) {
|
||||||
|
/* Ensure adjusted reflection coefficients has the original sign */
|
||||||
|
rc_Q31 = -rc_Q31;
|
||||||
|
}
|
||||||
|
invGain_Q30 = minInvGain_Q30;
|
||||||
|
reached_max_gain = 1;
|
||||||
|
} else {
|
||||||
|
invGain_Q30 = tmp1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update the AR coefficients */
|
/* Update the AR coefficients */
|
||||||
for( k = 0; k < (n + 1) >> 1; k++ ) {
|
for( k = 0; k < (n + 1) >> 1; k++ ) {
|
||||||
tmp1 = Af_QA[ k ]; /* QA*/
|
tmp1 = Af_QA[ k ]; /* QA */
|
||||||
tmp2 = Af_QA[ n - k - 1 ]; /* QA*/
|
tmp2 = Af_QA[ n - k - 1 ]; /* QA */
|
||||||
Af_QA[ k ] = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( tmp2, rc_Q31 ), 1 ); /* QA*/
|
Af_QA[ k ] = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( tmp2, rc_Q31 ), 1 ); /* QA */
|
||||||
Af_QA[ n - k - 1 ] = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( tmp1, rc_Q31 ), 1 ); /* QA*/
|
Af_QA[ n - k - 1 ] = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( tmp1, rc_Q31 ), 1 ); /* QA */
|
||||||
|
}
|
||||||
|
Af_QA[ n ] = silk_RSHIFT32( rc_Q31, 31 - QA ); /* QA */
|
||||||
|
|
||||||
|
if( reached_max_gain ) {
|
||||||
|
/* Reached max prediction gain; set remaining coefficients to zero and exit loop */
|
||||||
|
for( k = n + 1; k < D; k++ ) {
|
||||||
|
Af_QA[ k ] = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
Af_QA[ n ] = silk_RSHIFT32( rc_Q31, 31 - QA ); /* QA*/
|
|
||||||
|
|
||||||
/* Update C * Af and C * Ab */
|
/* Update C * Af and C * Ab */
|
||||||
for( k = 0; k <= n + 1; k++ ) {
|
for( k = 0; k <= n + 1; k++ ) {
|
||||||
tmp1 = CAf[ k ]; /* Q( -rshifts )*/
|
tmp1 = CAf[ k ]; /* Q( -rshifts ) */
|
||||||
tmp2 = CAb[ n - k + 1 ]; /* Q( -rshifts )*/
|
tmp2 = CAb[ n - k + 1 ]; /* Q( -rshifts ) */
|
||||||
CAf[ k ] = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( tmp2, rc_Q31 ), 1 ); /* Q( -rshifts )*/
|
CAf[ k ] = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( tmp2, rc_Q31 ), 1 ); /* Q( -rshifts ) */
|
||||||
CAb[ n - k + 1 ] = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( tmp1, rc_Q31 ), 1 ); /* Q( -rshifts )*/
|
CAb[ n - k + 1 ] = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( tmp1, rc_Q31 ), 1 ); /* Q( -rshifts ) */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return residual energy */
|
if( reached_max_gain ) {
|
||||||
nrg = CAf[ 0 ]; /* Q( -rshifts )*/
|
for( k = 0; k < D; k++ ) {
|
||||||
tmp1 = 1 << 16; /* Q16*/
|
/* Scale coefficients */
|
||||||
for( k = 0; k < D; k++ ) {
|
A_Q16[ k ] = -silk_RSHIFT_ROUND( Af_QA[ k ], QA - 16 );
|
||||||
Atmp1 = silk_RSHIFT_ROUND( Af_QA[ k ], QA - 16 ); /* Q16*/
|
}
|
||||||
nrg = silk_SMLAWW( nrg, CAf[ k + 1 ], Atmp1 ); /* Q( -rshifts )*/
|
/* Subtract energy of preceeding samples from C0 */
|
||||||
tmp1 = silk_SMLAWW( tmp1, Atmp1, Atmp1 ); /* Q16*/
|
if( rshifts > 0 ) {
|
||||||
A_Q16[ k ] = -Atmp1;
|
for( s = 0; s < nb_subfr; s++ ) {
|
||||||
|
x_ptr = x + s * subfr_length;
|
||||||
|
C0 -= (opus_int32)silk_RSHIFT64( silk_inner_prod16_aligned_64( x_ptr, x_ptr, D ), rshifts );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for( s = 0; s < nb_subfr; s++ ) {
|
||||||
|
x_ptr = x + s * subfr_length;
|
||||||
|
C0 -= silk_LSHIFT32( silk_inner_prod_aligned( x_ptr, x_ptr, D ), -rshifts );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Approximate residual energy */
|
||||||
|
*res_nrg = silk_LSHIFT( silk_SMMUL( invGain_Q30, C0 ), 2 );
|
||||||
|
*res_nrg_Q = -rshifts;
|
||||||
|
} else {
|
||||||
|
/* Return residual energy */
|
||||||
|
nrg = CAf[ 0 ]; /* Q( -rshifts ) */
|
||||||
|
tmp1 = 1 << 16; /* Q16 */
|
||||||
|
for( k = 0; k < D; k++ ) {
|
||||||
|
Atmp1 = silk_RSHIFT_ROUND( Af_QA[ k ], QA - 16 ); /* Q16 */
|
||||||
|
nrg = silk_SMLAWW( nrg, CAf[ k + 1 ], Atmp1 ); /* Q( -rshifts ) */
|
||||||
|
tmp1 = silk_SMLAWW( tmp1, Atmp1, Atmp1 ); /* Q16 */
|
||||||
|
A_Q16[ k ] = -Atmp1;
|
||||||
|
}
|
||||||
|
*res_nrg = silk_SMLAWW( nrg, silk_SMMUL( FIND_LPC_COND_FAC, C0 ), -tmp1 ); /* Q( -rshifts ) */
|
||||||
|
*res_nrg_Q = -rshifts;
|
||||||
}
|
}
|
||||||
*res_nrg = silk_SMLAWW( nrg, silk_SMMUL( WhiteNoiseFrac_Q32, C0 ), -tmp1 ); /* Q( -rshifts )*/
|
|
||||||
*res_nrg_Q = -rshifts;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
static inline void silk_LBRR_encode_FIX(
|
static inline void silk_LBRR_encode_FIX(
|
||||||
silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */
|
silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */
|
||||||
silk_encoder_control_FIX *psEncCtrl, /* I/O Pointer to Silk FIX encoder control struct */
|
silk_encoder_control_FIX *psEncCtrl, /* I/O Pointer to Silk FIX encoder control struct */
|
||||||
const opus_int16 xfw[], /* I Input signal */
|
const opus_int32 xfw_Q10[], /* I Input signal */
|
||||||
opus_int condCoding /* I The type of conditional coding used so far for this frame */
|
opus_int condCoding /* I The type of conditional coding used so far for this frame */
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ opus_int silk_encode_frame_FIX(
|
||||||
silk_encoder_control_FIX sEncCtrl;
|
silk_encoder_control_FIX sEncCtrl;
|
||||||
opus_int i, iter, maxIter, found_upper, found_lower, ret = 0;
|
opus_int i, iter, maxIter, found_upper, found_lower, ret = 0;
|
||||||
opus_int16 *x_frame, *res_pitch_frame;
|
opus_int16 *x_frame, *res_pitch_frame;
|
||||||
opus_int16 xfw[ MAX_FRAME_LENGTH ];
|
opus_int32 xfw_Q10[ MAX_FRAME_LENGTH ];
|
||||||
opus_int16 res_pitch[ 2 * MAX_FRAME_LENGTH + LA_PITCH_MAX ];
|
opus_int16 res_pitch[ 2 * MAX_FRAME_LENGTH + LA_PITCH_MAX ];
|
||||||
ec_enc sRangeEnc_copy, sRangeEnc_copy2;
|
ec_enc sRangeEnc_copy, sRangeEnc_copy2;
|
||||||
silk_nsq_state sNSQ_copy, sNSQ_copy2;
|
silk_nsq_state sNSQ_copy, sNSQ_copy2;
|
||||||
|
@ -103,7 +103,7 @@ opus_int silk_encode_frame_FIX(
|
||||||
psEnc->sCmn.indices.Seed = psEnc->sCmn.frameCounter++ & 3;
|
psEnc->sCmn.indices.Seed = psEnc->sCmn.frameCounter++ & 3;
|
||||||
|
|
||||||
/**************************************************************/
|
/**************************************************************/
|
||||||
/* Setup Input Pointers, and insert frame in input buffer */
|
/* Set up Input Pointers, and insert frame in input buffer */
|
||||||
/*************************************************************/
|
/*************************************************************/
|
||||||
/* pointers aligned with start of frame to encode */
|
/* pointers aligned with start of frame to encode */
|
||||||
x_frame = psEnc->x_buf + psEnc->sCmn.ltp_mem_length; /* start of frame to encode */
|
x_frame = psEnc->x_buf + psEnc->sCmn.ltp_mem_length; /* start of frame to encode */
|
||||||
|
@ -143,15 +143,15 @@ opus_int silk_encode_frame_FIX(
|
||||||
/*****************************************/
|
/*****************************************/
|
||||||
/* Prefiltering for noise shaper */
|
/* Prefiltering for noise shaper */
|
||||||
/*****************************************/
|
/*****************************************/
|
||||||
silk_prefilter_FIX( psEnc, &sEncCtrl, xfw, x_frame );
|
silk_prefilter_FIX( psEnc, &sEncCtrl, xfw_Q10, x_frame );
|
||||||
|
|
||||||
/****************************************/
|
/****************************************/
|
||||||
/* Low Bitrate Redundant Encoding */
|
/* Low Bitrate Redundant Encoding */
|
||||||
/****************************************/
|
/****************************************/
|
||||||
silk_LBRR_encode_FIX( psEnc, &sEncCtrl, xfw, condCoding );
|
silk_LBRR_encode_FIX( psEnc, &sEncCtrl, xfw_Q10, condCoding );
|
||||||
|
|
||||||
/* Loop over quantizer and entropy coding to control bitrate */
|
/* Loop over quantizer and entropy coding to control bitrate */
|
||||||
maxIter = 5;
|
maxIter = 6;
|
||||||
gainMult_Q8 = SILK_FIX_CONST( 1, 8 );
|
gainMult_Q8 = SILK_FIX_CONST( 1, 8 );
|
||||||
found_lower = 0;
|
found_lower = 0;
|
||||||
found_upper = 0;
|
found_upper = 0;
|
||||||
|
@ -183,11 +183,11 @@ opus_int silk_encode_frame_FIX(
|
||||||
/* Noise shaping quantization */
|
/* Noise shaping quantization */
|
||||||
/*****************************************/
|
/*****************************************/
|
||||||
if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
|
if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
|
||||||
silk_NSQ_del_dec( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, xfw, psEnc->sCmn.pulses,
|
silk_NSQ_del_dec( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, xfw_Q10, psEnc->sCmn.pulses,
|
||||||
sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14,
|
sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14,
|
||||||
sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14 );
|
sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14 );
|
||||||
} else {
|
} else {
|
||||||
silk_NSQ( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, xfw, psEnc->sCmn.pulses,
|
silk_NSQ( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, xfw_Q10, psEnc->sCmn.pulses,
|
||||||
sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14,
|
sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14,
|
||||||
sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14 );
|
sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14 );
|
||||||
}
|
}
|
||||||
|
@ -316,7 +316,7 @@ opus_int silk_encode_frame_FIX(
|
||||||
static inline void silk_LBRR_encode_FIX(
|
static inline void silk_LBRR_encode_FIX(
|
||||||
silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */
|
silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */
|
||||||
silk_encoder_control_FIX *psEncCtrl, /* I/O Pointer to Silk FIX encoder control struct */
|
silk_encoder_control_FIX *psEncCtrl, /* I/O Pointer to Silk FIX encoder control struct */
|
||||||
const opus_int16 xfw[], /* I Input signal */
|
const opus_int32 xfw_Q10[], /* I Input signal */
|
||||||
opus_int condCoding /* I The type of conditional coding used so far for this frame */
|
opus_int condCoding /* I The type of conditional coding used so far for this frame */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
@ -355,12 +355,12 @@ static inline void silk_LBRR_encode_FIX(
|
||||||
/* Noise shaping quantization */
|
/* Noise shaping quantization */
|
||||||
/*****************************************/
|
/*****************************************/
|
||||||
if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
|
if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
|
||||||
silk_NSQ_del_dec( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, xfw,
|
silk_NSQ_del_dec( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, xfw_Q10,
|
||||||
psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14,
|
psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14,
|
||||||
psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14,
|
psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14,
|
||||||
psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14 );
|
psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14 );
|
||||||
} else {
|
} else {
|
||||||
silk_NSQ( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, xfw,
|
silk_NSQ( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, xfw_Q10,
|
||||||
psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14,
|
psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14,
|
||||||
psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14,
|
psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14,
|
||||||
psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14 );
|
psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14 );
|
||||||
|
|
|
@ -34,18 +34,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
/* Finds LPC vector from correlations, and converts to NLSF */
|
/* Finds LPC vector from correlations, and converts to NLSF */
|
||||||
void silk_find_LPC_FIX(
|
void silk_find_LPC_FIX(
|
||||||
|
silk_encoder_state *psEncC, /* I/O Encoder state */
|
||||||
opus_int16 NLSF_Q15[], /* O NLSFs */
|
opus_int16 NLSF_Q15[], /* O NLSFs */
|
||||||
opus_int8 *interpIndex, /* O NLSF interpolation index, only used for NLSF interpolation */
|
|
||||||
const opus_int16 prev_NLSFq_Q15[], /* I previous NLSFs, only used for NLSF interpolation */
|
|
||||||
const opus_int useInterpNLSFs, /* I Flag */
|
|
||||||
const opus_int firstFrameAfterReset, /* I Flag */
|
|
||||||
const opus_int LPC_order, /* I LPC order */
|
|
||||||
const opus_int16 x[], /* I Input signal */
|
const opus_int16 x[], /* I Input signal */
|
||||||
const opus_int subfr_length, /* I Input signal subframe length including preceeding samples */
|
const opus_int32 minInvGain_Q30 /* I Inverse of max prediction gain */
|
||||||
const opus_int nb_subfr /* I Number of subframes */
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
opus_int k;
|
opus_int k, subfr_length;
|
||||||
opus_int32 a_Q16[ MAX_LPC_ORDER ];
|
opus_int32 a_Q16[ MAX_LPC_ORDER ];
|
||||||
opus_int isInterpLower, shift;
|
opus_int isInterpLower, shift;
|
||||||
opus_int32 res_nrg0, res_nrg1;
|
opus_int32 res_nrg0, res_nrg1;
|
||||||
|
@ -56,27 +51,19 @@ void silk_find_LPC_FIX(
|
||||||
opus_int res_nrg_interp_Q, res_nrg_Q, res_tmp_nrg_Q;
|
opus_int res_nrg_interp_Q, res_nrg_Q, res_tmp_nrg_Q;
|
||||||
opus_int16 a_tmp_Q12[ MAX_LPC_ORDER ];
|
opus_int16 a_tmp_Q12[ MAX_LPC_ORDER ];
|
||||||
opus_int16 NLSF0_Q15[ MAX_LPC_ORDER ];
|
opus_int16 NLSF0_Q15[ MAX_LPC_ORDER ];
|
||||||
opus_int16 LPC_res[ ( MAX_FRAME_LENGTH + MAX_NB_SUBFR * MAX_LPC_ORDER ) / 2 ];
|
opus_int16 LPC_res[ MAX_FRAME_LENGTH + MAX_NB_SUBFR * MAX_LPC_ORDER ];
|
||||||
|
|
||||||
|
subfr_length = psEncC->subfr_length + psEncC->predictLPCOrder;
|
||||||
|
|
||||||
/* Default: no interpolation */
|
/* Default: no interpolation */
|
||||||
*interpIndex = 4;
|
psEncC->indices.NLSFInterpCoef_Q2 = 4;
|
||||||
|
|
||||||
/* Burg AR analysis for the full frame */
|
/* Burg AR analysis for the full frame */
|
||||||
silk_burg_modified( &res_nrg, &res_nrg_Q, a_Q16, x, subfr_length, nb_subfr, SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), LPC_order );
|
silk_burg_modified( &res_nrg, &res_nrg_Q, a_Q16, x, minInvGain_Q30, subfr_length, psEncC->nb_subfr, psEncC->predictLPCOrder );
|
||||||
|
|
||||||
if( firstFrameAfterReset ) {
|
|
||||||
silk_bwexpander_32( a_Q16, LPC_order, SILK_FIX_CONST( FIND_LPC_CHIRP_FIRST_FRAME, 16 ) );
|
|
||||||
} else {
|
|
||||||
silk_bwexpander_32( a_Q16, LPC_order, SILK_FIX_CONST( FIND_LPC_CHIRP, 16 ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( useInterpNLSFs && !firstFrameAfterReset && nb_subfr == MAX_NB_SUBFR ) {
|
|
||||||
|
|
||||||
|
if( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) {
|
||||||
/* Optimal solution for last 10 ms */
|
/* Optimal solution for last 10 ms */
|
||||||
silk_burg_modified( &res_tmp_nrg, &res_tmp_nrg_Q, a_tmp_Q16, x + ( MAX_NB_SUBFR >> 1 ) * subfr_length,
|
silk_burg_modified( &res_tmp_nrg, &res_tmp_nrg_Q, a_tmp_Q16, x + 2 * subfr_length, minInvGain_Q30, subfr_length, 2, psEncC->predictLPCOrder );
|
||||||
subfr_length, ( MAX_NB_SUBFR >> 1 ), SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), LPC_order );
|
|
||||||
|
|
||||||
silk_bwexpander_32( a_tmp_Q16, LPC_order, SILK_FIX_CONST( FIND_LPC_CHIRP, 16 ) );
|
|
||||||
|
|
||||||
/* subtract residual energy here, as that's easier than adding it to the */
|
/* subtract residual energy here, as that's easier than adding it to the */
|
||||||
/* residual energy of the first 10 ms in each iteration of the search below */
|
/* residual energy of the first 10 ms in each iteration of the search below */
|
||||||
|
@ -92,21 +79,21 @@ void silk_find_LPC_FIX(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert to NLSFs */
|
/* Convert to NLSFs */
|
||||||
silk_A2NLSF( NLSF_Q15, a_tmp_Q16, LPC_order );
|
silk_A2NLSF( NLSF_Q15, a_tmp_Q16, psEncC->predictLPCOrder );
|
||||||
|
|
||||||
/* Search over interpolation indices to find the one with lowest residual energy */
|
/* Search over interpolation indices to find the one with lowest residual energy */
|
||||||
for( k = 3; k >= 0; k-- ) {
|
for( k = 3; k >= 0; k-- ) {
|
||||||
/* Interpolate NLSFs for first half */
|
/* Interpolate NLSFs for first half */
|
||||||
silk_interpolate( NLSF0_Q15, prev_NLSFq_Q15, NLSF_Q15, k, LPC_order );
|
silk_interpolate( NLSF0_Q15, psEncC->prev_NLSFq_Q15, NLSF_Q15, k, psEncC->predictLPCOrder );
|
||||||
|
|
||||||
/* Convert to LPC for residual energy evaluation */
|
/* Convert to LPC for residual energy evaluation */
|
||||||
silk_NLSF2A( a_tmp_Q12, NLSF0_Q15, LPC_order );
|
silk_NLSF2A( a_tmp_Q12, NLSF0_Q15, psEncC->predictLPCOrder );
|
||||||
|
|
||||||
/* Calculate residual energy with NLSF interpolation */
|
/* Calculate residual energy with NLSF interpolation */
|
||||||
silk_LPC_analysis_filter( LPC_res, x, a_tmp_Q12, 2 * subfr_length, LPC_order );
|
silk_LPC_analysis_filter( LPC_res, x, a_tmp_Q12, 2 * subfr_length, psEncC->predictLPCOrder );
|
||||||
|
|
||||||
silk_sum_sqr_shift( &res_nrg0, &rshift0, LPC_res + LPC_order, subfr_length - LPC_order );
|
silk_sum_sqr_shift( &res_nrg0, &rshift0, LPC_res + psEncC->predictLPCOrder, subfr_length - psEncC->predictLPCOrder );
|
||||||
silk_sum_sqr_shift( &res_nrg1, &rshift1, LPC_res + LPC_order + subfr_length, subfr_length - LPC_order );
|
silk_sum_sqr_shift( &res_nrg1, &rshift1, LPC_res + psEncC->predictLPCOrder + subfr_length, subfr_length - psEncC->predictLPCOrder );
|
||||||
|
|
||||||
/* Add subframe energies from first half frame */
|
/* Add subframe energies from first half frame */
|
||||||
shift = rshift0 - rshift1;
|
shift = rshift0 - rshift1;
|
||||||
|
@ -144,15 +131,15 @@ void silk_find_LPC_FIX(
|
||||||
/* Interpolation has lower residual energy */
|
/* Interpolation has lower residual energy */
|
||||||
res_nrg = res_nrg_interp;
|
res_nrg = res_nrg_interp;
|
||||||
res_nrg_Q = res_nrg_interp_Q;
|
res_nrg_Q = res_nrg_interp_Q;
|
||||||
*interpIndex = (opus_int8)k;
|
psEncC->indices.NLSFInterpCoef_Q2 = (opus_int8)k;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( *interpIndex == 4 ) {
|
if( psEncC->indices.NLSFInterpCoef_Q2 == 4 ) {
|
||||||
/* NLSF interpolation is currently inactive, calculate NLSFs from full frame AR coefficients */
|
/* NLSF interpolation is currently inactive, calculate NLSFs from full frame AR coefficients */
|
||||||
silk_A2NLSF( NLSF_Q15, a_Q16, LPC_order );
|
silk_A2NLSF( NLSF_Q15, a_Q16, psEncC->predictLPCOrder );
|
||||||
}
|
}
|
||||||
|
|
||||||
silk_assert( *interpIndex == 4 || ( useInterpNLSFs && !firstFrameAfterReset && nb_subfr == MAX_NB_SUBFR ) );
|
silk_assert( psEncC->indices.NLSFInterpCoef_Q2 == 4 || ( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) );
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,7 +113,7 @@ void silk_find_LTP_FIX(
|
||||||
silk_RSHIFT( silk_SMULWB( subfr_length, 655 ), corr_rshifts[ k ] - extra_shifts ); /* Q( -corr_rshifts[ k ] + extra_shifts ) */
|
silk_RSHIFT( silk_SMULWB( subfr_length, 655 ), corr_rshifts[ k ] - extra_shifts ); /* Q( -corr_rshifts[ k ] + extra_shifts ) */
|
||||||
denom32 = silk_max( denom32, 1 );
|
denom32 = silk_max( denom32, 1 );
|
||||||
silk_assert( ((opus_int64)Wght_Q15[ k ] << 16 ) < silk_int32_MAX ); /* Wght always < 0.5 in Q0 */
|
silk_assert( ((opus_int64)Wght_Q15[ k ] << 16 ) < silk_int32_MAX ); /* Wght always < 0.5 in Q0 */
|
||||||
temp32 = silk_DIV32( silk_LSHIFT( ( opus_int32 )Wght_Q15[ k ], 16 ), denom32 ); /* Q( 15 + 16 + corr_rshifts[k] - extra_shifts ) */
|
temp32 = silk_DIV32( silk_LSHIFT( (opus_int32)Wght_Q15[ k ], 16 ), denom32 ); /* Q( 15 + 16 + corr_rshifts[k] - extra_shifts ) */
|
||||||
temp32 = silk_RSHIFT( temp32, 31 + corr_rshifts[ k ] - extra_shifts - 26 ); /* Q26 */
|
temp32 = silk_RSHIFT( temp32, 31 + corr_rshifts[ k ] - extra_shifts - 26 ); /* Q26 */
|
||||||
|
|
||||||
/* Limit temp such that the below scaling never wraps around */
|
/* Limit temp such that the below scaling never wraps around */
|
||||||
|
@ -124,7 +124,7 @@ void silk_find_LTP_FIX(
|
||||||
lshift = silk_CLZ32( WLTP_max ) - 1 - 3; /* keep 3 bits free for vq_nearest_neighbor_fix */
|
lshift = silk_CLZ32( WLTP_max ) - 1 - 3; /* keep 3 bits free for vq_nearest_neighbor_fix */
|
||||||
silk_assert( 26 - 18 + lshift >= 0 );
|
silk_assert( 26 - 18 + lshift >= 0 );
|
||||||
if( 26 - 18 + lshift < 31 ) {
|
if( 26 - 18 + lshift < 31 ) {
|
||||||
temp32 = silk_min_32( temp32, silk_LSHIFT( ( opus_int32 )1, 26 - 18 + lshift ) );
|
temp32 = silk_min_32( temp32, silk_LSHIFT( (opus_int32)1, 26 - 18 + lshift ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
silk_scale_vector32_Q26_lshift_18( WLTP_ptr, temp32, LTP_ORDER * LTP_ORDER ); /* WLTP_ptr in Q( 18 - corr_rshifts[ k ] ) */
|
silk_scale_vector32_Q26_lshift_18( WLTP_ptr, temp32, LTP_ORDER * LTP_ORDER ); /* WLTP_ptr in Q( 18 - corr_rshifts[ k ] ) */
|
||||||
|
@ -216,16 +216,16 @@ void silk_find_LTP_FIX(
|
||||||
silk_DIV32(
|
silk_DIV32(
|
||||||
SILK_FIX_CONST( LTP_SMOOTHING, 26 ),
|
SILK_FIX_CONST( LTP_SMOOTHING, 26 ),
|
||||||
silk_RSHIFT( SILK_FIX_CONST( LTP_SMOOTHING, 26 ), 10 ) + temp32 ), /* Q10 */
|
silk_RSHIFT( SILK_FIX_CONST( LTP_SMOOTHING, 26 ), 10 ) + temp32 ), /* Q10 */
|
||||||
silk_LSHIFT_SAT32( silk_SUB_SAT32( ( opus_int32 )m_Q12, silk_RSHIFT( d_Q14[ k ], 2 ) ), 4 ) ); /* Q16 */
|
silk_LSHIFT_SAT32( silk_SUB_SAT32( (opus_int32)m_Q12, silk_RSHIFT( d_Q14[ k ], 2 ) ), 4 ) ); /* Q16 */
|
||||||
|
|
||||||
temp32 = 0;
|
temp32 = 0;
|
||||||
for( i = 0; i < LTP_ORDER; i++ ) {
|
for( i = 0; i < LTP_ORDER; i++ ) {
|
||||||
delta_b_Q14[ i ] = silk_max_16( b_Q14_ptr[ i ], 1638 ); /* 1638_Q14 = 0.1_Q0 */
|
delta_b_Q14[ i ] = silk_max_16( b_Q14_ptr[ i ], 1638 ); /* 1638_Q14 = 0.1_Q0 */
|
||||||
temp32 += delta_b_Q14[ i ]; /* Q14 */
|
temp32 += delta_b_Q14[ i ]; /* Q14 */
|
||||||
}
|
}
|
||||||
temp32 = silk_DIV32( g_Q26, temp32 ); /* Q14->Q12 */
|
temp32 = silk_DIV32( g_Q26, temp32 ); /* Q14 -> Q12 */
|
||||||
for( i = 0; i < LTP_ORDER; i++ ) {
|
for( i = 0; i < LTP_ORDER; i++ ) {
|
||||||
b_Q14_ptr[ i ] = silk_LIMIT_32( ( opus_int32 )b_Q14_ptr[ i ] + silk_SMULWB( silk_LSHIFT_SAT32( temp32, 4 ), delta_b_Q14[ i ] ), -16000, 28000 );
|
b_Q14_ptr[ i ] = silk_LIMIT_32( (opus_int32)b_Q14_ptr[ i ] + silk_SMULWB( silk_LSHIFT_SAT32( temp32, 4 ), delta_b_Q14[ i ] ), -16000, 28000 );
|
||||||
}
|
}
|
||||||
b_Q14_ptr += LTP_ORDER;
|
b_Q14_ptr += LTP_ORDER;
|
||||||
}
|
}
|
||||||
|
@ -239,6 +239,6 @@ void silk_fit_LTP(
|
||||||
opus_int i;
|
opus_int i;
|
||||||
|
|
||||||
for( i = 0; i < LTP_ORDER; i++ ) {
|
for( i = 0; i < LTP_ORDER; i++ ) {
|
||||||
LTP_coefs_Q14[ i ] = ( opus_int16 )silk_SAT16( silk_RSHIFT_ROUND( LTP_coefs_Q16[ i ], 2 ) );
|
LTP_coefs_Q14[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( LTP_coefs_Q16[ i ], 2 ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ void silk_find_pitch_lags_FIX(
|
||||||
opus_int16 A_Q12[ MAX_FIND_PITCH_LPC_ORDER ];
|
opus_int16 A_Q12[ MAX_FIND_PITCH_LPC_ORDER ];
|
||||||
|
|
||||||
/******************************************/
|
/******************************************/
|
||||||
/* Setup buffer lengths etc based on Fs */
|
/* Set up buffer lengths etc based on Fs */
|
||||||
/******************************************/
|
/******************************************/
|
||||||
buf_len = psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length + psEnc->sCmn.ltp_mem_length;
|
buf_len = psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length + psEnc->sCmn.ltp_mem_length;
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ void silk_find_pitch_lags_FIX(
|
||||||
|
|
||||||
/* Convert From 32 bit Q24 to 16 bit Q12 coefs */
|
/* Convert From 32 bit Q24 to 16 bit Q12 coefs */
|
||||||
for( i = 0; i < psEnc->sCmn.pitchEstimationLPCOrder; i++ ) {
|
for( i = 0; i < psEnc->sCmn.pitchEstimationLPCOrder; i++ ) {
|
||||||
A_Q12[ i ] = ( opus_int16 )silk_SAT16( silk_RSHIFT( A_Q24[ i ], 12 ) );
|
A_Q12[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT( A_Q24[ i ], 12 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do BWE */
|
/* Do BWE */
|
||||||
|
@ -122,7 +122,7 @@ void silk_find_pitch_lags_FIX(
|
||||||
/*****************************************/
|
/*****************************************/
|
||||||
if( silk_pitch_analysis_core( res, psEncCtrl->pitchL, &psEnc->sCmn.indices.lagIndex, &psEnc->sCmn.indices.contourIndex,
|
if( silk_pitch_analysis_core( res, psEncCtrl->pitchL, &psEnc->sCmn.indices.lagIndex, &psEnc->sCmn.indices.contourIndex,
|
||||||
&psEnc->LTPCorr_Q15, psEnc->sCmn.prevLag, psEnc->sCmn.pitchEstimationThreshold_Q16,
|
&psEnc->LTPCorr_Q15, psEnc->sCmn.prevLag, psEnc->sCmn.pitchEstimationThreshold_Q16,
|
||||||
( opus_int16 )thrhld_Q15, psEnc->sCmn.fs_kHz, psEnc->sCmn.pitchEstimationComplexity, psEnc->sCmn.nb_subfr ) == 0 )
|
(opus_int16)thrhld_Q15, psEnc->sCmn.fs_kHz, psEnc->sCmn.pitchEstimationComplexity, psEnc->sCmn.nb_subfr ) == 0 )
|
||||||
{
|
{
|
||||||
psEnc->sCmn.indices.signalType = TYPE_VOICED;
|
psEnc->sCmn.indices.signalType = TYPE_VOICED;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -45,7 +45,7 @@ void silk_find_pred_coefs_FIX(
|
||||||
opus_int16 NLSF_Q15[ MAX_LPC_ORDER ];
|
opus_int16 NLSF_Q15[ MAX_LPC_ORDER ];
|
||||||
const opus_int16 *x_ptr;
|
const opus_int16 *x_ptr;
|
||||||
opus_int16 *x_pre_ptr, LPC_in_pre[ MAX_NB_SUBFR * MAX_LPC_ORDER + MAX_FRAME_LENGTH ];
|
opus_int16 *x_pre_ptr, LPC_in_pre[ MAX_NB_SUBFR * MAX_LPC_ORDER + MAX_FRAME_LENGTH ];
|
||||||
opus_int32 tmp, min_gain_Q16;
|
opus_int32 tmp, min_gain_Q16, minInvGain_Q30;
|
||||||
opus_int LTP_corrs_rshift[ MAX_NB_SUBFR ];
|
opus_int LTP_corrs_rshift[ MAX_NB_SUBFR ];
|
||||||
|
|
||||||
/* weighting for weighted least squares */
|
/* weighting for weighted least squares */
|
||||||
|
@ -111,10 +111,18 @@ void silk_find_pred_coefs_FIX(
|
||||||
psEncCtrl->LTPredCodGain_Q7 = 0;
|
psEncCtrl->LTPredCodGain_Q7 = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Limit on total predictive coding gain */
|
||||||
|
if( psEnc->sCmn.first_frame_after_reset ) {
|
||||||
|
minInvGain_Q30 = SILK_FIX_CONST( 1.0f / MAX_PREDICTION_POWER_GAIN_AFTER_RESET, 30 );
|
||||||
|
} else {
|
||||||
|
minInvGain_Q30 = silk_log2lin( silk_SMLAWB( 16 << 7, psEncCtrl->LTPredCodGain_Q7, SILK_FIX_CONST( 1.0 / 3, 16 ) ) ); /* Q16 */
|
||||||
|
minInvGain_Q30 = silk_DIV32_varQ( minInvGain_Q30,
|
||||||
|
silk_SMULWW( SILK_FIX_CONST( MAX_PREDICTION_POWER_GAIN, 0 ),
|
||||||
|
silk_SMLAWB( SILK_FIX_CONST( 0.1, 18 ), SILK_FIX_CONST( 0.9, 18 ), psEncCtrl->coding_quality_Q14 ) ), 14 );
|
||||||
|
}
|
||||||
|
|
||||||
/* LPC_in_pre contains the LTP-filtered input for voiced, and the unfiltered input for unvoiced */
|
/* LPC_in_pre contains the LTP-filtered input for voiced, and the unfiltered input for unvoiced */
|
||||||
silk_find_LPC_FIX( NLSF_Q15, &psEnc->sCmn.indices.NLSFInterpCoef_Q2, psEnc->sCmn.prev_NLSFq_Q15,
|
silk_find_LPC_FIX( &psEnc->sCmn, NLSF_Q15, LPC_in_pre, minInvGain_Q30 );
|
||||||
psEnc->sCmn.useInterpolatedNLSFs, psEnc->sCmn.first_frame_after_reset, psEnc->sCmn.predictLPCOrder,
|
|
||||||
LPC_in_pre, psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder, psEnc->sCmn.nb_subfr );
|
|
||||||
|
|
||||||
/* Quantize LSFs */
|
/* Quantize LSFs */
|
||||||
silk_process_NLSFs( &psEnc->sCmn, psEncCtrl->PredCoef_Q12, NLSF_Q15, psEnc->sCmn.prev_NLSFq_Q15 );
|
silk_process_NLSFs( &psEnc->sCmn, psEncCtrl->PredCoef_Q12, NLSF_Q15, psEnc->sCmn.prev_NLSFq_Q15 );
|
||||||
|
|
|
@ -92,7 +92,7 @@ opus_int silk_control_encoder(
|
||||||
void silk_prefilter_FIX(
|
void silk_prefilter_FIX(
|
||||||
silk_encoder_state_FIX *psEnc, /* I/O Encoder state */
|
silk_encoder_state_FIX *psEnc, /* I/O Encoder state */
|
||||||
const silk_encoder_control_FIX *psEncCtrl, /* I Encoder control */
|
const silk_encoder_control_FIX *psEncCtrl, /* I Encoder control */
|
||||||
opus_int16 xw[], /* O Weighted signal */
|
opus_int32 xw_Q10[], /* O Weighted signal */
|
||||||
const opus_int16 x[] /* I Speech signal */
|
const opus_int16 x[] /* I Speech signal */
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -146,15 +146,10 @@ void silk_find_pred_coefs_FIX(
|
||||||
|
|
||||||
/* LPC analysis */
|
/* LPC analysis */
|
||||||
void silk_find_LPC_FIX(
|
void silk_find_LPC_FIX(
|
||||||
|
silk_encoder_state *psEncC, /* I/O Encoder state */
|
||||||
opus_int16 NLSF_Q15[], /* O NLSFs */
|
opus_int16 NLSF_Q15[], /* O NLSFs */
|
||||||
opus_int8 *interpIndex, /* O NLSF interpolation index, only used for NLSF interpolation */
|
|
||||||
const opus_int16 prev_NLSFq_Q15[], /* I previous NLSFs, only used for NLSF interpolation */
|
|
||||||
const opus_int useInterpNLSFs, /* I Flag */
|
|
||||||
const opus_int firstFrameAfterReset, /* I Flag */
|
|
||||||
const opus_int LPC_order, /* I LPC order */
|
|
||||||
const opus_int16 x[], /* I Input signal */
|
const opus_int16 x[], /* I Input signal */
|
||||||
const opus_int subfr_length, /* I Input signal subframe length including preceeding samples */
|
const opus_int32 minInvGain_Q30 /* I Inverse of max prediction gain */
|
||||||
const opus_int nb_subfr /* I Number of subframes */
|
|
||||||
);
|
);
|
||||||
|
|
||||||
/* LTP analysis */
|
/* LTP analysis */
|
||||||
|
|
|
@ -166,12 +166,12 @@ void silk_noise_shape_analysis_FIX(
|
||||||
SNR_adj_dB_Q7 = psEnc->sCmn.SNR_dB_Q7;
|
SNR_adj_dB_Q7 = psEnc->sCmn.SNR_dB_Q7;
|
||||||
|
|
||||||
/* Input quality is the average of the quality in the lowest two VAD bands */
|
/* Input quality is the average of the quality in the lowest two VAD bands */
|
||||||
psEncCtrl->input_quality_Q14 = ( opus_int )silk_RSHIFT( ( opus_int32 )psEnc->sCmn.input_quality_bands_Q15[ 0 ]
|
psEncCtrl->input_quality_Q14 = ( opus_int )silk_RSHIFT( (opus_int32)psEnc->sCmn.input_quality_bands_Q15[ 0 ]
|
||||||
+ psEnc->sCmn.input_quality_bands_Q15[ 1 ], 2 );
|
+ psEnc->sCmn.input_quality_bands_Q15[ 1 ], 2 );
|
||||||
|
|
||||||
/* Coding quality level, between 0.0_Q0 and 1.0_Q0, but in Q14 */
|
/* Coding quality level, between 0.0_Q0 and 1.0_Q0, but in Q14 */
|
||||||
psEncCtrl->coding_quality_Q14 = silk_RSHIFT( silk_sigm_Q15( silk_RSHIFT_ROUND( SNR_adj_dB_Q7 -
|
psEncCtrl->coding_quality_Q14 = silk_RSHIFT( silk_sigm_Q15( silk_RSHIFT_ROUND( SNR_adj_dB_Q7 -
|
||||||
SILK_FIX_CONST( 18.0, 7 ), 4 ) ), 1 );
|
SILK_FIX_CONST( 20.0, 7 ), 4 ) ), 1 );
|
||||||
|
|
||||||
/* Reduce coding SNR during low speech activity */
|
/* Reduce coding SNR during low speech activity */
|
||||||
if( psEnc->sCmn.useCBR == 0 ) {
|
if( psEnc->sCmn.useCBR == 0 ) {
|
||||||
|
@ -326,8 +326,8 @@ void silk_noise_shape_analysis_FIX(
|
||||||
silk_bwexpander_32( AR1_Q24, psEnc->sCmn.shapingLPCOrder, BWExp1_Q16 );
|
silk_bwexpander_32( AR1_Q24, psEnc->sCmn.shapingLPCOrder, BWExp1_Q16 );
|
||||||
|
|
||||||
/* Ratio of prediction gains, in energy domain */
|
/* Ratio of prediction gains, in energy domain */
|
||||||
silk_LPC_inverse_pred_gain_Q24( &pre_nrg_Q30, AR2_Q24, psEnc->sCmn.shapingLPCOrder );
|
pre_nrg_Q30 = silk_LPC_inverse_pred_gain_Q24( AR2_Q24, psEnc->sCmn.shapingLPCOrder );
|
||||||
silk_LPC_inverse_pred_gain_Q24( &nrg, AR1_Q24, psEnc->sCmn.shapingLPCOrder );
|
nrg = silk_LPC_inverse_pred_gain_Q24( AR1_Q24, psEnc->sCmn.shapingLPCOrder );
|
||||||
|
|
||||||
/*psEncCtrl->GainsPre[ k ] = 1.0f - 0.7f * ( 1.0f - pre_nrg / nrg ) = 0.3f + 0.7f * pre_nrg / nrg;*/
|
/*psEncCtrl->GainsPre[ k ] = 1.0f - 0.7f * ( 1.0f - pre_nrg / nrg ) = 0.3f + 0.7f * pre_nrg / nrg;*/
|
||||||
pre_nrg_Q30 = silk_LSHIFT32( silk_SMULWB( pre_nrg_Q30, SILK_FIX_CONST( 0.7, 15 ) ), 1 );
|
pre_nrg_Q30 = silk_LSHIFT32( silk_SMULWB( pre_nrg_Q30, SILK_FIX_CONST( 0.7, 15 ) ), 1 );
|
||||||
|
|
|
@ -116,7 +116,7 @@ opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0
|
||||||
silk_assert( search_thres1_Q16 >= 0 && search_thres1_Q16 <= (1<<16) );
|
silk_assert( search_thres1_Q16 >= 0 && search_thres1_Q16 <= (1<<16) );
|
||||||
silk_assert( search_thres2_Q15 >= 0 && search_thres2_Q15 <= (1<<15) );
|
silk_assert( search_thres2_Q15 >= 0 && search_thres2_Q15 <= (1<<15) );
|
||||||
|
|
||||||
/* Setup frame lengths max / min lag for the sampling frequency */
|
/* Set up frame lengths max / min lag for the sampling frequency */
|
||||||
frame_length = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * Fs_kHz;
|
frame_length = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * Fs_kHz;
|
||||||
frame_length_4kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 4;
|
frame_length_4kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 4;
|
||||||
frame_length_8kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 8;
|
frame_length_8kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 8;
|
||||||
|
@ -375,7 +375,7 @@ opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0
|
||||||
prevLag_log2_Q7 = 0;
|
prevLag_log2_Q7 = 0;
|
||||||
}
|
}
|
||||||
silk_assert( search_thres2_Q15 == silk_SAT16( search_thres2_Q15 ) );
|
silk_assert( search_thres2_Q15 == silk_SAT16( search_thres2_Q15 ) );
|
||||||
/* Setup stage 2 codebook based on number of subframes */
|
/* Set up stage 2 codebook based on number of subframes */
|
||||||
if( nb_subfr == PE_MAX_NB_SUBFR ) {
|
if( nb_subfr == PE_MAX_NB_SUBFR ) {
|
||||||
cbk_size = PE_NB_CBKS_STAGE2_EXT;
|
cbk_size = PE_NB_CBKS_STAGE2_EXT;
|
||||||
Lag_CB_ptr = &silk_CB_lags_stage2[ 0 ][ 0 ];
|
Lag_CB_ptr = &silk_CB_lags_stage2[ 0 ][ 0 ];
|
||||||
|
@ -500,7 +500,7 @@ opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0
|
||||||
silk_assert( lag == silk_SAT16( lag ) );
|
silk_assert( lag == silk_SAT16( lag ) );
|
||||||
contour_bias_Q20 = silk_DIV32_16( SILK_FIX_CONST( PE_FLATCONTOUR_BIAS, 20 ), lag );
|
contour_bias_Q20 = silk_DIV32_16( SILK_FIX_CONST( PE_FLATCONTOUR_BIAS, 20 ), lag );
|
||||||
|
|
||||||
/* Setup cbk parameters acording to complexity setting and frame length */
|
/* Set up codebook parameters acording to complexity setting and frame length */
|
||||||
if( nb_subfr == PE_MAX_NB_SUBFR ) {
|
if( nb_subfr == PE_MAX_NB_SUBFR ) {
|
||||||
nb_cbk_search = (opus_int)silk_nb_cbk_searchs_stage3[ complexity ];
|
nb_cbk_search = (opus_int)silk_nb_cbk_searchs_stage3[ complexity ];
|
||||||
cbk_size = PE_NB_CBKS_STAGE3_MAX;
|
cbk_size = PE_NB_CBKS_STAGE3_MAX;
|
||||||
|
|
|
@ -36,7 +36,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
static inline void silk_prefilt_FIX(
|
static inline void silk_prefilt_FIX(
|
||||||
silk_prefilter_state_FIX *P, /* I/O state */
|
silk_prefilter_state_FIX *P, /* I/O state */
|
||||||
opus_int32 st_res_Q12[], /* I short term residual signal */
|
opus_int32 st_res_Q12[], /* I short term residual signal */
|
||||||
opus_int16 xw[], /* O prefiltered signal */
|
opus_int32 pxw_Q10[], /* O prefiltered signal */
|
||||||
opus_int32 HarmShapeFIRPacked_Q12, /* I Harmonic shaping coeficients */
|
opus_int32 HarmShapeFIRPacked_Q12, /* I Harmonic shaping coeficients */
|
||||||
opus_int Tilt_Q14, /* I Tilt shaping coeficient */
|
opus_int Tilt_Q14, /* I Tilt shaping coeficient */
|
||||||
opus_int32 LF_shp_Q14, /* I Low-frequancy shaping coeficients */
|
opus_int32 LF_shp_Q14, /* I Low-frequancy shaping coeficients */
|
||||||
|
@ -46,7 +46,7 @@ static inline void silk_prefilt_FIX(
|
||||||
|
|
||||||
void silk_warped_LPC_analysis_filter_FIX(
|
void silk_warped_LPC_analysis_filter_FIX(
|
||||||
opus_int32 state[], /* I/O State [order + 1] */
|
opus_int32 state[], /* I/O State [order + 1] */
|
||||||
opus_int16 res[], /* O Residual signal [length] */
|
opus_int32 res_Q2[], /* O Residual signal [length] */
|
||||||
const opus_int16 coef_Q13[], /* I Coefficients [order] */
|
const opus_int16 coef_Q13[], /* I Coefficients [order] */
|
||||||
const opus_int16 input[], /* I Input signal [length] */
|
const opus_int16 input[], /* I Input signal [length] */
|
||||||
const opus_int16 lambda_Q16, /* I Warping factor */
|
const opus_int16 lambda_Q16, /* I Warping factor */
|
||||||
|
@ -81,14 +81,14 @@ void silk_warped_LPC_analysis_filter_FIX(
|
||||||
}
|
}
|
||||||
state[ order ] = tmp1;
|
state[ order ] = tmp1;
|
||||||
acc_Q11 = silk_SMLAWB( acc_Q11, tmp1, coef_Q13[ order - 1 ] );
|
acc_Q11 = silk_SMLAWB( acc_Q11, tmp1, coef_Q13[ order - 1 ] );
|
||||||
res[ n ] = ( opus_int16 )silk_SAT16( ( opus_int32 )input[ n ] - silk_RSHIFT_ROUND( acc_Q11, 11 ) );
|
res_Q2[ n ] = silk_LSHIFT( (opus_int32)input[ n ], 2 ) - silk_RSHIFT_ROUND( acc_Q11, 9 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void silk_prefilter_FIX(
|
void silk_prefilter_FIX(
|
||||||
silk_encoder_state_FIX *psEnc, /* I/O Encoder state */
|
silk_encoder_state_FIX *psEnc, /* I/O Encoder state */
|
||||||
const silk_encoder_control_FIX *psEncCtrl, /* I Encoder control */
|
const silk_encoder_control_FIX *psEncCtrl, /* I Encoder control */
|
||||||
opus_int16 xw[], /* O Weighted signal */
|
opus_int32 xw_Q10[], /* O Weighted signal */
|
||||||
const opus_int16 x[] /* I Speech signal */
|
const opus_int16 x[] /* I Speech signal */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
@ -97,16 +97,16 @@ void silk_prefilter_FIX(
|
||||||
opus_int32 tmp_32;
|
opus_int32 tmp_32;
|
||||||
const opus_int16 *AR1_shp_Q13;
|
const opus_int16 *AR1_shp_Q13;
|
||||||
const opus_int16 *px;
|
const opus_int16 *px;
|
||||||
opus_int16 *pxw;
|
opus_int32 *pxw_Q10;
|
||||||
opus_int HarmShapeGain_Q12, Tilt_Q14;
|
opus_int HarmShapeGain_Q12, Tilt_Q14;
|
||||||
opus_int32 HarmShapeFIRPacked_Q12, LF_shp_Q14;
|
opus_int32 HarmShapeFIRPacked_Q12, LF_shp_Q14;
|
||||||
opus_int32 x_filt_Q12[ MAX_FRAME_LENGTH / MAX_NB_SUBFR ];
|
opus_int32 x_filt_Q12[ MAX_SUB_FRAME_LENGTH ];
|
||||||
opus_int16 st_res[ ( MAX_FRAME_LENGTH / MAX_NB_SUBFR ) + MAX_LPC_ORDER ];
|
opus_int32 st_res_Q2[ MAX_SUB_FRAME_LENGTH + MAX_LPC_ORDER ];
|
||||||
opus_int16 B_Q12[ 2 ];
|
opus_int16 B_Q10[ 2 ];
|
||||||
|
|
||||||
/* Setup pointers */
|
/* Set up pointers */
|
||||||
px = x;
|
px = x;
|
||||||
pxw = xw;
|
pxw_Q10 = xw_Q10;
|
||||||
lag = P->lagPrev;
|
lag = P->lagPrev;
|
||||||
for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
|
for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
|
||||||
/* Update Variables that change per sub frame */
|
/* Update Variables that change per sub frame */
|
||||||
|
@ -118,34 +118,33 @@ void silk_prefilter_FIX(
|
||||||
HarmShapeGain_Q12 = silk_SMULWB( psEncCtrl->HarmShapeGain_Q14[ k ], 16384 - psEncCtrl->HarmBoost_Q14[ k ] );
|
HarmShapeGain_Q12 = silk_SMULWB( psEncCtrl->HarmShapeGain_Q14[ k ], 16384 - psEncCtrl->HarmBoost_Q14[ k ] );
|
||||||
silk_assert( HarmShapeGain_Q12 >= 0 );
|
silk_assert( HarmShapeGain_Q12 >= 0 );
|
||||||
HarmShapeFIRPacked_Q12 = silk_RSHIFT( HarmShapeGain_Q12, 2 );
|
HarmShapeFIRPacked_Q12 = silk_RSHIFT( HarmShapeGain_Q12, 2 );
|
||||||
HarmShapeFIRPacked_Q12 |= silk_LSHIFT( ( opus_int32 )silk_RSHIFT( HarmShapeGain_Q12, 1 ), 16 );
|
HarmShapeFIRPacked_Q12 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q12, 1 ), 16 );
|
||||||
Tilt_Q14 = psEncCtrl->Tilt_Q14[ k ];
|
Tilt_Q14 = psEncCtrl->Tilt_Q14[ k ];
|
||||||
LF_shp_Q14 = psEncCtrl->LF_shp_Q14[ k ];
|
LF_shp_Q14 = psEncCtrl->LF_shp_Q14[ k ];
|
||||||
AR1_shp_Q13 = &psEncCtrl->AR1_Q13[ k * MAX_SHAPE_LPC_ORDER ];
|
AR1_shp_Q13 = &psEncCtrl->AR1_Q13[ k * MAX_SHAPE_LPC_ORDER ];
|
||||||
|
|
||||||
/* Short term FIR filtering*/
|
/* Short term FIR filtering*/
|
||||||
silk_warped_LPC_analysis_filter_FIX( P->sAR_shp, st_res, AR1_shp_Q13, px,
|
silk_warped_LPC_analysis_filter_FIX( P->sAR_shp, st_res_Q2, AR1_shp_Q13, px,
|
||||||
psEnc->sCmn.warping_Q16, psEnc->sCmn.subfr_length, psEnc->sCmn.shapingLPCOrder );
|
psEnc->sCmn.warping_Q16, psEnc->sCmn.subfr_length, psEnc->sCmn.shapingLPCOrder );
|
||||||
|
|
||||||
/* reduce (mainly) low frequencies during harmonic emphasis */
|
/* Reduce (mainly) low frequencies during harmonic emphasis */
|
||||||
B_Q12[ 0 ] = silk_RSHIFT_ROUND( psEncCtrl->GainsPre_Q14[ k ], 2 );
|
B_Q10[ 0 ] = silk_RSHIFT_ROUND( psEncCtrl->GainsPre_Q14[ k ], 4 );
|
||||||
tmp_32 = silk_SMLABB( SILK_FIX_CONST( INPUT_TILT, 26 ), psEncCtrl->HarmBoost_Q14[ k ], HarmShapeGain_Q12 ); /* Q26 */
|
tmp_32 = silk_SMLABB( SILK_FIX_CONST( INPUT_TILT, 26 ), psEncCtrl->HarmBoost_Q14[ k ], HarmShapeGain_Q12 ); /* Q26 */
|
||||||
tmp_32 = silk_SMLABB( tmp_32, psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( HIGH_RATE_INPUT_TILT, 12 ) ); /* Q26 */
|
tmp_32 = silk_SMLABB( tmp_32, psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( HIGH_RATE_INPUT_TILT, 12 ) ); /* Q26 */
|
||||||
tmp_32 = silk_SMULWB( tmp_32, -psEncCtrl->GainsPre_Q14[ k ] ); /* Q24 */
|
tmp_32 = silk_SMULWB( tmp_32, -psEncCtrl->GainsPre_Q14[ k ] ); /* Q24 */
|
||||||
tmp_32 = silk_RSHIFT_ROUND( tmp_32, 12 ); /* Q12 */
|
tmp_32 = silk_RSHIFT_ROUND( tmp_32, 14 ); /* Q10 */
|
||||||
B_Q12[ 1 ]= silk_SAT16( tmp_32 );
|
B_Q10[ 1 ]= silk_SAT16( tmp_32 );
|
||||||
|
x_filt_Q12[ 0 ] = silk_SMLABB( silk_SMULBB( st_res_Q2[ 0 ], B_Q10[ 0 ] ), P->sHarmHP_Q2, B_Q10[ 1 ] );
|
||||||
x_filt_Q12[ 0 ] = silk_SMLABB( silk_SMULBB( st_res[ 0 ], B_Q12[ 0 ] ), P->sHarmHP, B_Q12[ 1 ] );
|
|
||||||
for( j = 1; j < psEnc->sCmn.subfr_length; j++ ) {
|
for( j = 1; j < psEnc->sCmn.subfr_length; j++ ) {
|
||||||
x_filt_Q12[ j ] = silk_SMLABB( silk_SMULBB( st_res[ j ], B_Q12[ 0 ] ), st_res[ j - 1 ], B_Q12[ 1 ] );
|
x_filt_Q12[ j ] = silk_SMLABB( silk_SMULBB( st_res_Q2[ j ], B_Q10[ 0 ] ), st_res_Q2[ j - 1 ], B_Q10[ 1 ] );
|
||||||
}
|
}
|
||||||
P->sHarmHP = st_res[ psEnc->sCmn.subfr_length - 1 ];
|
P->sHarmHP_Q2 = st_res_Q2[ psEnc->sCmn.subfr_length - 1 ];
|
||||||
|
|
||||||
silk_prefilt_FIX( P, x_filt_Q12, pxw, HarmShapeFIRPacked_Q12, Tilt_Q14,
|
silk_prefilt_FIX( P, x_filt_Q12, pxw_Q10, HarmShapeFIRPacked_Q12, Tilt_Q14,
|
||||||
LF_shp_Q14, lag, psEnc->sCmn.subfr_length );
|
LF_shp_Q14, lag, psEnc->sCmn.subfr_length );
|
||||||
|
|
||||||
px += psEnc->sCmn.subfr_length;
|
px += psEnc->sCmn.subfr_length;
|
||||||
pxw += psEnc->sCmn.subfr_length;
|
pxw_Q10 += psEnc->sCmn.subfr_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
P->lagPrev = psEncCtrl->pitchL[ psEnc->sCmn.nb_subfr - 1 ];
|
P->lagPrev = psEncCtrl->pitchL[ psEnc->sCmn.nb_subfr - 1 ];
|
||||||
|
@ -155,7 +154,7 @@ void silk_prefilter_FIX(
|
||||||
static inline void silk_prefilt_FIX(
|
static inline void silk_prefilt_FIX(
|
||||||
silk_prefilter_state_FIX *P, /* I/O state */
|
silk_prefilter_state_FIX *P, /* I/O state */
|
||||||
opus_int32 st_res_Q12[], /* I short term residual signal */
|
opus_int32 st_res_Q12[], /* I short term residual signal */
|
||||||
opus_int16 xw[], /* O prefiltered signal */
|
opus_int32 xw_Q10[], /* O prefiltered signal */
|
||||||
opus_int32 HarmShapeFIRPacked_Q12, /* I Harmonic shaping coeficients */
|
opus_int32 HarmShapeFIRPacked_Q12, /* I Harmonic shaping coeficients */
|
||||||
opus_int Tilt_Q14, /* I Tilt shaping coeficient */
|
opus_int Tilt_Q14, /* I Tilt shaping coeficient */
|
||||||
opus_int32 LF_shp_Q14, /* I Low-frequancy shaping coeficients */
|
opus_int32 LF_shp_Q14, /* I Low-frequancy shaping coeficients */
|
||||||
|
@ -193,9 +192,9 @@ static inline void silk_prefilt_FIX(
|
||||||
sLF_MA_shp_Q12 = silk_SUB32( sLF_AR_shp_Q12, silk_LSHIFT( n_LF_Q10, 2 ) );
|
sLF_MA_shp_Q12 = silk_SUB32( sLF_AR_shp_Q12, silk_LSHIFT( n_LF_Q10, 2 ) );
|
||||||
|
|
||||||
LTP_shp_buf_idx = ( LTP_shp_buf_idx - 1 ) & LTP_MASK;
|
LTP_shp_buf_idx = ( LTP_shp_buf_idx - 1 ) & LTP_MASK;
|
||||||
LTP_shp_buf[ LTP_shp_buf_idx ] = ( opus_int16 )silk_SAT16( silk_RSHIFT_ROUND( sLF_MA_shp_Q12, 12 ) );
|
LTP_shp_buf[ LTP_shp_buf_idx ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sLF_MA_shp_Q12, 12 ) );
|
||||||
|
|
||||||
xw[i] = ( opus_int16 )silk_SAT16( silk_RSHIFT_ROUND( silk_SUB32( sLF_MA_shp_Q12, n_LTP_Q12 ), 12 ) );
|
xw_Q10[i] = silk_RSHIFT_ROUND( silk_SUB32( sLF_MA_shp_Q12, n_LTP_Q12 ), 2 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy temp variable back to state */
|
/* Copy temp variable back to state */
|
||||||
|
|
|
@ -57,7 +57,7 @@ opus_int32 silk_residual_energy16_covar_FIX(
|
||||||
|
|
||||||
c_max = 0;
|
c_max = 0;
|
||||||
for( i = 0; i < D; i++ ) {
|
for( i = 0; i < D; i++ ) {
|
||||||
c_max = silk_max_32( c_max, silk_abs( ( opus_int32 )c[ i ] ) );
|
c_max = silk_max_32( c_max, silk_abs( (opus_int32)c[ i ] ) );
|
||||||
}
|
}
|
||||||
Qxtra = silk_min_int( Qxtra, silk_CLZ32( c_max ) - 17 );
|
Qxtra = silk_min_int( Qxtra, silk_CLZ32( c_max ) - 17 );
|
||||||
|
|
||||||
|
|
|
@ -76,7 +76,7 @@ opus_int32 silk_schur( /* O Returns residual ene
|
||||||
rc_tmp_Q15 = silk_SAT16( rc_tmp_Q15 );
|
rc_tmp_Q15 = silk_SAT16( rc_tmp_Q15 );
|
||||||
|
|
||||||
/* Store */
|
/* Store */
|
||||||
rc_Q15[ k ] = ( opus_int16 )rc_tmp_Q15;
|
rc_Q15[ k ] = (opus_int16)rc_tmp_Q15;
|
||||||
|
|
||||||
/* Update correlations */
|
/* Update correlations */
|
||||||
for( n = 0; n < order - k; n++ ) {
|
for( n = 0; n < order - k; n++ ) {
|
||||||
|
|
|
@ -56,7 +56,7 @@ typedef struct {
|
||||||
opus_int sLTP_shp_buf_idx;
|
opus_int sLTP_shp_buf_idx;
|
||||||
opus_int32 sLF_AR_shp_Q12;
|
opus_int32 sLF_AR_shp_Q12;
|
||||||
opus_int32 sLF_MA_shp_Q12;
|
opus_int32 sLF_MA_shp_Q12;
|
||||||
opus_int sHarmHP;
|
opus_int32 sHarmHP_Q2;
|
||||||
opus_int32 rand_seed;
|
opus_int32 rand_seed;
|
||||||
opus_int lagPrev;
|
opus_int lagPrev;
|
||||||
} silk_prefilter_state_FIX;
|
} silk_prefilter_state_FIX;
|
||||||
|
@ -72,10 +72,6 @@ typedef struct {
|
||||||
/* Buffer for find pitch and noise shape analysis */
|
/* Buffer for find pitch and noise shape analysis */
|
||||||
silk_DWORD_ALIGN opus_int16 x_buf[ 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ];/* Buffer for find pitch and noise shape analysis */
|
silk_DWORD_ALIGN opus_int16 x_buf[ 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ];/* Buffer for find pitch and noise shape analysis */
|
||||||
opus_int LTPCorr_Q15; /* Normalized correlation from pitch lag estimator */
|
opus_int LTPCorr_Q15; /* Normalized correlation from pitch lag estimator */
|
||||||
|
|
||||||
/* Parameters For LTP scaling Control */
|
|
||||||
opus_int prevLTPredCodGain_Q7;
|
|
||||||
opus_int HPLTPredCodGain_Q7;
|
|
||||||
} silk_encoder_state_FIX;
|
} silk_encoder_state_FIX;
|
||||||
|
|
||||||
/************************/
|
/************************/
|
||||||
|
|
|
@ -55,7 +55,7 @@ void silk_warped_autocorrelation_FIX(
|
||||||
|
|
||||||
/* Loop over samples */
|
/* Loop over samples */
|
||||||
for( n = 0; n < length; n++ ) {
|
for( n = 0; n < length; n++ ) {
|
||||||
tmp1_QS = silk_LSHIFT32( ( opus_int32 )input[ n ], QS );
|
tmp1_QS = silk_LSHIFT32( (opus_int32)input[ n ], QS );
|
||||||
/* Loop over allpass sections */
|
/* Loop over allpass sections */
|
||||||
for( i = 0; i < order; i += 2 ) {
|
for( i = 0; i < order; i += 2 ) {
|
||||||
/* Output of allpass section */
|
/* Output of allpass section */
|
||||||
|
@ -77,11 +77,11 @@ void silk_warped_autocorrelation_FIX(
|
||||||
silk_assert( *scale >= -30 && *scale <= 12 );
|
silk_assert( *scale >= -30 && *scale <= 12 );
|
||||||
if( lsh >= 0 ) {
|
if( lsh >= 0 ) {
|
||||||
for( i = 0; i < order + 1; i++ ) {
|
for( i = 0; i < order + 1; i++ ) {
|
||||||
corr[ i ] = ( opus_int32 )silk_CHECK_FIT32( silk_LSHIFT64( corr_QC[ i ], lsh ) );
|
corr[ i ] = (opus_int32)silk_CHECK_FIT32( silk_LSHIFT64( corr_QC[ i ], lsh ) );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for( i = 0; i < order + 1; i++ ) {
|
for( i = 0; i < order + 1; i++ ) {
|
||||||
corr[ i ] = ( opus_int32 )silk_CHECK_FIT32( silk_RSHIFT64( corr_QC[ i ], -lsh ) );
|
corr[ i ] = (opus_int32)silk_CHECK_FIT32( silk_RSHIFT64( corr_QC[ i ], -lsh ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
silk_assert( corr_QC[ 0 ] >= 0 ); /* If breaking, decrease QC*/
|
silk_assert( corr_QC[ 0 ] >= 0 ); /* If breaking, decrease QC*/
|
||||||
|
|
|
@ -37,29 +37,28 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
/* compute inverse of LPC prediction gain, and */
|
/* compute inverse of LPC prediction gain, and */
|
||||||
/* test if LPC coefficients are stable (all poles within unit circle) */
|
/* test if LPC coefficients are stable (all poles within unit circle) */
|
||||||
/* this code is based on silk_a2k_FLP() */
|
/* this code is based on silk_a2k_FLP() */
|
||||||
opus_int silk_LPC_inverse_pred_gain_FLP( /* O returns 1 if unstable, otherwise 0 */
|
silk_float silk_LPC_inverse_pred_gain_FLP( /* O return inverse prediction gain, energy domain */
|
||||||
silk_float *invGain, /* O inverse prediction gain, energy domain */
|
|
||||||
const silk_float *A, /* I prediction coefficients [order] */
|
const silk_float *A, /* I prediction coefficients [order] */
|
||||||
opus_int32 order /* I prediction order */
|
opus_int32 order /* I prediction order */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
opus_int k, n;
|
opus_int k, n;
|
||||||
double rc, rc_mult1, rc_mult2;
|
double invGain, rc, rc_mult1, rc_mult2;
|
||||||
silk_float Atmp[ 2 ][ SILK_MAX_ORDER_LPC ];
|
silk_float Atmp[ 2 ][ SILK_MAX_ORDER_LPC ];
|
||||||
silk_float *Aold, *Anew;
|
silk_float *Aold, *Anew;
|
||||||
|
|
||||||
Anew = Atmp[ order & 1 ];
|
Anew = Atmp[ order & 1 ];
|
||||||
silk_memcpy( Anew, A, order * sizeof(silk_float) );
|
silk_memcpy( Anew, A, order * sizeof(silk_float) );
|
||||||
|
|
||||||
*invGain = 1.0f;
|
invGain = 1.0;
|
||||||
for( k = order - 1; k > 0; k-- ) {
|
for( k = order - 1; k > 0; k-- ) {
|
||||||
rc = -Anew[ k ];
|
rc = -Anew[ k ];
|
||||||
if( rc > RC_THRESHOLD || rc < -RC_THRESHOLD ) {
|
if( rc > RC_THRESHOLD || rc < -RC_THRESHOLD ) {
|
||||||
return 1;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
rc_mult1 = 1.0f - rc * rc;
|
rc_mult1 = 1.0f - rc * rc;
|
||||||
rc_mult2 = 1.0f / rc_mult1;
|
rc_mult2 = 1.0f / rc_mult1;
|
||||||
*invGain *= (silk_float)rc_mult1;
|
invGain *= rc_mult1;
|
||||||
/* swap pointers */
|
/* swap pointers */
|
||||||
Aold = Anew;
|
Aold = Anew;
|
||||||
Anew = Atmp[ k & 1 ];
|
Anew = Atmp[ k & 1 ];
|
||||||
|
@ -69,9 +68,9 @@ opus_int silk_LPC_inverse_pred_gain_FLP( /* O returns 1 if unstable, other
|
||||||
}
|
}
|
||||||
rc = -Anew[ 0 ];
|
rc = -Anew[ 0 ];
|
||||||
if( rc > RC_THRESHOLD || rc < -RC_THRESHOLD ) {
|
if( rc > RC_THRESHOLD || rc < -RC_THRESHOLD ) {
|
||||||
return 1;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
rc_mult1 = 1.0f - rc * rc;
|
rc_mult1 = 1.0f - rc * rc;
|
||||||
*invGain *= (silk_float)rc_mult1;
|
invGain *= rc_mult1;
|
||||||
return 0;
|
return (silk_float)invGain;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,19 +39,14 @@ void silk_LTP_scale_ctrl_FLP(
|
||||||
{
|
{
|
||||||
opus_int round_loss;
|
opus_int round_loss;
|
||||||
|
|
||||||
/* 1st order high-pass filter */
|
|
||||||
/*g_HP(n) = g(n) - 0.5 * g(n-1) + 0.5 * g_HP(n-1);*/
|
|
||||||
psEnc->HPLTPredCodGain = silk_max_float( psEncCtrl->LTPredCodGain - 0.5f * psEnc->prevLTPredCodGain, 0.0f )
|
|
||||||
+ 0.5f * psEnc->HPLTPredCodGain;
|
|
||||||
psEnc->prevLTPredCodGain = psEncCtrl->LTPredCodGain;
|
|
||||||
|
|
||||||
/* Only scale if first frame in packet */
|
|
||||||
if( condCoding == CODE_INDEPENDENTLY ) {
|
if( condCoding == CODE_INDEPENDENTLY ) {
|
||||||
|
/* Only scale if first frame in packet */
|
||||||
round_loss = psEnc->sCmn.PacketLoss_perc + psEnc->sCmn.nFramesPerPacket;
|
round_loss = psEnc->sCmn.PacketLoss_perc + psEnc->sCmn.nFramesPerPacket;
|
||||||
psEnc->sCmn.indices.LTP_scaleIndex = (opus_int8)silk_LIMIT( round_loss * psEnc->HPLTPredCodGain * 0.1f, 0.0f, 2.0f );
|
psEnc->sCmn.indices.LTP_scaleIndex = (opus_int8)silk_LIMIT( round_loss * psEncCtrl->LTPredCodGain * 0.1f, 0.0f, 2.0f );
|
||||||
} else {
|
} else {
|
||||||
/* Default is minimum scaling */
|
/* Default is minimum scaling */
|
||||||
psEnc->sCmn.indices.LTP_scaleIndex = 0;
|
psEnc->sCmn.indices.LTP_scaleIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
psEncCtrl->LTP_scale = (silk_float)silk_LTPScales_table_Q14[ psEnc->sCmn.indices.LTP_scaleIndex ] / 16384.0f;
|
psEncCtrl->LTP_scale = (silk_float)silk_LTPScales_table_Q14[ psEnc->sCmn.indices.LTP_scaleIndex ] / 16384.0f;
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,8 +50,7 @@ void silk_bwexpander_FLP(
|
||||||
/* compute inverse of LPC prediction gain, and */
|
/* compute inverse of LPC prediction gain, and */
|
||||||
/* test if LPC coefficients are stable (all poles within unit circle) */
|
/* test if LPC coefficients are stable (all poles within unit circle) */
|
||||||
/* this code is based on silk_FLP_a2k() */
|
/* this code is based on silk_FLP_a2k() */
|
||||||
opus_int silk_LPC_inverse_pred_gain_FLP( /* O returns 1 if unstable, otherwise 0 */
|
silk_float silk_LPC_inverse_pred_gain_FLP( /* O return inverse prediction gain, energy domain */
|
||||||
silk_float *invGain, /* O inverse prediction gain, energy domain */
|
|
||||||
const silk_float *A, /* I prediction coefficients [order] */
|
const silk_float *A, /* I prediction coefficients [order] */
|
||||||
opus_int32 order /* I prediction order */
|
opus_int32 order /* I prediction order */
|
||||||
);
|
);
|
||||||
|
@ -108,9 +107,9 @@ void silk_insertion_sort_decreasing_FLP(
|
||||||
silk_float silk_burg_modified_FLP( /* O returns residual energy */
|
silk_float silk_burg_modified_FLP( /* O returns residual energy */
|
||||||
silk_float A[], /* O prediction coefficients (length order) */
|
silk_float A[], /* O prediction coefficients (length order) */
|
||||||
const silk_float x[], /* I input signal, length: nb_subfr*(D+L_sub) */
|
const silk_float x[], /* I input signal, length: nb_subfr*(D+L_sub) */
|
||||||
|
const silk_float minInvGain, /* I minimum inverse prediction gain */
|
||||||
const opus_int subfr_length, /* I input signal subframe length (incl. D preceeding samples) */
|
const opus_int subfr_length, /* I input signal subframe length (incl. D preceeding samples) */
|
||||||
const opus_int nb_subfr, /* I number of subframes stacked in x */
|
const opus_int nb_subfr, /* I number of subframes stacked in x */
|
||||||
const silk_float WhiteNoiseFrac, /* I fraction added to zero-lag autocorrelation */
|
|
||||||
const opus_int D /* I order */
|
const opus_int D /* I order */
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -30,29 +30,29 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "SigProc_FLP.h"
|
#include "SigProc_FLP.h"
|
||||||
|
#include "tuning_parameters.h"
|
||||||
|
#include "define.h"
|
||||||
|
|
||||||
#define MAX_FRAME_SIZE 384 /* subfr_length * nb_subfr = ( 0.005 * 16000 + 16 ) * 4 = 384*/
|
#define MAX_FRAME_SIZE 384 /* subfr_length * nb_subfr = ( 0.005 * 16000 + 16 ) * 4 = 384*/
|
||||||
#define MAX_NB_SUBFR 4
|
|
||||||
|
|
||||||
/* Compute reflection coefficients from input signal */
|
/* Compute reflection coefficients from input signal */
|
||||||
silk_float silk_burg_modified_FLP( /* O returns residual energy */
|
silk_float silk_burg_modified_FLP( /* O returns residual energy */
|
||||||
silk_float A[], /* O prediction coefficients (length order) */
|
silk_float A[], /* O prediction coefficients (length order) */
|
||||||
const silk_float x[], /* I input signal, length: nb_subfr*(D+L_sub) */
|
const silk_float x[], /* I input signal, length: nb_subfr*(D+L_sub) */
|
||||||
|
const silk_float minInvGain, /* I minimum inverse prediction gain */
|
||||||
const opus_int subfr_length, /* I input signal subframe length (incl. D preceeding samples) */
|
const opus_int subfr_length, /* I input signal subframe length (incl. D preceeding samples) */
|
||||||
const opus_int nb_subfr, /* I number of subframes stacked in x */
|
const opus_int nb_subfr, /* I number of subframes stacked in x */
|
||||||
const silk_float WhiteNoiseFrac, /* I fraction added to zero-lag autocorrelation */
|
|
||||||
const opus_int D /* I order */
|
const opus_int D /* I order */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
opus_int k, n, s;
|
opus_int k, n, s, reached_max_gain;
|
||||||
double C0, num, nrg_f, nrg_b, rc, Atmp, tmp1, tmp2;
|
double C0, invGain, num, nrg_f, nrg_b, rc, Atmp, tmp1, tmp2;
|
||||||
const silk_float *x_ptr;
|
const silk_float *x_ptr;
|
||||||
double C_first_row[ SILK_MAX_ORDER_LPC ], C_last_row[ SILK_MAX_ORDER_LPC ];
|
double C_first_row[ SILK_MAX_ORDER_LPC ], C_last_row[ SILK_MAX_ORDER_LPC ];
|
||||||
double CAf[ SILK_MAX_ORDER_LPC + 1 ], CAb[ SILK_MAX_ORDER_LPC + 1 ];
|
double CAf[ SILK_MAX_ORDER_LPC + 1 ], CAb[ SILK_MAX_ORDER_LPC + 1 ];
|
||||||
double Af[ SILK_MAX_ORDER_LPC ];
|
double Af[ SILK_MAX_ORDER_LPC ];
|
||||||
|
|
||||||
silk_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE );
|
silk_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE );
|
||||||
silk_assert( nb_subfr <= MAX_NB_SUBFR );
|
|
||||||
|
|
||||||
/* Compute autocorrelations, added over subframes */
|
/* Compute autocorrelations, added over subframes */
|
||||||
C0 = silk_energy_FLP( x, nb_subfr * subfr_length );
|
C0 = silk_energy_FLP( x, nb_subfr * subfr_length );
|
||||||
|
@ -66,8 +66,9 @@ silk_float silk_burg_modified_FLP( /* O returns residual energy
|
||||||
silk_memcpy( C_last_row, C_first_row, SILK_MAX_ORDER_LPC * sizeof( double ) );
|
silk_memcpy( C_last_row, C_first_row, SILK_MAX_ORDER_LPC * sizeof( double ) );
|
||||||
|
|
||||||
/* Initialize */
|
/* Initialize */
|
||||||
CAb[ 0 ] = CAf[ 0 ] = C0 + WhiteNoiseFrac * C0 + 1e-9f;
|
CAb[ 0 ] = CAf[ 0 ] = C0 + FIND_LPC_COND_FAC * C0 + 1e-9f;
|
||||||
|
invGain = 1.0f;
|
||||||
|
reached_max_gain = 0;
|
||||||
for( n = 0; n < D; n++ ) {
|
for( n = 0; n < D; n++ ) {
|
||||||
/* Update first row of correlation matrix (without first element) */
|
/* Update first row of correlation matrix (without first element) */
|
||||||
/* Update last row of correlation matrix (without last element, stored in reversed order) */
|
/* Update last row of correlation matrix (without last element, stored in reversed order) */
|
||||||
|
@ -93,7 +94,7 @@ silk_float silk_burg_modified_FLP( /* O returns residual energy
|
||||||
tmp2 = C_last_row[ n ];
|
tmp2 = C_last_row[ n ];
|
||||||
for( k = 0; k < n; k++ ) {
|
for( k = 0; k < n; k++ ) {
|
||||||
Atmp = Af[ k ];
|
Atmp = Af[ k ];
|
||||||
tmp1 += C_last_row[ n - k - 1 ] * Atmp;
|
tmp1 += C_last_row[ n - k - 1 ] * Atmp;
|
||||||
tmp2 += C_first_row[ n - k - 1 ] * Atmp;
|
tmp2 += C_first_row[ n - k - 1 ] * Atmp;
|
||||||
}
|
}
|
||||||
CAf[ n + 1 ] = tmp1;
|
CAf[ n + 1 ] = tmp1;
|
||||||
|
@ -116,6 +117,21 @@ silk_float silk_burg_modified_FLP( /* O returns residual energy
|
||||||
rc = -2.0 * num / ( nrg_f + nrg_b );
|
rc = -2.0 * num / ( nrg_f + nrg_b );
|
||||||
silk_assert( rc > -1.0 && rc < 1.0 );
|
silk_assert( rc > -1.0 && rc < 1.0 );
|
||||||
|
|
||||||
|
/* Update inverse prediction gain */
|
||||||
|
tmp1 = invGain * ( 1.0 - rc * rc );
|
||||||
|
if( tmp1 <= minInvGain ) {
|
||||||
|
/* Max prediction gain exceeded; set reflection coefficient such that max prediction gain is exactly hit */
|
||||||
|
rc = sqrt( 1.0 - minInvGain / invGain );
|
||||||
|
if( num > 0 ) {
|
||||||
|
/* Ensure adjusted reflection coefficients has the original sign */
|
||||||
|
rc = -rc;
|
||||||
|
}
|
||||||
|
invGain = minInvGain;
|
||||||
|
reached_max_gain = 1;
|
||||||
|
} else {
|
||||||
|
invGain = tmp1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Update the AR coefficients */
|
/* Update the AR coefficients */
|
||||||
for( k = 0; k < (n + 1) >> 1; k++ ) {
|
for( k = 0; k < (n + 1) >> 1; k++ ) {
|
||||||
tmp1 = Af[ k ];
|
tmp1 = Af[ k ];
|
||||||
|
@ -125,6 +141,14 @@ silk_float silk_burg_modified_FLP( /* O returns residual energy
|
||||||
}
|
}
|
||||||
Af[ n ] = rc;
|
Af[ n ] = rc;
|
||||||
|
|
||||||
|
if( reached_max_gain ) {
|
||||||
|
/* Reached max prediction gain; set remaining coefficients to zero and exit loop */
|
||||||
|
for( k = n + 1; k < D; k++ ) {
|
||||||
|
Af[ k ] = 0.0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* Update C * Af and C * Ab */
|
/* Update C * Af and C * Ab */
|
||||||
for( k = 0; k <= n + 1; k++ ) {
|
for( k = 0; k <= n + 1; k++ ) {
|
||||||
tmp1 = CAf[ k ];
|
tmp1 = CAf[ k ];
|
||||||
|
@ -133,16 +157,30 @@ silk_float silk_burg_modified_FLP( /* O returns residual energy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return residual energy */
|
if( reached_max_gain ) {
|
||||||
nrg_f = CAf[ 0 ];
|
/* Convert to silk_float */
|
||||||
tmp1 = 1.0;
|
for( k = 0; k < D; k++ ) {
|
||||||
for( k = 0; k < D; k++ ) {
|
A[ k ] = (silk_float)( -Af[ k ] );
|
||||||
Atmp = Af[ k ];
|
}
|
||||||
nrg_f += CAf[ k + 1 ] * Atmp;
|
/* Subtract energy of preceeding samples from C0 */
|
||||||
tmp1 += Atmp * Atmp;
|
for( s = 0; s < nb_subfr; s++ ) {
|
||||||
A[ k ] = (silk_float)(-Atmp);
|
C0 -= silk_energy_FLP( x + s * subfr_length, D );
|
||||||
|
}
|
||||||
|
/* Approximate residual energy */
|
||||||
|
nrg_f = C0 * invGain;
|
||||||
|
} else {
|
||||||
|
/* Compute residual energy and store coefficients as silk_float */
|
||||||
|
nrg_f = CAf[ 0 ];
|
||||||
|
tmp1 = 1.0;
|
||||||
|
for( k = 0; k < D; k++ ) {
|
||||||
|
Atmp = Af[ k ];
|
||||||
|
nrg_f += CAf[ k + 1 ] * Atmp;
|
||||||
|
tmp1 += Atmp * Atmp;
|
||||||
|
A[ k ] = (silk_float)(-Atmp);
|
||||||
|
}
|
||||||
|
nrg_f -= FIND_LPC_COND_FAC * C0 * tmp1;
|
||||||
}
|
}
|
||||||
nrg_f -= WhiteNoiseFrac * C0 * tmp1;
|
|
||||||
|
|
||||||
|
/* Return residual energy */
|
||||||
return (silk_float)nrg_f;
|
return (silk_float)nrg_f;
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,8 +104,8 @@ opus_int silk_encode_frame_FLP(
|
||||||
psEnc->sCmn.indices.Seed = psEnc->sCmn.frameCounter++ & 3;
|
psEnc->sCmn.indices.Seed = psEnc->sCmn.frameCounter++ & 3;
|
||||||
|
|
||||||
/**************************************************************/
|
/**************************************************************/
|
||||||
/* Setup Input Pointers, and insert frame in input buffer */
|
/* Set up Input Pointers, and insert frame in input buffer */
|
||||||
/*************************************************************/
|
/**************************************************************/
|
||||||
/* pointers aligned with start of frame to encode */
|
/* pointers aligned with start of frame to encode */
|
||||||
x_frame = psEnc->x_buf + psEnc->sCmn.ltp_mem_length; /* start of frame to encode */
|
x_frame = psEnc->x_buf + psEnc->sCmn.ltp_mem_length; /* start of frame to encode */
|
||||||
res_pitch_frame = res_pitch + psEnc->sCmn.ltp_mem_length; /* start of pitch LPC residual frame */
|
res_pitch_frame = res_pitch + psEnc->sCmn.ltp_mem_length; /* start of pitch LPC residual frame */
|
||||||
|
@ -157,7 +157,7 @@ opus_int silk_encode_frame_FLP(
|
||||||
silk_LBRR_encode_FLP( psEnc, &sEncCtrl, xfw, condCoding );
|
silk_LBRR_encode_FLP( psEnc, &sEncCtrl, xfw, condCoding );
|
||||||
|
|
||||||
/* Loop over quantizer and entroy coding to control bitrate */
|
/* Loop over quantizer and entroy coding to control bitrate */
|
||||||
maxIter = 5;
|
maxIter = 6;
|
||||||
gainMult_Q8 = SILK_FIX_CONST( 1, 8 );
|
gainMult_Q8 = SILK_FIX_CONST( 1, 8 );
|
||||||
found_lower = 0;
|
found_lower = 0;
|
||||||
found_upper = 0;
|
found_upper = 0;
|
||||||
|
|
|
@ -29,73 +29,63 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "define.h"
|
||||||
#include "main_FLP.h"
|
#include "main_FLP.h"
|
||||||
#include "tuning_parameters.h"
|
#include "tuning_parameters.h"
|
||||||
|
|
||||||
|
/* LPC analysis */
|
||||||
void silk_find_LPC_FLP(
|
void silk_find_LPC_FLP(
|
||||||
|
silk_encoder_state *psEncC, /* I/O Encoder state */
|
||||||
opus_int16 NLSF_Q15[], /* O NLSFs */
|
opus_int16 NLSF_Q15[], /* O NLSFs */
|
||||||
opus_int8 *interpIndex, /* O NLSF interp. index for NLSF interp. */
|
|
||||||
const opus_int16 prev_NLSFq_Q15[], /* I Previous NLSFs, for NLSF interpolation */
|
|
||||||
const opus_int useInterpNLSFs, /* I Flag */
|
|
||||||
const opus_int firstFrameAfterReset, /* I Flag */
|
|
||||||
const opus_int LPC_order, /* I LPC order */
|
|
||||||
const silk_float x[], /* I Input signal */
|
const silk_float x[], /* I Input signal */
|
||||||
const opus_int subfr_length, /* I Subframe length incl preceeding samples */
|
const silk_float minInvGain /* I Inverse of max prediction gain */
|
||||||
const opus_int nb_subfr /* I Number of subframes */
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
opus_int k;
|
opus_int k, subfr_length;
|
||||||
silk_float a[ MAX_LPC_ORDER ];
|
silk_float a[ MAX_LPC_ORDER ];
|
||||||
|
|
||||||
/* Used only for NLSF interpolation */
|
/* Used only for NLSF interpolation */
|
||||||
double res_nrg, res_nrg_2nd, res_nrg_interp;
|
silk_float res_nrg, res_nrg_2nd, res_nrg_interp;
|
||||||
opus_int16 NLSF0_Q15[ MAX_LPC_ORDER ];
|
opus_int16 NLSF0_Q15[ MAX_LPC_ORDER ];
|
||||||
silk_float a_tmp[ MAX_LPC_ORDER ];
|
silk_float a_tmp[ MAX_LPC_ORDER ];
|
||||||
silk_float LPC_res[ ( MAX_FRAME_LENGTH + MAX_NB_SUBFR * MAX_LPC_ORDER ) / 2 ];
|
silk_float LPC_res[ MAX_FRAME_LENGTH + MAX_NB_SUBFR * MAX_LPC_ORDER ];
|
||||||
|
|
||||||
|
subfr_length = psEncC->subfr_length + psEncC->predictLPCOrder;
|
||||||
|
|
||||||
/* Default: No interpolation */
|
/* Default: No interpolation */
|
||||||
*interpIndex = 4;
|
psEncC->indices.NLSFInterpCoef_Q2 = 4;
|
||||||
|
|
||||||
/* Burg AR analysis for the full frame */
|
/* Burg AR analysis for the full frame */
|
||||||
res_nrg = silk_burg_modified_FLP( a, x, subfr_length, nb_subfr, FIND_LPC_COND_FAC, LPC_order );
|
res_nrg = silk_burg_modified_FLP( a, x, minInvGain, subfr_length, psEncC->nb_subfr, psEncC->predictLPCOrder );
|
||||||
|
|
||||||
if( firstFrameAfterReset ) {
|
if( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) {
|
||||||
silk_bwexpander_FLP( a, LPC_order, FIND_LPC_CHIRP_FIRST_FRAME );
|
|
||||||
} else {
|
|
||||||
silk_bwexpander_FLP( a_tmp, LPC_order, FIND_LPC_CHIRP );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( useInterpNLSFs && !firstFrameAfterReset && nb_subfr == MAX_NB_SUBFR ) {
|
|
||||||
/* Optimal solution for last 10 ms; subtract residual energy here, as that's easier than */
|
/* Optimal solution for last 10 ms; subtract residual energy here, as that's easier than */
|
||||||
/* adding it to the residual energy of the first 10 ms in each iteration of the search below */
|
/* adding it to the residual energy of the first 10 ms in each iteration of the search below */
|
||||||
res_nrg -= silk_burg_modified_FLP( a_tmp, x + ( MAX_NB_SUBFR / 2 ) * subfr_length,
|
res_nrg -= silk_burg_modified_FLP( a_tmp, x + ( MAX_NB_SUBFR / 2 ) * subfr_length, minInvGain, subfr_length, MAX_NB_SUBFR / 2, psEncC->predictLPCOrder );
|
||||||
subfr_length, MAX_NB_SUBFR / 2, FIND_LPC_COND_FAC, LPC_order );
|
|
||||||
|
|
||||||
silk_bwexpander_FLP( a_tmp, LPC_order, FIND_LPC_CHIRP );
|
|
||||||
|
|
||||||
/* Convert to NLSFs */
|
/* Convert to NLSFs */
|
||||||
silk_A2NLSF_FLP( NLSF_Q15, a_tmp, LPC_order );
|
silk_A2NLSF_FLP( NLSF_Q15, a_tmp, psEncC->predictLPCOrder );
|
||||||
|
|
||||||
/* Search over interpolation indices to find the one with lowest residual energy */
|
/* Search over interpolation indices to find the one with lowest residual energy */
|
||||||
res_nrg_2nd = silk_float_MAX;
|
res_nrg_2nd = silk_float_MAX;
|
||||||
for( k = 3; k >= 0; k-- ) {
|
for( k = 3; k >= 0; k-- ) {
|
||||||
/* Interpolate NLSFs for first half */
|
/* Interpolate NLSFs for first half */
|
||||||
silk_interpolate( NLSF0_Q15, prev_NLSFq_Q15, NLSF_Q15, k, LPC_order );
|
silk_interpolate( NLSF0_Q15, psEncC->prev_NLSFq_Q15, NLSF_Q15, k, psEncC->predictLPCOrder );
|
||||||
|
|
||||||
/* Convert to LPC for residual energy evaluation */
|
/* Convert to LPC for residual energy evaluation */
|
||||||
silk_NLSF2A_FLP( a_tmp, NLSF0_Q15, LPC_order );
|
silk_NLSF2A_FLP( a_tmp, NLSF0_Q15, psEncC->predictLPCOrder );
|
||||||
|
|
||||||
/* Calculate residual energy with LSF interpolation */
|
/* Calculate residual energy with LSF interpolation */
|
||||||
silk_LPC_analysis_filter_FLP( LPC_res, a_tmp, x, 2 * subfr_length, LPC_order );
|
silk_LPC_analysis_filter_FLP( LPC_res, a_tmp, x, 2 * subfr_length, psEncC->predictLPCOrder );
|
||||||
res_nrg_interp =
|
res_nrg_interp = (silk_float)(
|
||||||
silk_energy_FLP( LPC_res + LPC_order, subfr_length - LPC_order ) +
|
silk_energy_FLP( LPC_res + psEncC->predictLPCOrder, subfr_length - psEncC->predictLPCOrder ) +
|
||||||
silk_energy_FLP( LPC_res + LPC_order + subfr_length, subfr_length - LPC_order );
|
silk_energy_FLP( LPC_res + psEncC->predictLPCOrder + subfr_length, subfr_length - psEncC->predictLPCOrder ) );
|
||||||
|
|
||||||
/* Determine whether current interpolated NLSFs are best so far */
|
/* Determine whether current interpolated NLSFs are best so far */
|
||||||
if( res_nrg_interp < res_nrg ) {
|
if( res_nrg_interp < res_nrg ) {
|
||||||
/* Interpolation has lower residual energy */
|
/* Interpolation has lower residual energy */
|
||||||
res_nrg = res_nrg_interp;
|
res_nrg = res_nrg_interp;
|
||||||
*interpIndex = (opus_int8)k;
|
psEncC->indices.NLSFInterpCoef_Q2 = (opus_int8)k;
|
||||||
} else if( res_nrg_interp > res_nrg_2nd ) {
|
} else if( res_nrg_interp > res_nrg_2nd ) {
|
||||||
/* No reason to continue iterating - residual energies will continue to climb */
|
/* No reason to continue iterating - residual energies will continue to climb */
|
||||||
break;
|
break;
|
||||||
|
@ -104,10 +94,11 @@ void silk_find_LPC_FLP(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( *interpIndex == 4 ) {
|
if( psEncC->indices.NLSFInterpCoef_Q2 == 4 ) {
|
||||||
/* NLSF interpolation is currently inactive, calculate NLSFs from full frame AR coefficients */
|
/* NLSF interpolation is currently inactive, calculate NLSFs from full frame AR coefficients */
|
||||||
silk_A2NLSF_FLP( NLSF_Q15, a, LPC_order );
|
silk_A2NLSF_FLP( NLSF_Q15, a, psEncC->predictLPCOrder );
|
||||||
}
|
}
|
||||||
|
|
||||||
silk_assert( *interpIndex == 4 || ( useInterpNLSFs && !firstFrameAfterReset && nb_subfr == MAX_NB_SUBFR ) );
|
silk_assert( psEncC->indices.NLSFInterpCoef_Q2 == 4 ||
|
||||||
|
( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) );
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ void silk_find_pitch_lags_FLP(
|
||||||
silk_float *Wsig_ptr;
|
silk_float *Wsig_ptr;
|
||||||
|
|
||||||
/******************************************/
|
/******************************************/
|
||||||
/* Setup buffer lengths etc based on Fs */
|
/* Set up buffer lengths etc based on Fs */
|
||||||
/******************************************/
|
/******************************************/
|
||||||
buf_len = psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length + psEnc->sCmn.ltp_mem_length;
|
buf_len = psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length + psEnc->sCmn.ltp_mem_length;
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@ void silk_find_pred_coefs_FLP(
|
||||||
opus_int16 NLSF_Q15[ MAX_LPC_ORDER ];
|
opus_int16 NLSF_Q15[ MAX_LPC_ORDER ];
|
||||||
const silk_float *x_ptr;
|
const silk_float *x_ptr;
|
||||||
silk_float *x_pre_ptr, LPC_in_pre[ MAX_NB_SUBFR * MAX_LPC_ORDER + MAX_FRAME_LENGTH ];
|
silk_float *x_pre_ptr, LPC_in_pre[ MAX_NB_SUBFR * MAX_LPC_ORDER + MAX_FRAME_LENGTH ];
|
||||||
|
silk_float minInvGain;
|
||||||
|
|
||||||
/* Weighting for weighted least squares */
|
/* Weighting for weighted least squares */
|
||||||
for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
|
for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
|
||||||
|
@ -74,7 +75,6 @@ void silk_find_pred_coefs_FLP(
|
||||||
/* Create LTP residual */
|
/* Create LTP residual */
|
||||||
silk_LTP_analysis_filter_FLP( LPC_in_pre, x - psEnc->sCmn.predictLPCOrder, psEncCtrl->LTPCoef,
|
silk_LTP_analysis_filter_FLP( LPC_in_pre, x - psEnc->sCmn.predictLPCOrder, psEncCtrl->LTPCoef,
|
||||||
psEncCtrl->pitchL, invGains, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder );
|
psEncCtrl->pitchL, invGains, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder );
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/************/
|
/************/
|
||||||
/* UNVOICED */
|
/* UNVOICED */
|
||||||
|
@ -88,15 +88,20 @@ void silk_find_pred_coefs_FLP(
|
||||||
x_pre_ptr += psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder;
|
x_pre_ptr += psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder;
|
||||||
x_ptr += psEnc->sCmn.subfr_length;
|
x_ptr += psEnc->sCmn.subfr_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
silk_memset( psEncCtrl->LTPCoef, 0, psEnc->sCmn.nb_subfr * LTP_ORDER * sizeof( silk_float ) );
|
silk_memset( psEncCtrl->LTPCoef, 0, psEnc->sCmn.nb_subfr * LTP_ORDER * sizeof( silk_float ) );
|
||||||
psEncCtrl->LTPredCodGain = 0.0f;
|
psEncCtrl->LTPredCodGain = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Limit on total predictive coding gain */
|
||||||
|
if( psEnc->sCmn.first_frame_after_reset ) {
|
||||||
|
minInvGain = 1.0f / MAX_PREDICTION_POWER_GAIN_AFTER_RESET;
|
||||||
|
} else {
|
||||||
|
minInvGain = (silk_float)powf( 2, psEncCtrl->LTPredCodGain / 3 ) / MAX_PREDICTION_POWER_GAIN;
|
||||||
|
minInvGain /= 0.1f + 0.9f * psEncCtrl->coding_quality;
|
||||||
|
}
|
||||||
|
|
||||||
/* LPC_in_pre contains the LTP-filtered input for voiced, and the unfiltered input for unvoiced */
|
/* LPC_in_pre contains the LTP-filtered input for voiced, and the unfiltered input for unvoiced */
|
||||||
silk_find_LPC_FLP( NLSF_Q15, &psEnc->sCmn.indices.NLSFInterpCoef_Q2, psEnc->sCmn.prev_NLSFq_Q15,
|
silk_find_LPC_FLP( &psEnc->sCmn, NLSF_Q15, LPC_in_pre, minInvGain );
|
||||||
psEnc->sCmn.useInterpolatedNLSFs, psEnc->sCmn.first_frame_after_reset, psEnc->sCmn.predictLPCOrder,
|
|
||||||
LPC_in_pre, psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder, psEnc->sCmn.nb_subfr );
|
|
||||||
|
|
||||||
/* Quantize LSFs */
|
/* Quantize LSFs */
|
||||||
silk_process_NLSFs_FLP( &psEnc->sCmn, psEncCtrl->PredCoef, NLSF_Q15, psEnc->sCmn.prev_NLSFq_Q15 );
|
silk_process_NLSFs_FLP( &psEnc->sCmn, psEncCtrl->PredCoef, NLSF_Q15, psEnc->sCmn.prev_NLSFq_Q15 );
|
||||||
|
|
|
@ -143,15 +143,10 @@ void silk_find_pred_coefs_FLP(
|
||||||
|
|
||||||
/* LPC analysis */
|
/* LPC analysis */
|
||||||
void silk_find_LPC_FLP(
|
void silk_find_LPC_FLP(
|
||||||
|
silk_encoder_state *psEncC, /* I/O Encoder state */
|
||||||
opus_int16 NLSF_Q15[], /* O NLSFs */
|
opus_int16 NLSF_Q15[], /* O NLSFs */
|
||||||
opus_int8 *interpIndex, /* O NLSF interp. index for NLSF interp. */
|
|
||||||
const opus_int16 prev_NLSFq_Q15[], /* I Previous NLSFs, for NLSF interpolation */
|
|
||||||
const opus_int useInterpNLSFs, /* I Flag */
|
|
||||||
const opus_int firstFrameAfterReset, /* I Flag */
|
|
||||||
const opus_int LPC_order, /* I LPC order */
|
|
||||||
const silk_float x[], /* I Input signal */
|
const silk_float x[], /* I Input signal */
|
||||||
const opus_int subfr_length, /* I Subframe length incl preceeding samples */
|
const silk_float minInvGain /* I Prediction gain from LTP (dB) */
|
||||||
const opus_int nb_subfr /* I Number of subframes */
|
|
||||||
);
|
);
|
||||||
|
|
||||||
/* LTP analysis */
|
/* LTP analysis */
|
||||||
|
|
|
@ -151,7 +151,7 @@ void silk_noise_shape_analysis_FLP(
|
||||||
psEncCtrl->input_quality = 0.5f * ( psEnc->sCmn.input_quality_bands_Q15[ 0 ] + psEnc->sCmn.input_quality_bands_Q15[ 1 ] ) * ( 1.0f / 32768.0f );
|
psEncCtrl->input_quality = 0.5f * ( psEnc->sCmn.input_quality_bands_Q15[ 0 ] + psEnc->sCmn.input_quality_bands_Q15[ 1 ] ) * ( 1.0f / 32768.0f );
|
||||||
|
|
||||||
/* Coding quality level, between 0.0 and 1.0 */
|
/* Coding quality level, between 0.0 and 1.0 */
|
||||||
psEncCtrl->coding_quality = silk_sigmoid( 0.25f * ( SNR_adj_dB - 18.0f ) );
|
psEncCtrl->coding_quality = silk_sigmoid( 0.25f * ( SNR_adj_dB - 20.0f ) );
|
||||||
|
|
||||||
if( psEnc->sCmn.useCBR == 0 ) {
|
if( psEnc->sCmn.useCBR == 0 ) {
|
||||||
/* Reduce coding SNR during low speech activity */
|
/* Reduce coding SNR during low speech activity */
|
||||||
|
@ -274,8 +274,8 @@ void silk_noise_shape_analysis_FLP(
|
||||||
silk_bwexpander_FLP( &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder, BWExp1 );
|
silk_bwexpander_FLP( &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder, BWExp1 );
|
||||||
|
|
||||||
/* Ratio of prediction gains, in energy domain */
|
/* Ratio of prediction gains, in energy domain */
|
||||||
silk_LPC_inverse_pred_gain_FLP( &pre_nrg, &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder );
|
pre_nrg = silk_LPC_inverse_pred_gain_FLP( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder );
|
||||||
silk_LPC_inverse_pred_gain_FLP( &nrg, &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder );
|
nrg = silk_LPC_inverse_pred_gain_FLP( &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder );
|
||||||
psEncCtrl->GainsPre[ k ] = 1.0f - 0.7f * ( 1.0f - pre_nrg / nrg );
|
psEncCtrl->GainsPre[ k ] = 1.0f - 0.7f * ( 1.0f - pre_nrg / nrg );
|
||||||
|
|
||||||
/* Convert to monic warped prediction coefficients and limit absolute values */
|
/* Convert to monic warped prediction coefficients and limit absolute values */
|
||||||
|
|
|
@ -115,7 +115,7 @@ opus_int silk_pitch_analysis_core_FLP( /* O Voicing estimate: 0 voiced,
|
||||||
silk_assert( search_thres1 >= 0.0f && search_thres1 <= 1.0f );
|
silk_assert( search_thres1 >= 0.0f && search_thres1 <= 1.0f );
|
||||||
silk_assert( search_thres2 >= 0.0f && search_thres2 <= 1.0f );
|
silk_assert( search_thres2 >= 0.0f && search_thres2 <= 1.0f );
|
||||||
|
|
||||||
/* Setup frame lengths max / min lag for the sampling frequency */
|
/* Set up frame lengths max / min lag for the sampling frequency */
|
||||||
frame_length = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * Fs_kHz;
|
frame_length = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * Fs_kHz;
|
||||||
frame_length_4kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 4;
|
frame_length_4kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 4;
|
||||||
frame_length_8kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 8;
|
frame_length_8kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 8;
|
||||||
|
@ -322,7 +322,7 @@ opus_int silk_pitch_analysis_core_FLP( /* O Voicing estimate: 0 voiced,
|
||||||
prevLag_log2 = 0;
|
prevLag_log2 = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup stage 2 codebook based on number of subframes */
|
/* Set up stage 2 codebook based on number of subframes */
|
||||||
if( nb_subfr == PE_MAX_NB_SUBFR ) {
|
if( nb_subfr == PE_MAX_NB_SUBFR ) {
|
||||||
cbk_size = PE_NB_CBKS_STAGE2_EXT;
|
cbk_size = PE_NB_CBKS_STAGE2_EXT;
|
||||||
Lag_CB_ptr = &silk_CB_lags_stage2[ 0 ][ 0 ];
|
Lag_CB_ptr = &silk_CB_lags_stage2[ 0 ][ 0 ];
|
||||||
|
@ -419,7 +419,7 @@ opus_int silk_pitch_analysis_core_FLP( /* O Voicing estimate: 0 voiced,
|
||||||
silk_assert( lag == silk_SAT16( lag ) );
|
silk_assert( lag == silk_SAT16( lag ) );
|
||||||
contour_bias = PE_FLATCONTOUR_BIAS / lag;
|
contour_bias = PE_FLATCONTOUR_BIAS / lag;
|
||||||
|
|
||||||
/* Setup cbk parameters acording to complexity setting and frame length */
|
/* Set up cbk parameters acording to complexity setting and frame length */
|
||||||
if( nb_subfr == PE_MAX_NB_SUBFR ) {
|
if( nb_subfr == PE_MAX_NB_SUBFR ) {
|
||||||
nb_cbk_search = (opus_int)silk_nb_cbk_searchs_stage3[ complexity ];
|
nb_cbk_search = (opus_int)silk_nb_cbk_searchs_stage3[ complexity ];
|
||||||
cbk_size = PE_NB_CBKS_STAGE3_MAX;
|
cbk_size = PE_NB_CBKS_STAGE3_MAX;
|
||||||
|
|
|
@ -108,7 +108,7 @@ void silk_prefilter_FLP(
|
||||||
silk_float HarmShapeFIR[ 3 ];
|
silk_float HarmShapeFIR[ 3 ];
|
||||||
silk_float st_res[ MAX_SUB_FRAME_LENGTH + MAX_LPC_ORDER ];
|
silk_float st_res[ MAX_SUB_FRAME_LENGTH + MAX_LPC_ORDER ];
|
||||||
|
|
||||||
/* Setup pointers */
|
/* Set up pointers */
|
||||||
px = x;
|
px = x;
|
||||||
pxw = xw;
|
pxw = xw;
|
||||||
lag = P->lagPrev;
|
lag = P->lagPrev;
|
||||||
|
|
|
@ -64,7 +64,7 @@ void silk_process_gains_FLP(
|
||||||
|
|
||||||
/* Prepare gains for noise shaping quantization */
|
/* Prepare gains for noise shaping quantization */
|
||||||
for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
|
for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
|
||||||
pGains_Q16[ k ] = ( opus_int32 ) ( psEncCtrl->Gains[ k ] * 65536.0f );
|
pGains_Q16[ k ] = (opus_int32)( psEncCtrl->Gains[ k ] * 65536.0f );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save unquantized gains and gain Index */
|
/* Save unquantized gains and gain Index */
|
||||||
|
|
|
@ -72,10 +72,6 @@ typedef struct {
|
||||||
/* Buffer for find pitch and noise shape analysis */
|
/* Buffer for find pitch and noise shape analysis */
|
||||||
silk_float x_buf[ 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ];/* Buffer for find pitch and noise shape analysis */
|
silk_float x_buf[ 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ];/* Buffer for find pitch and noise shape analysis */
|
||||||
silk_float LTPCorr; /* Normalized correlation from pitch lag estimator */
|
silk_float LTPCorr; /* Normalized correlation from pitch lag estimator */
|
||||||
|
|
||||||
/* Parameters for LTP scaling control */
|
|
||||||
silk_float prevLTPredCodGain;
|
|
||||||
silk_float HPLTPredCodGain;
|
|
||||||
} silk_encoder_state_FLP;
|
} silk_encoder_state_FLP;
|
||||||
|
|
||||||
/************************/
|
/************************/
|
||||||
|
|
|
@ -102,7 +102,7 @@ void silk_NSQ_wrapper_FLP(
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
opus_int i, j;
|
opus_int i, j;
|
||||||
opus_int16 x_16[ MAX_FRAME_LENGTH ];
|
opus_int32 x_Q10[ MAX_FRAME_LENGTH ];
|
||||||
opus_int32 Gains_Q16[ MAX_NB_SUBFR ];
|
opus_int32 Gains_Q16[ MAX_NB_SUBFR ];
|
||||||
silk_DWORD_ALIGN opus_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ];
|
silk_DWORD_ALIGN opus_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ];
|
||||||
opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ];
|
opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ];
|
||||||
|
@ -133,12 +133,12 @@ void silk_NSQ_wrapper_FLP(
|
||||||
|
|
||||||
/* prediction and coding parameters */
|
/* prediction and coding parameters */
|
||||||
for( i = 0; i < psEnc->sCmn.nb_subfr * LTP_ORDER; i++ ) {
|
for( i = 0; i < psEnc->sCmn.nb_subfr * LTP_ORDER; i++ ) {
|
||||||
LTPCoef_Q14[ i ] = ( opus_int16 )silk_float2int( psEncCtrl->LTPCoef[ i ] * 16384.0f );
|
LTPCoef_Q14[ i ] = (opus_int16)silk_float2int( psEncCtrl->LTPCoef[ i ] * 16384.0f );
|
||||||
}
|
}
|
||||||
|
|
||||||
for( j = 0; j < 2; j++ ) {
|
for( j = 0; j < 2; j++ ) {
|
||||||
for( i = 0; i < psEnc->sCmn.predictLPCOrder; i++ ) {
|
for( i = 0; i < psEnc->sCmn.predictLPCOrder; i++ ) {
|
||||||
PredCoef_Q12[ j ][ i ] = ( opus_int16 )silk_float2int( psEncCtrl->PredCoef[ j ][ i ] * 4096.0f );
|
PredCoef_Q12[ j ][ i ] = (opus_int16)silk_float2int( psEncCtrl->PredCoef[ j ][ i ] * 4096.0f );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,14 +154,16 @@ void silk_NSQ_wrapper_FLP(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert input to fix */
|
/* Convert input to fix */
|
||||||
silk_float2short_array( x_16, x, psEnc->sCmn.frame_length );
|
for( i = 0; i < psEnc->sCmn.frame_length; i++ ) {
|
||||||
|
x_Q10[ i ] = silk_float2int( 1024.0 * x[ i ] );
|
||||||
|
}
|
||||||
|
|
||||||
/* Call NSQ */
|
/* Call NSQ */
|
||||||
if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
|
if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
|
||||||
silk_NSQ_del_dec( &psEnc->sCmn, psNSQ, psIndices, x_16, pulses, PredCoef_Q12[ 0 ], LTPCoef_Q14,
|
silk_NSQ_del_dec( &psEnc->sCmn, psNSQ, psIndices, x_Q10, pulses, PredCoef_Q12[ 0 ], LTPCoef_Q14,
|
||||||
AR2_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, psEncCtrl->pitchL, Lambda_Q10, LTP_scale_Q14 );
|
AR2_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, psEncCtrl->pitchL, Lambda_Q10, LTP_scale_Q14 );
|
||||||
} else {
|
} else {
|
||||||
silk_NSQ( &psEnc->sCmn, psNSQ, psIndices, x_16, pulses, PredCoef_Q12[ 0 ], LTPCoef_Q14,
|
silk_NSQ( &psEnc->sCmn, psNSQ, psIndices, x_Q10, pulses, PredCoef_Q12[ 0 ], LTPCoef_Q14,
|
||||||
AR2_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, psEncCtrl->pitchL, Lambda_Q10, LTP_scale_Q14 );
|
AR2_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, psEncCtrl->pitchL, Lambda_Q10, LTP_scale_Q14 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,6 @@ void silk_interpolate(
|
||||||
silk_assert( ifact_Q2 <= 4 );
|
silk_assert( ifact_Q2 <= 4 );
|
||||||
|
|
||||||
for( i = 0; i < d; i++ ) {
|
for( i = 0; i < d; i++ ) {
|
||||||
xi[ i ] = ( opus_int16 )silk_ADD_RSHIFT( x0[ i ], silk_SMULBB( x1[ i ] - x0[ i ], ifact_Q2 ), 2 );
|
xi[ i ] = (opus_int16)silk_ADD_RSHIFT( x0[ i ], silk_SMULBB( x1[ i ] - x0[ i ], ifact_Q2 ), 2 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,8 +25,12 @@ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
#ifndef SILK_API_C_H
|
#ifndef SILK_MACROS_H
|
||||||
#define SILK_API_C_H
|
#define SILK_MACROS_H
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/* This is an inline header file for general platform. */
|
/* This is an inline header file for general platform. */
|
||||||
|
|
||||||
|
@ -128,5 +132,5 @@ static inline opus_int32 silk_CLZ32(opus_int32 in32)
|
||||||
#endif
|
#endif
|
||||||
#define matrix_c_adr(Matrix_base_adr, row, column, M) (Matrix_base_adr + ((row)+(M)*(column)))
|
#define matrix_c_adr(Matrix_base_adr, row, column, M) (Matrix_base_adr + ((row)+(M)*(column)))
|
||||||
|
|
||||||
#endif /* SILK_API_C_H */
|
#endif /* SILK_MACROS_H */
|
||||||
|
|
||||||
|
|
|
@ -38,9 +38,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "entenc.h"
|
#include "entenc.h"
|
||||||
#include "entdec.h"
|
#include "entdec.h"
|
||||||
|
|
||||||
/* Simple way to make [8000, 12000, 16000, 24000, 48000] to [0,1,2,3,4] */
|
|
||||||
#define rateID(R) ( ( ( ((R)>>12) - ((R)>16000) ) >> ((R)>24000) ) - 1 )
|
|
||||||
|
|
||||||
/* Convert Left/Right stereo signal to adaptive Mid/Side representation */
|
/* Convert Left/Right stereo signal to adaptive Mid/Side representation */
|
||||||
void silk_stereo_LR_to_MS(
|
void silk_stereo_LR_to_MS(
|
||||||
stereo_enc_state *state, /* I/O State */
|
stereo_enc_state *state, /* I/O State */
|
||||||
|
@ -232,7 +229,7 @@ void silk_NSQ(
|
||||||
const silk_encoder_state *psEncC, /* I/O Encoder State */
|
const silk_encoder_state *psEncC, /* I/O Encoder State */
|
||||||
silk_nsq_state *NSQ, /* I/O NSQ state */
|
silk_nsq_state *NSQ, /* I/O NSQ state */
|
||||||
SideInfoIndices *psIndices, /* I/O Quantization Indices */
|
SideInfoIndices *psIndices, /* I/O Quantization Indices */
|
||||||
const opus_int16 x[], /* I Prefiltered input signal */
|
const opus_int32 x_Q10[], /* I Prefiltered input signal */
|
||||||
opus_int8 pulses[], /* O Quantized pulse signal */
|
opus_int8 pulses[], /* O Quantized pulse signal */
|
||||||
const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
|
const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
|
||||||
const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
|
const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
|
||||||
|
@ -251,7 +248,7 @@ void silk_NSQ_del_dec(
|
||||||
const silk_encoder_state *psEncC, /* I/O Encoder State */
|
const silk_encoder_state *psEncC, /* I/O Encoder State */
|
||||||
silk_nsq_state *NSQ, /* I/O NSQ state */
|
silk_nsq_state *NSQ, /* I/O NSQ state */
|
||||||
SideInfoIndices *psIndices, /* I/O Quantization Indices */
|
SideInfoIndices *psIndices, /* I/O Quantization Indices */
|
||||||
const opus_int16 x[], /* I Prefiltered input signal */
|
const opus_int32 x_Q10[], /* I Prefiltered input signal */
|
||||||
opus_int8 pulses[], /* O Quantized pulse signal */
|
opus_int8 pulses[], /* O Quantized pulse signal */
|
||||||
const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
|
const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
|
||||||
const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
|
const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
|
||||||
|
|
|
@ -59,7 +59,7 @@ void silk_quant_LTP_gains(
|
||||||
cbk_ptr_Q7 = silk_LTP_vq_ptrs_Q7[ k ];
|
cbk_ptr_Q7 = silk_LTP_vq_ptrs_Q7[ k ];
|
||||||
cbk_size = silk_LTP_vq_sizes[ k ];
|
cbk_size = silk_LTP_vq_sizes[ k ];
|
||||||
|
|
||||||
/* Setup pointer to first subframe */
|
/* Set up pointer to first subframe */
|
||||||
W_Q18_ptr = W_Q18;
|
W_Q18_ptr = W_Q18;
|
||||||
b_Q14_ptr = B_Q14;
|
b_Q14_ptr = B_Q14;
|
||||||
|
|
||||||
|
|
132
silk/resampler.c
132
silk/resampler.c
|
@ -29,30 +29,46 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Matrix of resampling methods used:
|
/*
|
||||||
|
* Matrix of resampling methods used:
|
||||||
* Fs_out (kHz)
|
* Fs_out (kHz)
|
||||||
* 8 12 16 24 48
|
* 8 12 16 24 48
|
||||||
*
|
*
|
||||||
* 8 C UF U UF UF
|
* 8 C UF U UF UF
|
||||||
* 12 AF C UF U UF
|
* 12 AF C UF U UF
|
||||||
* Fs_in (kHz) 16 D AF C UF UF
|
* Fs_in (kHz) 16 D AF C UF UF
|
||||||
* 24 AIF D AF C U
|
* 24 AF D AF C U
|
||||||
* 48 DAF DAF AF D C
|
* 48 AF AF AF D C
|
||||||
*
|
|
||||||
* default method: UF
|
|
||||||
*
|
*
|
||||||
* C -> Copy (no resampling)
|
* C -> Copy (no resampling)
|
||||||
* D -> Allpass-based 2x downsampling
|
* D -> Allpass-based 2x downsampling
|
||||||
* U -> Allpass-based 2x upsampling
|
* U -> Allpass-based 2x upsampling
|
||||||
* DAF -> Allpass-based 2x downsampling followed by AR2 filter followed by FIR interpolation
|
|
||||||
* UF -> Allpass-based 2x upsampling followed by FIR interpolation
|
* UF -> Allpass-based 2x upsampling followed by FIR interpolation
|
||||||
* AF -> AR2 filter followed by FIR interpolation
|
* AF -> AR2 filter followed by FIR interpolation
|
||||||
*
|
|
||||||
* Signals sampled above 48 kHz are not supported.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "resampler_private.h"
|
#include "resampler_private.h"
|
||||||
|
|
||||||
|
/* Tables with delay compensation values to equalize total delay for different modes */
|
||||||
|
static const opus_int8 delay_matrix_enc[ 5 ][ 3 ] = {
|
||||||
|
/* in \ out 8 12 16 */
|
||||||
|
/* 8 */ { 6, 0, 3 },
|
||||||
|
/* 12 */ { 0, 7, 3 },
|
||||||
|
/* 16 */ { 0, 1, 10 },
|
||||||
|
/* 24 */ { 0, 2, 6 },
|
||||||
|
/* 48 */ { 18, 10, 12 }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const opus_int8 delay_matrix_dec[ 3 ][ 5 ] = {
|
||||||
|
/* in \ out 8 12 16 24 48 */
|
||||||
|
/* 8 */ { 4, 0, 2, 0, 0 },
|
||||||
|
/* 12 */ { 0, 9, 4, 7, 4 },
|
||||||
|
/* 16 */ { 0, 3, 12, 7, 7 }
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Simple way to make [8000, 12000, 16000, 24000, 48000] to [0, 1, 2, 3, 4] */
|
||||||
|
#define rateID(R) ( ( ( ((R)>>12) - ((R)>16000) ) >> ((R)>24000) ) - 1 )
|
||||||
|
|
||||||
#define USE_silk_resampler_copy (0)
|
#define USE_silk_resampler_copy (0)
|
||||||
#define USE_silk_resampler_private_up2_HQ_wrapper (1)
|
#define USE_silk_resampler_private_up2_HQ_wrapper (1)
|
||||||
#define USE_silk_resampler_private_IIR_FIR (2)
|
#define USE_silk_resampler_private_IIR_FIR (2)
|
||||||
|
@ -60,27 +76,42 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
/* Initialize/reset the resampler state for a given pair of input/output sampling rates */
|
/* Initialize/reset the resampler state for a given pair of input/output sampling rates */
|
||||||
opus_int silk_resampler_init(
|
opus_int silk_resampler_init(
|
||||||
silk_resampler_state_struct *S, /* I/O Resampler state */
|
silk_resampler_state_struct *S, /* I/O Resampler state */
|
||||||
opus_int32 Fs_Hz_in, /* I Input sampling rate (Hz) */
|
opus_int32 Fs_Hz_in, /* I Input sampling rate (Hz) */
|
||||||
opus_int32 Fs_Hz_out /* I Output sampling rate (Hz) */
|
opus_int32 Fs_Hz_out, /* I Output sampling rate (Hz) */
|
||||||
|
opus_int forEnc /* I If 1: encoder; if 0: decoder */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
opus_int32 up2 = 0, down2 = 0;
|
opus_int up2x;
|
||||||
|
|
||||||
/* Clear state */
|
/* Clear state */
|
||||||
silk_memset( S, 0, sizeof( silk_resampler_state_struct ) );
|
silk_memset( S, 0, sizeof( silk_resampler_state_struct ) );
|
||||||
|
|
||||||
/* Input checking */
|
/* Input checking */
|
||||||
if( ( Fs_Hz_in != 8000 && Fs_Hz_in != 12000 && Fs_Hz_in != 16000 && Fs_Hz_in != 24000 && Fs_Hz_in != 48000 ) ||
|
if( forEnc ) {
|
||||||
( Fs_Hz_out != 8000 && Fs_Hz_out != 12000 && Fs_Hz_out != 16000 && Fs_Hz_out != 24000 && Fs_Hz_out != 48000 ) ) {
|
if( ( Fs_Hz_in != 8000 && Fs_Hz_in != 12000 && Fs_Hz_in != 16000 && Fs_Hz_in != 24000 && Fs_Hz_in != 48000 ) ||
|
||||||
silk_assert( 0 );
|
( Fs_Hz_out != 8000 && Fs_Hz_out != 12000 && Fs_Hz_out != 16000 ) ) {
|
||||||
return -1;
|
silk_assert( 0 );
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
S->inputDelay = delay_matrix_enc[ rateID( Fs_Hz_in ) ][ rateID( Fs_Hz_out ) ];
|
||||||
|
} else {
|
||||||
|
if( ( Fs_Hz_in != 8000 && Fs_Hz_in != 12000 && Fs_Hz_in != 16000 ) ||
|
||||||
|
( Fs_Hz_out != 8000 && Fs_Hz_out != 12000 && Fs_Hz_out != 16000 && Fs_Hz_out != 24000 && Fs_Hz_out != 48000 ) ) {
|
||||||
|
silk_assert( 0 );
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
S->inputDelay = delay_matrix_dec[ rateID( Fs_Hz_in ) ][ rateID( Fs_Hz_out ) ];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
S->Fs_in_kHz = silk_DIV32_16( Fs_Hz_in, 1000 );
|
||||||
|
S->Fs_out_kHz = silk_DIV32_16( Fs_Hz_out, 1000 );
|
||||||
|
|
||||||
/* Number of samples processed per batch */
|
/* Number of samples processed per batch */
|
||||||
S->batchSize = silk_DIV32_16( Fs_Hz_in, 100 );
|
S->batchSize = S->Fs_in_kHz * RESAMPLER_MAX_BATCH_SIZE_MS;
|
||||||
|
|
||||||
/* Find resampler with the right sampling ratio */
|
/* Find resampler with the right sampling ratio */
|
||||||
|
up2x = 0;
|
||||||
if( Fs_Hz_out > Fs_Hz_in ) {
|
if( Fs_Hz_out > Fs_Hz_in ) {
|
||||||
/* Upsample */
|
/* Upsample */
|
||||||
if( Fs_Hz_out == silk_MUL( Fs_Hz_in, 2 ) ) { /* Fs_out : Fs_in = 2 : 1 */
|
if( Fs_Hz_out == silk_MUL( Fs_Hz_in, 2 ) ) { /* Fs_out : Fs_in = 2 : 1 */
|
||||||
|
@ -89,36 +120,35 @@ opus_int silk_resampler_init(
|
||||||
} else {
|
} else {
|
||||||
/* Default resampler */
|
/* Default resampler */
|
||||||
S->resampler_function = USE_silk_resampler_private_IIR_FIR;
|
S->resampler_function = USE_silk_resampler_private_IIR_FIR;
|
||||||
up2 = 1;
|
up2x = 1;
|
||||||
}
|
}
|
||||||
} else if ( Fs_Hz_out < Fs_Hz_in ) {
|
} else if ( Fs_Hz_out < Fs_Hz_in ) {
|
||||||
/* Downsample */
|
/* Downsample */
|
||||||
|
S->resampler_function = USE_silk_resampler_private_down_FIR;
|
||||||
if( silk_MUL( Fs_Hz_out, 4 ) == silk_MUL( Fs_Hz_in, 3 ) ) { /* Fs_out : Fs_in = 3 : 4 */
|
if( silk_MUL( Fs_Hz_out, 4 ) == silk_MUL( Fs_Hz_in, 3 ) ) { /* Fs_out : Fs_in = 3 : 4 */
|
||||||
S->FIR_Fracs = 3;
|
S->FIR_Fracs = 3;
|
||||||
|
S->FIR_Order = RESAMPLER_DOWN_ORDER_FIR0;
|
||||||
S->Coefs = silk_Resampler_3_4_COEFS;
|
S->Coefs = silk_Resampler_3_4_COEFS;
|
||||||
S->resampler_function = USE_silk_resampler_private_down_FIR;
|
|
||||||
} else if( silk_MUL( Fs_Hz_out, 3 ) == silk_MUL( Fs_Hz_in, 2 ) ) { /* Fs_out : Fs_in = 2 : 3 */
|
} else if( silk_MUL( Fs_Hz_out, 3 ) == silk_MUL( Fs_Hz_in, 2 ) ) { /* Fs_out : Fs_in = 2 : 3 */
|
||||||
S->FIR_Fracs = 2;
|
S->FIR_Fracs = 2;
|
||||||
|
S->FIR_Order = RESAMPLER_DOWN_ORDER_FIR0;
|
||||||
S->Coefs = silk_Resampler_2_3_COEFS;
|
S->Coefs = silk_Resampler_2_3_COEFS;
|
||||||
S->resampler_function = USE_silk_resampler_private_down_FIR;
|
|
||||||
} else if( silk_MUL( Fs_Hz_out, 2 ) == Fs_Hz_in ) { /* Fs_out : Fs_in = 1 : 2 */
|
} else if( silk_MUL( Fs_Hz_out, 2 ) == Fs_Hz_in ) { /* Fs_out : Fs_in = 1 : 2 */
|
||||||
S->FIR_Fracs = 1;
|
S->FIR_Fracs = 1;
|
||||||
|
S->FIR_Order = RESAMPLER_DOWN_ORDER_FIR1;
|
||||||
S->Coefs = silk_Resampler_1_2_COEFS;
|
S->Coefs = silk_Resampler_1_2_COEFS;
|
||||||
S->resampler_function = USE_silk_resampler_private_down_FIR;
|
|
||||||
} else if( silk_MUL( Fs_Hz_out, 3 ) == Fs_Hz_in ) { /* Fs_out : Fs_in = 1 : 3 */
|
} else if( silk_MUL( Fs_Hz_out, 3 ) == Fs_Hz_in ) { /* Fs_out : Fs_in = 1 : 3 */
|
||||||
S->FIR_Fracs = 1;
|
S->FIR_Fracs = 1;
|
||||||
|
S->FIR_Order = RESAMPLER_DOWN_ORDER_FIR2;
|
||||||
S->Coefs = silk_Resampler_1_3_COEFS;
|
S->Coefs = silk_Resampler_1_3_COEFS;
|
||||||
S->resampler_function = USE_silk_resampler_private_down_FIR;
|
|
||||||
} else if( silk_MUL( Fs_Hz_out, 4 ) == Fs_Hz_in ) { /* Fs_out : Fs_in = 1 : 4 */
|
} else if( silk_MUL( Fs_Hz_out, 4 ) == Fs_Hz_in ) { /* Fs_out : Fs_in = 1 : 4 */
|
||||||
S->FIR_Fracs = 1;
|
S->FIR_Fracs = 1;
|
||||||
down2 = 1;
|
S->FIR_Order = RESAMPLER_DOWN_ORDER_FIR2;
|
||||||
S->Coefs = silk_Resampler_1_2_COEFS;
|
S->Coefs = silk_Resampler_1_4_COEFS;
|
||||||
S->resampler_function = USE_silk_resampler_private_down_FIR;
|
|
||||||
} else if( silk_MUL( Fs_Hz_out, 6 ) == Fs_Hz_in ) { /* Fs_out : Fs_in = 1 : 6 */
|
} else if( silk_MUL( Fs_Hz_out, 6 ) == Fs_Hz_in ) { /* Fs_out : Fs_in = 1 : 6 */
|
||||||
S->FIR_Fracs = 1;
|
S->FIR_Fracs = 1;
|
||||||
down2 = 1;
|
S->FIR_Order = RESAMPLER_DOWN_ORDER_FIR2;
|
||||||
S->Coefs = silk_Resampler_1_3_COEFS;
|
S->Coefs = silk_Resampler_1_6_COEFS;
|
||||||
S->resampler_function = USE_silk_resampler_private_down_FIR;
|
|
||||||
} else {
|
} else {
|
||||||
/* None available */
|
/* None available */
|
||||||
silk_assert( 0 );
|
silk_assert( 0 );
|
||||||
|
@ -129,12 +159,10 @@ opus_int silk_resampler_init(
|
||||||
S->resampler_function = USE_silk_resampler_copy;
|
S->resampler_function = USE_silk_resampler_copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
S->input2x = up2 | down2;
|
|
||||||
|
|
||||||
/* Ratio of input/output samples */
|
/* Ratio of input/output samples */
|
||||||
S->invRatio_Q16 = silk_LSHIFT32( silk_DIV32( silk_LSHIFT32( Fs_Hz_in, 14 + up2 - down2 ), Fs_Hz_out ), 2 );
|
S->invRatio_Q16 = silk_LSHIFT32( silk_DIV32( silk_LSHIFT32( Fs_Hz_in, 14 + up2x ), Fs_Hz_out ), 2 );
|
||||||
/* Make sure the ratio is rounded up */
|
/* Make sure the ratio is rounded up */
|
||||||
while( silk_SMULWW( S->invRatio_Q16, silk_LSHIFT32( Fs_Hz_out, down2 ) ) < silk_LSHIFT32( Fs_Hz_in, up2 ) ) {
|
while( silk_SMULWW( S->invRatio_Q16, Fs_Hz_out ) < silk_LSHIFT32( Fs_Hz_in, up2x ) ) {
|
||||||
S->invRatio_Q16++;
|
S->invRatio_Q16++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,26 +170,46 @@ opus_int silk_resampler_init(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Resampler: convert from one sampling rate to another */
|
/* Resampler: convert from one sampling rate to another */
|
||||||
|
/* Input and output sampling rate are at most 48000 Hz */
|
||||||
opus_int silk_resampler(
|
opus_int silk_resampler(
|
||||||
silk_resampler_state_struct *S, /* I/O Resampler state */
|
silk_resampler_state_struct *S, /* I/O Resampler state */
|
||||||
opus_int16 out[], /* O Output signal */
|
opus_int16 out[], /* O Output signal */
|
||||||
const opus_int16 in[], /* I Input signal */
|
const opus_int16 in[], /* I Input signal */
|
||||||
opus_int32 inLen /* I Number of input samples */
|
opus_int32 inLen /* I Number of input samples */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
/* Input and output sampling rate are at most 48000 Hz */
|
opus_int nSamples;
|
||||||
|
|
||||||
|
/* Need at least 1 ms of input data */
|
||||||
|
silk_assert( inLen >= S->Fs_in_kHz );
|
||||||
|
/* Delay can't exceed the 1 ms of buffering */
|
||||||
|
silk_assert( S->inputDelay <= S->Fs_in_kHz );
|
||||||
|
|
||||||
|
nSamples = S->Fs_in_kHz - S->inputDelay;
|
||||||
|
|
||||||
|
/* Copy to delay buffer */
|
||||||
|
silk_memcpy( &S->delayBuf[ S->inputDelay ], in, nSamples * sizeof( opus_int16 ) );
|
||||||
|
|
||||||
switch( S->resampler_function ) {
|
switch( S->resampler_function ) {
|
||||||
case USE_silk_resampler_private_up2_HQ_wrapper:
|
case USE_silk_resampler_private_up2_HQ_wrapper:
|
||||||
silk_resampler_private_up2_HQ_wrapper( S, out, in, inLen );
|
silk_resampler_private_up2_HQ_wrapper( S, out, S->delayBuf, S->Fs_in_kHz );
|
||||||
|
silk_resampler_private_up2_HQ_wrapper( S, &out[ S->Fs_out_kHz ], &in[ nSamples ], inLen - S->Fs_in_kHz );
|
||||||
break;
|
break;
|
||||||
case USE_silk_resampler_private_IIR_FIR:
|
case USE_silk_resampler_private_IIR_FIR:
|
||||||
silk_resampler_private_IIR_FIR( S, out, in, inLen );
|
silk_resampler_private_IIR_FIR( S, out, S->delayBuf, S->Fs_in_kHz );
|
||||||
|
silk_resampler_private_IIR_FIR( S, &out[ S->Fs_out_kHz ], &in[ nSamples ], inLen - S->Fs_in_kHz );
|
||||||
break;
|
break;
|
||||||
case USE_silk_resampler_private_down_FIR:
|
case USE_silk_resampler_private_down_FIR:
|
||||||
silk_resampler_private_down_FIR( S, out, in, inLen );
|
silk_resampler_private_down_FIR( S, out, S->delayBuf, S->Fs_in_kHz );
|
||||||
|
silk_resampler_private_down_FIR( S, &out[ S->Fs_out_kHz ], &in[ nSamples ], inLen - S->Fs_in_kHz );
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
silk_memcpy( out, in, inLen * sizeof( opus_int16 ) );
|
silk_memcpy( out, S->delayBuf, S->Fs_in_kHz * sizeof( opus_int16 ) );
|
||||||
|
silk_memcpy( &out[ S->Fs_out_kHz ], &in[ nSamples ], ( inLen - S->Fs_in_kHz ) * sizeof( opus_int16 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Copy to delay buffer */
|
||||||
|
silk_memcpy( S->delayBuf, &in[ inLen - S->inputDelay ], S->inputDelay * sizeof( opus_int16 ) );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "SigProc_FIX.h"
|
#include "SigProc_FIX.h"
|
||||||
#include "resampler_rom.h"
|
#include "resampler_rom.h"
|
||||||
|
|
||||||
/* Downsample by a factor 2, mediocre quality */
|
/* Downsample by a factor 2 */
|
||||||
void silk_resampler_down2(
|
void silk_resampler_down2(
|
||||||
opus_int32 *S, /* I/O State vector [ 2 ] */
|
opus_int32 *S, /* I/O State vector [ 2 ] */
|
||||||
opus_int16 *out, /* O Output signal [ len ] */
|
opus_int16 *out, /* O Output signal [ len ] */
|
||||||
|
|
|
@ -25,8 +25,8 @@ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
#ifndef SILK_RESAMPLER_H
|
#ifndef SILK_RESAMPLER_PRIVATE_H
|
||||||
#define SILK_RESAMPLER_H
|
#define SILK_RESAMPLER_PRIVATE_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -37,7 +37,9 @@ extern "C" {
|
||||||
#include "resampler_rom.h"
|
#include "resampler_rom.h"
|
||||||
|
|
||||||
/* Number of input samples to process in the inner loop */
|
/* Number of input samples to process in the inner loop */
|
||||||
#define RESAMPLER_MAX_BATCH_SIZE_IN 480
|
#define RESAMPLER_MAX_BATCH_SIZE_MS 10
|
||||||
|
#define RESAMPLER_MAX_FS_KHZ 48
|
||||||
|
#define RESAMPLER_MAX_BATCH_SIZE_IN ( RESAMPLER_MAX_BATCH_SIZE_MS * RESAMPLER_MAX_FS_KHZ )
|
||||||
|
|
||||||
/* Description: Hybrid IIR/FIR polyphase implementation of resampling */
|
/* Description: Hybrid IIR/FIR polyphase implementation of resampling */
|
||||||
void silk_resampler_private_IIR_FIR(
|
void silk_resampler_private_IIR_FIR(
|
||||||
|
@ -83,4 +85,4 @@ void silk_resampler_private_AR2(
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif /* SILK_RESAMPLER_H */
|
#endif /* SILK_RESAMPLER_PRIVATE_H */
|
||||||
|
|
|
@ -45,15 +45,17 @@ static inline opus_int16 *silk_resampler_private_IIR_FIR_INTERPOL(
|
||||||
|
|
||||||
/* Interpolate upsampled signal and store in output array */
|
/* Interpolate upsampled signal and store in output array */
|
||||||
for( index_Q16 = 0; index_Q16 < max_index_Q16; index_Q16 += index_increment_Q16 ) {
|
for( index_Q16 = 0; index_Q16 < max_index_Q16; index_Q16 += index_increment_Q16 ) {
|
||||||
table_index = silk_SMULWB( index_Q16 & 0xFFFF, 144 );
|
table_index = silk_SMULWB( index_Q16 & 0xFFFF, 12 );
|
||||||
buf_ptr = &buf[ index_Q16 >> 16 ];
|
buf_ptr = &buf[ index_Q16 >> 16 ];
|
||||||
|
|
||||||
res_Q15 = silk_SMULBB( buf_ptr[ 0 ], silk_resampler_frac_FIR_144[ table_index ][ 0 ] );
|
res_Q15 = silk_SMULBB( buf_ptr[ 0 ], silk_resampler_frac_FIR_12[ table_index ][ 0 ] );
|
||||||
res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 1 ], silk_resampler_frac_FIR_144[ table_index ][ 1 ] );
|
res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 1 ], silk_resampler_frac_FIR_12[ table_index ][ 1 ] );
|
||||||
res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 2 ], silk_resampler_frac_FIR_144[ table_index ][ 2 ] );
|
res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 2 ], silk_resampler_frac_FIR_12[ table_index ][ 2 ] );
|
||||||
res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 3 ], silk_resampler_frac_FIR_144[ 143 - table_index ][ 2 ] );
|
res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 3 ], silk_resampler_frac_FIR_12[ table_index ][ 3 ] );
|
||||||
res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 4 ], silk_resampler_frac_FIR_144[ 143 - table_index ][ 1 ] );
|
res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 4 ], silk_resampler_frac_FIR_12[ 11 - table_index ][ 3 ] );
|
||||||
res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 5 ], silk_resampler_frac_FIR_144[ 143 - table_index ][ 0 ] );
|
res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 5 ], silk_resampler_frac_FIR_12[ 11 - table_index ][ 2 ] );
|
||||||
|
res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 6 ], silk_resampler_frac_FIR_12[ 11 - table_index ][ 1 ] );
|
||||||
|
res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 7 ], silk_resampler_frac_FIR_12[ 11 - table_index ][ 0 ] );
|
||||||
*out++ = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( res_Q15, 15 ) );
|
*out++ = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( res_Q15, 15 ) );
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
|
@ -69,34 +71,33 @@ void silk_resampler_private_IIR_FIR(
|
||||||
silk_resampler_state_struct *S = (silk_resampler_state_struct *)SS;
|
silk_resampler_state_struct *S = (silk_resampler_state_struct *)SS;
|
||||||
opus_int32 nSamplesIn;
|
opus_int32 nSamplesIn;
|
||||||
opus_int32 max_index_Q16, index_increment_Q16;
|
opus_int32 max_index_Q16, index_increment_Q16;
|
||||||
opus_int16 buf[ 2 * RESAMPLER_MAX_BATCH_SIZE_IN + RESAMPLER_ORDER_FIR_144 ];
|
opus_int16 buf[ RESAMPLER_MAX_BATCH_SIZE_IN + RESAMPLER_ORDER_FIR_12 ];
|
||||||
|
|
||||||
/* Copy buffered samples to start of buffer */
|
/* Copy buffered samples to start of buffer */
|
||||||
silk_memcpy( buf, S->sFIR, RESAMPLER_ORDER_FIR_144 * sizeof( opus_int32 ) );
|
silk_memcpy( buf, S->sFIR, RESAMPLER_ORDER_FIR_12 * sizeof( opus_int32 ) );
|
||||||
|
|
||||||
/* Iterate over blocks of frameSizeIn input samples */
|
/* Iterate over blocks of frameSizeIn input samples */
|
||||||
index_increment_Q16 = S->invRatio_Q16;
|
index_increment_Q16 = S->invRatio_Q16;
|
||||||
while( 1 ) {
|
while( 1 ) {
|
||||||
nSamplesIn = silk_min( inLen, S->batchSize );
|
nSamplesIn = silk_min( inLen, S->batchSize );
|
||||||
|
|
||||||
silk_assert( S->input2x );
|
|
||||||
/* Upsample 2x */
|
/* Upsample 2x */
|
||||||
silk_resampler_private_up2_HQ( S->sIIR, &buf[ RESAMPLER_ORDER_FIR_144 ], in, nSamplesIn );
|
silk_resampler_private_up2_HQ( S->sIIR, &buf[ RESAMPLER_ORDER_FIR_12 ], in, nSamplesIn );
|
||||||
|
|
||||||
max_index_Q16 = silk_LSHIFT32( nSamplesIn, 16 + S->input2x ); /* +1 if 2x upsampling */
|
max_index_Q16 = silk_LSHIFT32( nSamplesIn, 16 + 1 ); /* + 1 because 2x upsampling */
|
||||||
out = silk_resampler_private_IIR_FIR_INTERPOL(out, buf, max_index_Q16, index_increment_Q16);
|
out = silk_resampler_private_IIR_FIR_INTERPOL( out, buf, max_index_Q16, index_increment_Q16 );
|
||||||
in += nSamplesIn;
|
in += nSamplesIn;
|
||||||
inLen -= nSamplesIn;
|
inLen -= nSamplesIn;
|
||||||
|
|
||||||
if( inLen > 0 ) {
|
if( inLen > 0 ) {
|
||||||
/* More iterations to do; copy last part of filtered signal to beginning of buffer */
|
/* More iterations to do; copy last part of filtered signal to beginning of buffer */
|
||||||
silk_memcpy( buf, &buf[ nSamplesIn << S->input2x ], RESAMPLER_ORDER_FIR_144 * sizeof( opus_int32 ) );
|
silk_memcpy( buf, &buf[ nSamplesIn << 1 ], RESAMPLER_ORDER_FIR_12 * sizeof( opus_int32 ) );
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy last part of filtered signal to the state for the next call */
|
/* Copy last part of filtered signal to the state for the next call */
|
||||||
silk_memcpy( S->sFIR, &buf[nSamplesIn << S->input2x ], RESAMPLER_ORDER_FIR_144 * sizeof( opus_int32 ) );
|
silk_memcpy( S->sFIR, &buf[ nSamplesIn << 1 ], RESAMPLER_ORDER_FIR_12 * sizeof( opus_int32 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,86 +32,115 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "SigProc_FIX.h"
|
#include "SigProc_FIX.h"
|
||||||
#include "resampler_private.h"
|
#include "resampler_private.h"
|
||||||
|
|
||||||
static inline opus_int16 *silk_resampler_private_down_FIR_INTERPOL0(
|
static inline opus_int16 *silk_resampler_private_down_FIR_INTERPOL(
|
||||||
opus_int16 *out,
|
opus_int16 *out,
|
||||||
opus_int32 *buf2,
|
opus_int32 *buf,
|
||||||
const opus_int16 *FIR_Coefs,
|
const opus_int16 *FIR_Coefs,
|
||||||
|
opus_int FIR_Order,
|
||||||
|
opus_int FIR_Fracs,
|
||||||
opus_int32 max_index_Q16,
|
opus_int32 max_index_Q16,
|
||||||
opus_int32 index_increment_Q16
|
opus_int32 index_increment_Q16
|
||||||
)
|
)
|
||||||
{
|
|
||||||
opus_int32 index_Q16, res_Q6;
|
|
||||||
opus_int32 *buf_ptr;
|
|
||||||
|
|
||||||
for( index_Q16 = 0; index_Q16 < max_index_Q16; index_Q16 += index_increment_Q16 ) {
|
|
||||||
/* Integer part gives pointer to buffered input */
|
|
||||||
buf_ptr = buf2 + silk_RSHIFT( index_Q16, 16 );
|
|
||||||
|
|
||||||
/* Inner product */
|
|
||||||
res_Q6 = silk_SMULWB( silk_ADD32( buf_ptr[ 0 ], buf_ptr[ 15 ] ), FIR_Coefs[ 0 ] );
|
|
||||||
res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 1 ], buf_ptr[ 14 ] ), FIR_Coefs[ 1 ] );
|
|
||||||
res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 2 ], buf_ptr[ 13 ] ), FIR_Coefs[ 2 ] );
|
|
||||||
res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 3 ], buf_ptr[ 12 ] ), FIR_Coefs[ 3 ] );
|
|
||||||
res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 4 ], buf_ptr[ 11 ] ), FIR_Coefs[ 4 ] );
|
|
||||||
res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 5 ], buf_ptr[ 10 ] ), FIR_Coefs[ 5 ] );
|
|
||||||
res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 6 ], buf_ptr[ 9 ] ), FIR_Coefs[ 6 ] );
|
|
||||||
res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 7 ], buf_ptr[ 8 ] ), FIR_Coefs[ 7 ] );
|
|
||||||
|
|
||||||
/* Scale down, saturate and store in output array */
|
|
||||||
*out++ = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( res_Q6, 6 ) );
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline opus_int16 *silk_resampler_private_down_FIR_INTERPOL1(
|
|
||||||
opus_int16 *out,
|
|
||||||
opus_int32 *buf2,
|
|
||||||
const opus_int16 *FIR_Coefs,
|
|
||||||
opus_int32 max_index_Q16,
|
|
||||||
opus_int32 index_increment_Q16,
|
|
||||||
opus_int32 FIR_Fracs
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
opus_int32 index_Q16, res_Q6;
|
opus_int32 index_Q16, res_Q6;
|
||||||
opus_int32 *buf_ptr;
|
opus_int32 *buf_ptr;
|
||||||
opus_int32 interpol_ind;
|
opus_int32 interpol_ind;
|
||||||
const opus_int16 *interpol_ptr;
|
const opus_int16 *interpol_ptr;
|
||||||
|
|
||||||
for( index_Q16 = 0; index_Q16 < max_index_Q16; index_Q16 += index_increment_Q16 ) {
|
switch( FIR_Order ) {
|
||||||
/* Integer part gives pointer to buffered input */
|
case RESAMPLER_DOWN_ORDER_FIR0:
|
||||||
buf_ptr = buf2 + silk_RSHIFT( index_Q16, 16 );
|
for( index_Q16 = 0; index_Q16 < max_index_Q16; index_Q16 += index_increment_Q16 ) {
|
||||||
|
/* Integer part gives pointer to buffered input */
|
||||||
|
buf_ptr = buf + silk_RSHIFT( index_Q16, 16 );
|
||||||
|
|
||||||
/* Fractional part gives interpolation coefficients */
|
/* Fractional part gives interpolation coefficients */
|
||||||
interpol_ind = silk_SMULWB( index_Q16 & 0xFFFF, FIR_Fracs );
|
interpol_ind = silk_SMULWB( index_Q16 & 0xFFFF, FIR_Fracs );
|
||||||
|
|
||||||
/* Inner product */
|
/* Inner product */
|
||||||
interpol_ptr = &FIR_Coefs[ RESAMPLER_DOWN_ORDER_FIR / 2 * interpol_ind ];
|
interpol_ptr = &FIR_Coefs[ RESAMPLER_DOWN_ORDER_FIR0 / 2 * interpol_ind ];
|
||||||
res_Q6 = silk_SMULWB( buf_ptr[ 0 ], interpol_ptr[ 0 ] );
|
res_Q6 = silk_SMULWB( buf_ptr[ 0 ], interpol_ptr[ 0 ] );
|
||||||
res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 1 ], interpol_ptr[ 1 ] );
|
res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 1 ], interpol_ptr[ 1 ] );
|
||||||
res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 2 ], interpol_ptr[ 2 ] );
|
res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 2 ], interpol_ptr[ 2 ] );
|
||||||
res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 3 ], interpol_ptr[ 3 ] );
|
res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 3 ], interpol_ptr[ 3 ] );
|
||||||
res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 4 ], interpol_ptr[ 4 ] );
|
res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 4 ], interpol_ptr[ 4 ] );
|
||||||
res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 5 ], interpol_ptr[ 5 ] );
|
res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 5 ], interpol_ptr[ 5 ] );
|
||||||
res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 6 ], interpol_ptr[ 6 ] );
|
res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 6 ], interpol_ptr[ 6 ] );
|
||||||
res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 7 ], interpol_ptr[ 7 ] );
|
res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 7 ], interpol_ptr[ 7 ] );
|
||||||
interpol_ptr = &FIR_Coefs[ RESAMPLER_DOWN_ORDER_FIR / 2 * ( FIR_Fracs - 1 - interpol_ind ) ];
|
res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 8 ], interpol_ptr[ 8 ] );
|
||||||
res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 15 ], interpol_ptr[ 0 ] );
|
interpol_ptr = &FIR_Coefs[ RESAMPLER_DOWN_ORDER_FIR0 / 2 * ( FIR_Fracs - 1 - interpol_ind ) ];
|
||||||
res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 14 ], interpol_ptr[ 1 ] );
|
res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 17 ], interpol_ptr[ 0 ] );
|
||||||
res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 13 ], interpol_ptr[ 2 ] );
|
res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 16 ], interpol_ptr[ 1 ] );
|
||||||
res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 12 ], interpol_ptr[ 3 ] );
|
res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 15 ], interpol_ptr[ 2 ] );
|
||||||
res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 11 ], interpol_ptr[ 4 ] );
|
res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 14 ], interpol_ptr[ 3 ] );
|
||||||
res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 10 ], interpol_ptr[ 5 ] );
|
res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 13 ], interpol_ptr[ 4 ] );
|
||||||
res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 9 ], interpol_ptr[ 6 ] );
|
res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 12 ], interpol_ptr[ 5 ] );
|
||||||
res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 8 ], interpol_ptr[ 7 ] );
|
res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 11 ], interpol_ptr[ 6 ] );
|
||||||
|
res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 10 ], interpol_ptr[ 7 ] );
|
||||||
|
res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 9 ], interpol_ptr[ 8 ] );
|
||||||
|
|
||||||
/* Scale down, saturate and store in output array */
|
/* Scale down, saturate and store in output array */
|
||||||
*out++ = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( res_Q6, 6 ) );
|
*out++ = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( res_Q6, 6 ) );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case RESAMPLER_DOWN_ORDER_FIR1:
|
||||||
|
for( index_Q16 = 0; index_Q16 < max_index_Q16; index_Q16 += index_increment_Q16 ) {
|
||||||
|
/* Integer part gives pointer to buffered input */
|
||||||
|
buf_ptr = buf + silk_RSHIFT( index_Q16, 16 );
|
||||||
|
|
||||||
|
/* Inner product */
|
||||||
|
res_Q6 = silk_SMULWB( silk_ADD32( buf_ptr[ 0 ], buf_ptr[ 23 ] ), FIR_Coefs[ 0 ] );
|
||||||
|
res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 1 ], buf_ptr[ 22 ] ), FIR_Coefs[ 1 ] );
|
||||||
|
res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 2 ], buf_ptr[ 21 ] ), FIR_Coefs[ 2 ] );
|
||||||
|
res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 3 ], buf_ptr[ 20 ] ), FIR_Coefs[ 3 ] );
|
||||||
|
res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 4 ], buf_ptr[ 19 ] ), FIR_Coefs[ 4 ] );
|
||||||
|
res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 5 ], buf_ptr[ 18 ] ), FIR_Coefs[ 5 ] );
|
||||||
|
res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 6 ], buf_ptr[ 17 ] ), FIR_Coefs[ 6 ] );
|
||||||
|
res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 7 ], buf_ptr[ 16 ] ), FIR_Coefs[ 7 ] );
|
||||||
|
res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 8 ], buf_ptr[ 15 ] ), FIR_Coefs[ 8 ] );
|
||||||
|
res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 9 ], buf_ptr[ 14 ] ), FIR_Coefs[ 9 ] );
|
||||||
|
res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 10 ], buf_ptr[ 13 ] ), FIR_Coefs[ 10 ] );
|
||||||
|
res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 11 ], buf_ptr[ 12 ] ), FIR_Coefs[ 11 ] );
|
||||||
|
|
||||||
|
/* Scale down, saturate and store in output array */
|
||||||
|
*out++ = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( res_Q6, 6 ) );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case RESAMPLER_DOWN_ORDER_FIR2:
|
||||||
|
for( index_Q16 = 0; index_Q16 < max_index_Q16; index_Q16 += index_increment_Q16 ) {
|
||||||
|
/* Integer part gives pointer to buffered input */
|
||||||
|
buf_ptr = buf + silk_RSHIFT( index_Q16, 16 );
|
||||||
|
|
||||||
|
/* Inner product */
|
||||||
|
res_Q6 = silk_SMULWB( silk_ADD32( buf_ptr[ 0 ], buf_ptr[ 35 ] ), FIR_Coefs[ 0 ] );
|
||||||
|
res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 1 ], buf_ptr[ 34 ] ), FIR_Coefs[ 1 ] );
|
||||||
|
res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 2 ], buf_ptr[ 33 ] ), FIR_Coefs[ 2 ] );
|
||||||
|
res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 3 ], buf_ptr[ 32 ] ), FIR_Coefs[ 3 ] );
|
||||||
|
res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 4 ], buf_ptr[ 31 ] ), FIR_Coefs[ 4 ] );
|
||||||
|
res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 5 ], buf_ptr[ 30 ] ), FIR_Coefs[ 5 ] );
|
||||||
|
res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 6 ], buf_ptr[ 29 ] ), FIR_Coefs[ 6 ] );
|
||||||
|
res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 7 ], buf_ptr[ 28 ] ), FIR_Coefs[ 7 ] );
|
||||||
|
res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 8 ], buf_ptr[ 27 ] ), FIR_Coefs[ 8 ] );
|
||||||
|
res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 9 ], buf_ptr[ 26 ] ), FIR_Coefs[ 9 ] );
|
||||||
|
res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 10 ], buf_ptr[ 25 ] ), FIR_Coefs[ 10 ] );
|
||||||
|
res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 11 ], buf_ptr[ 24 ] ), FIR_Coefs[ 11 ] );
|
||||||
|
res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 12 ], buf_ptr[ 23 ] ), FIR_Coefs[ 12 ] );
|
||||||
|
res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 13 ], buf_ptr[ 22 ] ), FIR_Coefs[ 13 ] );
|
||||||
|
res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 14 ], buf_ptr[ 21 ] ), FIR_Coefs[ 14 ] );
|
||||||
|
res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 15 ], buf_ptr[ 20 ] ), FIR_Coefs[ 15 ] );
|
||||||
|
res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 16 ], buf_ptr[ 19 ] ), FIR_Coefs[ 16 ] );
|
||||||
|
res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 17 ], buf_ptr[ 18 ] ), FIR_Coefs[ 17 ] );
|
||||||
|
|
||||||
|
/* Scale down, saturate and store in output array */
|
||||||
|
*out++ = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( res_Q6, 6 ) );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
silk_assert( 0 );
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Resample with a 2nd order AR filter followed by FIR interpolation */
|
||||||
/* Resample with a 2x downsampler (optional), a 2nd order AR filter followed by FIR interpolation */
|
|
||||||
void silk_resampler_private_down_FIR(
|
void silk_resampler_private_down_FIR(
|
||||||
void *SS, /* I/O Resampler state */
|
void *SS, /* I/O Resampler state */
|
||||||
opus_int16 out[], /* O Output signal */
|
opus_int16 out[], /* O Output signal */
|
||||||
|
@ -122,12 +151,11 @@ void silk_resampler_private_down_FIR(
|
||||||
silk_resampler_state_struct *S = (silk_resampler_state_struct *)SS;
|
silk_resampler_state_struct *S = (silk_resampler_state_struct *)SS;
|
||||||
opus_int32 nSamplesIn;
|
opus_int32 nSamplesIn;
|
||||||
opus_int32 max_index_Q16, index_increment_Q16;
|
opus_int32 max_index_Q16, index_increment_Q16;
|
||||||
opus_int16 buf1[ RESAMPLER_MAX_BATCH_SIZE_IN / 2 ];
|
opus_int32 buf[ RESAMPLER_MAX_BATCH_SIZE_IN + SILK_RESAMPLER_MAX_FIR_ORDER ];
|
||||||
opus_int32 buf2[ RESAMPLER_MAX_BATCH_SIZE_IN + RESAMPLER_DOWN_ORDER_FIR ];
|
|
||||||
const opus_int16 *FIR_Coefs;
|
const opus_int16 *FIR_Coefs;
|
||||||
|
|
||||||
/* Copy buffered samples to start of buffer */
|
/* Copy buffered samples to start of buffer */
|
||||||
silk_memcpy( buf2, S->sFIR, RESAMPLER_DOWN_ORDER_FIR * sizeof( opus_int32 ) );
|
silk_memcpy( buf, S->sFIR, S->FIR_Order * sizeof( opus_int32 ) );
|
||||||
|
|
||||||
FIR_Coefs = &S->Coefs[ 2 ];
|
FIR_Coefs = &S->Coefs[ 2 ];
|
||||||
|
|
||||||
|
@ -136,40 +164,26 @@ void silk_resampler_private_down_FIR(
|
||||||
while( 1 ) {
|
while( 1 ) {
|
||||||
nSamplesIn = silk_min( inLen, S->batchSize );
|
nSamplesIn = silk_min( inLen, S->batchSize );
|
||||||
|
|
||||||
if( S->input2x == 1 ) {
|
/* Second-order AR filter (output in Q8) */
|
||||||
/* Downsample 2x */
|
silk_resampler_private_AR2( S->sIIR, &buf[ S->FIR_Order ], in, S->Coefs, nSamplesIn );
|
||||||
silk_resampler_down2( S->sDown2, buf1, in, nSamplesIn );
|
|
||||||
|
|
||||||
nSamplesIn = silk_RSHIFT32( nSamplesIn, 1 );
|
|
||||||
|
|
||||||
/* Second-order AR filter (output in Q8) */
|
|
||||||
silk_resampler_private_AR2( S->sIIR, &buf2[ RESAMPLER_DOWN_ORDER_FIR ], buf1, S->Coefs, nSamplesIn );
|
|
||||||
} else {
|
|
||||||
/* Second-order AR filter (output in Q8) */
|
|
||||||
silk_resampler_private_AR2( S->sIIR, &buf2[ RESAMPLER_DOWN_ORDER_FIR ], in, S->Coefs, nSamplesIn );
|
|
||||||
}
|
|
||||||
|
|
||||||
max_index_Q16 = silk_LSHIFT32( nSamplesIn, 16 );
|
max_index_Q16 = silk_LSHIFT32( nSamplesIn, 16 );
|
||||||
|
|
||||||
/* Interpolate filtered signal */
|
/* Interpolate filtered signal */
|
||||||
if( S->FIR_Fracs == 1 ) {
|
out = silk_resampler_private_down_FIR_INTERPOL( out, buf, FIR_Coefs, S->FIR_Order,
|
||||||
out = silk_resampler_private_down_FIR_INTERPOL0(out, buf2, FIR_Coefs, max_index_Q16, index_increment_Q16);
|
S->FIR_Fracs, max_index_Q16, index_increment_Q16 );
|
||||||
} else {
|
|
||||||
out = silk_resampler_private_down_FIR_INTERPOL1(out, buf2, FIR_Coefs, max_index_Q16, index_increment_Q16, S->FIR_Fracs);
|
|
||||||
}
|
|
||||||
|
|
||||||
in += nSamplesIn << S->input2x;
|
in += nSamplesIn;
|
||||||
inLen -= nSamplesIn << S->input2x;
|
inLen -= nSamplesIn;
|
||||||
|
|
||||||
if( inLen > S->input2x ) {
|
if( inLen > 1 ) {
|
||||||
/* More iterations to do; copy last part of filtered signal to beginning of buffer */
|
/* More iterations to do; copy last part of filtered signal to beginning of buffer */
|
||||||
silk_memcpy( buf2, &buf2[ nSamplesIn ], RESAMPLER_DOWN_ORDER_FIR * sizeof( opus_int32 ) );
|
silk_memcpy( buf, &buf[ nSamplesIn ], S->FIR_Order * sizeof( opus_int32 ) );
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy last part of filtered signal to the state for the next call */
|
/* Copy last part of filtered signal to the state for the next call */
|
||||||
silk_memcpy( S->sFIR, &buf2[ nSamplesIn ], RESAMPLER_DOWN_ORDER_FIR * sizeof( opus_int32 ) );
|
silk_memcpy( S->sFIR, &buf[ nSamplesIn ], S->FIR_Order * sizeof( opus_int32 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,9 +46,11 @@ void silk_resampler_private_up2_HQ(
|
||||||
opus_int32 in32, out32_1, out32_2, Y, X;
|
opus_int32 in32, out32_1, out32_2, Y, X;
|
||||||
|
|
||||||
silk_assert( silk_resampler_up2_hq_0[ 0 ] > 0 );
|
silk_assert( silk_resampler_up2_hq_0[ 0 ] > 0 );
|
||||||
silk_assert( silk_resampler_up2_hq_0[ 1 ] < 0 );
|
silk_assert( silk_resampler_up2_hq_0[ 1 ] > 0 );
|
||||||
|
silk_assert( silk_resampler_up2_hq_0[ 2 ] < 0 );
|
||||||
silk_assert( silk_resampler_up2_hq_1[ 0 ] > 0 );
|
silk_assert( silk_resampler_up2_hq_1[ 0 ] > 0 );
|
||||||
silk_assert( silk_resampler_up2_hq_1[ 1 ] < 0 );
|
silk_assert( silk_resampler_up2_hq_1[ 1 ] > 0 );
|
||||||
|
silk_assert( silk_resampler_up2_hq_1[ 2 ] < 0 );
|
||||||
|
|
||||||
/* Internal variables and state are in Q10 format */
|
/* Internal variables and state are in Q10 format */
|
||||||
for( k = 0; k < len; k++ ) {
|
for( k = 0; k < len; k++ ) {
|
||||||
|
@ -63,41 +65,39 @@ void silk_resampler_private_up2_HQ(
|
||||||
|
|
||||||
/* Second all-pass section for even output sample */
|
/* Second all-pass section for even output sample */
|
||||||
Y = silk_SUB32( out32_1, S[ 1 ] );
|
Y = silk_SUB32( out32_1, S[ 1 ] );
|
||||||
X = silk_SMLAWB( Y, Y, silk_resampler_up2_hq_0[ 1 ] );
|
X = silk_SMULWB( Y, silk_resampler_up2_hq_0[ 1 ] );
|
||||||
out32_2 = silk_ADD32( S[ 1 ], X );
|
out32_2 = silk_ADD32( S[ 1 ], X );
|
||||||
S[ 1 ] = silk_ADD32( out32_1, X );
|
S[ 1 ] = silk_ADD32( out32_1, X );
|
||||||
|
|
||||||
/* Biquad notch filter */
|
/* Third all-pass section for even output sample */
|
||||||
out32_2 = silk_SMLAWB( out32_2, S[ 5 ], silk_resampler_up2_hq_notch[ 2 ] );
|
Y = silk_SUB32( out32_2, S[ 2 ] );
|
||||||
out32_2 = silk_SMLAWB( out32_2, S[ 4 ], silk_resampler_up2_hq_notch[ 1 ] );
|
X = silk_SMLAWB( Y, Y, silk_resampler_up2_hq_0[ 2 ] );
|
||||||
out32_1 = silk_SMLAWB( out32_2, S[ 4 ], silk_resampler_up2_hq_notch[ 0 ] );
|
out32_1 = silk_ADD32( S[ 2 ], X );
|
||||||
S[ 5 ] = silk_SUB32( out32_2, S[ 5 ] );
|
S[ 2 ] = silk_ADD32( out32_2, X );
|
||||||
|
|
||||||
/* Apply gain in Q15, convert back to int16 and store to output */
|
/* Apply gain in Q15, convert back to int16 and store to output */
|
||||||
out[ 2 * k ] = (opus_int16)silk_SAT16( silk_RSHIFT32(
|
out[ 2 * k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( out32_1, 10 ) );
|
||||||
silk_SMLAWB( 256, out32_1, silk_resampler_up2_hq_notch[ 3 ] ), 9 ) );
|
|
||||||
|
|
||||||
/* First all-pass section for odd output sample */
|
/* First all-pass section for odd output sample */
|
||||||
Y = silk_SUB32( in32, S[ 2 ] );
|
Y = silk_SUB32( in32, S[ 3 ] );
|
||||||
X = silk_SMULWB( Y, silk_resampler_up2_hq_1[ 0 ] );
|
X = silk_SMULWB( Y, silk_resampler_up2_hq_1[ 0 ] );
|
||||||
out32_1 = silk_ADD32( S[ 2 ], X );
|
out32_1 = silk_ADD32( S[ 3 ], X );
|
||||||
S[ 2 ] = silk_ADD32( in32, X );
|
S[ 3 ] = silk_ADD32( in32, X );
|
||||||
|
|
||||||
/* Second all-pass section for odd output sample */
|
/* Second all-pass section for odd output sample */
|
||||||
Y = silk_SUB32( out32_1, S[ 3 ] );
|
Y = silk_SUB32( out32_1, S[ 4 ] );
|
||||||
X = silk_SMLAWB( Y, Y, silk_resampler_up2_hq_1[ 1 ] );
|
X = silk_SMULWB( Y, silk_resampler_up2_hq_1[ 1 ] );
|
||||||
out32_2 = silk_ADD32( S[ 3 ], X );
|
out32_2 = silk_ADD32( S[ 4 ], X );
|
||||||
S[ 3 ] = silk_ADD32( out32_1, X );
|
S[ 4 ] = silk_ADD32( out32_1, X );
|
||||||
|
|
||||||
/* Biquad notch filter */
|
/* Third all-pass section for odd output sample */
|
||||||
out32_2 = silk_SMLAWB( out32_2, S[ 4 ], silk_resampler_up2_hq_notch[ 2 ] );
|
Y = silk_SUB32( out32_2, S[ 5 ] );
|
||||||
out32_2 = silk_SMLAWB( out32_2, S[ 5 ], silk_resampler_up2_hq_notch[ 1 ] );
|
X = silk_SMLAWB( Y, Y, silk_resampler_up2_hq_1[ 2 ] );
|
||||||
out32_1 = silk_SMLAWB( out32_2, S[ 5 ], silk_resampler_up2_hq_notch[ 0 ] );
|
out32_1 = silk_ADD32( S[ 5 ], X );
|
||||||
S[ 4 ] = silk_SUB32( out32_2, S[ 4 ] );
|
S[ 5 ] = silk_ADD32( out32_2, X );
|
||||||
|
|
||||||
/* Apply gain in Q15, convert back to int16 and store to output */
|
/* Apply gain in Q15, convert back to int16 and store to output */
|
||||||
out[ 2 * k + 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT32(
|
out[ 2 * k + 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( out32_1, 10 ) );
|
||||||
silk_SMLAWB( 256, out32_1, silk_resampler_up2_hq_notch[ 3 ] ), 9 ) );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Filter coefficients for IIR/FIR polyphase resampling *
|
/* Filter coefficients for IIR/FIR polyphase resampling *
|
||||||
* Total size: < 600 Words (1.2 kB) */
|
* Total size: 179 Words (358 Bytes) */
|
||||||
|
|
||||||
#include "resampler_private.h"
|
#include "resampler_private.h"
|
||||||
|
|
||||||
|
@ -39,32 +39,46 @@ const opus_int16 silk_resampler_down2_0 = 9872;
|
||||||
const opus_int16 silk_resampler_down2_1 = 39809 - 65536;
|
const opus_int16 silk_resampler_down2_1 = 39809 - 65536;
|
||||||
|
|
||||||
/* Tables for 2x upsampler, high quality */
|
/* Tables for 2x upsampler, high quality */
|
||||||
const opus_int16 silk_resampler_up2_hq_0[ 2 ] = { 4280, 33727 - 65536 };
|
const opus_int16 silk_resampler_up2_hq_0[ 3 ] = { 1746, 14986, 39083 - 65536 };
|
||||||
const opus_int16 silk_resampler_up2_hq_1[ 2 ] = { 16295, 54015 - 65536 };
|
const opus_int16 silk_resampler_up2_hq_1[ 3 ] = { 6854, 25769, 55542 - 65536 };
|
||||||
const opus_int16 silk_resampler_up2_hq_notch[ 4 ] = { 6554, -3932, 6554, 30573 };
|
|
||||||
|
|
||||||
/* Tables with IIR and FIR coefficients for fractional downsamplers (90 Words) */
|
/* Matlab code for the notch filter coefficients: */
|
||||||
silk_DWORD_ALIGN const opus_int16 silk_Resampler_3_4_COEFS[ 2 + 3 * RESAMPLER_DOWN_ORDER_FIR / 2 ] = {
|
/* B = [1, 0.147, 1]; A = [1, 0.107, 0.89]; G = 0.93; freqz(G * B, A, 2^14, 16e3); axis([0, 8000, -10, 1]) */
|
||||||
-20253, -13986,
|
/* fprintf('\t%6d, %6d, %6d, %6d\n', round(B(2)*2^16), round(-A(2)*2^16), round((1-A(3))*2^16), round(G*2^15)) */
|
||||||
86, 7, -151, 368, -542, 232, 11041, 21904,
|
const opus_int16 silk_resampler_up2_hq_notch[ 4 ] = { 9634, -7012, 7209, 30474 };
|
||||||
39, 90, -181, 216, -17, -877, 6408, 19695,
|
|
||||||
2, 113, -108, 2, 314, -977, 2665, 15787,
|
/* Tables with IIR and FIR coefficients for fractional downsamplers (123 Words) */
|
||||||
|
silk_DWORD_ALIGN const opus_int16 silk_Resampler_3_4_COEFS[ 2 + 3 * RESAMPLER_DOWN_ORDER_FIR0 / 2 ] = {
|
||||||
|
-20694, -13867,
|
||||||
|
-49, 64, 17, -157, 353, -496, 163, 11047, 22205,
|
||||||
|
-39, 6, 91, -170, 186, 23, -896, 6336, 19928,
|
||||||
|
-19, -36, 102, -89, -24, 328, -951, 2568, 15909,
|
||||||
};
|
};
|
||||||
|
|
||||||
silk_DWORD_ALIGN const opus_int16 silk_Resampler_2_3_COEFS[ 2 + 2 * RESAMPLER_DOWN_ORDER_FIR / 2 ] = {
|
silk_DWORD_ALIGN const opus_int16 silk_Resampler_2_3_COEFS[ 2 + 2 * RESAMPLER_DOWN_ORDER_FIR0 / 2 ] = {
|
||||||
-13997, -14120,
|
-14457, -14019,
|
||||||
60, -174, 71, 298, -800, 659, 9238, 17461,
|
64, 128, -122, 36, 310, -768, 584, 9267, 17733,
|
||||||
48, -40, -150, 314, -155, -845, 4188, 14293,
|
12, 128, 18, -142, 288, -117, -865, 4123, 14459,
|
||||||
};
|
};
|
||||||
|
|
||||||
silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_2_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR / 2 ] = {
|
silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_2_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR1 / 2 ] = {
|
||||||
1233, -14293,
|
616, -14323,
|
||||||
-91, 162, 169, -342, -505, 1332, 5281, 8742,
|
-10, 39, 58, -46, -84, 120, 184, -315, -541, 1284, 5380, 9024,
|
||||||
};
|
};
|
||||||
|
|
||||||
silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_3_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR / 2 ] = {
|
silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_3_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ] = {
|
||||||
16306, -14409,
|
16102, -15162,
|
||||||
99, -201, -220, -16, 572, 1483, 2433, 3043,
|
-13, 0, 20, 26, 5, -31, -43, -4, 65, 90, 7, -157, -248, -44, 593, 1583, 2612, 3271,
|
||||||
|
};
|
||||||
|
|
||||||
|
silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_4_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ] = {
|
||||||
|
22500, -15099,
|
||||||
|
3, -14, -20, -15, 2, 25, 37, 25, -16, -71, -107, -79, 50, 292, 623, 982, 1288, 1464,
|
||||||
|
};
|
||||||
|
|
||||||
|
silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_6_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ] = {
|
||||||
|
27540, -15257,
|
||||||
|
17, 12, 8, 1, -10, -22, -30, -32, -22, 3, 44, 100, 168, 243, 317, 381, 429, 455,
|
||||||
};
|
};
|
||||||
|
|
||||||
silk_DWORD_ALIGN const opus_int16 silk_Resampler_2_3_COEFS_LQ[ 2 + 2 * 2 ] = {
|
silk_DWORD_ALIGN const opus_int16 silk_Resampler_2_3_COEFS_LQ[ 2 + 2 * 2 ] = {
|
||||||
|
@ -73,150 +87,18 @@ silk_DWORD_ALIGN const opus_int16 silk_Resampler_2_3_COEFS_LQ[ 2 + 2 * 2 ] = {
|
||||||
1567, 8276,
|
1567, 8276,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Table with interplation fractions of 1/288 : 2/288 : 287/288 (432 Words) */
|
/* Table with interplation fractions of 1/24, 3/24, 5/24, ... , 23/24 : 23/24 (46 Words) */
|
||||||
silk_DWORD_ALIGN const opus_int16 silk_resampler_frac_FIR_144[ 144 ][ RESAMPLER_ORDER_FIR_144 / 2 ] = {
|
silk_DWORD_ALIGN const opus_int16 silk_resampler_frac_FIR_12[ 12 ][ RESAMPLER_ORDER_FIR_12 / 2 ] = {
|
||||||
{ -25, 58, 32526},
|
{ 189, -600, 617, 30567 },
|
||||||
{ -8, -69, 32461},
|
{ 117, -159, -1070, 29704 },
|
||||||
{ 8, -195, 32393},
|
{ 52, 221, -2392, 28276 },
|
||||||
{ 25, -318, 32321},
|
{ -4, 529, -3350, 26341 },
|
||||||
{ 41, -439, 32244},
|
{ -48, 758, -3956, 23973 },
|
||||||
{ 57, -557, 32163},
|
{ -80, 905, -4235, 21254 },
|
||||||
{ 72, -673, 32079},
|
{ -99, 972, -4222, 18278 },
|
||||||
{ 88, -787, 31990},
|
{ -107, 967, -3957, 15143 },
|
||||||
{ 103, -899, 31897},
|
{ -103, 896, -3487, 11950 },
|
||||||
{ 118, -1009, 31801},
|
{ -91, 773, -2865, 8798 },
|
||||||
{ 133, -1116, 31700},
|
{ -71, 611, -2143, 5784 },
|
||||||
{ 148, -1221, 31596},
|
{ -46, 425, -1375, 2996 },
|
||||||
{ 162, -1324, 31488},
|
|
||||||
{ 177, -1424, 31376},
|
|
||||||
{ 191, -1522, 31260},
|
|
||||||
{ 205, -1618, 31140},
|
|
||||||
{ 218, -1712, 31017},
|
|
||||||
{ 231, -1803, 30890},
|
|
||||||
{ 245, -1893, 30759},
|
|
||||||
{ 257, -1980, 30625},
|
|
||||||
{ 270, -2065, 30487},
|
|
||||||
{ 282, -2147, 30346},
|
|
||||||
{ 295, -2228, 30201},
|
|
||||||
{ 306, -2306, 30052},
|
|
||||||
{ 318, -2382, 29900},
|
|
||||||
{ 330, -2456, 29745},
|
|
||||||
{ 341, -2528, 29586},
|
|
||||||
{ 352, -2597, 29424},
|
|
||||||
{ 362, -2664, 29259},
|
|
||||||
{ 373, -2730, 29090},
|
|
||||||
{ 383, -2793, 28918},
|
|
||||||
{ 393, -2854, 28743},
|
|
||||||
{ 402, -2912, 28565},
|
|
||||||
{ 411, -2969, 28384},
|
|
||||||
{ 421, -3024, 28199},
|
|
||||||
{ 429, -3076, 28012},
|
|
||||||
{ 438, -3126, 27822},
|
|
||||||
{ 446, -3175, 27628},
|
|
||||||
{ 454, -3221, 27432},
|
|
||||||
{ 462, -3265, 27233},
|
|
||||||
{ 469, -3307, 27031},
|
|
||||||
{ 476, -3348, 26826},
|
|
||||||
{ 483, -3386, 26619},
|
|
||||||
{ 490, -3422, 26409},
|
|
||||||
{ 496, -3456, 26196},
|
|
||||||
{ 502, -3488, 25981},
|
|
||||||
{ 508, -3518, 25763},
|
|
||||||
{ 514, -3547, 25543},
|
|
||||||
{ 519, -3573, 25320},
|
|
||||||
{ 524, -3597, 25095},
|
|
||||||
{ 529, -3620, 24867},
|
|
||||||
{ 533, -3640, 24637},
|
|
||||||
{ 538, -3659, 24405},
|
|
||||||
{ 541, -3676, 24171},
|
|
||||||
{ 545, -3691, 23934},
|
|
||||||
{ 548, -3704, 23696},
|
|
||||||
{ 552, -3716, 23455},
|
|
||||||
{ 554, -3726, 23212},
|
|
||||||
{ 557, -3733, 22967},
|
|
||||||
{ 559, -3740, 22721},
|
|
||||||
{ 561, -3744, 22472},
|
|
||||||
{ 563, -3747, 22222},
|
|
||||||
{ 565, -3748, 21970},
|
|
||||||
{ 566, -3747, 21716},
|
|
||||||
{ 567, -3745, 21460},
|
|
||||||
{ 568, -3741, 21203},
|
|
||||||
{ 568, -3735, 20944},
|
|
||||||
{ 568, -3728, 20684},
|
|
||||||
{ 568, -3719, 20422},
|
|
||||||
{ 568, -3708, 20159},
|
|
||||||
{ 568, -3697, 19894},
|
|
||||||
{ 567, -3683, 19628},
|
|
||||||
{ 566, -3668, 19361},
|
|
||||||
{ 564, -3652, 19093},
|
|
||||||
{ 563, -3634, 18823},
|
|
||||||
{ 561, -3614, 18552},
|
|
||||||
{ 559, -3594, 18280},
|
|
||||||
{ 557, -3571, 18008},
|
|
||||||
{ 554, -3548, 17734},
|
|
||||||
{ 552, -3523, 17459},
|
|
||||||
{ 549, -3497, 17183},
|
|
||||||
{ 546, -3469, 16907},
|
|
||||||
{ 542, -3440, 16630},
|
|
||||||
{ 539, -3410, 16352},
|
|
||||||
{ 535, -3379, 16074},
|
|
||||||
{ 531, -3346, 15794},
|
|
||||||
{ 527, -3312, 15515},
|
|
||||||
{ 522, -3277, 15235},
|
|
||||||
{ 517, -3241, 14954},
|
|
||||||
{ 513, -3203, 14673},
|
|
||||||
{ 507, -3165, 14392},
|
|
||||||
{ 502, -3125, 14110},
|
|
||||||
{ 497, -3085, 13828},
|
|
||||||
{ 491, -3043, 13546},
|
|
||||||
{ 485, -3000, 13264},
|
|
||||||
{ 479, -2957, 12982},
|
|
||||||
{ 473, -2912, 12699},
|
|
||||||
{ 466, -2867, 12417},
|
|
||||||
{ 460, -2820, 12135},
|
|
||||||
{ 453, -2772, 11853},
|
|
||||||
{ 446, -2724, 11571},
|
|
||||||
{ 439, -2675, 11289},
|
|
||||||
{ 432, -2625, 11008},
|
|
||||||
{ 424, -2574, 10727},
|
|
||||||
{ 417, -2522, 10446},
|
|
||||||
{ 409, -2470, 10166},
|
|
||||||
{ 401, -2417, 9886},
|
|
||||||
{ 393, -2363, 9607},
|
|
||||||
{ 385, -2309, 9328},
|
|
||||||
{ 376, -2253, 9050},
|
|
||||||
{ 368, -2198, 8773},
|
|
||||||
{ 359, -2141, 8497},
|
|
||||||
{ 351, -2084, 8221},
|
|
||||||
{ 342, -2026, 7946},
|
|
||||||
{ 333, -1968, 7672},
|
|
||||||
{ 324, -1910, 7399},
|
|
||||||
{ 315, -1850, 7127},
|
|
||||||
{ 305, -1791, 6856},
|
|
||||||
{ 296, -1731, 6586},
|
|
||||||
{ 286, -1670, 6317},
|
|
||||||
{ 277, -1609, 6049},
|
|
||||||
{ 267, -1548, 5783},
|
|
||||||
{ 257, -1486, 5517},
|
|
||||||
{ 247, -1424, 5254},
|
|
||||||
{ 237, -1362, 4991},
|
|
||||||
{ 227, -1300, 4730},
|
|
||||||
{ 217, -1237, 4470},
|
|
||||||
{ 207, -1174, 4212},
|
|
||||||
{ 197, -1110, 3956},
|
|
||||||
{ 187, -1047, 3701},
|
|
||||||
{ 176, -984, 3448},
|
|
||||||
{ 166, -920, 3196},
|
|
||||||
{ 155, -856, 2946},
|
|
||||||
{ 145, -792, 2698},
|
|
||||||
{ 134, -728, 2452},
|
|
||||||
{ 124, -664, 2207},
|
|
||||||
{ 113, -600, 1965},
|
|
||||||
{ 102, -536, 1724},
|
|
||||||
{ 92, -472, 1486},
|
|
||||||
{ 81, -408, 1249},
|
|
||||||
{ 70, -345, 1015},
|
|
||||||
{ 60, -281, 783},
|
|
||||||
{ 49, -217, 553},
|
|
||||||
{ 38, -154, 325},
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -36,27 +36,30 @@ extern "C"
|
||||||
#include "typedef.h"
|
#include "typedef.h"
|
||||||
#include "resampler_structs.h"
|
#include "resampler_structs.h"
|
||||||
|
|
||||||
#define RESAMPLER_DOWN_ORDER_FIR 16
|
#define RESAMPLER_DOWN_ORDER_FIR0 18
|
||||||
#define RESAMPLER_ORDER_FIR_144 6
|
#define RESAMPLER_DOWN_ORDER_FIR1 24
|
||||||
|
#define RESAMPLER_DOWN_ORDER_FIR2 36
|
||||||
|
#define RESAMPLER_ORDER_FIR_12 8
|
||||||
|
|
||||||
/* Tables for 2x downsampler. Values above 32767 intentionally wrap to a negative value. */
|
/* Tables for 2x downsampler */
|
||||||
extern const opus_int16 silk_resampler_down2_0;
|
extern const opus_int16 silk_resampler_down2_0;
|
||||||
extern const opus_int16 silk_resampler_down2_1;
|
extern const opus_int16 silk_resampler_down2_1;
|
||||||
|
|
||||||
/* Tables for 2x upsampler, high quality. Values above 32767 intentionally wrap to a negative value. */
|
/* Tables for 2x upsampler, high quality */
|
||||||
extern const opus_int16 silk_resampler_up2_hq_0[ 2 ];
|
extern const opus_int16 silk_resampler_up2_hq_0[ 3 ];
|
||||||
extern const opus_int16 silk_resampler_up2_hq_1[ 2 ];
|
extern const opus_int16 silk_resampler_up2_hq_1[ 3 ];
|
||||||
extern const opus_int16 silk_resampler_up2_hq_notch[ 4 ];
|
|
||||||
|
|
||||||
/* Tables with IIR and FIR coefficients for fractional downsamplers */
|
/* Tables with IIR and FIR coefficients for fractional downsamplers */
|
||||||
extern const opus_int16 silk_Resampler_3_4_COEFS[ 2 + 3 * RESAMPLER_DOWN_ORDER_FIR / 2 ];
|
extern const opus_int16 silk_Resampler_3_4_COEFS[ 2 + 3 * RESAMPLER_DOWN_ORDER_FIR0 / 2 ];
|
||||||
extern const opus_int16 silk_Resampler_2_3_COEFS[ 2 + 2 * RESAMPLER_DOWN_ORDER_FIR / 2 ];
|
extern const opus_int16 silk_Resampler_2_3_COEFS[ 2 + 2 * RESAMPLER_DOWN_ORDER_FIR0 / 2 ];
|
||||||
extern const opus_int16 silk_Resampler_1_2_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR / 2 ];
|
extern const opus_int16 silk_Resampler_1_2_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR1 / 2 ];
|
||||||
extern const opus_int16 silk_Resampler_1_3_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR / 2 ];
|
extern const opus_int16 silk_Resampler_1_3_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ];
|
||||||
|
extern const opus_int16 silk_Resampler_1_4_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ];
|
||||||
|
extern const opus_int16 silk_Resampler_1_6_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ];
|
||||||
extern const opus_int16 silk_Resampler_2_3_COEFS_LQ[ 2 + 2 * 2 ];
|
extern const opus_int16 silk_Resampler_2_3_COEFS_LQ[ 2 + 2 * 2 ];
|
||||||
|
|
||||||
/* Table with interplation fractions of 1/288 : 2/288 : 287/288 (432 Words) */
|
/* Table with interplation fractions of 1/24, 3/24, ..., 23/24 */
|
||||||
extern const opus_int16 silk_resampler_frac_FIR_144[ 144 ][ RESAMPLER_ORDER_FIR_144 / 2 ];
|
extern const opus_int16 silk_resampler_frac_FIR_12[ 12 ][ RESAMPLER_ORDER_FIR_12 / 2 ];
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,18 +32,21 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define SILK_RESAMPLER_MAX_FIR_ORDER 16
|
#define SILK_RESAMPLER_MAX_FIR_ORDER 36
|
||||||
#define SILK_RESAMPLER_MAX_IIR_ORDER 6
|
#define SILK_RESAMPLER_MAX_IIR_ORDER 6
|
||||||
|
|
||||||
typedef struct _silk_resampler_state_struct{
|
typedef struct _silk_resampler_state_struct{
|
||||||
opus_int32 sIIR[ SILK_RESAMPLER_MAX_IIR_ORDER ]; /* this must be the first element of this struct */
|
opus_int32 sIIR[ SILK_RESAMPLER_MAX_IIR_ORDER ]; /* this must be the first element of this struct */
|
||||||
opus_int32 sFIR[ SILK_RESAMPLER_MAX_FIR_ORDER ];
|
opus_int32 sFIR[ SILK_RESAMPLER_MAX_FIR_ORDER ];
|
||||||
opus_int32 sDown2[ 2 ];
|
opus_int16 delayBuf[ 48 ];
|
||||||
opus_int32 resampler_function;
|
opus_int resampler_function;
|
||||||
opus_int32 batchSize;
|
opus_int batchSize;
|
||||||
opus_int32 invRatio_Q16;
|
opus_int32 invRatio_Q16;
|
||||||
opus_int32 FIR_Fracs;
|
opus_int FIR_Order;
|
||||||
opus_int32 input2x;
|
opus_int FIR_Fracs;
|
||||||
|
opus_int Fs_in_kHz;
|
||||||
|
opus_int Fs_out_kHz;
|
||||||
|
opus_int inputDelay;
|
||||||
const opus_int16 *Coefs;
|
const opus_int16 *Coefs;
|
||||||
} silk_resampler_state_struct;
|
} silk_resampler_state_struct;
|
||||||
|
|
||||||
|
|
|
@ -198,9 +198,9 @@ void silk_stereo_LR_to_MS(
|
||||||
pred0_Q13 += delta0_Q13;
|
pred0_Q13 += delta0_Q13;
|
||||||
pred1_Q13 += delta1_Q13;
|
pred1_Q13 += delta1_Q13;
|
||||||
w_Q24 += deltaw_Q24;
|
w_Q24 += deltaw_Q24;
|
||||||
sum = silk_LSHIFT( silk_ADD_LSHIFT( mid[ n ] + mid[ n + 2 ], mid[ n + 1 ], 1 ), 9 ); /* Q11 */
|
sum = silk_LSHIFT( silk_ADD_LSHIFT( mid[ n ] + mid[ n + 2 ], mid[ n + 1 ], 1 ), 9 ); /* Q11 */
|
||||||
sum = silk_SMLAWB( silk_SMULWB( w_Q24, side[ n + 1 ] ), sum, pred0_Q13 ); /* Q8 */
|
sum = silk_SMLAWB( silk_SMULWB( w_Q24, side[ n + 1 ] ), sum, pred0_Q13 ); /* Q8 */
|
||||||
sum = silk_SMLAWB( sum, silk_LSHIFT( ( opus_int32 )mid[ n + 1 ], 11 ), pred1_Q13 ); /* Q8 */
|
sum = silk_SMLAWB( sum, silk_LSHIFT( (opus_int32)mid[ n + 1 ], 11 ), pred1_Q13 ); /* Q8 */
|
||||||
x2[ n - 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sum, 8 ) );
|
x2[ n - 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sum, 8 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,9 +208,9 @@ void silk_stereo_LR_to_MS(
|
||||||
pred1_Q13 = -pred_Q13[ 1 ];
|
pred1_Q13 = -pred_Q13[ 1 ];
|
||||||
w_Q24 = silk_LSHIFT( width_Q14, 10 );
|
w_Q24 = silk_LSHIFT( width_Q14, 10 );
|
||||||
for( n = STEREO_INTERP_LEN_MS * fs_kHz; n < frame_length; n++ ) {
|
for( n = STEREO_INTERP_LEN_MS * fs_kHz; n < frame_length; n++ ) {
|
||||||
sum = silk_LSHIFT( silk_ADD_LSHIFT( mid[ n ] + mid[ n + 2 ], mid[ n + 1 ], 1 ), 9 ); /* Q11 */
|
sum = silk_LSHIFT( silk_ADD_LSHIFT( mid[ n ] + mid[ n + 2 ], mid[ n + 1 ], 1 ), 9 ); /* Q11 */
|
||||||
sum = silk_SMLAWB( silk_SMULWB( w_Q24, side[ n + 1 ] ), sum, pred0_Q13 ); /* Q8 */
|
sum = silk_SMLAWB( silk_SMULWB( w_Q24, side[ n + 1 ] ), sum, pred0_Q13 ); /* Q8 */
|
||||||
sum = silk_SMLAWB( sum, silk_LSHIFT( ( opus_int32 )mid[ n + 1 ], 11 ), pred1_Q13 ); /* Q8 */
|
sum = silk_SMLAWB( sum, silk_LSHIFT( (opus_int32)mid[ n + 1 ], 11 ), pred1_Q13 ); /* Q8 */
|
||||||
x2[ n - 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sum, 8 ) );
|
x2[ n - 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sum, 8 ) );
|
||||||
}
|
}
|
||||||
state->pred_prev_Q13[ 0 ] = (opus_int16)pred_Q13[ 0 ];
|
state->pred_prev_Q13[ 0 ] = (opus_int16)pred_Q13[ 0 ];
|
||||||
|
|
|
@ -59,17 +59,17 @@ void silk_stereo_MS_to_LR(
|
||||||
for( n = 0; n < STEREO_INTERP_LEN_MS * fs_kHz; n++ ) {
|
for( n = 0; n < STEREO_INTERP_LEN_MS * fs_kHz; n++ ) {
|
||||||
pred0_Q13 += delta0_Q13;
|
pred0_Q13 += delta0_Q13;
|
||||||
pred1_Q13 += delta1_Q13;
|
pred1_Q13 += delta1_Q13;
|
||||||
sum = silk_LSHIFT( silk_ADD_LSHIFT( x1[ n ] + x1[ n + 2 ], x1[ n + 1 ], 1 ), 9 ); /* Q11 */
|
sum = silk_LSHIFT( silk_ADD_LSHIFT( x1[ n ] + x1[ n + 2 ], x1[ n + 1 ], 1 ), 9 ); /* Q11 */
|
||||||
sum = silk_SMLAWB( silk_LSHIFT( ( opus_int32 )x2[ n + 1 ], 8 ), sum, pred0_Q13 ); /* Q8 */
|
sum = silk_SMLAWB( silk_LSHIFT( (opus_int32)x2[ n + 1 ], 8 ), sum, pred0_Q13 ); /* Q8 */
|
||||||
sum = silk_SMLAWB( sum, silk_LSHIFT( ( opus_int32 )x1[ n + 1 ], 11 ), pred1_Q13 ); /* Q8 */
|
sum = silk_SMLAWB( sum, silk_LSHIFT( (opus_int32)x1[ n + 1 ], 11 ), pred1_Q13 ); /* Q8 */
|
||||||
x2[ n + 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sum, 8 ) );
|
x2[ n + 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sum, 8 ) );
|
||||||
}
|
}
|
||||||
pred0_Q13 = pred_Q13[ 0 ];
|
pred0_Q13 = pred_Q13[ 0 ];
|
||||||
pred1_Q13 = pred_Q13[ 1 ];
|
pred1_Q13 = pred_Q13[ 1 ];
|
||||||
for( n = STEREO_INTERP_LEN_MS * fs_kHz; n < frame_length; n++ ) {
|
for( n = STEREO_INTERP_LEN_MS * fs_kHz; n < frame_length; n++ ) {
|
||||||
sum = silk_LSHIFT( silk_ADD_LSHIFT( x1[ n ] + x1[ n + 2 ], x1[ n + 1 ], 1 ), 9 ); /* Q11 */
|
sum = silk_LSHIFT( silk_ADD_LSHIFT( x1[ n ] + x1[ n + 2 ], x1[ n + 1 ], 1 ), 9 ); /* Q11 */
|
||||||
sum = silk_SMLAWB( silk_LSHIFT( ( opus_int32 )x2[ n + 1 ], 8 ), sum, pred0_Q13 ); /* Q8 */
|
sum = silk_SMLAWB( silk_LSHIFT( (opus_int32)x2[ n + 1 ], 8 ), sum, pred0_Q13 ); /* Q8 */
|
||||||
sum = silk_SMLAWB( sum, silk_LSHIFT( ( opus_int32 )x1[ n + 1 ], 11 ), pred1_Q13 ); /* Q8 */
|
sum = silk_SMLAWB( sum, silk_LSHIFT( (opus_int32)x1[ n + 1 ], 11 ), pred1_Q13 ); /* Q8 */
|
||||||
x2[ n + 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sum, 8 ) );
|
x2[ n + 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sum, 8 ) );
|
||||||
}
|
}
|
||||||
state->pred_prev_Q13[ 0 ] = pred_Q13[ 0 ];
|
state->pred_prev_Q13[ 0 ] = pred_Q13[ 0 ];
|
||||||
|
|
|
@ -150,7 +150,6 @@ typedef struct {
|
||||||
opus_int minInternal_fs_Hz; /* Minimum internal sampling frequency (Hz) */
|
opus_int minInternal_fs_Hz; /* Minimum internal sampling frequency (Hz) */
|
||||||
opus_int desiredInternal_fs_Hz; /* Soft request for internal sampling frequency (Hz) */
|
opus_int desiredInternal_fs_Hz; /* Soft request for internal sampling frequency (Hz) */
|
||||||
opus_int fs_kHz; /* Internal sampling frequency (kHz) */
|
opus_int fs_kHz; /* Internal sampling frequency (kHz) */
|
||||||
opus_int delay; /* Number of samples of delay to apply */
|
|
||||||
opus_int nb_subfr; /* Number of 5 ms subframes in a frame */
|
opus_int nb_subfr; /* Number of 5 ms subframes in a frame */
|
||||||
opus_int frame_length; /* Frame length (samples) */
|
opus_int frame_length; /* Frame length (samples) */
|
||||||
opus_int subfr_length; /* Subframe length (samples) */
|
opus_int subfr_length; /* Subframe length (samples) */
|
||||||
|
@ -194,7 +193,6 @@ typedef struct {
|
||||||
|
|
||||||
/* Input/output buffering */
|
/* Input/output buffering */
|
||||||
opus_int16 inputBuf[ MAX_FRAME_LENGTH + 2 ]; /* Buffer containing input signal */
|
opus_int16 inputBuf[ MAX_FRAME_LENGTH + 2 ]; /* Buffer containing input signal */
|
||||||
opus_int16 delayBuf[MAX_ENCODER_DELAY];
|
|
||||||
opus_int inputBufIx;
|
opus_int inputBufIx;
|
||||||
opus_int nFramesPerPacket;
|
opus_int nFramesPerPacket;
|
||||||
opus_int nFramesEncoded; /* Number of frames analyzed in current packet */
|
opus_int nFramesEncoded; /* Number of frames analyzed in current packet */
|
||||||
|
@ -261,8 +259,6 @@ typedef struct {
|
||||||
opus_int32 exc_Q10[ MAX_FRAME_LENGTH ];
|
opus_int32 exc_Q10[ MAX_FRAME_LENGTH ];
|
||||||
opus_int32 sLPC_Q14_buf[ MAX_LPC_ORDER ];
|
opus_int32 sLPC_Q14_buf[ MAX_LPC_ORDER ];
|
||||||
opus_int16 outBuf[ MAX_FRAME_LENGTH + 2 * MAX_SUB_FRAME_LENGTH ]; /* Buffer for output signal */
|
opus_int16 outBuf[ MAX_FRAME_LENGTH + 2 * MAX_SUB_FRAME_LENGTH ]; /* Buffer for output signal */
|
||||||
opus_int16 delayBuf[ MAX_DECODER_DELAY ]; /* Buffer for delaying the SILK output prior to resampling */
|
|
||||||
opus_int delay; /* How much decoder delay to add */
|
|
||||||
opus_int lagPrev; /* Previous Lag */
|
opus_int lagPrev; /* Previous Lag */
|
||||||
opus_int8 LastGainIndex; /* Previous gain index */
|
opus_int8 LastGainIndex; /* Previous gain index */
|
||||||
opus_int fs_kHz; /* Sampling frequency in kHz */
|
opus_int fs_kHz; /* Sampling frequency in kHz */
|
||||||
|
|
|
@ -51,13 +51,11 @@ extern "C"
|
||||||
/*********************/
|
/*********************/
|
||||||
|
|
||||||
/* LPC analysis defines: regularization and bandwidth expansion */
|
/* LPC analysis defines: regularization and bandwidth expansion */
|
||||||
#define FIND_LPC_COND_FAC 2.5e-5f
|
#define FIND_LPC_COND_FAC 1e-5f
|
||||||
#define FIND_LPC_CHIRP 0.99995f
|
|
||||||
#define FIND_LPC_CHIRP_FIRST_FRAME 0.96f
|
|
||||||
|
|
||||||
/* LTP analysis defines */
|
/* LTP analysis defines */
|
||||||
#define FIND_LTP_COND_FAC 1e-5f
|
#define FIND_LTP_COND_FAC 1e-5f
|
||||||
#define LTP_DAMPING 0.01f
|
#define LTP_DAMPING 0.05f
|
||||||
#define LTP_SMOOTHING 0.1f
|
#define LTP_SMOOTHING 0.1f
|
||||||
|
|
||||||
/* LTP quantization settings */
|
/* LTP quantization settings */
|
||||||
|
@ -108,7 +106,7 @@ extern "C"
|
||||||
#define WARPING_MULTIPLIER 0.015f
|
#define WARPING_MULTIPLIER 0.015f
|
||||||
|
|
||||||
/* fraction added to first autocorrelation value */
|
/* fraction added to first autocorrelation value */
|
||||||
#define SHAPE_WHITE_NOISE_FRACTION 1e-5f
|
#define SHAPE_WHITE_NOISE_FRACTION 5e-5f
|
||||||
|
|
||||||
/* noise shaping filter chirp factor */
|
/* noise shaping filter chirp factor */
|
||||||
#define BANDWIDTH_EXPANSION 0.95f
|
#define BANDWIDTH_EXPANSION 0.95f
|
||||||
|
|
|
@ -126,10 +126,6 @@ static const opus_int32 mode_thresholds[2][2] = {
|
||||||
{ 48000, 24000}, /* stereo */
|
{ 48000, 24000}, /* stereo */
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int celt_delay_table[5] = {
|
|
||||||
/* API 8 12 16 24 48 */
|
|
||||||
10, 16, 21, 27, 55
|
|
||||||
};
|
|
||||||
int opus_encoder_get_size(int channels)
|
int opus_encoder_get_size(int channels)
|
||||||
{
|
{
|
||||||
int silkEncSizeBytes, celtEncSizeBytes;
|
int silkEncSizeBytes, celtEncSizeBytes;
|
||||||
|
@ -209,11 +205,11 @@ int opus_encoder_init(OpusEncoder* st, opus_int32 Fs, int channels, int applicat
|
||||||
st->voice_ratio = -1;
|
st->voice_ratio = -1;
|
||||||
st->encoder_buffer = st->Fs/100;
|
st->encoder_buffer = st->Fs/100;
|
||||||
|
|
||||||
st->delay_compensation = st->Fs/400;
|
/* Delay compensation of 4 ms (2.5 ms for SILK's extra look-ahead
|
||||||
|
+ 1.5 ms for SILK resamplers and stereo prediction) */
|
||||||
|
st->delay_compensation = st->Fs/250;
|
||||||
|
|
||||||
st->delay_compensation += celt_delay_table[rateID(st->Fs)];
|
st->hybrid_stereo_width_Q14 = 1 << 14;
|
||||||
|
|
||||||
st->hybrid_stereo_width_Q14 = 1 << 14;
|
|
||||||
st->variable_HP_smth2_Q15 = silk_LSHIFT( silk_lin2log( VARIABLE_HP_MIN_CUTOFF_HZ ), 8 );
|
st->variable_HP_smth2_Q15 = silk_LSHIFT( silk_lin2log( VARIABLE_HP_MIN_CUTOFF_HZ ), 8 );
|
||||||
st->first = 1;
|
st->first = 1;
|
||||||
st->mode = MODE_HYBRID;
|
st->mode = MODE_HYBRID;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue