shithub: opus

Download patch

ref: bd54e279d524f21e69e26feb4f9f340a4430c2f6
parent: ab148485dab4c8a66866d02852940bcdac19851d
author: Mark Harris <mark.hsj@gmail.com>
date: Wed Nov 16 15:03:25 EST 2016

Correct SILK encoder gain limit

Ensure that the SILK encoder's log gain is 63, not 64, when encoding
a maximum-value delta gain index of 40.  This matches the decoder
and RFC 6716 4.2.7.4, and prevents an assertion failure in the rare
case that the gain is later independently coded.

--- a/silk/gain_quant.c
+++ b/silk/gain_quant.c
@@ -76,6 +76,7 @@
             /* Accumulate deltas */
             if( ind[ k ] > double_step_size_threshold ) {
                 *prev_ind += silk_LSHIFT( ind[ k ], 1 ) - double_step_size_threshold;
+                *prev_ind = silk_min_int( *prev_ind, N_LEVELS_QGAIN - 1 );
             } else {
                 *prev_ind += ind[ k ];
             }
--- a/tests/opus_encode_regressions.c
+++ b/tests/opus_encode_regressions.c
@@ -983,6 +983,42 @@
     return 0;
 }
 
+static int silk_gain_assert(void)
+{
+    OpusEncoder *enc;
+    int err;
+    int data_len;
+    unsigned char data[1000];
+    static const short pcm1[160] = { 0 };
+    static const short pcm2[960] =
+    {
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        32767, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 32767
+    };
+
+    enc = opus_encoder_create(8000, 1, OPUS_APPLICATION_AUDIO, &err);
+    opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(3));
+    opus_encoder_ctl(enc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND));
+    opus_encoder_ctl(enc, OPUS_SET_BITRATE(6000));
+    data_len = opus_encode(enc, pcm1, 160, data, 1000);
+    assert(data_len > 0);
+
+    opus_encoder_ctl(enc, OPUS_SET_VBR(0));
+    opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(0));
+    opus_encoder_ctl(enc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_MEDIUMBAND));
+    opus_encoder_ctl(enc, OPUS_SET_BITRATE(2867));
+    data_len = opus_encode(enc, pcm2, 960, data, 1000);
+    assert(data_len > 0);
+
+    opus_encoder_destroy(enc);
+    return 0;
+}
+
 void regression_test(void)
 {
    fprintf(stderr, "Running simple tests for bugs that have been fixed previously\n");
@@ -992,4 +1028,5 @@
    surround_analysis_uninit();
    ec_enc_shrink_assert();
    ec_enc_shrink_assert2();
+   silk_gain_assert();
 }