diff options
author | Jean-Marc Valin <jmvalin@jmvalin.ca> | 2013-11-21 23:43:53 +0400 |
---|---|---|
committer | Jean-Marc Valin <jmvalin@jmvalin.ca> | 2013-11-21 23:43:53 +0400 |
commit | ae39180bad8a451fee2825cadb22132d4be6025d (patch) | |
tree | aff468abec6f9623b6002525a5df2be70735c1ea | |
parent | 21b131fbe52a4e5e5c0376ceb0da627ce04e715f (diff) | |
parent | 9864c51592078072a84bf8a4776760c850dd875a (diff) |
Merge branch 'silk_pitch_fix'
-rw-r--r-- | silk/VQ_WMat_EC.c | 11 | ||||
-rw-r--r-- | silk/fixed/find_pred_coefs_FIX.c | 3 | ||||
-rw-r--r-- | silk/float/find_pred_coefs_FLP.c | 3 | ||||
-rw-r--r-- | silk/float/main_FLP.h | 1 | ||||
-rw-r--r-- | silk/float/wrappers_FLP.c | 3 | ||||
-rw-r--r-- | silk/log2lin.c | 4 | ||||
-rw-r--r-- | silk/main.h | 4 | ||||
-rw-r--r-- | silk/quant_LTP_gains.c | 21 | ||||
-rw-r--r-- | silk/structs.h | 1 | ||||
-rw-r--r-- | silk/tables.h | 2 | ||||
-rw-r--r-- | silk/tables_LTP.c | 24 | ||||
-rw-r--r-- | silk/tuning_parameters.h | 5 |
12 files changed, 76 insertions, 6 deletions
diff --git a/silk/VQ_WMat_EC.c b/silk/VQ_WMat_EC.c index c5c6f714..13d5d34e 100644 --- a/silk/VQ_WMat_EC.c +++ b/silk/VQ_WMat_EC.c @@ -35,15 +35,18 @@ POSSIBILITY OF SUCH DAMAGE. void silk_VQ_WMat_EC( opus_int8 *ind, /* O index of best codebook vector */ opus_int32 *rate_dist_Q14, /* O best weighted quant error + mu * rate */ + opus_int *gain_Q7, /* O sum of absolute LTP coefficients */ const opus_int16 *in_Q14, /* I input vector to be quantized */ const opus_int32 *W_Q18, /* I weighting matrix */ const opus_int8 *cb_Q7, /* I codebook */ + const opus_uint8 *cb_gain_Q7, /* I codebook effective gain */ const opus_uint8 *cl_Q5, /* I code length for each codebook vector */ const opus_int mu_Q9, /* I tradeoff betw. weighted error and rate */ + const opus_int32 max_gain_Q7, /* I maximum sum of absolute LTP coefficients */ opus_int L /* I number of vectors in codebook */ ) { - opus_int k; + opus_int k, gain_tmp_Q7; const opus_int8 *cb_row_Q7; opus_int16 diff_Q14[ 5 ]; opus_int32 sum1_Q14, sum2_Q16; @@ -52,6 +55,8 @@ void silk_VQ_WMat_EC( *rate_dist_Q14 = silk_int32_MAX; cb_row_Q7 = cb_Q7; for( k = 0; k < L; k++ ) { + gain_tmp_Q7 = cb_gain_Q7[k]; + diff_Q14[ 0 ] = in_Q14[ 0 ] - silk_LSHIFT( cb_row_Q7[ 0 ], 7 ); diff_Q14[ 1 ] = in_Q14[ 1 ] - silk_LSHIFT( cb_row_Q7[ 1 ], 7 ); diff_Q14[ 2 ] = in_Q14[ 2 ] - silk_LSHIFT( cb_row_Q7[ 2 ], 7 ); @@ -61,6 +66,9 @@ void silk_VQ_WMat_EC( /* Weighted rate */ sum1_Q14 = silk_SMULBB( mu_Q9, cl_Q5[ k ] ); + /* Penalty for too large gain */ + sum1_Q14 = silk_ADD_LSHIFT32( sum1_Q14, silk_max( silk_SUB32( gain_tmp_Q7, max_gain_Q7 ), 0 ), 10 ); + silk_assert( sum1_Q14 >= 0 ); /* first row of W_Q18 */ @@ -103,6 +111,7 @@ void silk_VQ_WMat_EC( if( sum1_Q14 < *rate_dist_Q14 ) { *rate_dist_Q14 = sum1_Q14; *ind = (opus_int8)k; + *gain_Q7 = gain_tmp_Q7; } /* Go to next cbk vector */ diff --git a/silk/fixed/find_pred_coefs_FIX.c b/silk/fixed/find_pred_coefs_FIX.c index 70d0279a..5c22f828 100644 --- a/silk/fixed/find_pred_coefs_FIX.c +++ b/silk/fixed/find_pred_coefs_FIX.c @@ -93,7 +93,7 @@ void silk_find_pred_coefs_FIX( /* Quantize LTP gain parameters */ silk_quant_LTP_gains( psEncCtrl->LTPCoef_Q14, psEnc->sCmn.indices.LTPIndex, &psEnc->sCmn.indices.PERIndex, - WLTP, psEnc->sCmn.mu_LTP_Q9, psEnc->sCmn.LTPQuantLowComplexity, psEnc->sCmn.nb_subfr); + &psEnc->sCmn.sum_log_gain_Q7, WLTP, psEnc->sCmn.mu_LTP_Q9, psEnc->sCmn.LTPQuantLowComplexity, psEnc->sCmn.nb_subfr); /* Control LTP scaling */ silk_LTP_scale_ctrl_FIX( psEnc, psEncCtrl, condCoding ); @@ -118,6 +118,7 @@ void silk_find_pred_coefs_FIX( silk_memset( psEncCtrl->LTPCoef_Q14, 0, psEnc->sCmn.nb_subfr * LTP_ORDER * sizeof( opus_int16 ) ); psEncCtrl->LTPredCodGain_Q7 = 0; + psEnc->sCmn.sum_log_gain_Q7 = 0; } /* Limit on total predictive coding gain */ diff --git a/silk/float/find_pred_coefs_FLP.c b/silk/float/find_pred_coefs_FLP.c index 0c6f0d6b..ea2c6c43 100644 --- a/silk/float/find_pred_coefs_FLP.c +++ b/silk/float/find_pred_coefs_FLP.c @@ -67,7 +67,7 @@ void silk_find_pred_coefs_FLP( /* Quantize LTP gain parameters */ silk_quant_LTP_gains_FLP( psEncCtrl->LTPCoef, psEnc->sCmn.indices.LTPIndex, &psEnc->sCmn.indices.PERIndex, - WLTP, psEnc->sCmn.mu_LTP_Q9, psEnc->sCmn.LTPQuantLowComplexity, psEnc->sCmn.nb_subfr ); + &psEnc->sCmn.sum_log_gain_Q7, WLTP, psEnc->sCmn.mu_LTP_Q9, psEnc->sCmn.LTPQuantLowComplexity, psEnc->sCmn.nb_subfr ); /* Control LTP scaling */ silk_LTP_scale_ctrl_FLP( psEnc, psEncCtrl, condCoding ); @@ -90,6 +90,7 @@ void silk_find_pred_coefs_FLP( } silk_memset( psEncCtrl->LTPCoef, 0, psEnc->sCmn.nb_subfr * LTP_ORDER * sizeof( silk_float ) ); psEncCtrl->LTPredCodGain = 0.0f; + psEnc->sCmn.sum_log_gain_Q7 = 0; } /* Limit on total predictive coding gain */ diff --git a/silk/float/main_FLP.h b/silk/float/main_FLP.h index 71d58c20..fb553b61 100644 --- a/silk/float/main_FLP.h +++ b/silk/float/main_FLP.h @@ -201,6 +201,7 @@ void silk_quant_LTP_gains_FLP( silk_float B[ MAX_NB_SUBFR * LTP_ORDER ], /* I/O (Un-)quantized LTP gains */ opus_int8 cbk_index[ MAX_NB_SUBFR ], /* O Codebook index */ opus_int8 *periodicity_index, /* O Periodicity index */ + opus_int32 *sum_log_gain_Q7, /* I/O Cumulative max prediction gain */ const silk_float W[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* I Error weights */ const opus_int mu_Q10, /* I Mu value (R/D tradeoff) */ const opus_int lowComplexity, /* I Flag for low complexity */ diff --git a/silk/float/wrappers_FLP.c b/silk/float/wrappers_FLP.c index 0d33d9e5..350599b2 100644 --- a/silk/float/wrappers_FLP.c +++ b/silk/float/wrappers_FLP.c @@ -175,6 +175,7 @@ void silk_quant_LTP_gains_FLP( silk_float B[ MAX_NB_SUBFR * LTP_ORDER ], /* I/O (Un-)quantized LTP gains */ opus_int8 cbk_index[ MAX_NB_SUBFR ], /* O Codebook index */ opus_int8 *periodicity_index, /* O Periodicity index */ + opus_int32 *sum_log_gain_Q7, /* I/O Cumulative max prediction gain */ const silk_float W[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* I Error weights */ const opus_int mu_Q10, /* I Mu value (R/D tradeoff) */ const opus_int lowComplexity, /* I Flag for low complexity */ @@ -192,7 +193,7 @@ void silk_quant_LTP_gains_FLP( W_Q18[ i ] = (opus_int32)silk_float2int( W[ i ] * 262144.0f ); } - silk_quant_LTP_gains( B_Q14, cbk_index, periodicity_index, W_Q18, mu_Q10, lowComplexity, nb_subfr ); + silk_quant_LTP_gains( B_Q14, cbk_index, periodicity_index, sum_log_gain_Q7, W_Q18, mu_Q10, lowComplexity, nb_subfr ); for( i = 0; i < nb_subfr * LTP_ORDER; i++ ) { B[ i ] = (silk_float)B_Q14[ i ] * ( 1.0f / 16384.0f ); diff --git a/silk/log2lin.c b/silk/log2lin.c index 07d97a95..a692e009 100644 --- a/silk/log2lin.c +++ b/silk/log2lin.c @@ -41,7 +41,9 @@ opus_int32 silk_log2lin( if( inLog_Q7 < 0 ) { return 0; - } + } else if ( inLog_Q7 >= 3967 ) { + return silk_int32_MAX; + } out = silk_LSHIFT( 1, silk_RSHIFT( inLog_Q7, 7 ) ); frac_Q7 = inLog_Q7 & 0x7F; diff --git a/silk/main.h b/silk/main.h index 8676316e..2bdf8978 100644 --- a/silk/main.h +++ b/silk/main.h @@ -204,6 +204,7 @@ void silk_quant_LTP_gains( opus_int16 B_Q14[ MAX_NB_SUBFR * LTP_ORDER ], /* I/O (un)quantized LTP gains */ opus_int8 cbk_index[ MAX_NB_SUBFR ], /* O Codebook Index */ opus_int8 *periodicity_index, /* O Periodicity Index */ + opus_int32 *sum_gain_dB_Q7, /* I/O Cumulative max prediction gain */ const opus_int32 W_Q18[ MAX_NB_SUBFR*LTP_ORDER*LTP_ORDER ], /* I Error Weights in Q18 */ opus_int mu_Q9, /* I Mu value (R/D tradeoff) */ opus_int lowComplexity, /* I Flag for low complexity */ @@ -214,11 +215,14 @@ void silk_quant_LTP_gains( void silk_VQ_WMat_EC( opus_int8 *ind, /* O index of best codebook vector */ opus_int32 *rate_dist_Q14, /* O best weighted quant error + mu * rate */ + opus_int *gain_Q7, /* O sum of absolute LTP coefficients */ const opus_int16 *in_Q14, /* I input vector to be quantized */ const opus_int32 *W_Q18, /* I weighting matrix */ const opus_int8 *cb_Q7, /* I codebook */ + const opus_uint8 *cb_gain_Q7, /* I codebook effective gain */ const opus_uint8 *cl_Q5, /* I code length for each codebook vector */ const opus_int mu_Q9, /* I tradeoff betw. weighted error and rate */ + const opus_int32 max_gain_Q7, /* I maximum sum of absolute LTP coefficients */ opus_int L /* I number of vectors in codebook */ ); diff --git a/silk/quant_LTP_gains.c b/silk/quant_LTP_gains.c index 43b43cb8..fd0870da 100644 --- a/silk/quant_LTP_gains.c +++ b/silk/quant_LTP_gains.c @@ -30,11 +30,13 @@ POSSIBILITY OF SUCH DAMAGE. #endif #include "main.h" +#include "tuning_parameters.h" void silk_quant_LTP_gains( opus_int16 B_Q14[ MAX_NB_SUBFR * LTP_ORDER ], /* I/O (un)quantized LTP gains */ opus_int8 cbk_index[ MAX_NB_SUBFR ], /* O Codebook Index */ opus_int8 *periodicity_index, /* O Periodicity Index */ + opus_int32 *sum_log_gain_Q7, /* I/O Cumulative max prediction gain */ const opus_int32 W_Q18[ MAX_NB_SUBFR*LTP_ORDER*LTP_ORDER ], /* I Error Weights in Q18 */ opus_int mu_Q9, /* I Mu value (R/D tradeoff) */ opus_int lowComplexity, /* I Flag for low complexity */ @@ -45,18 +47,26 @@ void silk_quant_LTP_gains( opus_int8 temp_idx[ MAX_NB_SUBFR ]; const opus_uint8 *cl_ptr_Q5; const opus_int8 *cbk_ptr_Q7; + const opus_uint8 *cbk_gain_ptr_Q7; const opus_int16 *b_Q14_ptr; const opus_int32 *W_Q18_ptr; opus_int32 rate_dist_Q14_subfr, rate_dist_Q14, min_rate_dist_Q14; + opus_int32 sum_log_gain_tmp_Q7, best_sum_log_gain_Q7, max_gain_Q7, gain_Q7; /***************************************************/ /* iterate over different codebooks with different */ /* rates/distortions, and choose best */ /***************************************************/ min_rate_dist_Q14 = silk_int32_MAX; + best_sum_log_gain_Q7 = 0; for( k = 0; k < 3; k++ ) { + /* Safety margin for pitch gain control, to take into account factors + such as state rescaling/rewhitening. */ + opus_int32 gain_safety = SILK_FIX_CONST( 0.4, 7 ); + cl_ptr_Q5 = silk_LTP_gain_BITS_Q5_ptrs[ k ]; cbk_ptr_Q7 = silk_LTP_vq_ptrs_Q7[ k ]; + cbk_gain_ptr_Q7 = silk_LTP_vq_gain_ptrs_Q7[ k ]; cbk_size = silk_LTP_vq_sizes[ k ]; /* Set up pointer to first subframe */ @@ -64,19 +74,28 @@ void silk_quant_LTP_gains( b_Q14_ptr = B_Q14; rate_dist_Q14 = 0; + sum_log_gain_tmp_Q7 = *sum_log_gain_Q7; for( j = 0; j < nb_subfr; j++ ) { + max_gain_Q7 = silk_log2lin( ( SILK_FIX_CONST( MAX_SUM_LOG_GAIN_DB / 6.0, 7 ) - sum_log_gain_tmp_Q7 ) + + SILK_FIX_CONST( 7, 7 ) ) - gain_safety; + silk_VQ_WMat_EC( &temp_idx[ j ], /* O index of best codebook vector */ &rate_dist_Q14_subfr, /* O best weighted quantization error + mu * rate */ + &gain_Q7, /* O sum of absolute LTP coefficients */ b_Q14_ptr, /* I input vector to be quantized */ W_Q18_ptr, /* I weighting matrix */ cbk_ptr_Q7, /* I codebook */ + cbk_gain_ptr_Q7, /* I codebook effective gains */ cl_ptr_Q5, /* I code length for each codebook vector */ mu_Q9, /* I tradeoff between weighted error and rate */ + max_gain_Q7, /* I maximum sum of absolute LTP coefficients */ cbk_size /* I number of vectors in codebook */ ); rate_dist_Q14 = silk_ADD_POS_SAT32( rate_dist_Q14, rate_dist_Q14_subfr ); + sum_log_gain_tmp_Q7 = silk_max(0, sum_log_gain_tmp_Q7 + + silk_lin2log( gain_safety + gain_Q7 ) - SILK_FIX_CONST( 7, 7 )); b_Q14_ptr += LTP_ORDER; W_Q18_ptr += LTP_ORDER * LTP_ORDER; @@ -89,6 +108,7 @@ void silk_quant_LTP_gains( min_rate_dist_Q14 = rate_dist_Q14; *periodicity_index = (opus_int8)k; silk_memcpy( cbk_index, temp_idx, nb_subfr * sizeof( opus_int8 ) ); + best_sum_log_gain_Q7 = sum_log_gain_tmp_Q7; } /* Break early in low-complexity mode if rate distortion is below threshold */ @@ -103,5 +123,6 @@ void silk_quant_LTP_gains( B_Q14[ j * LTP_ORDER + k ] = silk_LSHIFT( cbk_ptr_Q7[ cbk_index[ j ] * LTP_ORDER + k ], 7 ); } } + *sum_log_gain_Q7 = best_sum_log_gain_Q7; } diff --git a/silk/structs.h b/silk/structs.h index aa84a528..1826b36a 100644 --- a/silk/structs.h +++ b/silk/structs.h @@ -171,6 +171,7 @@ typedef struct { opus_int32 pitchEstimationThreshold_Q16; /* Threshold for pitch estimator */ opus_int LTPQuantLowComplexity; /* Flag for low complexity LTP quantization */ opus_int mu_LTP_Q9; /* Rate-distortion tradeoff in LTP quantization */ + opus_int32 sum_log_gain_Q7; /* Cumulative max prediction gain */ opus_int NLSF_MSVQ_Survivors; /* Number of survivors in NLSF MSVQ */ opus_int first_frame_after_reset; /* Flag for deactivating NLSF interpolation, pitch prediction */ opus_int controlled_since_last_payload; /* Flag for ensuring codec_control only runs once per packet */ diff --git a/silk/tables.h b/silk/tables.h index 18bf9f2d..a91431e8 100644 --- a/silk/tables.h +++ b/silk/tables.h @@ -78,6 +78,8 @@ extern const opus_uint8 * const silk_LTP_gain_iCDF_ptrs[ NB_LTP_CBKS ]; extern const opus_uint8 * const silk_LTP_gain_BITS_Q5_ptrs[ NB_LTP_CBKS ]; /* 3 */ extern const opus_int16 silk_LTP_gain_middle_avg_RD_Q14; extern const opus_int8 * const silk_LTP_vq_ptrs_Q7[ NB_LTP_CBKS ]; /* 168 */ +extern const opus_uint8 * const silk_LTP_vq_gain_ptrs_Q7[NB_LTP_CBKS]; + extern const opus_int8 silk_LTP_vq_sizes[ NB_LTP_CBKS ]; /* 3 */ extern const opus_uint8 silk_LTPscale_iCDF[ 3 ]; /* 4 */ diff --git a/silk/tables_LTP.c b/silk/tables_LTP.c index b0cff443..0e6a0254 100644 --- a/silk/tables_LTP.c +++ b/silk/tables_LTP.c @@ -267,6 +267,30 @@ const opus_int8 * const silk_LTP_vq_ptrs_Q7[NB_LTP_CBKS] = { (opus_int8 *)&silk_LTP_gain_vq_2[0][0] }; +/* Maximum frequency-dependent response of the pitch taps above, + computed as max(abs(freqz(taps))) */ +static const opus_uint8 silk_LTP_gain_vq_0_gain[8] = { + 46, 2, 90, 87, 93, 91, 82, 98 +}; + +static const opus_uint8 silk_LTP_gain_vq_1_gain[16] = { + 109, 120, 118, 12, 113, 115, 117, 119, + 99, 59, 87, 111, 63, 111, 112, 80 +}; + +static const opus_uint8 silk_LTP_gain_vq_2_gain[32] = { + 126, 124, 125, 124, 129, 121, 126, 23, + 132, 127, 127, 127, 126, 127, 122, 133, + 130, 134, 101, 118, 119, 145, 126, 86, + 124, 120, 123, 119, 170, 173, 107, 109 +}; + +const opus_uint8 * const silk_LTP_vq_gain_ptrs_Q7[NB_LTP_CBKS] = { + &silk_LTP_gain_vq_0_gain[0], + &silk_LTP_gain_vq_1_gain[0], + &silk_LTP_gain_vq_2_gain[0] +}; + const opus_int8 silk_LTP_vq_sizes[NB_LTP_CBKS] = { 8, 16, 32 }; diff --git a/silk/tuning_parameters.h b/silk/tuning_parameters.h index bf4f63f0..e1057bba 100644 --- a/silk/tuning_parameters.h +++ b/silk/tuning_parameters.h @@ -50,7 +50,7 @@ extern "C" /* Linear prediction */ /*********************/ -/* LPC analysis defines: regularization and bandwidth expansion */ +/* LPC analysis regularization */ #define FIND_LPC_COND_FAC 1e-5f /* LTP analysis defines */ @@ -63,6 +63,9 @@ extern "C" #define MU_LTP_QUANT_MB 0.025f #define MU_LTP_QUANT_WB 0.02f +/* Max cumulative LTP gain */ +#define MAX_SUM_LOG_GAIN_DB 250.0f + /***********************/ /* High pass filtering */ /***********************/ |