summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Marc Valin <jmvalin@jmvalin.ca>2013-11-21 14:43:53 -0500
committerJean-Marc Valin <jmvalin@jmvalin.ca>2013-11-21 14:43:53 -0500
commitae39180bad8a451fee2825cadb22132d4be6025d (patch)
treeaff468abec6f9623b6002525a5df2be70735c1ea
parent21b131fbe52a4e5e5c0376ceb0da627ce04e715f (diff)
parent9864c51592078072a84bf8a4776760c850dd875a (diff)
downloadopus-ae39180bad8a451fee2825cadb22132d4be6025d.tar.gz
Merge branch 'silk_pitch_fix'
-rw-r--r--silk/VQ_WMat_EC.c11
-rw-r--r--silk/fixed/find_pred_coefs_FIX.c3
-rw-r--r--silk/float/find_pred_coefs_FLP.c3
-rw-r--r--silk/float/main_FLP.h1
-rw-r--r--silk/float/wrappers_FLP.c3
-rw-r--r--silk/log2lin.c4
-rw-r--r--silk/main.h4
-rw-r--r--silk/quant_LTP_gains.c21
-rw-r--r--silk/structs.h1
-rw-r--r--silk/tables.h2
-rw-r--r--silk/tables_LTP.c24
-rw-r--r--silk/tuning_parameters.h5
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 */
/***********************/