changeset 10530:d428e57f14c6 libavcodec

Add long-term prediction to the ALS decoder.
author thilo.borgmann
date Sat, 14 Nov 2009 06:29:19 +0000
parents f8fc0a56745e
children 142645a57180
files als_data.h alsdec.c
diffstat 2 files changed, 55 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/als_data.h	Sat Nov 14 00:25:48 2009 +0000
+++ b/als_data.h	Sat Nov 14 06:29:19 2009 +0000
@@ -92,4 +92,14 @@
 };
 
 
+/** Gain values of p(0) for long-term prediction.
+ *  To be indexed by the Rice coded indices.
+ */
+static const uint8_t ltp_gain_values [4][4] = {
+    { 0,  8, 16,  24},
+    {32, 40, 48,  56},
+    {64, 70, 76,  82},
+    {88, 92, 96, 100}
+};
+
 #endif /* AVCODEC_ALS_DATA_H */
--- a/alsdec.c	Sat Nov 14 00:25:48 2009 +0000
+++ b/alsdec.c	Sat Nov 14 06:29:19 2009 +0000
@@ -78,6 +78,7 @@
     unsigned int frame_id;          ///< the frame ID / number of the current frame
     unsigned int js_switch;         ///< if true, joint-stereo decoding is enforced
     unsigned int num_blocks;        ///< number of blocks used in the current frame
+    int ltp_lag_length;             ///< number of bits used for ltp lag value
     int32_t *quant_cof;             ///< quantized parcor coefficients
     int32_t *lpc_cof;               ///< coefficients of the direct form prediction filter
     int32_t *prev_raw_samples;      ///< contains unshifted raw samples from the previous block
@@ -270,7 +271,6 @@
     }
 
     MISSING_ERR(sconf->floating,             "Floating point decoding",     -1);
-    MISSING_ERR(sconf->long_term_prediction, "Long-term prediction",        -1);
     MISSING_ERR(sconf->bgmc,                 "BGMC entropy decoding",       -1);
     MISSING_ERR(sconf->mc_coding,            "Multi-channel correlation",   -1);
     MISSING_ERR(sconf->rlslms,               "Adaptive RLS-LMS prediction", -1);
@@ -443,6 +443,9 @@
     int          smp        = 0;
     int          sb, store_prev_samples;
     int64_t      y;
+    int          use_ltp    = 0;
+    int          ltp_lag    = 0;
+    int          ltp_gain[5];
 
     *js_blocks  = get_bits1(gb);
 
@@ -540,7 +543,23 @@
         }
     }
 
-    // TODO: LTP mode
+    // read LTP gain and lag values
+    if (sconf->long_term_prediction) {
+        use_ltp = get_bits1(gb);
+
+        if (use_ltp) {
+            ltp_gain[0]   = decode_rice(gb, 1) << 3;
+            ltp_gain[1]   = decode_rice(gb, 2) << 3;
+
+            ltp_gain[2]   = ltp_gain_values[get_unary(gb, 0, 4)][get_bits(gb, 2)];
+
+            ltp_gain[3]   = decode_rice(gb, 2) << 3;
+            ltp_gain[4]   = decode_rice(gb, 1) << 3;
+
+            ltp_lag       = get_bits(gb, ctx->ltp_lag_length);
+            ltp_lag      += FFMAX(4, opt_order + 1);
+        }
+    }
 
     // read first value and residuals in case of a random access block
     if (ra_block) {
@@ -565,6 +584,26 @@
                 *current_res++ = decode_rice(gb, s[sb]);
      }
 
+    // reverse long-term prediction
+    if (use_ltp) {
+        int ltp_smp;
+
+        for (ltp_smp = FFMAX(ltp_lag - 2, 0); ltp_smp < block_length; ltp_smp++) {
+            int center = ltp_smp - ltp_lag;
+            int begin  = FFMAX(0, center - 2);
+            int end    = center + 3;
+            int tab    = 5 - (end - begin);
+            int base;
+
+            y = 1 << 6;
+
+            for (base = begin; base < end; base++, tab++)
+                y += MUL64(ltp_gain[tab], raw_samples[base]);
+
+            raw_samples[ltp_smp] += y >> 7;
+        }
+    }
+
     // reconstruct all samples from residuals
     if (ra_block) {
         for (smp = 0; smp < opt_order; smp++) {
@@ -949,6 +988,10 @@
         avctx->bits_per_raw_sample = (sconf->resolution + 1) * 8;
     }
 
+    // set lag value for long-term prediction
+    ctx->ltp_lag_length = 8 + (avctx->sample_rate >=  96000) +
+                              (avctx->sample_rate >= 192000);
+
     avctx->frame_size = sconf->frame_length;
     channel_size      = sconf->frame_length + sconf->max_order;