Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.xiph.org/xiph/opus.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKoen Vos <koenvos74@gmail.com>2013-11-20 17:32:32 +0400
committerJean-Marc Valin <jmvalin@jmvalin.ca>2013-11-20 17:32:32 +0400
commitc63fb978be59fd09179abe9d714ee598d888e789 (patch)
tree36deeaa6440ff80c943e19d6ab4016e29dd4ccbc /silk/VQ_WMat_EC.c
parentac31a0af4ace081404de39342eed41cf59f91e2d (diff)
Constrains accumulated pitch gain to avoid potential instability.
Signed-off-by: Jean-Marc Valin <jmvalin@jmvalin.ca>
Diffstat (limited to 'silk/VQ_WMat_EC.c')
-rw-r--r--silk/VQ_WMat_EC.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/silk/VQ_WMat_EC.c b/silk/VQ_WMat_EC.c
index c5c6f714..4b53c149 100644
--- a/silk/VQ_WMat_EC.c
+++ b/silk/VQ_WMat_EC.c
@@ -35,15 +35,17 @@ 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 *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 +54,12 @@ 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 = silk_abs( cb_row_Q7[ 0 ] ) +
+ silk_abs( cb_row_Q7[ 1 ] ) +
+ silk_abs( cb_row_Q7[ 2 ] ) +
+ silk_abs( cb_row_Q7[ 3 ] ) +
+ silk_abs( cb_row_Q7[ 4 ] );
+
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 +69,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 +114,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 */