[FFmpeg-soc] [soc]AMR-WB decoder branch, master, updated.

Marcelo Póvoa marspeoplester at gmail.com
Thu Jul 22 07:37:53 CEST 2010


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "AMR-WB decoder".

The branch, master has been updated
       via  ade74ca125016eab5a8c5766e192bd8885686b01 (commit)
       via  ee327e3dbb0cfa189db2b12dce8ea9154ade2943 (commit)
       via  5216a6b9e872b5c23c56f91011a83ac87c19b329 (commit)
       via  50f3a13500de12d7d9fb3b382965c133a9eea200 (commit)
      from  c2a8e2ad2d9c51c9d1f7b9101175db05f2fecabb (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit ade74ca125016eab5a8c5766e192bd8885686b01
Author: Marcelo Povoa <marspeoplester at gmail.com>
Date:   Thu Jul 22 02:35:50 2010 -0300

    Sketch the LP filter (6k60 mode) for the high freq band,
    up to the autocorrelation calculation

diff --git a/libavcodec/amrwbdata.h b/libavcodec/amrwbdata.h
index d16253a..7f221e4 100644
--- a/libavcodec/amrwbdata.h
+++ b/libavcodec/amrwbdata.h
@@ -25,6 +25,7 @@
 #include <stdint.h>
 
 #define LP_ORDER              16               ///< linear predictive coding filter order
+#define LP_ORDER_16k          20               ///< lpc filter order at 16kHz
 #define MIN_ISF_SPACING       (128 / 32768.0)  ///< minimum isf gap
 #define PRED_FACTOR           (1.0 / 3.0)
 #define MIN_ENERGY           -14.0             ///< initial innnovation energy (dB)
diff --git a/libavcodec/amrwbdec.c b/libavcodec/amrwbdec.c
index 58bbff6..a0bf66d 100644
--- a/libavcodec/amrwbdec.c
+++ b/libavcodec/amrwbdec.c
@@ -1038,6 +1038,50 @@ static void scaled_hb_excitation(AMRWBContext *ctx, float *hb_exc,
         hb_exc[i] *= hb_gain;
 }
 
+static float auto_correlation(float *diff_isf, float mean, int lag)
+{
+    int i;
+    float sum = 0.0;
+
+    for (i = 7; i < LP_ORDER - 2; i++) {
+        float prod = (diff_isf[i] - mean) * (diff_isf[i - lag] - mean);
+        sum += prod * prod;
+    }
+    return sum;
+}
+
+static void extrapolate_isf(float *out, float *isf)
+{
+    float diff_isf[LP_ORDER - 2], diff_mean;
+    float corr_lag[3];
+    int i, i_max_corr;
+
+    memcpy(out, isf, LP_ORDER - 1);
+    out[LP_ORDER_16k - 1] = isf[LP_ORDER - 1];
+
+    /* Calculate the difference vector */
+    for (i = 0; i < LP_ORDER - 2; i++)
+        diff_isf[i] = isf[i + 1] - isf[i];
+
+    diff_mean = 0.0;
+    for (i = 2; i < LP_ORDER - 2; i++)
+        diff_mean += diff_isf[i] / (LP_ORDER - 4);
+
+    /* Find which is the maximum autocorrelation */
+    i_max_corr = 0;
+    for (i = 0; i < 3; i++) {
+        corr_lag[i] = auto_correlation(diff_isf, diff_mean, i + 2);
+        if (corr_lag[i] > corr_lag[i_max_corr])
+            i_max_corr = i;
+    }
+    i_max_corr++;
+
+    for (i = LP_ORDER - 1; i < LP_ORDER_16k - 1; i++)
+        out[i] = isf[i - 1] + isf[i - 1 - i_max_corr]
+                            - isf[i - 2 - i_max_corr];
+    return;
+}
+
 /**
  * Update context state before the next subframe
  */

commit ee327e3dbb0cfa189db2b12dce8ea9154ade2943
Author: Marcelo Povoa <marspeoplester at gmail.com>
Date:   Thu Jul 22 02:33:20 2010 -0300

    Test: Fix ISF/ISP initialization, add new past ISF, fix typo in
    isf_set_min_dist, add ISP special case when in the first frame

diff --git a/libavcodec/amrwbdata.h b/libavcodec/amrwbdata.h
index a4404be..d16253a 100644
--- a/libavcodec/amrwbdata.h
+++ b/libavcodec/amrwbdata.h
@@ -25,8 +25,8 @@
 #include <stdint.h>
 
 #define LP_ORDER              16               ///< linear predictive coding filter order
-#define MIN_ISF_SPACING       50.0             // XXX: Taken from fixed-point 26.173, not sure
-#define PRED_FACTOR           (1.0/3.0)
+#define MIN_ISF_SPACING       (128 / 32768.0)  ///< minimum isf gap
+#define PRED_FACTOR           (1.0 / 3.0)
 #define MIN_ENERGY           -14.0             ///< initial innnovation energy (dB)
 #define ENERGY_MEAN           30.0             ///< mean innovation energy (dB) in all modes
 
@@ -1611,10 +1611,10 @@ static const int16_t isf_mean[LP_ORDER] = {
   8750,  9753, 10705, 11728, 12833, 13971, 15043,  4037
 };
 
-/* Initialization tables for the ISP vector */
-static const int16_t isp_init[LP_ORDER] = {
-  32138,  30274,  27246,  23170,  18205,  12540,   6393,    0,
-  -6393, -12540, -18205, -23170, -27246, -30274, -32138, 1475
+/* Initialization tables for the processed ISF vector */
+static const int16_t isf_init[LP_ORDER] = {
+  1024,  2048,  3072,  4096,  5120,  6144,  7168, 8192,
+  9216, 10240, 11264, 12288, 13312, 14336, 15360, 3840
 };
 
 /* Coefficients for FIR interpolation of excitation vector
diff --git a/libavcodec/amrwbdec.c b/libavcodec/amrwbdec.c
index 0281ae1..58bbff6 100644
--- a/libavcodec/amrwbdec.c
+++ b/libavcodec/amrwbdec.c
@@ -45,8 +45,9 @@ typedef struct {
     uint8_t                          fr_mode_ind; ///< mode indication field
     uint8_t                          fr_mode_req; ///< mode request field
     uint8_t                               fr_crc; ///< crc for class A bits
-    float                    isf_quant[LP_ORDER]; ///< quantized ISF vector from current frame
+    float                      isf_cur[LP_ORDER]; ///< working ISF vector from current frame
     float                   isf_q_past[LP_ORDER]; ///< quantized ISF vector of the previous frame
+    float               isf_past_final[LP_ORDER]; ///< final processed ISF vector of the prev frame
     double                      isp[4][LP_ORDER]; ///< ISP vectors from current frame
     double               isp_sub4_past[LP_ORDER]; ///< ISP vector for the 4th subframe of the previous frame
 
@@ -77,6 +78,7 @@ typedef struct {
     float          hpf_31_mem[4], hpf_400_mem[4]; ///< previous values in the high-pass filters
 
     AVLFG                                   prng; ///< random number generator for white noise excitation
+    uint8_t                          first_frame; ///< flag active in the first frame decoded
 } AMRWBContext;
 
 static av_cold int amrwb_decode_init(AVCodecContext *avctx)
@@ -88,12 +90,12 @@ static av_cold int amrwb_decode_init(AVCodecContext *avctx)
 
     av_lfg_init(&ctx->prng, 1);
 
-    ctx->excitation = &ctx->excitation_buf[PITCH_MAX + LP_ORDER + 1];
+    ctx->excitation  = &ctx->excitation_buf[PITCH_MAX + LP_ORDER + 1];
+    ctx->first_frame = 1;
+    ctx->tilt_coef   = ctx->prev_tr_gain = 0.0;
 
     for (i = 0; i < LP_ORDER; i++)
-        ctx->isp_sub4_past[i] = isp_init[i] / (float) (1 << 15);
-
-    ctx->tilt_coef = ctx->prev_tr_gain = 0.0;
+        ctx->isf_past_final[i] = isf_init[i] / (float) (1 << 15);
 
     for (i = 0; i < 4; i++)
         ctx->prediction_error[i] = MIN_ENERGY;
@@ -278,7 +280,7 @@ static void isf_set_min_dist(float *isf, float min_spacing, int size) {
     int i;
     float prev = 0.0;
 
-    for (i = 0; i < size; i++) {
+    for (i = 0; i < size - 1; i++) {
         isf[i] = FFMAX(isf[i], prev + min_spacing);
         prev = isf[i];
     }
@@ -813,7 +815,9 @@ static float stability_factor(const float *isf, const float *isf_past)
     for (i = 0; i < LP_ORDER - 1; i++)
         acc += (isf[i] - isf_past[i]) * (isf[i] - isf_past[i]);
 
-    return 1.25 - acc * 0.8 / 256;
+    // XXX: I could not understand well this part from ref code
+    // it made more sense changing the "/ 256" to "* 256"
+    return FFMAX(0.0, 1.25 - acc * 0.8 * 256);
 }
 
 /**
@@ -1073,21 +1077,27 @@ static int amrwb_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
 
     /* Decode the quantized ISF vector */
     if (ctx->fr_cur_mode == MODE_6k60) {
-        decode_isf_indices_36b(cf->isp_id, ctx->isf_quant, ctx->fr_quality);
+        decode_isf_indices_36b(cf->isp_id, ctx->isf_cur, ctx->fr_quality);
     }
     else {
-        decode_isf_indices_46b(cf->isp_id, ctx->isf_quant, ctx->fr_quality);
+        decode_isf_indices_46b(cf->isp_id, ctx->isf_cur, ctx->fr_quality);
     }
 
-    stab_fac = stability_factor(ctx->isf_quant, ctx->isf_q_past);
+    isf_add_mean_and_past(ctx->isf_cur, ctx->isf_q_past);
+    isf_set_min_dist(ctx->isf_cur, MIN_ISF_SPACING, LP_ORDER);
 
-    isf_add_mean_and_past(ctx->isf_quant, ctx->isf_q_past);
-    isf_set_min_dist(ctx->isf_quant, MIN_ISF_SPACING, LP_ORDER);
+    stab_fac = stability_factor(ctx->isf_cur, ctx->isf_past_final);
 
-    isf2isp(ctx->isf_quant, ctx->isp[3]);
+    isf2isp(ctx->isf_cur, ctx->isp[3]);
     /* Generate a ISP vector for each subframe */
+    if (ctx->first_frame) {
+        ctx->first_frame = 0;
+        memcpy(ctx->isp_sub4_past, ctx->isp[3], LP_ORDER * sizeof(double));
+    }
     interpolate_isp(ctx->isp, ctx->isp_sub4_past);
 
+    /* XXX: Tested against the ref code until here */
+
     for (sub = 0; sub < 4; sub++)
         isp2lp(ctx->isp[sub], ctx->lp_coef[sub], LP_ORDER/2);
 
@@ -1170,6 +1180,7 @@ static int amrwb_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
 
     // update state for next frame
     memcpy(ctx->isp_sub4_past, ctx->isp[3], LP_ORDER * sizeof(ctx->isp[3][0]));
+    memcpy(ctx->isf_past_final, ctx->isf_cur, LP_ORDER * sizeof(float));
 
     /* report how many samples we got */
     *data_size = 4 * AMRWB_SFR_SIZE_OUT * sizeof(float);

commit 5216a6b9e872b5c23c56f91011a83ac87c19b329
Author: Marcelo Povoa <marspeoplester at gmail.com>
Date:   Wed Jul 21 21:32:30 2010 -0300

    Fix the ISF past vector initialization, now to zero

diff --git a/libavcodec/amrwbdata.h b/libavcodec/amrwbdata.h
index 29624fa..a4404be 100644
--- a/libavcodec/amrwbdata.h
+++ b/libavcodec/amrwbdata.h
@@ -1611,12 +1611,7 @@ static const int16_t isf_mean[LP_ORDER] = {
   8750,  9753, 10705, 11728, 12833, 13971, 15043,  4037
 };
 
-/* Initialization tables for ISF and ISP vectors */
-static const int16_t isf_init[LP_ORDER] = {
-   1024,  2048,  3072,  4096,  5120,  6144,  7168, 8192,
-   9216, 10240, 11264, 12288, 13312, 14336, 15360, 3840
-};
-
+/* Initialization tables for the ISP vector */
 static const int16_t isp_init[LP_ORDER] = {
   32138,  30274,  27246,  23170,  18205,  12540,   6393,    0,
   -6393, -12540, -18205, -23170, -27246, -30274, -32138, 1475
diff --git a/libavcodec/amrwbdec.c b/libavcodec/amrwbdec.c
index 992bcdc..0281ae1 100644
--- a/libavcodec/amrwbdec.c
+++ b/libavcodec/amrwbdec.c
@@ -90,10 +90,8 @@ static av_cold int amrwb_decode_init(AVCodecContext *avctx)
 
     ctx->excitation = &ctx->excitation_buf[PITCH_MAX + LP_ORDER + 1];
 
-    for (i = 0; i < LP_ORDER; i++) {
-        ctx->isf_q_past[i]    = isf_init[i] / (float) (1 << 15);
+    for (i = 0; i < LP_ORDER; i++)
         ctx->isp_sub4_past[i] = isp_init[i] / (float) (1 << 15);
-    }
 
     ctx->tilt_coef = ctx->prev_tr_gain = 0.0;
 
@@ -262,8 +260,8 @@ static void isf_add_mean_and_past(float *isf_q, float *isf_past) {
 
     for (i = 0; i < LP_ORDER; i++) {
         tmp = isf_q[i];
-        isf_q[i] = tmp + isf_mean[i] / (float) (1<<15);
-        isf_q[i] = isf_q[i] + PRED_FACTOR * isf_past[i];
+        isf_q[i] += isf_mean[i] / (float) (1<<15);
+        isf_q[i] += PRED_FACTOR * isf_past[i];
         isf_past[i] = tmp;
     }
 }

commit 50f3a13500de12d7d9fb3b382965c133a9eea200
Author: Marcelo Povoa <marspeoplester at gmail.com>
Date:   Wed Jul 21 14:21:49 2010 -0300

    Use separate states for the high-pass filters

diff --git a/libavcodec/amrwbdec.c b/libavcodec/amrwbdec.c
index 063afc0..992bcdc 100644
--- a/libavcodec/amrwbdec.c
+++ b/libavcodec/amrwbdec.c
@@ -74,7 +74,7 @@ typedef struct {
     float samples_in[LP_ORDER + AMRWB_SUBFRAME_SIZE]; ///< floating point samples
 
     float                           demph_mem[1]; ///< previous value in the de-emphasis filter
-    float                             hpf_mem[4]; ///< previous values in the high-pass filter
+    float          hpf_31_mem[4], hpf_400_mem[4]; ///< previous values in the high-pass filters
 
     AVLFG                                   prng; ///< random number generator for white noise excitation
 } AMRWBContext;
@@ -1150,14 +1150,14 @@ static int amrwb_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
         de_emphasis(&ctx->samples_in[LP_ORDER], PREEMPH_FAC, ctx->demph_mem);
 
         high_pass_filter(&ctx->samples_in[LP_ORDER], hpf_31_coef,
-                         ctx->hpf_mem, &ctx->samples_in[LP_ORDER]);
+                         ctx->hpf_31_mem, &ctx->samples_in[LP_ORDER]);
 
         // XXX: the 5/4 upsampling for the lower band goes in here
 
 
         /* High frequency band generation */
         high_pass_filter(&ctx->samples_in[LP_ORDER], hpf_400_coef,
-                         ctx->hpf_mem, &ctx->samples_in[LP_ORDER]);
+                         ctx->hpf_400_mem, &ctx->samples_in[LP_ORDER]);
 
         hb_gain = find_hb_gain(ctx, &ctx->samples_in[LP_ORDER],
                                cur_subframe->hb_gain, cf->vad);

-----------------------------------------------------------------------

Summary of changes:
 libavcodec/amrwbdata.h |   16 +++-----
 libavcodec/amrwbdec.c  |   95 +++++++++++++++++++++++++++++++++++++-----------
 2 files changed, 80 insertions(+), 31 deletions(-)


hooks/post-receive
-- 
AMR-WB decoder


More information about the FFmpeg-soc mailing list