diff options
author | Koen Vos <koen.vos@skype.net> | 2012-01-31 10:51:22 +0400 |
---|---|---|
committer | Jean-Marc Valin <jmvalin@jmvalin.ca> | 2012-01-31 10:51:22 +0400 |
commit | 54518c879a6541eab749bc19628f1795daaad1e3 (patch) | |
tree | 3c2d0d08b9314dcb2d316e2ec4e477a6784b970b /silk | |
parent | a26b2be2f922502b821e81e2cb084393f1ccf405 (diff) |
Last part of the LPC work stabilization work discussed at the last meeting
Also adds the encoder part of commit ee8adbe701 as well as a few
minor cleanups.
Diffstat (limited to 'silk')
-rw-r--r-- | silk/A2NLSF.c | 25 | ||||
-rw-r--r-- | silk/NLSF2A.c | 19 | ||||
-rw-r--r-- | silk/NLSF_decode.c | 2 | ||||
-rw-r--r-- | silk/NLSF_unpack.c | 2 | ||||
-rw-r--r-- | silk/NSQ.c | 14 | ||||
-rw-r--r-- | silk/NSQ_del_dec.c | 20 | ||||
-rw-r--r-- | silk/decode_core.c | 3 | ||||
-rw-r--r-- | silk/define.h | 2 | ||||
-rw-r--r-- | silk/main.h | 2 |
9 files changed, 41 insertions, 48 deletions
diff --git a/silk/A2NLSF.c b/silk/A2NLSF.c index a739ef34..b6e2b41e 100644 --- a/silk/A2NLSF.c +++ b/silk/A2NLSF.c @@ -40,7 +40,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /* Number of binary divisions, when not in low complexity mode */ #define BIN_DIV_STEPS_A2NLSF_FIX 3 /* must be no higher than 16 - log2( LSF_COS_TAB_SZ_FIX ) */ -#define QPoly 16 #define MAX_ITERATIONS_A2NLSF_FIX 30 /* Helper function for A2NLSF(..) */ @@ -61,8 +60,8 @@ static inline void silk_A2NLSF_trans_poly( } /* Helper function for A2NLSF(..) */ /* Polynomial evaluation */ -static inline opus_int32 silk_A2NLSF_eval_poly( /* return the polynomial evaluation, in QPoly */ - opus_int32 *p, /* I Polynomial, QPoly */ +static inline opus_int32 silk_A2NLSF_eval_poly( /* return the polynomial evaluation, in Q16 */ + opus_int32 *p, /* I Polynomial, Q16 */ const opus_int32 x, /* I Evaluation point, Q12 */ const opus_int dd /* I Order */ ) @@ -70,10 +69,10 @@ static inline opus_int32 silk_A2NLSF_eval_poly( /* return the polynomial evaluat opus_int n; opus_int32 x_Q16, y32; - y32 = p[ dd ]; /* QPoly */ + y32 = p[ dd ]; /* Q16 */ x_Q16 = silk_LSHIFT( x, 4 ); for( n = dd - 1; n >= 0; n-- ) { - y32 = silk_SMLAWW( p[ n ], y32, x_Q16 ); /* QPoly */ + y32 = silk_SMLAWW( p[ n ], y32, x_Q16 ); /* Q16 */ } return y32; } @@ -88,19 +87,11 @@ static inline void silk_A2NLSF_init( opus_int k; /* Convert filter coefs to even and odd polynomials */ - P[dd] = silk_LSHIFT( 1, QPoly ); - Q[dd] = silk_LSHIFT( 1, QPoly ); + P[dd] = silk_LSHIFT( 1, 16 ); + Q[dd] = silk_LSHIFT( 1, 16 ); for( k = 0; k < dd; k++ ) { -#if( QPoly < 16 ) - P[ k ] = silk_RSHIFT_ROUND( -a_Q16[ dd - k - 1 ] - a_Q16[ dd + k ], 16 - QPoly ); /* QPoly */ - Q[ k ] = silk_RSHIFT_ROUND( -a_Q16[ dd - k - 1 ] + a_Q16[ dd + k ], 16 - QPoly ); /* QPoly */ -#elif( Qpoly == 16 ) - P[ k ] = -a_Q16[ dd - k - 1 ] - a_Q16[ dd + k ]; /* QPoly*/ - Q[ k ] = -a_Q16[ dd - k - 1 ] + a_Q16[ dd + k ]; /* QPoly*/ -#else - P[ k ] = silk_LSHIFT( -a_Q16[ dd - k - 1 ] - a_Q16[ dd + k ], QPoly - 16 ); /* QPoly */ - Q[ k ] = silk_LSHIFT( -a_Q16[ dd - k - 1 ] + a_Q16[ dd + k ], QPoly - 16 ); /* QPoly */ -#endif + P[ k ] = -a_Q16[ dd - k - 1 ] - a_Q16[ dd + k ]; /* Q16 */ + Q[ k ] = -a_Q16[ dd - k - 1 ] + a_Q16[ dd + k ]; /* Q16 */ } /* Divide out zeros as we have that for even filter orders, */ diff --git a/silk/NLSF2A.c b/silk/NLSF2A.c index b10c6901..e7fd5e67 100644 --- a/silk/NLSF2A.c +++ b/silk/NLSF2A.c @@ -137,7 +137,7 @@ void silk_NLSF2A( idx = k; } } - maxabs = silk_RSHIFT_ROUND( maxabs, QA + 1 - 12 ); /* QA+1 -> Q12 */ + maxabs = silk_RSHIFT_ROUND( maxabs, QA + 1 - 12 ); /* QA+1 -> Q12 */ if( maxabs > silk_int16_MAX ) { /* Reduce magnitude of prediction coefficients */ @@ -153,33 +153,26 @@ void silk_NLSF2A( if( i == 10 ) { /* Reached the last iteration, clip the coefficients */ for( k = 0; k < d; k++ ) { - a_Q12[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 ) ); /* QA+1 -> Q12 */ + a_Q12[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 ) ); /* QA+1 -> Q12 */ a32_QA1[ k ] = silk_LSHIFT( (opus_int32)a_Q12[ k ], QA + 1 - 12 ); } } else { for( k = 0; k < d; k++ ) { - a_Q12[ k ] = (opus_int16)silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 ); /* QA+1 -> Q12 */ + a_Q12[ k ] = (opus_int16)silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 ); /* QA+1 -> Q12 */ } } - for( i = 1; i <= MAX_LPC_STABILIZE_ITERATIONS; i++ ) { + for( i = 0; i < MAX_LPC_STABILIZE_ITERATIONS; i++ ) { 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 */ /* 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_LSHIFT( 2, i ) ); for( k = 0; k < d; k++ ) { - a_Q12[ k ] = (opus_int16)silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 ); /* QA+1 -> Q12 */ + a_Q12[ k ] = (opus_int16)silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 ); /* QA+1 -> Q12 */ } } else { break; } } - - if( i > MAX_LPC_STABILIZE_ITERATIONS ) { - /* Reached the last iteration, set coefficients to zero */ - for( k = 0; k < d; k++ ) { - a_Q12[ k ] = 0; - } - } } diff --git a/silk/NLSF_decode.c b/silk/NLSF_decode.c index 124be417..f2c2dec7 100644 --- a/silk/NLSF_decode.c +++ b/silk/NLSF_decode.c @@ -83,7 +83,7 @@ void silk_NLSF_decode( /* Unpack entropy table indices and predictor for current CB1 index */ silk_NLSF_unpack( ec_ix, pred_Q8, psNLSF_CB, NLSFIndices[ 0 ] ); - /* Trellis dequantizer */ + /* Predictive residual dequantizer */ silk_NLSF_residual_dequant( res_Q10, &NLSFIndices[ 1 ], pred_Q8, psNLSF_CB->quantStepSize_Q16, psNLSF_CB->order ); /* Weights from codebook vector */ diff --git a/silk/NLSF_unpack.c b/silk/NLSF_unpack.c index 46b29403..9db49265 100644 --- a/silk/NLSF_unpack.c +++ b/silk/NLSF_unpack.c @@ -33,7 +33,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /* Unpack predictor values and indices for entropy coding tables */ void silk_NLSF_unpack( - opus_int16 ec_ix[], /* O Indices to entropy tales [ LPC_ORDER ] */ + opus_int16 ec_ix[], /* O Indices to entropy tables [ LPC_ORDER ] */ opus_uint8 pred_Q8[], /* O LSF predictor [ LPC_ORDER ] */ const silk_NLSF_CB_struct *psNLSF_CB, /* I Codebook object */ const opus_int CB1_index /* I Index of vector in first LSF codebook */ @@ -190,7 +190,7 @@ static inline void silk_noise_shape_quantizer( opus_int i, j; opus_int32 LTP_pred_Q13, LPC_pred_Q10, n_AR_Q12, n_LTP_Q13; opus_int32 n_LF_Q12, r_Q10, rr_Q10, q1_Q0, q1_Q10, q2_Q10, rd1_Q20, rd2_Q20; - opus_int32 dither, exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10; + opus_int32 exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10; opus_int32 tmp1, tmp2, sLF_AR_shp_Q14; opus_int32 *psLPC_Q14, *shp_lag_ptr, *pred_lag_ptr; @@ -205,9 +205,6 @@ static inline void silk_noise_shape_quantizer( /* Generate dither */ NSQ->rand_seed = silk_RAND( NSQ->rand_seed ); - /* dither = rand_seed < 0 ? 0xFFFFFFFF : 0; */ - dither = silk_RSHIFT( NSQ->rand_seed, 31 ); - /* Short-term prediction */ silk_assert( predictLPCOrder == 10 || predictLPCOrder == 16 ); /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ @@ -292,7 +289,9 @@ static inline void silk_noise_shape_quantizer( r_Q10 = silk_SUB32( x_sc_Q10[ i ], tmp1 ); /* residual error Q10 */ /* Flip sign depending on dither */ - r_Q10 = r_Q10 ^ dither; + if ( NSQ->rand_seed < 0 ) { + r_Q10 = -r_Q10; + } r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 ); /* Find two quantization level candidates and measure their rate-distortion */ @@ -333,7 +332,10 @@ static inline void silk_noise_shape_quantizer( pulses[ i ] = (opus_int8)silk_RSHIFT_ROUND( q1_Q10, 10 ); /* Excitation */ - exc_Q14 = silk_LSHIFT( q1_Q10, 4 ) ^ dither; + exc_Q14 = silk_LSHIFT( q1_Q10, 4 ); + if ( NSQ->rand_seed < 0 ) { + exc_Q14 = -exc_Q14; + } /* Add predictions */ LPC_exc_Q14 = silk_ADD_LSHIFT32( exc_Q14, LTP_pred_Q13, 1 ); diff --git a/silk/NSQ_del_dec.c b/silk/NSQ_del_dec.c index 2fd2a9d1..d4ee0fbc 100644 --- a/silk/NSQ_del_dec.c +++ b/silk/NSQ_del_dec.c @@ -325,7 +325,7 @@ static inline void silk_noise_shape_quantizer_del_dec( opus_int32 Winner_rand_state; opus_int32 LTP_pred_Q14, LPC_pred_Q14, n_AR_Q14, n_LTP_Q14; opus_int32 n_LF_Q14, r_Q10, rr_Q10, rd1_Q10, rd2_Q10, RDmin_Q10, RDmax_Q10; - opus_int32 q1_Q0, q1_Q10, q2_Q10, dither, exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10; + opus_int32 q1_Q0, q1_Q10, q2_Q10, exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10; opus_int32 tmp1, tmp2, sLF_AR_shp_Q14; opus_int32 *pred_lag_ptr, *shp_lag_ptr, *psLPC_Q14; NSQ_sample_struct psSampleState[ MAX_DEL_DEC_STATES ][ 2 ]; @@ -378,9 +378,6 @@ static inline void silk_noise_shape_quantizer_del_dec( /* Generate dither */ psDD->Seed = silk_RAND( psDD->Seed ); - /* dither = rand_seed < 0 ? 0xFFFFFFFF : 0; */ - dither = silk_RSHIFT( psDD->Seed, 31 ); - /* Pointer used in short term prediction and shaping */ psLPC_Q14 = &psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 + i ]; /* Short-term prediction */ @@ -448,7 +445,9 @@ static inline void silk_noise_shape_quantizer_del_dec( r_Q10 = silk_SUB32( x_Q10[ i ], tmp1 ); /* residual error Q10 */ /* Flip sign depending on dither */ - r_Q10 = r_Q10 ^ dither; + if ( psDD->Seed < 0 ) { + r_Q10 = -r_Q10; + } r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 ); /* Find two quantization level candidates and measure their rate-distortion */ @@ -497,7 +496,10 @@ static inline void silk_noise_shape_quantizer_del_dec( /* Update states for best quantization */ /* Quantized excitation */ - exc_Q14 = silk_LSHIFT32( psSS[ 0 ].Q_Q10, 4 ) ^ dither; + exc_Q14 = silk_LSHIFT32( psSS[ 0 ].Q_Q10, 4 ); + if ( psDD->Seed < 0 ) { + exc_Q14 = -exc_Q14; + } /* Add predictions */ LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 ); @@ -513,7 +515,11 @@ static inline void silk_noise_shape_quantizer_del_dec( /* Update states for second best quantization */ /* Quantized excitation */ - exc_Q14 = silk_LSHIFT32( psSS[ 1 ].Q_Q10, 4 ) ^ dither; + exc_Q14 = silk_LSHIFT32( psSS[ 1 ].Q_Q10, 4 ); + if ( psDD->Seed < 0 ) { + exc_Q14 = -exc_Q14; + } + /* Add predictions */ LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 ); diff --git a/silk/decode_core.c b/silk/decode_core.c index 9854ccc7..ff3ab795 100644 --- a/silk/decode_core.c +++ b/silk/decode_core.c @@ -72,8 +72,9 @@ void silk_decode_core( psDec->exc_Q14[ i ] += QUANT_LEVEL_ADJUST_Q10 << 4; } psDec->exc_Q14[ i ] += offset_Q10 << 4; - if ( rand_seed < 0 ) + if( rand_seed < 0 ) { psDec->exc_Q14[ i ] = -psDec->exc_Q14[ i ]; + } rand_seed = silk_ADD32_ovflw( rand_seed, pulses[ i ] ); } diff --git a/silk/define.h b/silk/define.h index f398bf8b..3dc35959 100644 --- a/silk/define.h +++ b/silk/define.h @@ -130,7 +130,7 @@ extern "C" #define QUANT_LEVEL_ADJUST_Q10 80 /* Maximum numbers of iterations used to stabilize an LPC vector */ -#define MAX_LPC_STABILIZE_ITERATIONS 15 +#define MAX_LPC_STABILIZE_ITERATIONS 16 #define MAX_PREDICTION_POWER_GAIN 1e4f #define MAX_PREDICTION_POWER_GAIN_AFTER_RESET 1e2f diff --git a/silk/main.h b/silk/main.h index 8397384b..dd34c8a4 100644 --- a/silk/main.h +++ b/silk/main.h @@ -331,7 +331,7 @@ opus_int32 silk_NLSF_del_dec_quant( /* O Returns /* Unpack predictor values and indices for entropy coding tables */ void silk_NLSF_unpack( - opus_int16 ec_ix[], /* O Indices to entropy tales [ LPC_ORDER ] */ + opus_int16 ec_ix[], /* O Indices to entropy tables [ LPC_ORDER ] */ opus_uint8 pred_Q8[], /* O LSF predictor [ LPC_ORDER ] */ const silk_NLSF_CB_struct *psNLSF_CB, /* I Codebook object */ const opus_int CB1_index /* I Index of vector in first LSF codebook */ |